[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Why RNF_IGNORE?



About two years ago, RNF_IGNORE was added to the radix/routing code to 
flag routes related to a down interface as being out of commission.  I 
tried searching for some discussion regarding this feature, but have 
been unable to find any...

I ran into a bit of a weird problem that I think it caused by this flag. 
 Try something like this (assuming fxp0 is the only interface--or, at 
least, the one w/ the default route):

GW = default route (on the fxp0 subnet)
TEST = some box on the fxp0 subnet (other than GW)

route -n flush
ifconfig fxp0 down
route -n add default GW
ifconfig fxp0 up
ping TEST

Because the "RNF_IGNORE" is set on the radix_node for all the relevant 
routes when the route add is done, it also gets propagated from the 
radix_node's rn_flags to the new radix_mask's rm_flags.  The if_up() 
code only clears the RNF_IGNORE flag on the radix_nodes, so the 
radix_mask is still ignored (line 295 of radix.c).  This causes the 
traffic for the local network to use the default route.  The next odd 
thing that happens (at least, if the default route is an OpenBSD 3.1 
box), is that the router returns a host redirect with dst=TEST 
gateway=TEST author=GW.  The resulting entry in the routing table is a 
host route (flags UGHD) with a destination of TEST and gateway of TEST 
(the IP address--note the absence of an "L" in those flags).  After 
which, there is no connectivity to TEST.


Anyhow, I was hoping to find some archive of the discussion related to 
RNF_IGNORE to see if I could figure out what the system should be doing 
(e.g., using an RTM* flag instead, following the masks when marking an 
interface up, or masking the flags when copying from a route_node to a 
route_mask).   No luck.

I assume the idea is that if there is an alternate path to the routes 
that are now unreachable through that interface, then the system will 
automatically use them.  However, unless some routing daemon is running, 
the return path from those system will likely try to use the down 
interface (especially stuff on the same subnet as the down interface) 
and if a routing daemon is running, then it should be changing the 
routes to match the new topology anyway.   Perhaps it could even get 
confused if "hello"s and the like start going out unexpected interfaces...?


While poking around the routing code, I noticed some other things. 
 FreeBSD fixed a leak a while back:  
http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/net/route.c#rev1.57
This seems relevant to OpenBSD as well.

Also, there is an m_get() on line 794 of rtinit().  It get's m_free()ed 
in an error path a little further down, but I don't see where it would 
get consumed or m_free()ed otherwise.  Am I missing something obvious or 
is it leaking?  FreeBSD added some"if(m) m_free(m);" calls to rtinit() 
back here:  
http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/net/route.c#rev1.67