How to Fix “RTNETLINK answers: File exists” When Adding /23 Route in Linux Networking


3 views

When working with multiple network interfaces in Linux, I encountered an interesting routing behavior while trying to add a /23 network route:

# Attempting to add the /23 route
ip route add 172.21.136.0/23 via 172.21.137.251 dev eth4
RTNETLINK answers: File exists

# But these /24 routes work fine
ip route add 172.21.136.0/24 via 172.21.137.251 dev eth4
ip route add 172.21.137.0/24 via 172.21.137.251 dev eth4

Looking at the routing table reveals why the /23 route conflicts:

# netstat -nr output shows:
172.21.136.0    0.0.0.0         255.255.254.0   U         0 0          0 eth4

The system already has a connected route for the 172.21.136.0/23 network through eth4, which is automatically created when the interface is brought up with that IP address and netmask.

The key points of analysis:

  • The existing connected route (marked with 'U' flag) has higher precedence than our attempted static route
  • Linux routing prefers more specific routes (longer prefixes) first
  • The connected route covers exactly the same network range as our attempted static route

Here are several approaches to handle this situation:

# Option 1: Delete the conflicting route first
ip route del 172.21.136.0/23 dev eth4
ip route add 172.21.136.0/23 via 172.21.137.251 dev eth4

# Option 2: Use more specific /24 routes
ip route add 172.21.136.0/24 via 172.21.137.251 dev eth4
ip route add 172.21.137.0/24 via 172.21.137.251 dev eth4

# Option 3: Change interface configuration
# Edit /etc/sysconfig/network-scripts/ifcfg-eth4 to use a /24 netmask
NETMASK=255.255.255.0
# Then restart networking

For scripted environments, you might want to:

# Check for existing route first
if ! ip route show 172.21.136.0/23 | grep -q via; then
    ip route add 172.21.136.0/23 via 172.21.137.251 dev eth4
fi

Or handle the error case gracefully:

ip route add 172.21.136.0/23 via 172.21.137.251 dev eth4 2>/dev/null || \
echo "Route already exists or another error occurred"

If you need to verify the exact conflict:

# Show all routes for the network
ip route show 172.21.136.0/23

# Get detailed route information
ip -d route show 172.21.136.0/23

While setting up networking on a Linux server with multiple interfaces, I encountered a puzzling routing behavior. The system has two active interfaces:

Bond0: inet addr:170.242.57.113  Bcast:170.242.57.255  Mask:255.255.255.0
Eth4:  inet addr:172.21.136.124  Bcast:172.21.137.255  Mask:255.255.254.0

I configured /etc/sysconfig/network-scripts/route-eth4 with:

ADDRESS0=172.21.136.0
NETMASK0=255.255.254.0
GATEWAY0=172.21.137.251

However, the corresponding routing command failed:

ip route add 172.21.136.0/23 via 172.21.137.251 dev eth4
RTNETLINK answers: File exists

Interestingly, splitting the /23 network into two /24 networks worked:

ip route add 172.21.136.0/24 via 172.21.137.251 dev eth4
ip route add 172.21.137.0/24 via 172.21.137.251 dev eth4

Route table verification showed successful addition:

netstat -nr
Kernel IP routing table
Destination     Gateway         Genmask         Flags   MSS Window  irtt Iface
172.21.137.0    172.21.137.251  255.255.255.0   UG        0 0          0 eth4
172.21.136.0    172.21.137.251  255.255.255.0   UG        0 0          0 eth4
170.242.57.0    0.0.0.0         255.255.255.0   U         0 0          0 bond0
172.21.136.0    0.0.0.0         255.255.254.0   U         0 0          0 eth4
169.254.0.0     0.0.0.0         255.255.0.0     U         0 0          0 eth4
0.0.0.0         170.242.57.251  0.0.0.0         UG        0 0          0 bond0

The problem stems from route conflict detection in the Linux kernel. The system already has a directly connected route for the same network:

172.21.136.0    0.0.0.0         255.255.254.0   U         0 0          0 eth4

This is automatically created when the interface is configured with IP address 172.21.136.124/23. When attempting to add the same network via a gateway, the kernel rejects it as a duplicate route.

Instead of splitting into /24 routes, we should either:

  1. Remove the existing route first:
    ip route del 172.21.136.0/23 dev eth4
    ip route add 172.21.136.0/23 via 172.21.137.251 dev eth4
  2. Or better, use the replace command:
    ip route replace 172.21.136.0/23 via 172.21.137.251 dev eth4

For persistent configuration, modify the interface configuration to avoid the automatic route creation:

# In /etc/sysconfig/network-scripts/ifcfg-eth4
IPADDR=172.21.136.124
NETMASK=255.255.254.0
GATEWAY=172.21.137.251
DEFROUTE=no
PEERDNS=no
ONBOOT=yes

Then define the desired routing explicitly in route-eth4:

172.21.136.0/23 via 172.21.137.251