iproute2 Routing Rules vs iptables NAT: Technical Comparison for Multi-ISP Load Balancing


3 views

When dealing with multiple ISP connections, your former IT admin employed a hybrid approach because these tools solve fundamentally different problems:

# Example of iproute2 rules for multi-ISP routing
ip rule add from 192.168.1.100 table isp1
ip route add default via 203.0.113.1 dev eth0 table isp1
ip rule add from 192.168.1.101 table isp2
ip route add default via 198.51.100.1 dev eth1 table isp2

iproute2 operates at the network layer (L3) while iptables NAT works at the transport layer (L4):

  • iproute2: Makes routing decisions based on source IP before any packets hit iptables
  • iptables NAT: Modifies packet headers after routing decisions are made

Here's how both systems work together in a real multi-ISP setup:

# Mark packets for specific routing (iproute2)
iptables -t mangle -A PREROUTING -s 192.168.1.100 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -s 192.168.1.101 -j MARK --set-mark 2

# NAT rules for outbound traffic (iptables)
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 203.0.113.2
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 198.51.100.2

Theoretically yes, but practically no:

  • Pure iptables approach: Would require complex marking and NAT rules, making the firewall ruleset unwieldy
  • Pure iproute2 approach: Couldn't handle source NAT which is essential for outbound traffic

The hybrid approach actually improves performance:

# View routing cache to verify path selection
ip route show table cache
# Compare with NAT table stats
iptables -t nat -L -v -n

The separation of concerns allows each subsystem to handle what it's optimized for - routing decisions happen early in the packet flow, while NAT modifications occur later.


While both iproute2 (with its ip rule and ip route commands) and iptables NAT can influence traffic flow, they operate at different layers of the network stack with distinct purposes:

  • Policy Routing (iproute2): Operates at the routing layer (Layer 3), deciding which interface/ISP to use based on source/destination
  • iptables NAT: Operates at the packet filtering layer, modifying packet headers (source/destination IP/port)

In multi-ISP scenarios, we typically need both mechanisms working together:

# Example iproute2 rules for policy routing
ip rule add from 192.168.1.100 lookup ISP1
ip route add default via 203.0.113.1 dev eth0 table ISP1

ip rule add from 192.168.1.101 lookup ISP2
ip route add default via 198.51.100.1 dev eth1 table ISP2

# Corresponding iptables NAT rules
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 203.0.113.10
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 198.51.100.10

The iproute2 rules ensure outbound packets from specific internal hosts (192.168.1.100 and .101) take the correct ISP path, while NAT is required to translate the private IPs to the respective ISP's public IPs.

You couldn't replace the routing rules with just NAT because:

  • NAT doesn't control the routing decision - it only modifies packets after routing
  • Without proper routing rules, return traffic might come back through the wrong ISP
  • Routing decisions are more efficient when made at the routing layer rather than via packet filtering

Here's a more complete example for a multi-ISP router:

# Create custom routing tables
echo "100 ISP1" >> /etc/iproute2/rt_tables
echo "200 ISP2" >> /etc/iproute2/rt_tables

# ISP1 routing
ip route add 203.0.113.0/24 dev eth0 src 203.0.113.10 table ISP1
ip route add default via 203.0.113.1 table ISP1

# ISP2 routing
ip route add 198.51.100.0/24 dev eth1 src 198.51.100.10 table ISP2
ip route add default via 198.51.100.1 table ISP2

# Main table routes (for non-policy routed traffic)
ip route add 203.0.113.0/24 dev eth0 src 203.0.113.10
ip route add 198.51.100.0/24 dev eth1 src 198.51.100.10
ip route add default via 203.0.113.1  # Default route via ISP1

# Policy rules
ip rule add from 203.0.113.10 table ISP1
ip rule add from 198.51.100.10 table ISP2
ip rule add fwmark 1 table ISP1
ip rule add fwmark 2 table ISP2

# NAT configuration
iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 203.0.113.10
iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 198.51.100.10

# Mark packets for policy routing
iptables -t mangle -A PREROUTING -i lan0 -s 192.168.1.100 -j MARK --set-mark 1
iptables -t mangle -A PREROUTING -i lan0 -s 192.168.1.101 -j MARK --set-mark 2

Modern Linux networking offers alternative approaches that might simplify your setup:

  • nftables: Can sometimes combine routing and NAT logic more cleanly
  • VRF: For more complex multi-tenant routing scenarios
  • BGP: If you have control over both ISPs and want dynamic routing

However, the iproute2+iptables combination remains the most widely compatible and well-documented approach for multi-homing.