Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/netinet Implement RFC 5227 2.4 Ongoing Conflict Detectio...
details: https://anonhg.NetBSD.org/src/rev/689ccf915c9a
branches: trunk
changeset: 818384:689ccf915c9a
user: roy <roy%NetBSD.org@localhost>
date: Tue Oct 11 13:59:30 2016 +0000
description:
Implement RFC 5227 2.4 Ongoing Conflict Detection and Address Defence.
If ip_dad_count is 0, then the conflict is just logged and the address
is not marked as duplicated.
diffstat:
sys/netinet/if_arp.c | 83 +++++++++++++++++++++++----------------------------
sys/netinet/in_var.h | 3 +-
2 files changed, 40 insertions(+), 46 deletions(-)
diffs (153 lines):
diff -r a24c2885f321 -r 689ccf915c9a sys/netinet/if_arp.c
--- a/sys/netinet/if_arp.c Tue Oct 11 13:39:34 2016 +0000
+++ b/sys/netinet/if_arp.c Tue Oct 11 13:59:30 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_arp.c,v 1.229 2016/10/11 12:32:30 roy Exp $ */
+/* $NetBSD: if_arp.c,v 1.230 2016/10/11 13:59:30 roy Exp $ */
/*-
* Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
@@ -68,7 +68,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.229 2016/10/11 12:32:30 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.230 2016/10/11 13:59:30 roy Exp $");
#ifdef _KERNEL_OPT
#include "opt_ddb.h"
@@ -178,7 +178,7 @@
static void arp_dad_timer(struct ifaddr *);
static void arp_dad_start(struct ifaddr *);
static void arp_dad_stop(struct ifaddr *);
-static void arp_dad_duplicated(struct ifaddr *);
+static void arp_dad_duplicated(struct ifaddr *, const char *);
static void arp_init_llentry(struct ifnet *, struct llentry *);
#if NTOKEN > 0
@@ -1133,16 +1133,13 @@
if (in_nullhost(itaddr))
ARP_STATINC(ARP_STAT_RCVZEROTPA);
- /* DAD check, RFC 5227 2.1.1, Probe Details */
+ /* DAD check, RFC 5227 */
if (in_hosteq(isaddr, myaddr) ||
(in_nullhost(isaddr) && in_hosteq(itaddr, myaddr)))
{
- /* If our address is tentative, mark it as duplicated */
- if (ia->ia4_flags & IN_IFF_TENTATIVE)
- arp_dad_duplicated((struct ifaddr *)ia);
- /* If our address is unuseable, don't reply */
- if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED))
- goto out;
+ arp_dad_duplicated((struct ifaddr *)ia,
+ lla_snprintf(ar_sha(ah), ah->ar_hln));
+ goto out;
}
/*
@@ -1156,14 +1153,6 @@
if (in_nullhost(isaddr))
goto reply;
- if (in_hosteq(isaddr, myaddr)) {
- log(LOG_ERR,
- "duplicate IP address %s sent from link address %s\n",
- in_fmtaddr(isaddr), lla_snprintf(ar_sha(ah), ah->ar_hln));
- itaddr = myaddr;
- goto reply;
- }
-
if (in_hosteq(itaddr, myaddr))
la = arpcreate(ifp, m, &isaddr, NULL, 1);
else
@@ -1774,41 +1763,45 @@
}
static void
-arp_dad_duplicated(struct ifaddr *ifa)
+arp_dad_duplicated(struct ifaddr *ifa, const char *sha)
{
struct in_ifaddr *ia = (struct in_ifaddr *)ifa;
- struct ifnet *ifp;
- struct dadq *dp;
+ struct ifnet *ifp = ifa->ifa_ifp;
+ const char *iastr = in_fmtaddr(ia->ia_addr.sin_addr);
- mutex_enter(&arp_dad_lock);
- dp = arp_dad_find(ifa);
- if (dp == NULL) {
- mutex_exit(&arp_dad_lock);
- /* DAD seems to be stopping, so do nothing. */
+ if (ia->ia4_flags & (IN_IFF_TENTATIVE|IN_IFF_DUPLICATED)) {
+ log(LOG_ERR,
+ "%s: DAD duplicate address %s from %s\n",
+ if_name(ifp), iastr, sha);
+ } else if (ia->ia_dad_defended == 0 ||
+ ia->ia_dad_defended < time_uptime - DEFEND_INTERVAL) {
+ ia->ia_dad_defended = time_uptime;
+ arpannounce1(ifa);
+ log(LOG_ERR,
+ "%s: DAD defended address %s from %s\n",
+ if_name(ifp), iastr, sha);
return;
+ } else {
+ /* If DAD is disabled, just report the duplicate. */
+ if (ip_dad_count == 0) {
+ log(LOG_ERR,
+ "%s: DAD ignoring duplicate address %s from %s\n",
+ if_name(ifp), iastr, sha);
+ return;
+ }
+ log(LOG_ERR,
+ "%s: DAD defence failed for %s from %s\n",
+ if_name(ifp), iastr, sha);
}
- ifp = ifa->ifa_ifp;
- log(LOG_ERR,
- "%s: DAD detected duplicate IPv4 address %s: ARP out=%d\n",
- if_name(ifp), in_fmtaddr(ia->ia_addr.sin_addr),
- dp->dad_arp_ocount);
+ arp_dad_stop(ifa);
ia->ia4_flags &= ~IN_IFF_TENTATIVE;
- ia->ia4_flags |= IN_IFF_DUPLICATED;
-
- /* We are done with DAD, with duplicated address found. (failure) */
- arp_dad_stoptimer(dp);
-
- /* Inform the routing socket that DAD has completed */
- rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
-
- TAILQ_REMOVE(&dadq, dp, dad_list);
- mutex_exit(&arp_dad_lock);
-
- free(dp, M_IPARP);
- dp = NULL;
- ifafree(ifa);
+ if ((ia->ia4_flags & IN_IFF_DUPLICATED) == 0) {
+ ia->ia4_flags |= IN_IFF_DUPLICATED;
+ /* Inform the routing socket of the duplicate address */
+ rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL);
+ }
}
/*
diff -r a24c2885f321 -r 689ccf915c9a sys/netinet/in_var.h
--- a/sys/netinet/in_var.h Tue Oct 11 13:39:34 2016 +0000
+++ b/sys/netinet/in_var.h Tue Oct 11 13:59:30 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: in_var.h,v 1.87 2016/09/29 15:18:18 roy Exp $ */
+/* $NetBSD: in_var.h,v 1.88 2016/10/11 13:59:30 roy Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -107,6 +107,7 @@
int ia4_flags; /* address flags */
void (*ia_dad_start) (struct ifaddr *); /* DAD start function */
void (*ia_dad_stop) (struct ifaddr *); /* DAD stop function */
+ time_t ia_dad_defended; /* last time of DAD defence */
#ifdef _KERNEL
struct pslist_entry ia_hash_pslist_entry;
Home |
Main Index |
Thread Index |
Old Index