Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet6 Give DAD a chance to succeed even if the networ...



details:   https://anonhg.NetBSD.org/src/rev/c5a0447fc30f
branches:  trunk
changeset: 573606:c5a0447fc30f
user:      drochner <drochner%NetBSD.org@localhost>
date:      Wed Feb 02 20:56:27 2005 +0000

description:
Give DAD a chance to succeed even if the network is "slightly broken"
(in my case it as a switch set to "monitor" mode):
If we see an NS request for the address we are just probing for, for
three times the number of DAD packets we are supposed to send (the
"ip6.dad_count" sysctl variable), assume that these are our own packets
and let DAD succeed.
The code for this was mostly there, commented out. Just needed some fixes.
The "three times" is heuristic of course.
Being here, reset the "dad_ns_tcount" variable on a successful send;
otherwise we get strange interdependencies with user-settable variables
(ever tried to set ip6.dad_count to something >15?).

diffstat:

 sys/netinet6/nd6_nbr.c |  34 ++++++++++++++++------------------
 1 files changed, 16 insertions(+), 18 deletions(-)

diffs (97 lines):

diff -r d87d3b6f7a76 -r c5a0447fc30f sys/netinet6/nd6_nbr.c
--- a/sys/netinet6/nd6_nbr.c    Wed Feb 02 17:14:29 2005 +0000
+++ b/sys/netinet6/nd6_nbr.c    Wed Feb 02 20:56:27 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6_nbr.c,v 1.53 2004/02/10 20:57:20 itojun Exp $      */
+/*     $NetBSD: nd6_nbr.c,v 1.54 2005/02/02 20:56:27 drochner 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.53 2004/02/10 20:57:20 itojun Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.54 2005/02/02 20:56:27 drochner Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -1007,7 +1007,8 @@
 struct dadq {
        TAILQ_ENTRY(dadq) dad_list;
        struct ifaddr *dad_ifa;
-       int dad_count;          /* max NS to send */
+       int dad_count;          /* max NS to send, standard case */
+       int dad_maxcount;       /* max NS to send, loopback detection */
        int dad_ns_tcount;      /* # of trials to send NS */
        int dad_ns_ocount;      /* NS sent so far */
        int dad_ns_icount;
@@ -1120,6 +1121,7 @@
        dp->dad_ifa = ifa;
        IFAREF(ifa);    /* just for safety */
        dp->dad_count = ip6_dad_count;
+       dp->dad_maxcount = 3 * ip6_dad_count; /* XXX sysctl??? */
        dp->dad_ns_icount = dp->dad_na_icount = 0;
        dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
        if (tick == NULL) {
@@ -1211,7 +1213,9 @@
        }
 
        /* Need more checks? */
-       if (dp->dad_ns_ocount < dp->dad_count) {
+       if ((dp->dad_ns_ocount < dp->dad_count)
+           || ((dp->dad_ns_ocount < dp->dad_maxcount)
+               && (dp->dad_ns_icount == dp->dad_ns_ocount))) {
                /*
                 * We have more NS to go.  Send NS packet for DAD.
                 */
@@ -1235,34 +1239,27 @@
                        duplicate++;
                }
 
-               if (dp->dad_ns_icount) {
-#if 0 /* heuristics */
+               if (dp->dad_ns_icount) { /* heuristics */
                        /*
                         * if
-                        * - we have sent many(?) DAD NS, and
+                        * - we have sent many DAD NS, and
                         * - the number of NS we sent equals to the
                         *   number of NS we've got, and
                         * - we've got no NA
-                        * we may have a faulty network card/driver which
+                        * we may have a faulty network which
                         * loops back multicasts to myself.
                         */
-                       if (3 < dp->dad_count
-                        && dp->dad_ns_icount == dp->dad_count
+                       if (dp->dad_ns_ocount == dp->dad_maxcount
+                        && dp->dad_ns_icount == dp->dad_ns_ocount
                         && dp->dad_na_icount == 0) {
                                log(LOG_INFO, "DAD questionable for %s(%s): "
-                                   "network card loops back multicast?\n",
+                                   "network loops back multicast?\n",
                                    ip6_sprintf(&ia->ia_addr.sin6_addr),
                                    if_name(ifa->ifa_ifp));
-                               /* XXX consider it a duplicate or not? */
-                               /* duplicate++; */
                        } else {
-                               /* We've seen NS, means DAD has failed. */
+                               /* DAD has failed. */
                                duplicate++;
                        }
-#else
-                       /* We've seen NS, means DAD has failed. */
-                       duplicate++;
-#endif
                }
 
                if (duplicate) {
@@ -1349,6 +1346,7 @@
                return;
        }
 
+       dp->dad_ns_tcount = 0;
        dp->dad_ns_ocount++;
        nd6_ns_output(ifp, NULL, &ia->ia_addr.sin6_addr, NULL, 1);
 }



Home | Main Index | Thread Index | Old Index