Source-Changes-HG archive

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

[src/trunk]: src For IPv6, emit RTM_NEWADDR once DAD completes and also when ...



details:   https://anonhg.NetBSD.org/src/rev/d19356d152ec
branches:  trunk
changeset: 786919:d19356d152ec
user:      roy <roy%NetBSD.org@localhost>
date:      Tue May 21 08:37:27 2013 +0000

description:
For IPv6, emit RTM_NEWADDR once DAD completes and also when address flag
changes. Tentative addresses are not emitted.

Version bumped so userland can detect this behaviour change.

diffstat:

 share/man/man4/route.4 |  23 +++++++++++++++++++++--
 sys/netinet6/in6.c     |  32 ++++++++++++++++++++++++--------
 sys/netinet6/nd6.c     |  14 ++++++++++----
 sys/netinet6/nd6.h     |   3 ++-
 sys/netinet6/nd6_nbr.c |  48 +++++++++++++++++++++++++++++++++++++++++-------
 sys/netinet6/nd6_rtr.c |   8 ++++++--
 sys/sys/param.h        |   4 ++--
 7 files changed, 106 insertions(+), 26 deletions(-)

diffs (truncated from 324 to 300 lines):

diff -r c74ed72591d6 -r d19356d152ec share/man/man4/route.4
--- a/share/man/man4/route.4    Tue May 21 06:59:28 2013 +0000
+++ b/share/man/man4/route.4    Tue May 21 08:37:27 2013 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: route.4,v 1.18 2011/07/03 07:25:52 kefren Exp $
+.\"    $NetBSD: route.4,v 1.19 2013/05/21 08:37:27 roy Exp $
 .\"
 .\" Copyright (c) 1990, 1991, 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"     @(#)route.4    8.6 (Berkeley) 4/19/94
 .\"
-.Dd November 13, 2010
+.Dd May 21, 2013
 .Dt ROUTE 4
 .Os
 .Sh NAME
@@ -128,6 +128,11 @@
 .Pp
 Any messages sent to the kernel are returned, and copies are sent
 to all interested listeners.
+The exception to this is a new address marked as tentative, where copies
+will be sent once Duplicate Address Detection has completed and
+the tentative flag cleared or the duplicated flag set.
+Also, new address messages will also be emitted when other flags on the address
+change such as deprecated and detached.
 The kernel will provide the process ID for the sender, and the
 sender may use an additional sequence field to distinguish between
 outstanding messages.
@@ -329,6 +334,20 @@
 #define RTA_BRD       0x80   /* for NEWADDR, broadcast or p-p dest addr */
 #define RTA_TAG       0x100  /* route tag */
 .Ed
+.Pp
+Flags for IPv6 addresses:
+.Bd -literal
+#define IN6_IFF_ANYCAST                0x01    /* anycast address */
+#define IN6_IFF_TENTATIVE      0x02    /* tentative address */
+#define IN6_IFF_DUPLICATED     0x04    /* DAD detected duplicate */
+#define IN6_IFF_DETACHED       0x08    /* may be detached from the link */
+#define IN6_IFF_DEPRECATED     0x10    /* deprecated address */
+#define IN6_IFF_NODAD          0x20    /* don't perform DAD on this address
+                                        * (used only at first SIOC* call)
+                                        */
+#define IN6_IFF_AUTOCONF       0x40    /* autoconfigurable address. */
+#define IN6_IFF_TEMPORARY      0x80    /* temporary (anonymous) address. */
+.Ed
 .Sh SEE ALSO
 .Xr socket 2 ,
 .Xr sysctl 3
diff -r c74ed72591d6 -r d19356d152ec sys/netinet6/in6.c
--- a/sys/netinet6/in6.c        Tue May 21 06:59:28 2013 +0000
+++ b/sys/netinet6/in6.c        Tue May 21 08:37:27 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.c,v 1.161 2012/06/23 03:14:03 christos Exp $       */
+/*     $NetBSD: in6.c,v 1.162 2013/05/21 08:37:27 roy Exp $    */
 /*     $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $   */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.161 2012/06/23 03:14:03 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.162 2013/05/21 08:37:27 roy Exp $");
 
 #include "opt_inet.h"
 #include "opt_pfil_hooks.h"
@@ -191,13 +191,29 @@
                rt_replace_ifa(nrt, ifa);
 
        /*
-        * Report the addition/removal of the address to the routing socket.
+        * Report the addition/removal of the address to the routing socket
+        * unless the address is marked tentative, where it will be reported
+        * once DAD completes.
         * XXX: since we called rtinit for a p2p interface with a destination,
         *      we end up reporting twice in such a case.  Should we rather
         *      omit the second report?
         */
        if (nrt) {
-               rt_newaddrmsg(cmd, ifa, e, nrt);
+               if (cmd != RTM_ADD ||
+                   !(((struct in6_ifaddr *)ifa)->ia6_flags &IN6_IFF_TENTATIVE))
+               {
+#if 0
+                       struct in6_ifaddr *ia;
+
+                       ia = (struct in6_ifaddr *)ifa;
+                       log(LOG_DEBUG,
+                           "in6_ifloop_request: announced %s (%s %d)\n",
+                           ip6_sprintf(&ia->ia_addr.sin6_addr),
+                           cmd == RTM_ADD ? "RTM_ADD" : "RTM_DELETE",
+                           ia->ia6_flags);
+#endif
+                       rt_newaddrmsg(cmd, ifa, e, nrt);
+               }
                if (cmd == RTM_DELETE) {
                        if (nrt->rt_refcnt <= 0) {
                                /* XXX: we should free the entry ourselves. */
@@ -1058,10 +1074,6 @@
        } else
                ia->ia6_lifetime.ia6t_preferred = 0;
 
-       /* reset the interface and routing table appropriately. */
-       if ((error = in6_ifinit(ifp, ia, &ifra->ifra_addr, hostIsNew)) != 0)
-               goto unlink;
-
        /*
         * configure address flags.
         */
@@ -1084,6 +1096,10 @@
        if (hostIsNew && in6if_do_dad(ifp)) 
                ia->ia6_flags |= IN6_IFF_TENTATIVE;
 
+       /* reset the interface and routing table appropriately. */
+       if ((error = in6_ifinit(ifp, ia, &ifra->ifra_addr, hostIsNew)) != 0)
+               goto unlink;
+
        /*
         * We are done if we have simply modified an existing address.
         */
diff -r c74ed72591d6 -r d19356d152ec sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Tue May 21 06:59:28 2013 +0000
+++ b/sys/netinet6/nd6.c        Tue May 21 08:37:27 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.c,v 1.144 2013/01/24 14:23:09 joerg Exp $  */
+/*     $NetBSD: nd6.c,v 1.145 2013/05/21 08:37:27 roy Exp $    */
 /*     $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $   */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.144 2013/01/24 14:23:09 joerg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.145 2013/05/21 08:37:27 roy Exp $");
 
 #include "opt_ipsec.h"
 
@@ -582,7 +582,10 @@
                } else if (IFA6_IS_DEPRECATED(ia6)) {
                        int oldflags = ia6->ia6_flags;
 
-                       ia6->ia6_flags |= IN6_IFF_DEPRECATED;
+                       if ((oldflags & IN6_IFF_DEPRECATED) == 0) {
+                               ia6->ia6_flags |= IN6_IFF_DEPRECATED;
+                               nd6_newaddrmsg((struct ifaddr *)ia6);
+                       }
 
                        /*
                         * If a temporary address has just become deprecated,
@@ -613,7 +616,10 @@
                         * A new RA might have made a deprecated address
                         * preferred.
                         */
-                       ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
+                       if (ia6->ia6_flags & IN6_IFF_DEPRECATED) {
+                               ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
+                               nd6_newaddrmsg((struct ifaddr *)ia6);
+                       }
                }
        }
 
diff -r c74ed72591d6 -r d19356d152ec sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h        Tue May 21 06:59:28 2013 +0000
+++ b/sys/netinet6/nd6.h        Tue May 21 08:37:27 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.h,v 1.57 2012/06/23 03:14:04 christos Exp $        */
+/*     $NetBSD: nd6.h,v 1.58 2013/05/21 08:37:27 roy Exp $     */
 /*     $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $    */
 
 /*
@@ -435,6 +435,7 @@
 void nd6_ns_output(struct ifnet *, const struct in6_addr *,
        const struct in6_addr *, struct llinfo_nd6 *, int);
 const void *nd6_ifptomac(const struct ifnet *);
+void nd6_newaddrmsg(struct ifaddr *);
 void nd6_dad_start(struct ifaddr *, int);
 void nd6_dad_stop(struct ifaddr *);
 void nd6_dad_duplicated(struct ifaddr *);
diff -r c74ed72591d6 -r d19356d152ec sys/netinet6/nd6_nbr.c
--- a/sys/netinet6/nd6_nbr.c    Tue May 21 06:59:28 2013 +0000
+++ b/sys/netinet6/nd6_nbr.c    Tue May 21 08:37:27 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6_nbr.c,v 1.96 2012/03/22 20:34:41 drochner Exp $    */
+/*     $NetBSD: nd6_nbr.c,v 1.97 2013/05/21 08:37:27 roy Exp $ */
 /*     $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $        */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.96 2012/03/22 20:34:41 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.97 2013/05/21 08:37:27 roy Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -1056,6 +1056,39 @@
 }
 
 /*
+ * Routine to report address flag changes to the routing socket
+ */
+void
+nd6_newaddrmsg(struct ifaddr *ifa)
+{
+       struct sockaddr_in6 all1_sa;
+       struct rtentry *nrt = NULL;
+       int e;
+
+       sockaddr_in6_init(&all1_sa, &in6mask128, 0, 0, 0);
+
+       e = rtrequest(RTM_GET, ifa->ifa_addr, ifa->ifa_addr,
+           (struct sockaddr *)&all1_sa, RTF_UP|RTF_HOST|RTF_LLINFO, &nrt);
+       if (e != 0) {
+               log(LOG_ERR, "nd6_newaddrmsg: "
+                   "RTM_GET operation failed for %s (errno=%d)\n",
+                   ip6_sprintf(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr),
+                   e);
+       }
+
+       if (nrt) {
+               rt_newaddrmsg(RTM_ADD, ifa, e, nrt);
+//#if 0
+               log(LOG_DEBUG, "nd6_newaddrmsg: announced %s\n",
+                   ip6_sprintf(&((struct in6_ifaddr *)ifa)->ia_addr.sin6_addr)
+               );
+//#endif
+               nrt->rt_refcnt--;
+       }
+}
+
+
+/*
  * Start Duplicate Address Detection (DAD) for specified interface address.
  *
  * xtick: minimum delay ticks for IFF_UP event
@@ -1085,12 +1118,9 @@
                        ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
                return;
        }
-       if (ia->ia6_flags & IN6_IFF_ANYCAST) {
+       if (ia->ia6_flags & IN6_IFF_ANYCAST || !ip6_dad_count) {
                ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
-               return;
-       }
-       if (!ip6_dad_count) {
-               ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
+               nd6_newaddrmsg(ifa);
                return;
        }
        if (ifa->ifa_ifp == NULL)
@@ -1246,6 +1276,7 @@
                         * No duplicate address found.
                         */
                        ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
