Source-Changes-HG archive

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

[src/trunk]: src If IPv6 is disabled for an interface, mark all addresses as ...



details:   https://anonhg.NetBSD.org/src/rev/254e0327170c
branches:  trunk
changeset: 794637:254e0327170c
user:      roy <roy%NetBSD.org@localhost>
date:      Thu Mar 20 13:34:35 2014 +0000

description:
If IPv6 is disabled for an interface, mark all addresses as tentative.
If enabled, check for a duplicated link-local address and abort enabling
as per RFC 4862, section 5.4.5. If allowed to enable, perform DAD
on the tentative addresses.

Taken from FreeBSD.

diffstat:

 sys/netinet6/nd6.c |  57 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 usr.sbin/ndp/ndp.8 |   9 +++++--
 2 files changed, 61 insertions(+), 5 deletions(-)

diffs (108 lines):

diff -r c4a02bb0e06c -r 254e0327170c sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Thu Mar 20 10:15:13 2014 +0000
+++ b/sys/netinet6/nd6.c        Thu Mar 20 13:34:35 2014 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.c,v 1.147 2014/01/15 10:25:04 roy Exp $    */
+/*     $NetBSD: nd6.c,v 1.148 2014/03/20 13:34:35 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.147 2014/01/15 10:25:04 roy Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.148 2014/03/20 13:34:35 roy Exp $");
 
 #include "opt_ipsec.h"
 
@@ -1647,6 +1647,59 @@
                        ND_IFINFO(ifp)->chlim = ND.chlim;
                /* FALLTHROUGH */
        case SIOCSIFINFO_FLAGS:
+       {
+               struct ifaddr *ifa;
+               struct in6_ifaddr *ia;
+
+               if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
+                   !(ND.flags & ND6_IFF_IFDISABLED))
+               {
+                       /*
+                        * If the interface is marked as ND6_IFF_IFDISABLED and
+                        * has a link-local address with IN6_IFF_DUPLICATED,
+                        * do not clear ND6_IFF_IFDISABLED.
+                        * See RFC 4862, section 5.4.5.
+                        */
+                       int duplicated_linklocal = 0;
+
+                       IFADDR_FOREACH(ifa, ifp) {
+                               if (ifa->ifa_addr->sa_family != AF_INET6)
+                                       continue;
+                               ia = (struct in6_ifaddr *)ifa;
+                               if ((ia->ia6_flags & IN6_IFF_DUPLICATED) &&
+                                   IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia)))
+                               {
+                                       duplicated_linklocal = 1;
+                                       break;
+                               }
+                       }
+
+                       if (duplicated_linklocal) {
+                               ND.flags |= ND6_IFF_IFDISABLED;
+                               log(LOG_ERR, "Cannot enable an interface"
+                                   " with a link-local address marked"
+                                   " duplicate.\n");
+                       } else {
+                               ND_IFINFO(ifp)->flags &= ~ND6_IFF_IFDISABLED;
+                               if (ifp->if_flags & IFF_UP)
+                                       in6_if_up(ifp);
+                       }
+               } else if (!(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
+                   (ND.flags & ND6_IFF_IFDISABLED))
+               {
+                       /* Mark all IPv6 addresses as tentative. */
+
+                       ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED;
+                       IFADDR_FOREACH(ifa, ifp) {
+                               if (ifa->ifa_addr->sa_family != AF_INET6)
+                                       continue;
+                               nd6_dad_stop(ifa);
+                               ia = (struct in6_ifaddr *)ifa;
+                               ia->ia6_flags |= IN6_IFF_TENTATIVE;
+                       }
+               }
+       }
+
                ND_IFINFO(ifp)->flags = ND.flags;
                break;
 #undef ND
diff -r c4a02bb0e06c -r 254e0327170c usr.sbin/ndp/ndp.8
--- a/usr.sbin/ndp/ndp.8        Thu Mar 20 10:15:13 2014 +0000
+++ b/usr.sbin/ndp/ndp.8        Thu Mar 20 13:34:35 2014 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: ndp.8,v 1.25 2009/11/06 20:51:43 dyoung Exp $
+.\"    $NetBSD: ndp.8,v 1.26 2014/03/20 13:34:35 roy Exp $
 .\"    $KAME: ndp.8,v 1.33 2005/10/19 14:57:42 suz Exp $
 .\"
 .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -28,7 +28,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd November 6, 2009
+.Dd March 20, 2014
 .Dt NDP 8
 .Os
 .\"
@@ -210,7 +210,10 @@
 .It Ic disabled
 Disable IPv6 operation on the interface.
 When disabled, the interface discards any IPv6 packets
-received on or being sent to the interface.
+received on or being sent to the interface and any IPv6 addresses
+on the interface are marked as
+.Dq tentative .
+When the disabled flag is cleared, DAD will be performed.
 In the sending case, an error of ENETDOWN will be returned to the
 application.
 This flag is typically set automatically in the kernel as a result of



Home | Main Index | Thread Index | Old Index