21

I'm able change my network routing metrics with ifmetric, for example ifmetric enp0s3 1.

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.1.1     0.0.0.0         UG    1      0        0 enp0s3
0.0.0.0         192.168.237.1   0.0.0.0         UG    100    0        0 enp0s8

When I reboot though, the metric for enp0s3 reverts to 101. How can I make this change permanent or have it set automatically at boot time?

Rui F Ribeiro
  • 55,929
  • 26
  • 146
  • 227
marathon
  • 883
  • 3
  • 10
  • 25

6 Answers6

38

If you are using NetworkManager, the proper way to change the metric for the default route is to modify the connection associated with interface enp0s3 in this way:

nmcli connection modify <connection-name> ipv4.route-metric 1

and then re-activate the connection:

nmcli connection up <connection-name>

You can find the value for <connection-name> in the output of nmcli connection.

bengal
  • 519
  • 1
  • 3
  • 3
  • This does not really answer the question, because it does not do it at boot time, automatically. – MariusMatutiae Apr 01 '20 at 07:02
  • 3
    This is permanent and IMHO answer the question. Be aware, still, that this solution is attached to a connection, not an interface. If you happen to use several connections (typical case: roaming device connecting to various places) on the same interface (the machine's wifi or Ethernet), the operation has to be done for the each of the connections that need metric adjustment. This may or may not be what you want. I feel this is good because you can e.g. say "this specific Wifi costs me money by the byte so put a higher metric", "this Ethernet connection is high-performance, use it in priority". – Stéphane Gourichon Apr 14 '20 at 12:46
  • Unfortunately, it doesn't change the metric of the default gateway immediately, I posted a question here : https://unix.stackexchange.com/questions/625126/networkmanager-doesnt-change-the-metric-of-the-default-gateway-immediately – Aminos Dec 18 '20 at 15:43
  • This is THE answer for systems running NetworkManager – gatopeich Feb 25 '21 at 13:01
  • Related blog post titled "Changing NetworkManager route metrics": http://blog.felipe.lessa.nom.br/?p=129. – Gabriel Staples Mar 08 '21 at 07:45
  • Based on that blog post, you should also modify `ipv6.route-metric`. To give it a priority of `500` (where lower numbers are higher priority, and external WiFi adapters usually start at `600`), use: `nmcli connection modify ipv4.route-metric 500` AND `nmcli connection modify ipv6.route-metric 500`. – Gabriel Staples Mar 08 '21 at 07:47
  • You said, "If you are using NetworkManager...". What is NetworkManager and how do I know if I am using it? I am on Ubuntu 20.04. – Gabriel Staples Mar 08 '21 at 07:50
13

The correct way to do this, in Debian and derivatives, is to write a file in /etc/NetworkManager/dispatcher.d (call it whatever you like), with the following content:

#!/bin/sh

# Change the metric of the default route only on interface enp0s3

IF=$1
STATUS=$2
MY_METRIC=1

if [ "$IF" = "enp0s3" ]
then
        case "$STATUS" in
                up) 
                ip route del default dev $IF
                ip route add default via $DHCP4_ROUTERS dev $IF metric $MY_METRIC
                ;;
                *)
                ;;
        esac
fi

This way, your customization will not be overwritten upon each update. In order to check this, stop the Network Manager, kill the dhclient and flush the IP address of the interface, then restart network manager.

You can find documentation here.

EDIT:

as per FvD request:

systemctl stop network-manager
pkill dhclient
ip addr flush dev eth0   
systemctl start network-manager

if the interface in question is eth0, otherwise change accordingly.

MariusMatutiae
  • 4,363
  • 1
  • 23
  • 36
  • 1
    That's assuming that we're using Network Manager in Debian, which is still not necessarily the case (As in my case, for instance; I dropped it to avoid a systemd-as-init dependency that was causing boot failures at random). Other than that this is still a good answer for most (but definitely not all) Debian users. It works fine on my other system which still uses Network Manager. – Wyatt Ward Mar 31 '20 at 20:24
  • 1
    This answer would benefit from instructions on how to kill the dhclient, flush the IP address of the interface and restart the network manager. – FvD Jun 18 '20 at 03:19
  • 2
    @FvD: done, please read my edit. – MariusMatutiae Jun 18 '20 at 05:14
