Routing Fundamentals
Routing Fundamentals
Routing is longest-prefix match to a next hop or interface, plus the glue that resolves the next hop to L2. This chapter ties RIB/FIB, metrics, and host vs router behavior into one model you will reuse for statics and dynamic protocols.
Learning goals
By the end of this chapter you can:
- Explain longest prefix match with competing routes
- Distinguish connected, static, and protocol routes
- Resolve next hops (ARP/ND) and see failures when resolution dies
- Use
ip route getas a decision debugger
- Describe host default-route behavior vs multi-interface routers
Concepts
Forwarding equation
For each packet:
- Look up destination in FIB
- Select winning route (longest prefix, then tie-breakers)
- Find egress interface and L2 rewrite target
- Decrement TTL / hop limit; drop if zero
RIB vs FIB
| Store | Role |
|---|---|
| RIB | Routing information: all candidates, protocol owners |
| FIB | What data plane uses for forward |
On Linux, ip route shows kernel FIB. FRR holds protocol RIB and installs selected routes into the kernel via zebra.
ip route
vtysh -c 'show ip route' # FRR RIB viewLongest prefix match
Routes:
0.0.0.0/0via gwA
10.0.0.0/8via gwB
10.1.2.0/24via gwC
Destination 10.1.2.5 → gwC. Destination 10.9.0.1 → gwB. Destination 1.2.3.4 → gwA.
ip route add 10.0.0.0/8 via 192.0.2.1
ip route add 10.1.2.0/24 via 192.0.2.2
ip route get 10.1.2.5Metrics and distance (ideas)
Multiple protocols may offer the same prefix. Selection uses administrative preference (distance) then metric. Linux has metrics on routes; FRR has AD per protocol. Exact numbers differ—model is ranked sources.
Connected routes
Configuring 10.1.0.1/24 on eth1 installs connected route 10.1.0.0/24 dev eth1. Connected usually beats static/default for that space.
Host vs router
| Host | Router |
|---|---|
| Often one default route | Many specific routes |
| Forwards? usually no | ip_forward=1 |
| ARP for on-link and gateway | ARP for each next hop per interface |
| Care about DNS, apps | Care about RIB scale, policy |
Gateway ARP
When host sends off-link:
- Destination IP stays the remote
- Ethernet dest is gateway MAC
# host
ip route get 8.8.8.8
ip neigh show
tcpdump -ni eth1 -e host 8.8.8.8Next-hop resolution failures
Symptom: route exists, ping fails.
ip route get 10.2.0.10
# shows via 10.0.0.2 dev eth1
ip neigh show dev eth1
# if FAILED/INCOMPLETE for 10.0.0.2 → L2 problem or peer downControl vs data: Static route “up” in config does not guarantee next hop resolves.
Asymmetric routing
Forward path R1→R2→R3, return R3→R4→R1. Stateless ping may work; stateful firewalls and some reverse-path filters break.
Always verify both directions.
# from each side
ping -c 2 <other>
traceroute -n <other>Lab: competing prefixes
name: l3-lpm
topology:
nodes:
h1:
kind: linux
image: alpine:3.20
exec:
- apk add --no-cache iproute2 iputils
- ip addr add 192.168.0.10/24 dev eth1
- ip link set eth1 up
- ip route add default via 192.168.0.1
- ip route add 10.1.2.0/24 via 192.168.0.2
r1:
kind: linux
image: alpine:3.20
exec:
- apk add --no-cache iproute2 iputils
- ip addr add 192.168.0.1/24 dev eth1
- ip link set eth1 up
r2:
kind: linux
image: alpine:3.20
exec:
- apk add --no-cache iproute2 iputils
- ip addr add 192.168.0.2/24 dev eth1
- ip link set eth1 up
links:
- endpoints: ["h1:eth1", "r1:eth1"]
# NOTE: for a real multi-router demo, use a bridge multipoint or
# connect h1-r1 and h1-r2 carefully; simplest teaching variant below.Cleaner multipoint teaching lab: one LAN bridge with h1, gw1, gw2:
name: l3-lpm
topology:
nodes:
br0:
kind: linux
image: alpine:3.20
binds: ["./config/br.sh:/startup.sh"]
cmd: /bin/sh /startup.sh
h1:
kind: linux
image: alpine:3.20
exec:
- apk add --no-cache iproute2 iputils
- ip addr add 192.168.0.10/24 dev eth1 && ip link set eth1 up
- ip route add default via 192.168.0.1
- ip route add 10.1.2.0/24 via 192.168.0.2
gw1:
kind: linux
image: alpine:3.20
exec:
- apk add --no-cache iproute2 iputils
- ip addr add 192.168.0.1/24 dev eth1 && ip link set eth1 up
gw2:
kind: linux
image: alpine:3.20
exec:
- apk add --no-cache iproute2 iputils
- ip addr add 192.168.0.2/24 dev eth1 && ip link set eth1 up
links:
- endpoints: ["h1:eth1", "br0:eth1"]
- endpoints: ["gw1:eth1", "br0:eth2"]
- endpoints: ["gw2:eth1", "br0:eth3"]Predict / observe
docker exec clab-l3-lpm-h1 ip route get 10.1.2.5
# expect via 192.168.0.2
docker exec clab-l3-lpm-h1 ip route get 10.9.0.1
# expect via 192.168.0.1 (default) if no better routeLab: router with two interfaces
# r1
sysctl -w net.ipv4.ip_forward=1
ip addr add 10.1.0.1/24 dev eth1
ip addr add 10.2.0.1/24 dev eth2
# hosts with defaults via r1Predict: Connected routes cover both LANs; hosts need default only; r1 needs no static for inter-LAN.
Observe:
ip route
ip route get 10.2.0.10 from 10.1.0.10 iif eth1ARP/ND deep enough for routing
| IPv4 | IPv6 |
|---|---|
| ARP request/reply | NS/NA |
ip neigh |
ip -6 neigh |
| Broadcast | Multicast solicited-node |
ip monitor neighFlush for drills:
ip neigh flush dev eth1TTL and traceroute
Each hop decrements TTL. Traceroute infers path from ICMP time exceeded.
traceroute -n 10.2.0.10
# or
mtr -rwzc 20 10.2.0.10Filters that drop ICMP break traceroute but not always data—note for ops.
Policy preview
Policy routing (ip rule) can select alternate tables. Out of scope for depth here; know it exists when “ip route get” surprises you with marks/fwmasks.
ip rule listPredict → observe → fix drills
Drill: missing return route
Two routers between hosts; only one direction has statics.
Symptom: requests arrive, replies die.
Fix: install return route.
Harden: verify.sh pings both ways.
Drill: wrong gateway MAC path
Shut gateway interface; host neigh becomes FAILED.
ip neigh show
ping -c 2 <offlink>Drill: more-specific shadow
Add junk more-specific blackhole:
ip route add 10.2.0.10/32 via 192.0.2.254
# 192.0.2.254 dead
ping 10.2.0.10 # fail despite broader working route
ip route del 10.2.0.10/32Cheatsheet
ip route
ip route get 1.2.3.4
ip route add 10.0.0.0/8 via 192.168.0.1 metric 100
ip route del 10.0.0.0/8 via 192.168.0.1
ip neigh show
sysctl net.ipv4.ip_forwardSummary
- Longest prefix match drives selection
- Connected, static, and dynamic routes feed RIB→FIB
- Next hop must resolve at L2
- Hosts mostly default; routers interconnect prefixes
- Bidirectional reachability is the real goal
Next: static routing labs—triangles, floating statics, and deliberate failover.