8

If you have (in Linux) these two routes:

default via 192.168.1.1 dev enp58s0f1
default via 192.168.16.1 dev wlp59s0  proto static  metric 600

I would expect that the first one is used, but that's not the case: the second one is used instead.

If I change that to this:

default via 192.168.1.1 dev enp58s0f1  proto static  metric 100 
default via 192.168.16.1 dev wlp59s0  proto static  metric 600

Then it works as expected. It seems that "no metric" is a worse (higher) metric than any number, instead of metric 0.

What is this happening? Is it specific to Linux, or a networking standard?

Thanks in advance.

3

Are you sure about your first observation? What does ip route show or route -n show then? Does the result change if you add proto static in first case?

I have found at least two resources that explicitely says that 0 is the default value in Linux:

A Linux kernel hacker would surely be needed to sort that out.

Also whatever default is chosen is clearly OS specific. This article (https://support.microsoft.com/en-us/help/299540/an-explanation-of-the-automatic-metric-feature-for-ipv4-routes) for example shows that Windows choose the default metric based on the bandwidth of the link.

2

Since these routes are on different subnets, there's more involved here than just the metric. If originating traffic is on the 192.168.1.1 subnet, for instance, and there is a matching non-default route in your routing table, then that route will match via longest prefix match before the metric is ever considered.

Assuming a non-default route is not matching, then having no metric should be interpreted by the kernel as having a metric of 0, and therefore the highest priority route. Although that's a simplistic view because some routing daemons will later translate that default metric into another value like 1024. I expect this is what is happening to you and your unnamed distro.

If ip route shows no metric at all, you can confirm that it is indeed 0 by using the older route -n command from the net-tools package or cat /proc/net/route. However, this output doesn't necessarily match what the routing daemon will use internally when it encounters a 0 metric value.

Furthermore how you create the route matters too. ip route uses the netlink API, while route uses ioctl. The code for how default metrics are created between the two approaches result in different metric values. For instance: creating an IPv6 default route via ip route will result in a metric value of 1024 on RHEL 7, while creating the same route via route will result in a metric of 1.

From RedHat:

  • if nothing is passed to the route command as route metric the value of 1 is used by the command itself.
  • If nothing is passed to the ip command as route metric the attribute is not created at all and kernel understands to it as 0, which is later translated 1024 as default.

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.