Subject: Re: kern/3508 bug: cached ip route and interface up/down.
To: der Mouse <mouse@rodents.montreal.qc.ca>
From: Nick Amato <naamato@nexthop.com>
List: tech-net
Date: 11/12/2002 19:15:52
On Tue, Nov 12, 2002 at 11:42:54PM +0100, der Mouse wrote:
> >> 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.
Yes, it is true. A routing daemon cannot fix the problems in PR 3508.
However, as long as there is an absence of an alternate route (i.e. default)
while a destination is unreachable, it still works. When a route is deleted
and added the old route has RTF_UP reset and the new route will be rtalloc'd
in ip_output().
Not very useful. It seems to me that what needs to happen is to clear the
cache whenever a more specific route than the cached route is added to
the table. I don't know how practical this is.
Nick