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