Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet6 Fix net.inet6.ip6.accept_rtadv and 'ndp -i <int...



details:   https://anonhg.NetBSD.org/src/rev/f6c137f6d905
branches:  trunk
changeset: 748843:f6c137f6d905
user:      dyoung <dyoung%NetBSD.org@localhost>
date:      Fri Nov 06 20:41:22 2009 +0000

description:
Fix net.inet6.ip6.accept_rtadv and 'ndp -i <interface> accept_rtadv':

Add a flag ND6_IFF_OVERRIDE_RTADV that tells the kernel to override
ip6_accept_rtadv (net.inet6.ip6.accept_rtadv) on an interface.

Add a routine nd6_accepts_rtadv(ndi) that evaluates both the flags
on the interface represented by ndi and ip6_accept_rtadv, and
returns 'true' if the given interface should accept Router
Advertisements, and 'false' if not.

Now, ND6_IFF_ACCEPT_RTADV works as it was historically documented:
if it is set, then accept router advertisements iff ip6_accept_rtadv
!= 0.  Otherwise, do not accept router advertisements.

If ND6_IFF_OVERRIDE_RTADV is set, then the flag ND6_IFF_ACCEPT_RTADV
overrides ip6_accept_rtadv: if ND6_IFF_ACCEPT_RTADV is set, accept;
otherwise reject.  Ignore ip6_accept_rtadv.

If neither ND6_IFF_ACCEPT_RTADV nor ND6_IFF_OVERRIDE_RTADV is set,
reject Router Advertisements.

diffstat:

 sys/netinet6/nd6.c     |  32 +++++++++++++++++++++++---------
 sys/netinet6/nd6.h     |  38 +++++++++++++++++++++++++++++++-------
 sys/netinet6/nd6_rtr.c |  12 ++++++------
 3 files changed, 60 insertions(+), 22 deletions(-)

diffs (188 lines):

diff -r 56bb0a7a7ae3 -r f6c137f6d905 sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Fri Nov 06 20:31:18 2009 +0000
+++ b/sys/netinet6/nd6.c        Fri Nov 06 20:41:22 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.c,v 1.134 2009/08/31 12:37:59 yamt Exp $   */
+/*     $NetBSD: nd6.c,v 1.135 2009/11/06 20:41:22 dyoung 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.134 2009/08/31 12:37:59 yamt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.135 2009/11/06 20:41:22 dyoung Exp $");
 
 #include "opt_ipsec.h"
 
@@ -172,12 +172,11 @@
        nd->reachable = ND_COMPUTE_RTIME(nd->basereachable);
        nd->retrans = RETRANS_TIMER;
        /*
-        * Note that the default value of ip6_accept_rtadv is 0, which means
-        * we won't accept RAs by default even if we set ND6_IFF_ACCEPT_RTADV
-        * here.
+        * Note that the default value of ip6_accept_rtadv is 0.
+        * Because we do not set ND6_IFF_OVERRIDE_RTADV here, we won't
+        * accept RAs by default.
         */
-       nd->flags = (ND6_IFF_PERFORMNUD |
-               (ip6_accept_rtadv ? ND6_IFF_ACCEPT_RTADV : 0));
+       nd->flags = ND6_IFF_PERFORMNUD | ND6_IFF_ACCEPT_RTADV;
 
        /* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */
        nd6_setmtu0(ifp, nd);
@@ -704,6 +703,21 @@
        return -1;
 }
 
+bool
+nd6_accepts_rtadv(const struct nd_ifinfo *ndi)
+{
+       switch (ndi->flags & (ND6_IFF_ACCEPT_RTADV|ND6_IFF_OVERRIDE_RTADV)) {
+       case ND6_IFF_OVERRIDE_RTADV|ND6_IFF_ACCEPT_RTADV:
+               return true;
+       case ND6_IFF_ACCEPT_RTADV:
+               return ip6_accept_rtadv != 0;
+       case ND6_IFF_OVERRIDE_RTADV:
+       case 0:
+       default:
+               return false;
+       }
+}
+
 /*
  * Nuke neighbor cache/prefix/default router management table, right before
  * ifp goes away.
@@ -767,7 +781,7 @@
                nd6_setdefaultiface(0);
 
        /* XXX: too restrictive? */
-       if (!ip6_forwarding && ndi && (ndi->flags & ND6_IFF_ACCEPT_RTADV)) {
+       if (!ip6_forwarding && ndi && nd6_accepts_rtadv(ndi)) {
                /* refresh default router list */
                defrouter_select();
        }
@@ -1885,7 +1899,7 @@
         * cases for safety.
         */
        if (do_update && ln->ln_router && !ip6_forwarding &&
-               (ndi->flags & ND6_IFF_ACCEPT_RTADV))
+           nd6_accepts_rtadv(ndi))
                defrouter_select();
 
        return rt;
