[patch] interface routes

Alexander V. Chernikov melifaro at FreeBSD.org
Thu Mar 7 11:44:16 UTC 2013


On 07.03.2013 11:39, Andre Oppermann wrote:
> On 07.03.2013 07:34, Alexander V. Chernikov wrote:
>> Hello list!
>>
>> There is a known long-lived issue with interface routes
>> addition/deletion:
>>
>> ifconfig iface inet 1.2.3.4/24 can fail if given prefix is already in
>> kernel route table (for
>> example, advertised by IGP like OSPF).
>>
>> Interface route can be deleted via route(8) or any route socket user
>> (sometimes this happens with
>> popular opensource daemons like bird/quagga).
>>
>> Problem is reported at least in kern/106722 and kern/155772.
> 
> You patch is a welcome addition.
> 
>> This can be fixed the following way:
>> Immutable route flag (RTM_PINNED, added in 19995 with 'for future use'
>> comment) is utilised to mark
>> route 'immutable'.
>> rtrequest1_fib refuses to delete routes with given flag unless
>> RTM_PINNED is set in rti_flags.
> 
> How do the routing daemons react to being unable to change/delete
> such a route?
routing daemons live long with the fact that there route socket cmds can
fail (and the is route(8) utility which can do anything), so typically
bird/quagga yells like
'bird: KRT: Error sending route 11.0.0.0/24 to kernel: File exists'
and marks given route as not installed in internal RIB. Additionally,
daemon will probably re-try to insert such routes on every periodic KRT
rescan (tens of minutes).

Given that such sutiations usually happens for a very short time (e.g.
physical link flaps) everything should become to normal state quickly.

> 
> EADDRINUSE would likely be a more descriptive error instead of EPERM?
Well, not sure if EADDRINUSE is very descriptive for _deleting_ route.
"Yes, I know that it is in use so that's the reason I'm trying to delete
it".

> 
>> Every interface address manupulation is done via rtinit[1], so
>> rtinit1() sets this flag (and behavior does not change here).
>>
>> Adding interface address is handled via atomically deleting old prefix
>> and adding interface one.
> 
> This brings up a long standing sore point of our routing code
> which this patch makes more pronounced.  When an interface link
> state is down I don't want the route to it to persist but to
> become inactive so another path can be chosen.  This the very
> point of running a routing daemon.  So on the link-down event
> the installed interface routes should be removed from the routing
> table.  The configured addresses though should persist and the
> interface routes re-installed on a link-up event.  What's your
> opinion on it?
This is exactly what is done in current code for IPv4:
if_down calls if_unroute(), it cals prctlinput() for every interface
address, and domain-dependent function like rip_ctlinput calls
in_ifscrub() cleaning given interface route.
However, address route (/32) still remains (but route daemons, at least
bird, tends to ignore it since it is not listed as valid interface
address/mask).

This is not done for IPv6 and we should probably do the same.

> 
> Other than these points I think your code is fine and can go
> into the tree.
> 


-- 
WBR, Alexander


More information about the freebsd-net mailing list