[Bug] Static routes with recursive routes not going through filter when next hop changes
Wang Shanker
shankerwangmiao at gmail.com
Sun Oct 11 10:29:32 CEST 2020
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
More information about the Bird-users
mailing list