[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