Date: Wed, 06 May 2009 14:55:02 -0700 From: Bob Van Zant <bob@veznat.com> To: Bruce Simpson <bms@incunabulum.net> Cc: "freebsd-net@freebsd.org" <freebsd-net@freebsd.org> Subject: Re: IPv6 duplicate address detection Message-ID: <C6275546.226A7%bob@veznat.com> In-Reply-To: <4A019E40.1030606@incunabulum.net>
next in thread | previous in thread | raw e-mail | index | archive | help
On 5/6/09 7:27 AM, "Bruce Simpson" <bms@incunabulum.net> wrote: >> The problem is that I'm following RFC 2461 [1] in that I send an unsolicited >> neighbor advertisement to ff02::1 immediately after configuring the >> interface. >> > > How are you doing this? Do you do this from the kernel or from your own > userland code? Userland code. SOCK_RAW and IPPROTO_ICMPV6. > > Normally the kernel does DAD for you when a new IPv6 address is > configured, and you shouldn't need to do it manually. Just to be clear, I'm not trying to do DAD. You mention later that this sounds like gratuitous ARP and that's the best analogy for what I'm doing. I fire off a single packet into the wild and hope that my neighbors see my new link-layer address (we do NIC failover). > It sounds like what you are trying to do is useful (a bit like > gratuitous ARP) but I wonder exactly what conditions it's triggering in > nd6_nbr.c which would cause it to interpret what you send in this way. There's not really anything in nd6_nbr.c to prevent this behavior. I have a patch that changes this. I don't know if it's making an invalid assumption or not. In my basic tests it avoids the behavior where my IP gets marked as a duplicate but still allows DAD to work when the address really is a dup. --- nd6_nbr.c.backup Mon May 4 10:12:20 2009 +++ sys/netinet6/nd6_nbr.c Mon May 4 14:19:30 2009 @@ -618,8 +618,16 @@ lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1); lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3; } + /* Is the source address of this packet one of my + * addresses on this same interface? If so this packet was sent by me + * and should not trigger a DAD failure. + */ + ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &(ip6->ip6_src)); + if (ifa) + goto freeit; + > This seems like a bug. > Have you looked in the KAME repo to see if it got fixed there? > Perhaps NetBSD have already fixed it in their import of KAME? I took a look through head of the kame cvsweb sources and don't see any differences from 6.3 sources I have. They have some MIP6 code in place but that's the only difference I see. > >> An alternative view on this is that I shouldn't be sending out any packets, >> especially unsolicited NAs, using or referencing a tentative address. >> > > That can be tricky to implement. There is a function > in6ifa_ifpforlinklocal() which takes various flags. It is told to skip > tentative addresses or duplicates by passing IN6_IFF_NOTREADY. Normally > this will return the ifa pointer to the link-local address which was > auto-configured on the inerface. Being in userland I don't think I can call this. However, I discovered the SIOCGIFAFLAG_IN6 ioctl which gives me back the flags for an <interface, address> tuple. In this way I can poll for whether or not this IP is tentative or not. Similarly I can tell whether DAD failed. > > Can you try HEAD sources and disable IPv6 multicast loopback by default > (net.inet6.ip6.mcast.loop, off the top of my head) ? > > It is possible that your ff02::1 packet is being looped back and somehow > the NA/NS code is interpreting it as on-wire traffic. > 7.x will loop back by default. You could even try just setting > IPV6_MULTICAST_LOOP to 0 in your userland DAD code. I don't have a HEAD kernel handy. However, this socket option was a nice pointer, thank you. Setting this to 0 does prevent the behavior I was seeing. I guess this makes it extra clear that the multicast packet I'm sending is simply being looped back in. I'm guessing that the next step is for me to file a PR with this information? Or what do you suggest? -Bob
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?C6275546.226A7%bob>