Linux for Network Engineers: How to Set Route Priorities

By January 15, 2020Linux

Let’s consider the following scenario: you have a Linux host that has more than one network interface, both are routable and both are up and running. How do you determine which interface or route is used when trying to reach another host? 

In other words the routing table looks like this:$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface         UG    0      0        0 wlan0         UG    202    0        0 eth0   U     202    0        0 eth0   U     0      0        0 wlan0

As you can see, we have a WiFi wlan0 and a wired eth0 interface. 

Obviously, route specificity is the first deciding factor, then comes administrative distance, followed by “Metric,” in this order. In this example, if we try to access both interfaces have the same route specificity and administrative distance. The metric is the deciding factor, and wlan0 with the lower value would be prioritized. 

To remember this relationship think about network packets as electric current flow and metric as resistance: the lower the interface resistance the higher the priority on that interface.


The question is how can you manipulate the metric to suit your needs. A typical use case is having a host with a WiFi and a cellular interface, and prioritize the WiFi one when both are connected. 

The utility that can do this is called ifmetric. It can be installed as follows:

apt-get install ifmetric

It’s very simple to use and does one (and only one) thing, which is to set the metric value on an interface, shown as follows:

ifmetric <interface name> [metric value]

In the example above, wlan0 has higher priority than eth0. If you want to reverse that, you can do the following:$ ifmetric wlan0 203$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface         UG    202    0        0 eth0         UG    203    0        0 wlan0   U     202    0        0 eth0   U     203    0        0 wlan0

Note that now that eth0 has higher priority is listed first in the “route -n” output.

These changes are not permanent and will be reset once the host reboots. To make them permanent you have to add the metric value into its interface configuration file. For example, if you are using dhclient and /etc/network/interfaces, or /etc/network/interfaces.d/<interface name>, the metric value would look like this:$ cat /etc/network/interfaces.d/eth0
auto eth0
allow-hotplug eth0
iface eth0 inet dhcp
metric 1

If you are using dhcpcd then you need the following configuration in /etc/dhcpcd.conf:

interface eth0
metric 0

When the metric is the same for both interfaces, the one listed first in the output of “route -n” is the one that has the higher priority:$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface         UG    0      0        0 wlan0         UG    0      0        0 eth0   U     0      0        0 eth0   U     0      0        0 wlan0

Keep in mind that the metric also depends on the dhcp client that handles the interfaces. For example, if you are using dhcpcd as a DHCP client, according to its configuration, the metrics are configured as follows:

Metrics are used to prefer an interface over another one, lowest wins. dhcpcd will supply a default metric of 200 + if_nametoindex(3). An extra 100 will be added for wireless interfaces.

I haven’t been able to find any documentation about dhclient’s approach to assigning the metric value.