Module Name: src Committed By: roy Date: Sat May 16 12:12:46 UTC 2015
Modified Files: src/sys/netinet: if_arp.c if_inarp.h in.c in_var.h Log Message: Separate ARP handling DAD from inet. This is done by signalling the intent to try tentative addresses and then clearing the intent once the address is setup. When the ARP handler is installed (arp_ifinit) then it adds dad start and stop functions to the address which are used instead of calling ARP directly. To generate a diff of this commit: cvs rdiff -u -r1.164 -r1.165 src/sys/netinet/if_arp.c cvs rdiff -u -r1.45 -r1.46 src/sys/netinet/if_inarp.h cvs rdiff -u -r1.155 -r1.156 src/sys/netinet/in.c cvs rdiff -u -r1.71 -r1.72 src/sys/netinet/in_var.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/if_arp.c diff -u src/sys/netinet/if_arp.c:1.164 src/sys/netinet/if_arp.c:1.165 --- src/sys/netinet/if_arp.c:1.164 Sun May 3 10:44:04 2015 +++ src/sys/netinet/if_arp.c Sat May 16 12:12:46 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: if_arp.c,v 1.164 2015/05/03 10:44:04 justin Exp $ */ +/* $NetBSD: if_arp.c,v 1.165 2015/05/16 12:12:46 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.164 2015/05/03 10:44:04 justin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.165 2015/05/16 12:12:46 roy Exp $"); #include "opt_ddb.h" #include "opt_inet.h" @@ -164,6 +164,8 @@ static void in_arpinput(struct mbuf *); static void arp_drainstub(void); 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 *); LIST_HEAD(llinfo_arpq, llinfo_arp) llinfo_arp; @@ -1417,6 +1419,13 @@ arp_ifinit(struct ifnet *ifp, struct ifa ifa->ifa_rtrequest = arp_rtrequest; ifa->ifa_flags |= RTF_CLONING; + + /* ARP will handle DAD for this address. */ + if (ia->ia4_flags & IN_IFF_TRYTENTATIVE) { + ia->ia4_flags |= IN_IFF_TENTATIVE; + ia->ia_dad_start = arp_dad_start; + ia->ia_dad_stop = arp_dad_stop; + } } TAILQ_HEAD(dadq_head, dadq); @@ -1487,7 +1496,7 @@ arp_dad_output(struct dadq *dp, struct i /* * Start Duplicate Address Detection (DAD) for specified interface address. */ -void +static void arp_dad_start(struct ifaddr *ifa) { struct in_ifaddr *ia = (struct in_ifaddr *)ifa; @@ -1559,7 +1568,7 @@ arp_dad_start(struct ifaddr *ifa) /* * terminate DAD unconditionally. used for address removals. */ -void +static void arp_dad_stop(struct ifaddr *ifa) { struct dadq *dp; Index: src/sys/netinet/if_inarp.h diff -u src/sys/netinet/if_inarp.h:1.45 src/sys/netinet/if_inarp.h:1.46 --- src/sys/netinet/if_inarp.h:1.45 Sat May 2 14:41:32 2015 +++ src/sys/netinet/if_inarp.h Sat May 16 12:12:46 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: if_inarp.h,v 1.45 2015/05/02 14:41:32 roy Exp $ */ +/* $NetBSD: if_inarp.h,v 1.46 2015/05/16 12:12:46 roy Exp $ */ /* * Copyright (c) 1982, 1986, 1993 @@ -85,9 +85,6 @@ void arp_drain(void); int arpioctl(u_long, void *); void arpwhohas(struct ifnet *, struct in_addr *); -void arp_dad_start(struct ifaddr *); -void arp_dad_stop(struct ifaddr *); - void revarpinput(struct mbuf *); void in_revarpinput(struct mbuf *); void revarprequest(struct ifnet *); Index: src/sys/netinet/in.c diff -u src/sys/netinet/in.c:1.155 src/sys/netinet/in.c:1.156 --- src/sys/netinet/in.c:1.155 Tue May 5 08:52:51 2015 +++ src/sys/netinet/in.c Sat May 16 12:12:46 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: in.c,v 1.155 2015/05/05 08:52:51 roy Exp $ */ +/* $NetBSD: in.c,v 1.156 2015/05/16 12:12:46 roy Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.155 2015/05/05 08:52:51 roy Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in.c,v 1.156 2015/05/16 12:12:46 roy Exp $"); #include "arp.h" #include "opt_inet.h" @@ -664,10 +664,9 @@ in_purgeaddr(struct ifaddr *ifa) struct ifnet *ifp = ifa->ifa_ifp; struct in_ifaddr *ia = (void *) ifa; -#if NARP /* stop DAD processing */ - arp_dad_stop(ifa); -#endif + if (ia->ia_dad_stop != NULL) + ia->ia_dad_stop(ifa); in_ifscrub(ifp, ia); in_ifremlocal(ifa); @@ -905,14 +904,13 @@ in_ifinit(struct ifnet *ifp, struct in_i ia->ia_addr = *sin; LIST_INSERT_HEAD(&IN_IFADDR_HASH(ia->ia_addr.sin_addr.s_addr), ia, ia_hash); - /* Set IN_IFF flags early for arp_ifinit() */ + /* Set IN_IFF flags early for if_addr_init() */ if (hostIsNew && if_do_dad(ifp) && !in_nullhost(ia->ia_addr.sin_addr)) { if (ifp->if_link_state == LINK_STATE_DOWN) ia->ia4_flags |= IN_IFF_DETACHED; -#if NARP else - ia->ia4_flags |= IN_IFF_TENTATIVE; -#endif + /* State the intent to try DAD if possible */ + ia->ia4_flags |= IN_IFF_TRYTENTATIVE; } /* @@ -922,7 +920,10 @@ in_ifinit(struct ifnet *ifp, struct in_i */ if ((error = if_addr_init(ifp, &ia->ia_ifa, true)) != 0) goto bad; + /* Now clear the try tentative flag, it's job is done. */ + ia->ia4_flags &= ~IN_IFF_TRYTENTATIVE; splx(s); + if (scrub) { ia->ia_ifa.ifa_addr = sintosa(&oldaddr); in_ifscrub(ifp, ia); @@ -984,12 +985,10 @@ in_ifinit(struct ifnet *ifp, struct in_i ia->ia_allhosts = in_addmulti(&addr, ifp); } -#if NARP if (hostIsNew && if_do_dad(ifp) && !in_nullhost(ia->ia_addr.sin_addr) && ia->ia4_flags & IN_IFF_TENTATIVE) - arp_dad_start((struct ifaddr *)ia); -#endif + ia->ia_dad_start((struct ifaddr *)ia); return (error); bad: @@ -1179,22 +1178,17 @@ in_if_link_up(struct ifnet *ifp) /* If detached then mark as tentative */ if (ia->ia4_flags & IN_IFF_DETACHED) { ia->ia4_flags &= ~IN_IFF_DETACHED; -#if NARP - if (if_do_dad(ifp)) + if (if_do_dad(ifp) && ia->ia_dad_start != NULL) ia->ia4_flags |= IN_IFF_TENTATIVE; - else -#endif - if ((ia->ia4_flags & IN_IFF_TENTATIVE) == 0) + else if ((ia->ia4_flags & IN_IFF_TENTATIVE) == 0) rt_newaddrmsg(RTM_NEWADDR, ifa, 0, NULL); } -#if NARP if (ia->ia4_flags & IN_IFF_TENTATIVE) { /* Clear the duplicated flag as we're starting DAD. */ ia->ia4_flags &= ~IN_IFF_DUPLICATED; - arp_dad_start(ifa); + ia->ia_dad_start(ifa); } -#endif } } @@ -1220,10 +1214,9 @@ in_if_link_down(struct ifnet *ifp) continue; ia = (struct in_ifaddr *)ifa; -#if NARP /* Stop DAD processing */ - arp_dad_stop(ifa); -#endif + if (ia->ia_dad_stop != NULL) + ia->ia_dad_stop(ifa); /* * Mark the address as detached. Index: src/sys/netinet/in_var.h diff -u src/sys/netinet/in_var.h:1.71 src/sys/netinet/in_var.h:1.72 --- src/sys/netinet/in_var.h:1.71 Sat May 2 14:41:32 2015 +++ src/sys/netinet/in_var.h Sat May 16 12:12:46 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: in_var.h,v 1.71 2015/05/02 14:41:32 roy Exp $ */ +/* $NetBSD: in_var.h,v 1.72 2015/05/16 12:12:46 roy Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -69,9 +69,11 @@ #define IN_IFF_TENTATIVE 0x01 /* tentative address */ #define IN_IFF_DUPLICATED 0x02 /* DAD detected duplicate */ #define IN_IFF_DETACHED 0x04 /* may be detached from the link */ +#define IN_IFF_TRYTENTATIVE 0x08 /* intent to try DAD */ /* do not input/output */ -#define IN_IFF_NOTREADY (IN_IFF_TENTATIVE | IN_IFF_DUPLICATED) +#define IN_IFF_NOTREADY \ + (IN_IFF_TRYTENTATIVE | IN_IFF_TENTATIVE | IN_IFF_DUPLICATED) /* * Interface address, Internet version. One of these structures @@ -100,6 +102,8 @@ struct in_ifaddr { the allhosts multicast group */ uint16_t ia_idsalt; /* ip_id salt for this ia */ int ia4_flags; /* address flags */ + void (*ia_dad_start) (struct ifaddr *); /* DAD start function */ + void (*ia_dad_stop) (struct ifaddr *); /* DAD stop function */ }; struct in_aliasreq {