I understand that Linux chooses the most specific route to the destination when it does routing selection. But what about a route's metric? Does it have a higher priority than route's specificity?

A reference to the details of the routing selection algorithm used by Linux would also be appreciated.


The routes metric is to set preference among routes with equal specificity. That is true of routing in general (i.e. Cisco, Windows, etc). So the model works like:

  1. Find the most specific route (aka the longest prefix match*)
  2. If there are multiple routes with the same specificity, pick the one with the lowest administrative distance (This distinguishes between things like directly attached routes, static routes, and various routing protocols).
  3. Within that routing protocol and specific route (if route specificity and administrative distance are the same), chose the route with the lowest metric

Note that there are other things that could be going on such a policy based routing that lets you do things like route based on the source IP address. But route specificity, administrative distance, and then metric are what I would consider to be the main three things.

*It is called the longest prefix match because a subnet in binary (/24 for example) looks like 11111111.11111111.11111111.00000000. So a router can just scan the prefix for binary 1s and stop once it hits a zero, and then it has matched the prefix.

  • 1
    That's not quite true on Linux, where there's no distinction between metric and administrative distance. – jch Dec 20 '14 at 22:49
  • 1
    @jch Does quagga and co. mimic AD by setting the metric accordingly? (Not that your point isn't vital, just curious) – Kyle Brandt Dec 21 '14 at 2:37
  • 1
    No, Quagga implements AD internally in the zebra daemon, and only sends the selected routes to the kernel — so the kernel never needs to deal with AD. I'd need to check, but I think that Quagga sets the kernel metric to a constant value. – jch Dec 21 '14 at 2:39
  • Just want to mention that this doesn't hold true in ethernet bridges, for example two identical routes via different devices with the same metric still resulted in traffic being misdirected over the longer and incorrect link. – Areeb Soo Yasir Aug 17 '17 at 4:58

Linux provides a number of tools for flexible routing selection.

Single routing table

In the simplest case, there is just one kernel routing table and no routes with the SRC attribute. This table contains a number of routes, which were placed there manually (ip route add), by the DHCP daemon, or by routing daemons. In this case, the kernel chooses:

  • the most specific route;
  • if there are multiple equally specific routes, the one with the smallest kernel metric.

Note that the kernel metric (displayed by ip route show) is chosen by the routing daemon, and is not necessarily related to the metric of any particular routing protocol. For example, Quagga uses the same metric for all the routes it installs in the kernel, independently of the protocol's metric.

Source-specific routes

Linux also supports routes with a SRC attribute which only match packets with a given source address. SRC only works for IPv6, and was buggy until very recently (3.11, if memory serves); I don't recommend using it unless you know what you are doing.

Multiple routing tables

If you need more flexibility than the above provides, you will need to play with multiple routing tables, and write rules to choose one particular routing table for each packet. A common technique is to dispatch on source-address in order to simulate source-specific routes. Another technique is to run each routing daemon in its own routing table, and simulate Cisco's "administrative distance". All of this is described in detail in Chapter 4 of the LARTC.

  • That isn't what the src attribute does. You'll want to read man ip-route or other docs. And it does work with IPv4. I use it to get all traffic including the router's traffic through a single net-to-net IPSec tunnel. – Zan Lynx Sep 22 '16 at 20:01
  • 1
    The RTA_SRC attribute does exactly what I said; it can be accessed with the from option of the ip command. The ip command's src option sets the RTA_PREFSRC attribute, which is what you describe. – jch Oct 2 '16 at 15:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.