Bird6 picking up /128 routes from the routing cache
Hi, I noticed something a bit spooky in my lab. Bird6 appears to pick up and export routes that are added to the Linux kernel's routing cache. That is, with a bird6.conf as shown below, if I fire up bird6 in debug mode, and ping a destination with a reduced MTU (to get an ICMPv6 PTB back to trigger caching of the host route due to its lower PMTU): $ ping6 -M do -s 1452 2a01:79d:1234:: # Norwegian ISP using 6RD PING 2a01:79d:1234::(2a01:79d:1234::) 1452 data bytes
From 2a01:798:0:416::a1b:1 icmp_seq=1 Packet too big: mtu=1480
I see the following show up in bird6's stderr: $ /usr/sbin/bird6 -d -u bird -g bird bird: Started bird: Exporting external route ::/0; next-hop=fe80::e611:5bff:fe9b:90e1; source=kernel1 bird: Exporting external route 2a01:79d:1234::/128; next-hop=fe80::e611:5bff:fe9b:90e1; source=kernel1 This route does however *not* show up in Linux' "main" routing table, only in the cache one: $ ip -6 route show table cache 2a01:79d:1234:: via fe80::e611:5bff:fe9b:90e1 dev eth0 metric 0 cache expires 28sec mtu 1480 hoplimit 64 I've seen this both with bird 1.5.0 and 1.6.2, and on Ubuntu kernels 3.13.0 and 4.4.0. Question is, why does this happen? I certainly wouldn't expect it to and if it means that this router would start attracting traffic destined for the host in question I fear it'll create a blackhole/loop. If I change the kernel table number from 254 ("main") to some other random table number, it doesn't happen anymore. To complicate matters further I only see this in my lab. Even though I have the same versions and config in production I cannot see that the same thing happens there. One difference I can think of is that in production the default route is learned from OSPF while in the lab it is learned from SLAAC (and picked up by bird6 that way as shown in the debug output). Not sure if that makes any difference (and if so why). Tore $ cat /etc/bird/bird6.conf router id 192.0.2.1; protocol device {} protocol kernel { learn; export all; import all; kernel table 254; # "main" } protocol ospf { export filter { printn "Exporting external route "; printn net; if defined(gw) then { printn "; next-hop="; printn gw; } if defined(proto) then { printn "; source="; printn proto; } print ""; accept; }; area 0.0.0.0 { interface "eth0" { type broadcast; }; }; }
On Fri, Oct 21, 2016 at 12:50:26PM +0200, Tore Anderson wrote:
Hi,
I noticed something a bit spooky in my lab. Bird6 appears to pick up and export routes that are added to the Linux kernel's routing cache.
The same issue happened with babeld almost four years ago, due to a kernel change (or bug), see this commit: https://github.com/jech/babeld/commit/73d8f6621425c624864e63df98c7e49893da09... Since Bird apparently does not drop RTM_F_CLONED routes received from netlink, I am surprised that this issue has not been noticed earlier. That being said, I just tested with Bird 1.4.5 on Jessie. Even with a kernel filter that imports everyting from the kernel and "learn", the /128 routes do not show up in Bird6, even though they appear in the route cache shown by "ip". Maybe some other part of Bird discards these cloned routes?
That is, with a bird6.conf as shown below, if I fire up bird6 in debug mode, and ping a destination with a reduced MTU (to get an ICMPv6 PTB back to trigger caching of the host route due to its lower PMTU):
$ ping6 -M do -s 1452 2a01:79d:1234:: # Norwegian ISP using 6RD PING 2a01:79d:1234::(2a01:79d:1234::) 1452 data bytes From 2a01:798:0:416::a1b:1 icmp_seq=1 Packet too big: mtu=1480
I see the following show up in bird6's stderr:
$ /usr/sbin/bird6 -d -u bird -g bird bird: Started bird: Exporting external route ::/0; next-hop=fe80::e611:5bff:fe9b:90e1; source=kernel1 bird: Exporting external route 2a01:79d:1234::/128; next-hop=fe80::e611:5bff:fe9b:90e1; source=kernel1
This route does however *not* show up in Linux' "main" routing table, only in the cache one:
$ ip -6 route show table cache 2a01:79d:1234:: via fe80::e611:5bff:fe9b:90e1 dev eth0 metric 0 cache expires 28sec mtu 1480 hoplimit 64
I've seen this both with bird 1.5.0 and 1.6.2, and on Ubuntu kernels 3.13.0 and 4.4.0.
Question is, why does this happen? I certainly wouldn't expect it to and if it means that this router would start attracting traffic destined for the host in question I fear it'll create a blackhole/loop.
If I change the kernel table number from 254 ("main") to some other random table number, it doesn't happen anymore.
To complicate matters further I only see this in my lab. Even though I have the same versions and config in production I cannot see that the same thing happens there. One difference I can think of is that in production the default route is learned from OSPF while in the lab it is learned from SLAAC (and picked up by bird6 that way as shown in the debug output). Not sure if that makes any difference (and if so why).
Tore
$ cat /etc/bird/bird6.conf router id 192.0.2.1;
protocol device {}
protocol kernel { learn; export all; import all; kernel table 254; # "main" }
protocol ospf { export filter { printn "Exporting external route "; printn net; if defined(gw) then { printn "; next-hop="; printn gw; } if defined(proto) then { printn "; source="; printn proto; } print ""; accept; }; area 0.0.0.0 { interface "eth0" { type broadcast; }; }; }
participants (2)
-
Baptiste Jonglez -
Tore Anderson