How to Set Route Priorities

In this blog post I want to explain when and why it is important to set route priorities. 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:

netbeez.net$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 wlan0
0.0.0.0         172.31.0.1      0.0.0.0         UG    202    0        0 eth0
172.31.0.0      0.0.0.0         255.255.255.0   U     202    0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   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 google.com 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. This is the function of route priorities: let’s learn how to set them!

Configuration

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:

netbeez.net$ ifmetric wlan0 203
netbeez.net$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.31.0.1      0.0.0.0         UG    202    0        0 eth0
0.0.0.0         192.168.1.254   0.0.0.0         UG    203    0        0 wlan0
172.31.0.0      0.0.0.0         255.255.255.0   U     202    0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   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: 

netbeez.net$ 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:

netbeez.net$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.254   0.0.0.0         UG    0      0        0 wlan0
0.0.0.0         172.31.0.1      0.0.0.0         UG    0      0        0 eth0
172.31.0.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.1.0     0.0.0.0         255.255.255.0   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. 

decoration image

Get your free trial now

Monitor your network from the user perspective

You can share

Twitter Linkedin Facebook

Let's keep in touch

decoration image