[Bug] Static routes with recursive routes not going through filter when next hop changes
Hi, all I recently spotted when filters used with recursive static routes can sometimes fail to work. The minimum case for reproducing this issue is as follows: ``` router id 192.168.0.1; table tab1; table tab2; protocol device { }; protocol static s1 { disabled; table tab1; route 2001:db8::1/128 via fe80::1%eth0; }; protocol static s2 { table tab2; igp table tab1; route 2001:db8::/32 recursive 2001:db8::1; import filter { print "Filter called"; print "dest=", dest; if dest = RTD_UNREACHABLE then { reject; } else { accept; } }; }; ``` Suppose in routing table `tab2`, we want the nexthop of 2001:db8::/32 follows 2001:db8::1 in table `tab1`, only when 2001:db8::1 is reachable. Hence, a filter rejecting unreachable routes is used. In `tab1`, a static protocol `s1` is used to emulate the routing changes there. In actual scenario, the nexthop of 2001:db8::1 may be decided by more complex routing protocols. When bird started, everything looks fine, both routing tables are empty: ``` # ./bird -c bird-test.conf -d -s bird.ctl & bird: Filter called bird: dest=(enum 34)3 bird: Started # ./birdc -s bird.ctl sh route table tab1 BIRD 1.6.8 ready. # ./birdc -s bird.ctl sh route table tab2 BIRD 1.6.8 ready. ``` However, things begin to go wrong when I trigger a change in table `tab1`: ``` # ./birdc -s bird.ctl enable s1 BIRD 1.6.8 ready. bird: Enabling protocol s1 s1: enabled # ./birdc -s bird.ctl sh route table tab1 BIRD 1.6.8 ready. 2001:db8::1/128 via fe80::1 on eth0 [s1 16:20:47] * (200) # ./birdc -s bird.ctl sh route table tab2 BIRD 1.6.8 ready. ``` It seems that the changed route does not going through the filter and failed to be injected into table `tab2`. This also happens when the route is available at start and is withdrawn later. ``` # We edit the configuration and remove the "disabled" statement in protocol s1 # ./bird -c bird-test.conf -d -s bird.ctl & bird: Filter called bird: dest=(enum 34)0 bird: Started # ./birdc -s bird.ctl sh route table tab1 BIRD 1.6.8 ready. 2001:db8::1/128 via fe80::1 on eth0 [s1 16:25:33] * (200) # ./birdc -s bird.ctl sh route table tab2 BIRD 1.6.8 ready. 2001:db8::/32 via fe80::1 on eth0 [s2 16:25:33] * (200) # ./birdc -s bird.ctl disable s1 BIRD 1.6.8 ready. bird: Disabling protocol s1 s1: disabled # ./birdc -s bird.ctl sh route table tab1 BIRD 1.6.8 ready. # ./birdc -s bird.ctl sh route table tab2 BIRD 1.6.8 ready. 2001:db8::/32 unreachable [s2 16:25:32] * (200) ``` Expected behavior: I suggest that when there are any changes to the nexthop of recursive routes, they should be re-filtered. Cheers, Miao Wang
On Sun, Oct 11, 2020 at 04:29:32PM +0800, Wang Shanker wrote:
Hi, all
I recently spotted when filters used with recursive static routes can sometimes fail to work. The minimum case for reproducing this issue is as follows:
Suppose in routing table `tab2`, we want the nexthop of 2001:db8::/32 follows 2001:db8::1 in table `tab1`, only when 2001:db8::1 is reachable. Hence, a filter rejecting unreachable routes is used. In `tab1`, a static protocol `s1` is used to emulate the routing changes there. In actual scenario, the nexthop of 2001:db8::1 may be decided by more complex routing protocols.
It seems that the changed route does not going through the filter and failed to be injected into table `tab2`. This also happens when the route is available at start and is withdrawn later.
Hi (Noticed while looking for some missed / forgotten e-mails) This is more or less expected behavior because recalculation of recursive routes is done in routing tables, not in source protocols. The ugly issue is that import filter may access dependent properties (like immediate gw) and use their initial values. If import filters were re-evaluated after change of recursive nexthops, they may reject the route, route would be removed, and (in case of BGP, who does not keep separate copy of routes propagated to the routing table) could not re-appear again after another change as it would no longer be in the system. -- Elen sila lumenn' omentielvo Ondrej 'Santiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
participants (2)
-
Ondrej Zajicek -
Wang Shanker