Subject: IPv6: make DAD succeed with "multicast loopback"
To: None <tech-net@netbsd.org>
From: Matthias Drochner <M.Drochner@fz-juelich.de>
List: tech-net
Date: 02/01/2005 20:06:22
This is a multipart MIME message.

--==_Exmh_4310653195050
Content-Type: text/plain; charset=us-ascii


Hi -
when I had an ethernet switch configured to have one port as "monitor"
for another one I found that I couldn't set a (global) IPv6 address
on the "monitor" box anymore.
The reason is that the switch - configured that way - also reflects
a copy of the DAD NS multicast sent by my "monitor" box back to it.
IPv4's ARP code deals with this case -- the sender link-layer address
is checked against the receiving interface's one. See if_arp.c:949.
IPv6 doesn't. While RFC2462 suggests (in vague wording) to check
whether the solicitation originates from the node itself (ch. 5.4.3),
this isn't done easily.
I'd consider this worth fixing -- using NetBSD for network diagnostics
is common, and it would be bad if this affected normal operation.
There is some commented-out code in nd6_nbr.c which can be made
useful with little effort. See the appended patch. It tries to detect
whether we receive exactly 1 NS packet for each one sent, 5 times,
without influencing the normal case where just 1 packet is sent.

Comments?

best regards
Matthias



--==_Exmh_4310653195050
Content-Type: text/plain ; name="dad.txt"; charset=us-ascii
Content-Description: dad.txt
Content-Disposition: attachment; filename="dad.txt"

--- nd6_nbr.c.~1.53.~	Wed Feb 11 12:24:54 2004
+++ nd6_nbr.c	Tue Feb  1 19:30:26 2005
@@ -1211,7 +1211,12 @@ nd6_dad_timer(ifa)
 	}
 
 	/* Need more checks? */
-	if (dp->dad_ns_ocount < dp->dad_count) {
+	if ((dp->dad_ns_ocount < dp->dad_count)
+#if 1 /* for heuristics, see below */
+	    || ((dp->dad_ns_ocount < 5)
+		&& (dp->dad_ns_icount == dp->dad_ns_ocount))
+#endif
+		) {
 		/*
 		 * We have more NS to go.  Send NS packet for DAD.
 		 */
@@ -1236,7 +1241,7 @@ nd6_dad_timer(ifa)
 		}
 
 		if (dp->dad_ns_icount) {
-#if 0 /* heuristics */
+#if 1 /* heuristics */
 			/*
 			 * if
 			 * - we have sent many(?) DAD NS, and
@@ -1246,8 +1251,8 @@ nd6_dad_timer(ifa)
 			 * we may have a faulty network card/driver which
 			 * loops back multicasts to myself.
 			 */
-			if (3 < dp->dad_count
-			 && dp->dad_ns_icount == dp->dad_count
+			if (3 < dp->dad_ns_ocount
+			 && 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",

--==_Exmh_4310653195050--