Kernel export does not repair a stale `krt_prefsrc` after an external route attribute mutation
水兵
jxshuibei at gmail.com
Tue May 12 08:25:38 CEST 2026
# Title
Kernel export does not repair a stale `krt_prefsrc` after an external route
attribute mutation
# Description
BIRD keeps its control-plane route and kernel export view consistent with
the expected route attributes, but the Linux FIB can remain stale after an
externally mutated route is scanned back from the kernel.
In the reproduced case, BIRD exports `198.51.20.0/24` with `krt_metric = 120
` and `krt_prefsrc = 10.20.0.1`. An external `ip route replace` changes
only the kernel route preferred source to `10.20.0.2`, while keeping the
same prefix, next hop, protocol, and metric. After an unrelated interface
flap and a kernel scan, BIRD still reports that the exported route should
use `Kernel.prefsrc: 10.20.0.1`, but the Linux FIB remains installed with `src
10.20.0.2`.
# Version
Reproduced with:
```text
BIRD 2.18+branch.master.f0f859c26cf9
```
# How to reproduce
1. Create a single-router Linux namespace or VM with two interfaces. Only `
eth0` carries the tested route; `eth1` is used only to trigger an unrelated
interface event.
```text
10.20.0.254
|
10.20.0.1/24
+-------------+
| r1 |
| |
| eth0 eth1 |
+-------------+
|
unrelated link
```
2. Configure BIRD on `r1` with a static source route:
```bird
protocol static static_src {
ipv4;
route 198.51.20.0/24 via 10.20.0.254;
}
```
3. Export the route to the kernel with a fixed metric and preferred source:
```bird
protocol kernel krt_export {
ipv4 {
export filter {
krt_metric = 120;
krt_prefsrc = 10.20.0.1;
accept;
};
};
scan time 2;
}
```
4. Confirm BIRD initially installs the expected Linux route:
```bash
ip route show 198.51.20.0/24
```
Expected initial route:
```text
198.51.20.0/24 via 10.20.0.254 dev eth0 proto bird src 10.20.0.1 metric 120
```
5. Externally mutate the same kernel route to a different preferred source
while keeping the same destination, next hop, protocol, and metric:
```bash
ip route replace 198.51.20.0/24 via 10.20.0.254 dev eth0 proto bird src
10.20.0.2 metric 120
```
6. Flap the unrelated interface and wait longer than the kernel protocol
scan interval:
```bash
ip link set eth1 down
ip link set eth1 up
sleep 3
```
7. Compare BIRD's source/exported route view with the Linux FIB.
# Expected behavior
After the kernel scan, BIRD should notice that the kernel route attributes
no longer match the route it exports and should repair the Linux FIB back
to:
```text
198.51.20.0/24 via 10.20.0.254 dev eth0 proto bird src 10.20.0.1 metric 120
```
# Actual behavior
BIRD's source route and export view still indicate the expected route
with `Kernel.prefsrc:
10.20.0.1`, but the Linux FIB remains stale:
```text
198.51.20.0/24 via 10.20.0.254 dev eth0 proto bird src 10.20.0.2 metric 120
```
# Additional context
The suspected source path is `sysdep/unix/krt.c:krt_got_route()`. The
scan-side comparison checks `sync_map` and `krt_same_dest()`, but it does
not compare exported route eattrs such as `krt_prefsrc`. As a result, a
route with the same destination and kernel key can be treated as
synchronized even though its exported attributes differ from BIRD's
intended route.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://trubka.network.cz/pipermail/bird-users/attachments/20260512/542be145/attachment.htm>
More information about the Bird-users
mailing list