One of the primary functions of IP routing in a network device, such as a computer, is to identify the optimal path for data packets to navigate across networks, ensuring they arrive at their intended destination.
I am developing a backend and frontend application using a Raspberry Pi 4B. The Pi board connects to several devices via a network switch and operates on a local network with the subnet 192.168.9.x and gateway 192.168.9.1. During the software development process, the Pi board requires internet access for package installation, so I enabled the WiFi to connect to the router.
In the folder /etc/NetworkManager/system-connections, there are ultimately two files created.
The file “Wired connection 1.nmconnection” contains the configuration for eth0 as follows:
[connection]
id=Wired connection 1
uuid=4d969470-7470-3f55-850d-8d997cbc3088
type=ethernet
autoconnect-priority=-999
interface-name=eth0
timestamp=1734795611
[ethernet]
[ipv4]
address1=192.168.9.199/24;192.168.9.1
method=manual
[ipv6]
addr-gen-mode=stable-privacy
method=auto
[proxy]
“Xiaomi_E074.nmconnection” has the configuration for wlan0 as follows
[connection]
id=Xiaomi_E074
uuid=925b9ccc-8e69-4604-9b45-c7dd30b465d0
type=wifi
interface-name=wlan0
[wifi]
mode=infrastructure
ssid=Xiaomi_E074
[wifi-security]
auth-alg=open
key-mgmt=wpa-psk
psk=12345678
[ipv4]
method=auto
[ipv6]
addr-gen-mode=default
method=auto
[proxy]
However, I found that the Pi board is unable to connect to the internet. To troubleshoot this, I decided to check the IP routing on the Pi board. There are several methods to view the routing table on a Raspberry Pi, which indicates how network traffic is directed. The command ip route
is the most common and preferred way to display the routing table, as it is concise and provides all the essential information. I ran the following command in the terminal:
IP route
The routing table shows
default via 192.168.9.1 dev eth0 proto static metric 100
default via 192.168.2.12 dev wlan0 proto dhcp src 192.168.2.230 metric 600
192.168.2.0/24 dev wlan0 proto kernel scope link src 192.168.2.230 metric 600
192.168.9.0/24 dev eth0 proto kernel scope link src 192.168.9.199 metric 100
The IP address of the Pi’s LAN interface (eth0) is set to 192.168.9.199 with a static IP, while the Wi-Fi interface (wlan0) has an IP address of 192.168.2.230 assigned via DHCP. Traffic intended for any IP address within the 192.168.9.0/24 network will be routed directly through the eth0 interface, and traffic for the 192.168.2.0/24 network will be sent through the wlan0 interface. The metric value indicates the priority of the routes, with lower values having higher priority; a metric of 0 indicates the highest priority.
For any traffic directed to a network not explicitly listed in the routing table, typically the internet, it needs to be routed via the router at 192.168.2.12 through the wlan0 interface. However, having two default routes, with the one on wlan0 having a higher metric (and thus lower priority), can result in incorrect routing paths for internet access. As a result, I am unable to ping 8.8.8.8.
In fact, configuring two default routes on a single computer is generally problematic. While the computer may seem to function, it creates an unpredictable and unreliable network environment. The operating system must decide which default gateway to use for traffic destined outside the local network, a choice influenced by metrics (where lower is preferred), interface speed, or even random selection.
To resolve this issue, I plan to change the metric value of the default route on eth0 to give it a lower priority. First, I will remove the default route on eth0.
sudo ip route del default via 192.168.9.1 dev eth0
Then I add back this default with higher metric value, say 1000
sudo ip route add default via 192.168.9.1 dev eth0 metric 1000
Now that I can successfully ping 8.8.8.8, it indicates that there are no issues with internet access. However, I remain uncertain about the reliability of this connection. Additionally, I’m curious about the purpose of the eth0 route if no specific IP is listed. Therefore, I need to check the IP configuration of the destination network via gateway 192.168.9.1 on the eth0 interface and consider adding a static route. To proceed, I will remove the default route on eth0 once more.
sudo ip route del default via 192.168.9.1 dev eth0
Then I add a static route 172.0.0.0/8
through a gateway 192.168.9.1
on the eth0
interface.
sudo ip route add 172.0.0.0/8 via 192.168.9.1 dev eth0
172.0.0.0/8
: The destination network.via 192.168.9.1
: The gateway IP address. dev eth0
: The network interface to use.
As expected, I can ping 8.8.8.8.
The changes I made with ip route
are temporary and will be lost on reboot.
So I add the following to the “Wired connection 1.nmconnection” under [ipv4]
routes=172.0.0.0/8,192.168.9.1
routes=network,gateway,metric
: This line defines the static route. Separate the values with commas. 172.0.0.0/8 is the
destination network. 192.168.9.1
is the gateway IP address. The metric (optional) is omitted, NetworkManager assigns a default metric.
I try to restart the NetworkManager service to apply the changes by running the following command in the terminal:
sudo systemctl restart NetworkManager
But it fails to clear the previous routes. So I reboot the RPi, run “IP route” in the terminal and found the following routing table. It is so frustrating.
default via 192.168.9.1 dev eth0 proto static metric 100
default via 192.168.2.12 dev wlan0 proto dhcp src 192.168.2.230 metric 600
172.0.0.0/8 via 192.168.9.1 dev eth0 proto static metric 100
192.168.2.0/24 dev wlan0 proto kernel scope link src 192.168.2.230 metric 600
192.168.9.0/24 dev eth0 proto kernel scope link src 192.168.9.199 metric 100
Finally, I decide to execute to run the following command every time I reboot the RPi so that it can access to the internet.
sudo ip route del default via 192.168.9.1 dev eth0