What’s the meaning of `linkdown` and `onlink’ in Linux Route?
When I typed ip route show : What does linkdown actually mean? Sometimes I can still see onlink . Also want to know what onlink means. Does it affect the routing priority? For example, the case of two default routes in the picture
2 Answers 2
linkdown is the status that will show for a route that is in the table and configured to go out through an interface that is in the DOWN state. You can see this by running:
and looking for the statuses of the interfaces. On my laptop I have wifi on and the Ethernet adapter unplugged so it shows:
wlp3s0: mtu 1500 qdisc mq state UP group default qlen 1000 enp0s25: mtu 1500 qdisc pfifo_fast state DOWN group default qlen 1000
In my routing table I have a number of routes but I can add a couple garbage ones:
sudo ip route add 192.168.123.0/24 dev enp0s25 sudo ip route add 192.168.124.0/24 dev wlp3s0
Then my table will show linkdown for the ethernet route:
192.168.123.0/24 dev enp0s25 scope link linkdown 192.168.124.0/24 dev wlp3s0 scope link
onlink means that the routing should «pretend that the nexthop is directly attached to this link, even if it does not match any interface prefix». So we can make a fake one of those in the table too:
sudo ip route add 192.168.125.0/24 via 192.168.123.111 dev wlp3s0 onlink
Which will now show up in the routing table:
192.168.123.0/24 dev enp0s25 scope link linkdown 192.168.124.0/24 dev wlp3s0 scope link 192.168.125.0/24 via 192.168.123.111 dev wlp3s0 onlink
You can even get fancy and have both if you onlink to the down interface:
192.168.126.0/24 via 192.168.123.111 dev enp0s25 onlink linkdown
This answer does not metion «Does it affect the routing priority?» It seems that the behavior is controlled by ignore_routes_with_linkdown sysctl.
linkdown is the status that will show for a route that is in the table and configured to go out through an interface that is in the DOWN state.
I’ll try to give an example to see what the onlink option really does:
You have configured eth0 (on your machine) with an ip address/mask: 192.168.0.1/24
For some reason, you want to use a gateway on the physical LAN of eth0 which has an inconsistent configuration. Assume it has an address 10.0.10.1/24, which does not match the 192.168.0.1/24 configuration you gave your own machine.
ip route add default dev eth0 via 10.0.10.1
then you will get an error response (network unreachable or something). Why? Because (strictly speaking) it does not make sense to have a machine 10.0.10.1 on the eth0 lan, because you told your computer this lan’s network address is 192.168.0.0/24.
But here it comes: if you add «onlink» to the command, like this:
ip route add default dev eth0 via 10.0.10.1 onlink
then the route is accepted.
But now we come to another question: What does the kernel do if a packet has to routed to this «onlink» gateway? I checked (by experiment), and this is the result: The kernel sends an arp request on the eth0-lan asking «who-has 10.0.10.1», which is the «onlink» gateway you configured. When it receives a response, he has a MAC address where he can send his packets to and routing will be performed.
This means: when the gateway’s address doesn’t match the lan configuration on your computer (eth0), you can force the kernel to use this gateway by adding » onlink » to the statement.
I guess there very rare situations where you have to use this feature. Situations where you need the onlink option will mostly be a case of poor network design. I don’t think the average tunnel setup needs «onlink» either.