5

The easiest and the right way to do this is by editing /etc/network/interfaces.
(If this file does not exist, you can create it.)

Here is a simple example of /etc/network/interfaces:

auto lo eth0
iface lo inet loopback

allow-hotplug eth0
iface eth0 inet dhcp
    metric 700

Restart networking using service networking restart for the changes to take place.

Ref: Section 5.7.2. The ifmetric package of Debian Manual

The following sets the eth0 interface to be preferred over the wlan0 interface.

Install the ifmetric package.

Add an option line with "metric 0" just below the "iface eth0 inet dhcp" line in "/etc/network/interfaces".

Add an option line with "metric 1" just below the "iface wlan0 inet dhcp" line in "/etc/network/interfaces".

Extra Note:

  • auto <interface1> <interface2> starts interfaces on start of the system.
  • allow-hotplug <interface> starts the interface on hotplug event.
Jithin Pavithran
  • 503
  • 5
  • 10
  • `/etc/network/interfaces` does not exist on my machine, so this answer is somewhat confusing. – FvD Jun 18 '20 at 03:35
  • This is nearly correct for Raspbian. Instead of editing `/etc/network/interfaces` directly, add a file to `/etc/network/interfaces.d/` with the changes. Example: `sudo vim /etc/network/interfaces.d/wlan1`, add `allow-hotplug wlan1 \ iface wlan1 inet dhcp \ metric 200 ` – Michael Böckling Nov 17 '20 at 21:25
  • @FvD, sorry for noticing late. Hopefully you got the solution - You can simply creat the file. Updated the answer for anyone new looking for this. – Jithin Pavithran Mar 18 '22 at 11:53
  • The addition of "metric" has no effect for me on debian 10. – Graham Leggett Nov 04 '22 at 00:23
5

For Ubuntu

ip route replace default via 192.168.1.1 metric 1

For me, it doesn't require any more steps ever since I type that in and it is still metic 1 until now.

For Centos

The proper way is that you add the above entry to the "/etc/sysconfig/network-scripts/route-eth(x)" except for the ip route replace so add only default via 192.168.1.1 metric 1

Gabriel Staples
  • 2,192
  • 1
  • 24
  • 31
Seandex
  • 201
  • 3
  • 5
  • This doesn't seem to persist, I replaced a route added via IPv6 router advertisement, but the original entry keeps getting recreated with the original (wrong) metric – Ferrybig Nov 16 '21 at 14:08
  • @Ferrybig that could be your some other 3rd software keep changing it. find it and fix it. Linux systems alone don't do themselves. – Seandex Jan 13 '22 at 15:54
  • it was first party software that came with a default installation of Ubuntu. Network manager on Ubuntu is broken for IPv6 and requires the uninstall of the connection check package to respect the interface metrics – Ferrybig Jan 13 '22 at 17:02
  • 1
    This solution worked best for me when having more than 1 active network interface (e.g. two GSM modems) – George Rey Aug 17 '22 at 20:58
2

You should be able to make it permanent in /etc/dhcpd.conf where you can set an interface metric like this.

interface enp0s3;
metric 1;
ProdIssue
  • 855
  • 1
  • 7
  • 20
1
# vim /etc/dhcpcd.conf

interface enp0s3
metric 1

Without semicolon works for me.

Without semicolon

Without semicolon

Tested on

  • Raspberry Pi 4 Model B
  • Raspberry Pi OS Bullseye 32bit
bugggy
  • 11
  • 1
  • 3
  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 14 '23 at 07:32
  • This works when you use dhcpcd which needs to be running as a dhcp client of OS. – undefined Jul 17 '23 at 04:06