How to Determine the Network Interface and Source IP for a Specific Route in Linux


1 views

When working with multi-homed Linux systems, it's crucial to understand which network interface and source IP will be used for outbound connections. The routing decision is made based on the kernel's routing table, which can be complex to interpret manually.

The most efficient way to check the route for a specific destination is using the ip route get command:

ip route get 8.8.8.8
8.8.8.8 via 192.168.1.1 dev eth0 src 192.168.1.100 
    cache

This output shows:

  • Destination: 8.8.8.8
  • Gateway: 192.168.1.1
  • Interface: eth0
  • Source IP: 192.168.1.100

For understanding the complete path including interface selection:

traceroute -i any example.com

The first hop will reveal the outgoing interface.

To verify the source IP that will be used:

ip route get to 8.8.8.8 | grep -oP 'src \K[^ ]+'

Consider a server with two interfaces:

ip addr show
1: lo: ...
2: eth0: inet 192.168.1.100/24
3: eth1: inet 10.0.0.2/24

For a destination in 192.168.1.0/24:

ip route get 192.168.1.50
192.168.1.50 dev eth0 src 192.168.1.100 
    cache

For an external destination:

ip route get 1.1.1.1
1.1.1.1 via 192.168.1.1 dev eth0 src 192.168.1.100

When using multiple routing tables (policy routing), you might need to specify the table:

ip route get 8.8.8.8 table 100

For automated checks, use this bash function:

get_route_info() {
    dest=$1
    echo "Route information for $dest:"
    ip route get "$dest" | awk -F'[ ]' '/src/ {print "Interface:",$3,"\nSource IP:",$5}'
}

When dealing with multi-homed Linux systems, identifying the exact network path for specific destinations becomes critical for network debugging and configuration. The standard routing table output can be overwhelming when you just need to know:

  • Which physical interface handles traffic for a specific host
  • What source IP address will be used
  • Whether multiple paths exist

The most precise tool for this task is ip route get, which performs a route lookup simulation:

ip route get 8.8.8.8
# Output example:
# 8.8.8.8 via 192.168.1.1 dev eth0 src 192.168.1.100 uid 1000

For DNS-based destinations, combine with dig for complete analysis:

destination="example.com"
ip route get $(dig +short $destination | head -1) | \
  awk '{print "Interface: " $3 "\nSource IP: " $5}'

Using tracepath:

tracepath -n example.com | head -2

Network Namespace Variation:

ip netns exec namespace_name ip route get 10.0.0.5

Case 1: Multiple default routes

# With routing table:
# default via 192.168.1.1 dev eth0
# default via 10.0.0.1 dev eth1

ip route get 1.1.1.1 | grep -oP 'dev \K\S+'  # Shows active interface

Case 2: Policy-based routing

ip rule list
ip route get 8.8.8.8 from 10.0.0.5

Create a reusable bash function for your shell:

routeinfo() {
  local dest=$(dig +short $1 | head -1)
  [ -z "$dest" ] && dest=$1
  echo "Route analysis for $1 ($dest):"
  ip route get $dest | awk '{print "Interface:",$3,"| Source IP:",$5}'
}
  • If encountering "RTNETLINK answers: Invalid argument", try using the numeric IP
  • For containers/VMs, check both host and guest routing tables
  • Remember that iptables/nftables might affect source address selection