+                       nd6_newaddrmsg(ifa);
 
                        nd6log((LOG_DEBUG,
                            "%s: DAD complete for %s - no duplicates found\n",
@@ -1294,6 +1325,9 @@
        log(LOG_ERR, "%s: manual intervention required\n",
            if_name(ifp));
 
+       /* Inform the routing socket that DAD has completed */
+       nd6_newaddrmsg(ifa);
+
        /*
         * If the address is a link-local address formed from an interface
         * identifier based on the hardware address which is supposed to be
diff -r c74ed72591d6 -r d19356d152ec sys/netinet6/nd6_rtr.c
--- a/sys/netinet6/nd6_rtr.c    Tue May 21 06:59:28 2013 +0000
+++ b/sys/netinet6/nd6_rtr.c    Tue May 21 08:37:27 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6_rtr.c,v 1.86 2013/02/18 16:45:50 christos Exp $    */
+/*     $NetBSD: nd6_rtr.c,v 1.87 2013/05/21 08:37:27 roy Exp $ */
 /*     $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $        */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.86 2013/02/18 16:45:50 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.87 2013/05/21 08:37:27 roy Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1580,10 +1580,14 @@
                                        ifa->ia6_flags |= IN6_IFF_TENTATIVE;
                                        nd6_dad_start((struct ifaddr *)ifa,
                                            0);
+                                       /* We will notify the routing socket
+                                        * of the DAD result, so no need to
+                                        * here */
                                }
                        } else {



Home | Main Index | Thread Index | Old Index