Subject: Re: misc/33793: network stop & start breaks IPv6
To: None <tech-net@NetBSD.org>
From: David Young <dyoung@pobox.com>
List: tech-net
Date: 06/22/2006 11:57:13
On Thu, Jun 22, 2006 at 04:05:42PM +0000, Thomas E. Spanjaard wrote:
> As can be read in the PR, IPv6 breaks after an /etc/rc.d/network stop &
> start. Now, first I though it was because the stop routine only deletes
> inet addresses, and not inet6 before flushing routes. However, further
> inspection of the rc.d script show it only deletes addresses that are
> configured as ifaliases_$int in either /etc/rc.conf or /etc/ifaliases.
> Now, I don't use either of them, I use /etc/ifconfig.$int files, both
> for IPv4 and IPv6. So if I read things right, IPv4 addresses aren't
> deleted prior to route flushing either, which brings me to the question,
> why does IPv4 work after a stop & start, and IPv6 doesn't?
Here are a few ways to understand the problem.
The problem is that, after stop/start, the IPv6 stack starts dropping on
the floor any packets addressed to an interface's link-local address,
because the flags on the link-local address's routing table entry are
wrong (RTF_CLONED is present).
The problem is that '/etc/rc.d/network stop' removes the link-local
addresses (fe80::/16) from the interfaces, but 'network start' does not
add them back.
The problem is that a link-local host routing entry created by cloning
fe80::/16%sip0 (say) cannot "sink" packets; the KAME stack drops packets
matching the route entry in ip6_input:
/*
* Accept the packet if the forwarding interface to the destination
* according to the routing table is the loopback interface,
* unless the associated route has a gateway.
* Note that this approach causes to accept a packet if there is a
* route to the loopback interface for the destination of the packet.
* But we think it's even useful in some situations, e.g. when using
* a special daemon which wants to intercept the packet.
*/
if (ip6_forward_rt.ro_rt &&
(ip6_forward_rt.ro_rt->rt_flags &
(RTF_HOST|RTF_GATEWAY)) == RTF_HOST &&
!(ip6_forward_rt.ro_rt->rt_flags & RTF_CLONED) &&
/* #if 0 sources abridged -dyoung */
ip6_forward_rt.ro_rt->rt_ifp->if_type == IFT_LOOP) {
The problem is that the kernel does not add back an interface's link-local
IPv6 address, if it is missing, on a !IFF_UP->IFF_UP transition.
I believe that by addressing this last problem, the bug will be fixed.
Dave
--
David Young OJC Technologies
dyoung@ojctech.com Urbana, IL * (217) 278-3933