- How can I make changes to the network routing metric permanently
- 6 Answers 6
- How can I configure default route metric with dhcp and netplan?
- 1 Answer 1
- Changing the default routing metric with Netplan, NetworkManager and ifupdown
- Fixing Netplan
- Share this:
- Changing the metric of an interface permanently
- 1 Answer 1
How can I make changes to the network routing metric permanently
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?
6 Answers 6
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 ipv4.route-metric 1
and then re-activate the connection:
You can find the value for in the output of nmcli connection .
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».
Unfortunately, it doesn’t change the metric of the default gateway immediately, I posted a question here : unix.stackexchange.com/questions/625126/…
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.
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.
How can I configure default route metric with dhcp and netplan?
My problem is quite similar to this question. My vagrant machine sets default route metric incorrectly. The following is netplan configuration.
network: version: 2 ethernets: enp0s3: dhcp4: true match: macaddress: 02:70:4e:c8:68:e9 enp0s8: dhcp4: false addresses: [192.168.33.10/24] gateway4: 192.168.33.1 routes: - to: 192.168.33.0/24 via: 192.168.33.1 metric: 0
# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.33.1 0.0.0.0 UG 0 0 0 enp0s8 0.0.0.0 10.0.2.2 0.0.0.0 UG 100 0 0 enp0s3 10.0.2.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s3 10.0.2.2 0.0.0.0 255.255.255.255 UH 100 0 0 enp0s3 192.168.33.0 0.0.0.0 255.255.255.0 U 0 0 0 enp0s8 192.168.33.0 192.168.33.1 255.255.255.0 UG 0 0 0 enp0s8
enp0s3 is NAT interface and internet connection should use this. sudo route del default enp0s8 resolves this problem, but adding routes to yaml couldn’t solve the problem and has the limit of fixed gateway. What configuration should I use to reorder metrics automatically?
1 Answer 1
For systems with multiple interfaces, only the interface that should get the default gateway should have «gateway4:» set; keeping in mind that DHCP is quite likely to set the default gateway as well:
network: version: 2 ethernets: enp0s3: dhcp4: true match: macaddress: 02:70:4e:c8:68:e9 enp0s8: dhcp4: false addresses: [192.168.33.10/24]
Note that the additional route you had set is typically unneeded: 192.168.33.0/24 is already reachable, as it is directly connected to the enp0s8 interface in this case (when addresses: lists the subnet already). Having a metric: set to 0 can further confuse the kernel.
If you need the interface with static IP (in this case enp0s8 to have the default gateway instead of the interface that does DHCP, then you can set a route with a metric value lower than 100; so that it is picked before the default gateway set via DHCP by systemd-networkd. For example:
network: version: 2 ethernets: enp0s3: dhcp4: true match: macaddress: 02:70:4e:c8:68:e9 enp0s8: dhcp4: false addresses: [192.168.33.10/24] routes: - to: 0.0.0.0/0 via: 192.168.33.1 metric: 50
Changing the default routing metric with Netplan, NetworkManager and ifupdown
In the past few months I’ve been working on a project, and I’ve been doing the bulk of that work using Vagrant.
By default and convention, all Vagrant machines, set up using Virtualbox have a “NAT” interface defined as the first network interface, but I like to configure a second interface as a “Bridged” interface which gives the host a “Real” IP address on the network as this means that any security appliances I have on my network can see what device is causing what traffic, and I can quickly identify which hosts are misbehaving.
By default, Virtualbox uses the network 10.0.2.0/24 for the NAT interface, and runs a DHCP server for that interface. In the past, I’ve removed the default route which uses 10.0.2.2 (the IP address of the NAT interface on the host device), but with Ubuntu 20.04, this route keeps being re-injected, so I had to come up with a solution.
Fixing Netplan
Ubuntu, in at least 20.04, but (according to Wikipedia) probably since 17.10, has used Netplan to define network interfaces, superseding the earlier ifupdown package (which uses /etc/network/interfaces and /etc/network/interface.d/* files to define the network). Netplan is a kind of meta-script which, instructs systemd or NetworkManager to reconfigure the network interfaces, and so making the configuration changes here seemed most sensible.
Vagrant configures the file /etc/netplan/50-cloud-init.yml with a network configuration to support this DHCP interface, and then applies it. To fix it, we need to rewrite this file completely.
#!/bin/bash # Find details about the interface ifname="$(grep -A1 ethernets "/etc/netplan/50-cloud-init.yaml" | tail -n1 | sed -Ee 's/[ ]*//' | cut -d: -f1)" match="$(grep macaddress "/etc/netplan/50-cloud-init.yaml" | sed -Ee 's/[ ]*//' | cut -d\ -f2)" # Configure the netplan file < echo "network:" echo " ethernets:" echo " $:" echo " dhcp4: true" echo " dhcp4-overrides:" echo " route-metric: 250" echo " match:" echo " macaddress: $" echo " set-name: $" echo " version: 2" > >/etc/netplan/50-cloud-init.yaml # Apply the config netplan apply
When I then came to a box running Fedora, I had a similar issue, except now I don’t have NetPlan to work with? How do I resolve this one?!
Actually, this is a four line script!
#!/bin/bash # Get the name of the interface which has the IP address 10.0.2.2 netname="$(ip route | grep 10.0.2.2 | head -n 1 | sed -Ee 's/^(.*dev )(.*)$/\2/;s/proto [A-Za-z0-9]+//;s/metric 5+//;s/[ \t]+$//')" # Ask NetworkManager for a list of all the active connections, look for the string "eth0" and then just get the connection name. nm="$(nmcli connection show --active | grep "$" | sed -Ee 's/^(.*)([ \t][-0-9a-f])(.*)$/\1/;s/[\t ]+$//g')" # Set the network to have a metric of 250 nmcli connection modify "$nm" ipv4.route-metric 250 # And then re-apply the network config nmcli connection up "$nm"
The last major interface management tool I’ve experienced on standard server Linux is “ifupdown” – /etc/network/interfaces . This is mostly used on Debian. How do we fix that one? Well, that’s a bit more tricky!
#!/bin/bash # Get the name of the interface with the IP address 10.0.2.2 netname="$(ip route | grep 10.0.2.2 | head -n 1 | sed -Ee 's/^(.*dev )(.*)$/\2/;s/proto [A-Za-z0-9]+//;s/metric 8+//;s/[ \t]+$//')" # Create a new /etc/network/interfaces file which just looks in "interfaces.d" echo "source /etc/network/interfaces.d/*" > /etc/network/interfaces # Create the loopback interface file < echo "auto lo" echo "iface lo inet loopback" >> "/etc/network/interfaces.d/lo" # Bounce the interface ifdown lo ; ifup lo # Create the first "real" interface file < echo "allow-hotplug $" echo "iface $ inet dhcp" echo " metric 1000" > > "/etc/network/interfaces.d/$" # Bounce the interface ifdown "$" ; ifup "$" # Loop through the rest of the interfaces ip link | grep UP | grep -v lo | grep -v "$" | cut -d: -f2 | sed -Ee 's/[ \t]+([A-Za-z0-9.]+)[ \t]*/\1/' | while IFS= read -r int do # Create the interface file for this interface, assuming DHCP < echo "allow-hotplug $" echo "iface $ inet dhcp" > > "/etc/network/interfaces.d/$" # Bounce the interface ifdown "$" ; ifup "$" done
Looking for one consistent script which does this all?
#!/bin/bash # This script ensures that the metric of the first "NAT" interface is set to 1000, # while resetting the rest of the interfaces to "whatever" the DHCP server offers. function netname() < ip route | grep 10.0.2.2 | head -n 1 | sed -Ee 's/^(.*dev )(.*)$/\2/;s/proto [A-Za-z0-9]+//;s/metric 2+//;s/[ \t]+$//' >if command -v netplan then ################################################ # NETPLAN ################################################ # Find details about the interface ifname="$(grep -A1 ethernets "/etc/netplan/50-cloud-init.yaml" | tail -n1 | sed -Ee 's/[ ]*//' | cut -d: -f1)" match="$(grep macaddress "/etc/netplan/50-cloud-init.yaml" | sed -Ee 's/[ ]*//' | cut -d\ -f2)" # Configure the netplan file < echo "network:" echo " ethernets:" echo " $:" echo " dhcp4: true" echo " dhcp4-overrides:" echo " route-metric: 1000" echo " match:" echo " macaddress: $" echo " set-name: $" echo " version: 2" > >/etc/netplan/50-cloud-init.yaml # Apply the config netplan apply elif command -v nmcli then ################################################ # NETWORKMANAGER ################################################ # Ask NetworkManager for a list of all the active connections, look for the string "eth0" and then just get the connection name. nm="$(nmcli connection show --active | grep "$(netname)" | sed -Ee 's/^(.*)([ \t][-0-9a-f])(.*)$/\1/;s/[\t ]+$//g')" # Set the network to have a metric of 250 nmcli connection modify "$nm" ipv4.route-metric 1000 nmcli connection modify "$nm" ipv6.route-metric 1000 # And then re-apply the network config nmcli connection up "$nm" elif command -v ifup then ################################################ # IFUPDOWN ################################################ # Get the name of the interface with the IP address 10.0.2.2 netname="$(netname)" # Create a new /etc/network/interfaces file which just looks in "interfaces.d" echo "source /etc/network/interfaces.d/*" > /etc/network/interfaces # Create the loopback interface file < echo "auto lo" echo "iface lo inet loopback" >> "/etc/network/interfaces.d/lo" # Bounce the interface ifdown lo ; ifup lo # Create the first "real" interface file < echo "allow-hotplug $" echo "iface $ inet dhcp" echo " metric 1000" > > "/etc/network/interfaces.d/$" # Bounce the interface ifdown "$" ; ifup "$" # Loop through the rest of the interfaces ip link | grep UP | grep -v lo | grep -v "$" | cut -d: -f2 | sed -Ee 's/[ \t]+([A-Za-z0-9.]+)[ \t]*/\1/' | while IFS= read -r int do # Create the interface file for this interface, assuming DHCP < echo "allow-hotplug $" echo "iface $ inet dhcp" > > "/etc/network/interfaces.d/$" # Bounce the interface ifdown "$" ; ifup "$" done fi
Featured image is “Milestone, Otley ” by “Tim Green ” on Flickr and is released under a CC-BY license.
Share this:
Changing the metric of an interface permanently
This is my routing table when I connect my Android phone via USB to my Raspberry and enable USB-tethering.
$ route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 192.168.42.129 0.0.0.0 UG 204 0 0 usb0 0.0.0.0 192.168.0.1 0.0.0.0 UG 303 0 0 wlan0 192.168.0.0 0.0.0.0 255.255.255.0 U 303 0 0 wlan0 192.168.42.0 0.0.0.0 255.255.255.0 U 204 0 0 usb0
I want wlan0 to be the preferred interface. So how can I change the metric of one the interfaces permanently? Also how does Linux decide which metric value it will use for an interface?
Sorry, but these answers don’t work. 1) I don’t have nmcli. 2) /etc/dhcpd.conf does not exist. 3) /etc/NetworkManager/ does also not exist.
1 Answer 1
One of the solutions is to configure settings in /etc/network/interfaces adding default route with a predefined metric:
auto lo iface lo inet loopback # Primary interface auto wlan0 iface wlan0 inet static address 192.168.0.100 netmask 255.255.255.0 dns-nameservers 192.168.0.1 8.8.8.8 post-up /sbin/ip route add default via 192.168.0.1 dev wlan0 metric 10 post-down /sbin/ip route del default via 192.168.0.1 dev wlan0 metric 10 wpa-ssid wpa-psk
Maybe, you need to add another Wi-Fi options specific to your settings.
Another solution is to change the metric in the /etc/dhcpcd.conf . According to the dhcpcd manual metric can be assigned to the interface:
metric 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.
Add these lines to /etc/dhcpcd.conf :
interface wlan0 metric 200 interface usb0 metric 300
And restart dhcpcd and networking services.