Subject: Re: kern/3508 bug: cached ip route and interface up/down.
To: None <gnats-bugs@netbsd.org, tech-net@netbsd.org, tech-kern@netbsd.org>
From: der Mouse <mouse@Rodents.Montreal.QC.CA>
List: tech-net
Date: 11/12/2002 23:42:54
>>  The ip stack, when forwarding a packet, in ip_forward(), makes use
>>  of a cached route from a global variable called "ipforward_rt".

> It's been pointed out on current-users that the kernel is
> "simple-minded" about routing.  In your case, if the interface a
> route was using goes down, it's still up to a userland program to
> reroute the traffic by changing the table.

It's worse than that: even if userland _does_ change the routing table,
it doesn't affect routing until the kernel wants to forward a packet to
some other address.  Check out PR 3508.

You write that

> At this point ip_output() notices that the cached route is dead and
> fetches the new route.

I just had a look at -current's ip_output and I think what it does
isn't enough:

        /*
         * If there is a cached route,
         * check that it is to the same destination
         * and is still up.  If not, free it and try again.
         * The address family should also be checked in case of sharing the
         * cache with IPv6.
         */

The last two lines appear to be out of date, but the rest looks right:

        if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
            dst->sin_family != AF_INET ||
            !in_hosteq(dst->sin_addr, ip->ip_dst))) {

This won't fix anything in the scenario outlined in PR 3508.

/~\ The ASCII				der Mouse
\ / Ribbon Campaign
 X  Against HTML	       mouse@rodents.montreal.qc.ca
/ \ Email!	     7D C8 61 52 5D E7 2D 39  4E F1 31 3E E8 B3 27 4B