diff -r 56bb0a7a7ae3 -r f6c137f6d905 sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h        Fri Nov 06 20:31:18 2009 +0000
+++ b/sys/netinet6/nd6.h        Fri Nov 06 20:41:22 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.h,v 1.52 2009/01/15 18:20:48 christos Exp $        */
+/*     $NetBSD: nd6.h,v 1.53 2009/11/06 20:41:22 dyoung Exp $  */
 /*     $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $    */
 
 /*
@@ -90,12 +90,35 @@
        u_int8_t randomid[8];   /* current random ID */
 };
 
-#define ND6_IFF_PERFORMNUD     0x1
-#define ND6_IFF_ACCEPT_RTADV   0x2
-#define ND6_IFF_PREFER_SOURCE  0x4 /* XXX: not related to ND. */
-#define ND6_IFF_IFDISABLED     0x8 /* IPv6 operation is disabled due to
-                                    * DAD failure.  (XXX: not ND-specific)
-                                    */
+#define ND6_IFF_PERFORMNUD     0x01
+#define ND6_IFF_ACCEPT_RTADV   0x02    /* See "RTADV Key", below. */
+#define ND6_IFF_PREFER_SOURCE  0x04    /* XXX: not related to ND. */
+#define ND6_IFF_IFDISABLED     0x08    /* IPv6 operation is disabled due to
+                                        * DAD failure.  (XXX: not ND-specific)
+                                        */
+#define        ND6_IFF_OVERRIDE_RTADV  0x10    /* See "RTADV Key", below. */
+
+/*
+ * RTADV Key
+ *
+ * The flags ND6_IFF_ACCEPT_RTADV and ND6_IFF_OVERRIDE_RTADV form a
+ * tri-state variable.  (There are actually four different states, but
+ * two of the states are functionally identical.)
+ *
+ * ND6_IFF_OVERRIDE_RTADV or 0:        This interface does not accept
+ *                             Router Advertisements.
+ *
+ * ND6_IFF_OVERRIDE_RTADV|
+ * ND6_IFF_ACCEPT_RTADV:       This interface accepts Router
+ *                             Advertisements regardless of the
+ *                             global setting, ip6_accept_rtadv.
+ *
+ * ND6_IFF_ACCEPT_RTADV:       This interface follows the global setting,
+ *                             ip6_accept_rtadv.  If ip6_accept_rtadv == 0,
+ *                             this interface does not accept Router
+ *                             Advertisements.  If ip6_accept_rtadv != 0,
+ *                             this interface does accept them.
+ */
 
 #ifdef _KERNEL
 #define ND_IFINFO(ifp) \
@@ -437,6 +460,7 @@
 void rt6_flush(struct in6_addr *, struct ifnet *);
 int nd6_setdefaultiface(int);
 int in6_tmpifadd(const struct in6_ifaddr *, int, int);
+bool nd6_accepts_rtadv(const struct nd_ifinfo *);
 
 #endif /* _KERNEL */
 
diff -r 56bb0a7a7ae3 -r f6c137f6d905 sys/netinet6/nd6_rtr.c
--- a/sys/netinet6/nd6_rtr.c    Fri Nov 06 20:31:18 2009 +0000
+++ b/sys/netinet6/nd6_rtr.c    Fri Nov 06 20:41:22 2009 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6_rtr.c,v 1.79 2009/07/25 23:12:09 tonnerre Exp $    */
+/*     $NetBSD: nd6_rtr.c,v 1.80 2009/11/06 20:41:22 dyoung 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.79 2009/07/25 23:12:09 tonnerre Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.80 2009/11/06 20:41:22 dyoung Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -122,7 +122,7 @@
        union nd_opts ndopts;
 
        /* If I'm not a router, ignore it. */
-       if ((ndi->flags & ND6_IFF_ACCEPT_RTADV) || !ip6_forwarding)
+       if (nd6_accepts_rtadv(ndi) || !ip6_forwarding)
                goto freeit;
 
        /* Sanity checks */
@@ -210,7 +210,7 @@
         * the system-wide variable allows the acceptance, and
         * per-interface variable allows RAs on the receiving interface.
         */
-       if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV))
+       if (!nd6_accepts_rtadv(ndi))
                goto freeit;
 
        if (ip6->ip6_hlim != 255) {
@@ -490,7 +490,7 @@
         * as a next hop.
         */
        /* XXX: better condition? */
-       if (!ip6_forwarding && (ndi->flags & ND6_IFF_ACCEPT_RTADV))
+       if (!ip6_forwarding && nd6_accepts_rtadv(ndi))
                rt6_flush(&dr->rtaddr, dr->ifp);
 
        if (dr->installed) {
@@ -646,7 +646,7 @@
        for (dr = TAILQ_FIRST(&nd_defrouter); dr;
             dr = TAILQ_NEXT(dr, dr_entry)) {
                ndi = ND_IFINFO(dr->ifp);
-               if ((ndi->flags & ND6_IFF_ACCEPT_RTADV))
+               if (nd6_accepts_rtadv(ndi))
                        continue;
 
                if (selected_dr == NULL &&



Home | Main Index | Thread Index | Old Index