Every host has a routing table
Routing is not a router-only activity. Your laptop makes a routing decision for every single packet it sends, using a table it already has. Print yours:
ip route show
default via 192.168.1.1 dev eth0 proto dhcp metric 100 10.8.0.0/24 via 192.168.1.9 dev eth0 proto static metric 50 169.254.0.0/16 dev eth0 scope link metric 1000 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.42
Four lines, and each one is a rule of the form "to reach this destination prefix, do this". Read the fields:
| Field | Meaning |
|---|---|
| the prefix at the start | destination network this rule covers |
via X | send it to the router at X, the next hop |
no via | the destination is directly attached, ARP for it |
dev eth0 | send out this interface |
scope link | reachable on this link without a router |
proto | who installed the route, kernel, dhcp, static, or a daemon |
metric | preference when two routes tie, lower wins |
src | which source address to stamp on packets using this route |
Line four is the connected route, installed automatically when the interface got 192.168.1.42/24. Line one is the default route. Line two is a static route to a network reachable through a different router on the same link. Line three is the link local range from Lesson 4-2, which should never leave the host.
Longest prefix match
More than one line can match a destination, so a router needs a tie breaker. The rule is the single most important sentence in this unit:
The route with the longest prefix that contains the destination wins, regardless of order in the table, regardless of metric.
Longer prefix means more specific, and more specific means better information. Metric only breaks ties between routes of the same prefix length.
Work an example. Suppose a router holds these four routes:
| Route | Prefix length | Next hop |
|---|---|---|
| 0.0.0.0/0 | 0 | 203.0.113.1 |
| 10.0.0.0/8 | 8 | 10.1.0.1 |
| 10.20.0.0/16 | 16 | 10.20.0.1 |
| 10.20.30.0/24 | 24 | 10.20.30.1 |
Where does a packet for each destination go?
| Destination | Matches | Winner | Next hop |
|---|---|---|---|
| 10.20.30.55 | all four | /24 | 10.20.30.1 |
| 10.20.99.7 | /0, /8, /16 | /16 | 10.20.0.1 |
| 10.55.1.1 | /0, /8 | /8 | 10.1.0.1 |
| 93.184.216.34 | /0 only | /0 | 203.0.113.1 |
Check one by hand so the mechanism is not magic. Does 10.20.99.7 match 10.20.30.0/24? AND the address with 255.255.255.0 and you get 10.20.99.0, which is not 10.20.30.0, so no. Does it match 10.20.0.0/16? AND with 255.255.0.0 gives 10.20.0.0, which matches, so yes. The most specific match that survives is the /16.
This rule is why a /32 host route always wins over everything, and it is the standard trick for pushing one address down a different path than its neighbors.
The default route
0.0.0.0/0 has zero network bits, so it matches every address in existence, and
because it is the shortest possible prefix it loses to every other match. That is
exactly the behavior you want from "if nothing else fits, send it here".
The next hop of the default route is the default gateway, and it must be an address on a network you are directly attached to. You cannot point a default route at a router three networks away, because you would have no way to reach it.
Three consequences worth stating plainly:
- A host with no default route can reach only its own connected networks.
This is a very common symptom, and ip route shows it in one glance.
- A default route does not mean "the internet". It means "the direction of
everything I do not have a better answer for".
- Core internet routers have no default route at all. They must hold a
specific route for every reachable prefix on the planet, which is roughly a
million entries and is called a full table. That is why aggregation from
Lesson 4-4 matters.
ip route get 93.184.216.34
93.184.216.34 via 192.168.1.1 dev eth0 src 192.168.1.42 uid 1000
ip route get runs the real lookup for one address and prints the winner, which
makes it the fastest way to answer "why is this traffic going out that way".
What a table looks like on a real router
A router's table is the same idea with more sources of information. This is a trimmed view in a vendor neutral style, where the letter marks how the route was learned.
Codes: C connected, S static, O OSPF, B BGP C 10.20.30.0/24 is directly connected, eth1 C 203.0.113.0/30 is directly connected, eth0 S 10.99.0.0/16 [1/0] via 10.20.30.9 O 10.20.40.0/24 [110/20] via 10.20.30.2, 00:14:21, eth1 O 10.20.50.0/24 [110/30] via 10.20.30.2, 00:14:21, eth1 B 198.51.100.0/24 [20/0] via 203.0.113.2, 02:41:07 S 0.0.0.0/0 [1/0] via 203.0.113.2
The bracketed pair is [administrative distance / metric]. Administrative
distance ranks how much the router trusts the source of a route, and it only
matters when two different protocols offer the same prefix. Lower is more
trusted.
| Source | Typical distance |
|---|---|
| Connected | 0 |
| Static | 1 |
| BGP, external | 20 |
| OSPF | 110 |
| RIP | 120 |
So if OSPF and a static route both offer 10.99.0.0/16, the static route wins on distance 1 versus 110. But if OSPF offers 10.99.0.0/17 and the static offers 10.99.0.0/16, OSPF wins, because prefix length is checked first and distance never overrides it. Getting that order backwards is a classic source of confusion, so keep it in this sequence: longest prefix, then distance, then metric.