Octet

How do you find out exactly which route, interface and source address Linux will use for a destination?

Show the answer

Say this first

ip route get <destination> asks the kernel to do the real lookup, through the policy rules and every table, and prints the chosen next hop, output interface and source address. I add from, iif, oif or mark to simulate other traffic, for example a packet arriving on a given interface. It beats reading the table by eye whenever policy routing, ECMP or a cached path MTU is involved.

Go deeper

Examples

Output
$ ip route get 172.16.41.9
172.16.41.9 via 10.0.10.254 dev ens192 src 10.0.10.21 uid 1000
    cache

The kernel matched 172.16.40.0/22 via 10.0.10.254 and will source from 10.0.10.21.

Shell
ip route get 198.51.100.80 from 203.0.113.10    # what does traffic sourced from this IP do
ip route get 198.51.100.80 mark 0x2              # what does marked traffic do
ip route get 10.0.99.21 from 10.0.50.10 iif ens224   # simulate a packet arriving on ens224

Source address selection

If the route has a src hint, Linux uses it. Otherwise it picks the primary address of the output interface whose scope fits the destination. Applications can override it by binding to an address.

Two things it reveals that ip route does not

  • Reverse path filter drops. Simulating an inbound packet with iif returns RTNETLINK answers: Invalid cross-device link when rp_filter would drop it.
  • Path MTU. If the kernel learned a smaller MTU from an ICMP "fragmentation needed", the output shows cache expires 412sec mtu 1400.

Traps

  • Trusting a hand reading of ip route on a host with ip rule entries. Let the kernel do the lookup.
How did you do?