Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet Separate ARP handling DAD from inet.



details:   https://anonhg.NetBSD.org/src/rev/71544db40ae4
branches:  trunk
changeset: 338250:71544db40ae4
user:      roy <roy%NetBSD.org@localhost>
date:      Sat May 16 12:12:46 2015 +0000

description:
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.

diffstat:

 sys/netinet/if_arp.c   |  17 +++++++++++++----
 sys/netinet/if_inarp.h |   5 +----
 sys/netinet/in.c       |  39 ++++++++++++++++-----------------------
 sys/netinet/in_var.h   |   8 ++++++--
 4 files changed, 36 insertions(+), 33 deletions(-)

diffs (222 lines):

diff -r ae9a7aae8053 -r 71544db40ae4 sys/netinet/if_arp.c
--- a/sys/netinet/if_arp.c      Sat May 16 11:49:01 2015 +0000
+++ b/sys/netinet/if_arp.c      Sat May 16 12:12:46 2015 +0000
@@ -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 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 @@
 
        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 @@
 /*
  * 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 @@
 /*
  * terminate DAD unconditionally.  used for address removals.
  */
-void
+static void
 arp_dad_stop(struct ifaddr *ifa)
 {
        struct dadq *dp;
diff -r ae9a7aae8053 -r 71544db40ae4 sys/netinet/if_inarp.h
--- a/sys/netinet/if_inarp.h    Sat May 16 11:49:01 2015 +0000
+++ b/sys/netinet/if_inarp.h    Sat May 16 12:12:46 2015 +0000
@@ -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 @@
 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 *);
diff -r ae9a7aae8053 -r 71544db40ae4 sys/netinet/in.c
--- a/sys/netinet/in.c  Sat May 16 11:49:01 2015 +0000
+++ b/sys/netinet/in.c  Sat May 16 12:12:46 2015 +0000
@@ -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 @@
        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 @@
        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 @@
         */
        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 @@
                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 @@
                /* 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 @@
                        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.
diff -r ae9a7aae8053 -r 71544db40ae4 sys/netinet/in_var.h
--- a/sys/netinet/in_var.h      Sat May 16 11:49:01 2015 +0000
+++ b/sys/netinet/in_var.h      Sat May 16 12:12:46 2015 +0000
@@ -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 @@
                                           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 {



Home | Main Index | Thread Index | Old Index