How to Configure Preferred Network Interface Routing in Linux for Dual-NIC Systems


2 views

In my current setup (Arch Linux machine named "Calcium"), I have two network interfaces with distinct purposes:

  • eth0: Connected to a local router (192.168.10.0/24) with gigabit capability
  • eth1: Directly connected to university network via 10Mbps link

The router's uplink also connects to the same university network through another 10Mbps connection, creating potential routing inefficiencies.

To confirm which interface traffic is currently using:


# Check routing table
ip route show

# Monitor real-time traffic per interface
iftop -i eth0
iftop -i eth1

# Alternative traffic monitoring
nload eth0
nload eth1

We'll use Linux's advanced routing capabilities to create separate routing tables:


# Create custom routing tables
echo "200 internal" >> /etc/iproute2/rt_tables
echo "201 external" >> /etc/iproute2/rt_tables

# Add rules for each table
ip rule add from 192.168.10.0/24 lookup internal
ip rule add from [your_eth1_IP] lookup external

# Populate the routing tables
ip route add default via [router_IP] dev eth0 table internal
ip route add default via [university_gateway] dev eth1 table external

# Flush route cache (if needed)
ip route flush cache

For Arch Linux, create these systemd network configuration files:


# /etc/systemd/network/eth0.network
[Match]
Name=eth0

[Network]
Address=192.168.10.x/24
Gateway=[router_IP]

[Route]
Gateway=[router_IP]
Table=internal
Destination=192.168.10.0/24

# /etc/systemd/network/eth1.network
[Match]
Name=eth1

[Network]
Address=[university_IP]
Gateway=[university_gateway]

[Route]
Gateway=[university_gateway]
Table=external

Verify the configuration works as intended:


# Check which interface is used for specific destinations
ip route get 8.8.8.8
ip route get 192.168.10.1

# Comprehensive route testing
mtr -n 8.8.8.8
mtr -n 192.168.10.1

If you encounter problems:


# Check firewall rules that might interfere
iptables -L -v -n

# Verify rule priority
ip rule list

# Check all routing tables
ip route show table internal
ip route show table external

For systems using NetworkManager:


nmcli connection modify eth0 ipv4.route-table=200
nmcli connection modify eth1 ipv4.route-table=201
nmcli connection modify eth0 ipv4.routing-rules="priority 100 from 192.168.10.0/24 table 200"
nmcli connection modify eth1 ipv4.routing-rules="priority 200 from [university_IP] table 201"
nmcli connection up eth0
nmcli connection up eth1

In this setup, we have a Linux machine (Calcium) running Arch Linux with two network interfaces:

  • eth0: Connected to a local router (192.168.10.0/24) with gigabit capability
  • eth1: Directly connected to university network via 10Mbps link

The router's uplink also connects to the same university network through another 10Mbps connection.

To check current routing behavior, use these commands:

# Show routing table
ip route show

# Check interface metrics
ip route show | grep metric

# Verify default gateway
ip route show default

First, let's examine the current interface settings:

# View all interfaces
ip link show

# Check interface IP addresses
ip addr show

We'll create routing rules to ensure:

  1. 192.168.10.0/24 traffic goes through eth0
  2. All other traffic uses eth1

Method 1: Using iproute2

Create a new routing table for the local network:

# Add a new routing table
echo "200 localnet" >> /etc/iproute2/rt_tables

# Add route for local network
ip route add 192.168.10.0/24 dev eth0 src 192.168.10.x table localnet

# Add default route via eth1
ip route add default via university.gateway dev eth1

Method 2: Using Netplan (Ubuntu/Debian)

For systems using Netplan:

network:
  version: 2
  renderer: networkd
  ethernets:
    eth0:
      addresses: [192.168.10.x/24]
      routes:
        - to: 192.168.10.0/24
          via: 192.168.10.1
          metric: 100
    eth1:
      addresses: [university.ip/xx]
      routes:
        - to: 0.0.0.0/0
          via: university.gateway
          metric: 200

Verify the routing works as intended:

# Test local network route
traceroute 192.168.10.5

# Test external route
traceroute 8.8.8.8

# Check which interface is used for specific destinations
ip route get 192.168.10.1
ip route get 8.8.8.8

For Arch Linux, create a systemd service to make changes permanent:

[Unit]
Description=Custom Network Routing
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/bin/ip route add 192.168.10.0/24 dev eth0 table localnet
ExecStart=/usr/bin/ip route add default via university.gateway dev eth1

[Install]
WantedBy=multi-user.target
  • Check interface metrics with ip route show
  • Verify ARP tables with ip neigh show
  • Inspect network traffic with tcpdump -i eth0 and tcpdump -i eth1
  • Test bandwidth with iperf3 to confirm traffic paths

For more complex scenarios, consider policy routing:

# Create routing rule for local network
ip rule add from 192.168.10.0/24 table localnet

# Create routing rule for all other traffic
ip rule add from all table main