TIL - ignore_routes_with_linkdown

Posted by Marcus Folkesson on Tuesday, July 4, 2023

TIL - ignore_routes_with_linkdown

TIL, Today I Learned, is more of a "I just figured this out: here are my notes, you may find them useful too" rather than a full blog post

Usually, a high level network managers such as NetworkManager or Connman, removes routes for unaccessible ("linkdown" or "unplugged") link states.

If these links are not managed by a network manager but are managed in other ways or is somehow misconfigured, then you could end up with a default route that is still hanging around even if the link is down.

It doesn't sound too bad, if it weren't for the fact that it is still active and if its metric value is lower than some other default route, it will be the chosen route.

Consider the following routes:

1# ip route
2default via 10.42.0.1 dev rndis proto static metric 100 linkdown
3default via 192.168.30.1 dev br0 proto static metric 425
410.42.0.0/24 dev rndis proto kernel scope link src 10.42.0.20 metric 100 linkdown
5192.168.30.0/23 dev br0 proto static scope link metric 425
6192.168.30.0/23 dev br0 proto kernel scope link src 192.168.30.97 metric 425

Even if the rndis interface has the "linkdown" flag, Linux will use it as default route regardless (lowest metric value) for any FIB (Forward Information Base) lookup.

/media/ignore_routes_with_linkdown.png

The kernel provide a feature to ignore routes with the link down state; ignore_routes_with_linkdown.

This is a rather old feature [1] introduced in v4.2 and documented [3] as follows:

ignore_routes_with_linkdown - BOOLEAN
        Ignore routes whose link is down when performing a FIB lookup.

When set, the route will not only be set as linkdown but dead linkdown to indicate that the route is currently ignored during a FIB lookup.

The flag could be set with some granuality, both for IPv4/IPv6, all interfaces or just on a single interface. For example:

 1$sysctl -a | grep ignore_routes_with_link
 2net.ipv4.conf.all.ignore_routes_with_linkdown = 0
 3net.ipv4.conf.default.ignore_routes_with_linkdown = 0
 4net.ipv4.conf.docker0.ignore_routes_with_linkdown = 0
 5net.ipv4.conf.enp0s13f0u2u4.ignore_routes_with_linkdown = 0
 6net.ipv4.conf.enp0s31f6.ignore_routes_with_linkdown = 0
 7net.ipv4.conf.eth0.ignore_routes_with_linkdown = 0
 8net.ipv4.conf.lo.ignore_routes_with_linkdown = 0
 9net.ipv4.conf.tun0.ignore_routes_with_linkdown = 0
10net.ipv4.conf.wlp0s20f3.ignore_routes_with_linkdown = 0
11net.ipv6.conf.all.ignore_routes_with_linkdown = 0
12net.ipv6.conf.default.ignore_routes_with_linkdown = 0
13net.ipv6.conf.docker0.ignore_routes_with_linkdown = 0
14net.ipv6.conf.enp0s13f0u2u4.ignore_routes_with_linkdown = 0
15net.ipv6.conf.enp0s31f6.ignore_routes_with_linkdown = 0
16net.ipv6.conf.eth0.ignore_routes_with_linkdown = 0
17net.ipv6.conf.lo.ignore_routes_with_linkdown = 0
18net.ipv6.conf.tun0.ignore_routes_with_linkdown = 0
19net.ipv6.conf.wlp0s20f3.ignore_routes_with_linkdown = 0

Set the flag

The flag could be set in a few different ways:

  • Via sysctl [4] on command line:
1sudo sysctl -w net.ipv4.conf.all.ignore_routes_with_linkdown=1
  • Via sysctl configuration file:
1echo "net.ipv4.conf.all.ignore_routes_with_linkdown = 1" | sudo tee /etc/sysctl.conf
2sudo /sbin/sysctl -p
  • Via procfs:
1echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/ignore_routes_with_linkdown