路由表记的是「网络」,不是「主机」,一条记录能覆盖一整段地址。 查表的规则是「最长前缀优先」,越具体的路由越先被选中。
4.3 讲的是「地址长什么样」,这一节讲「地址怎么被用来找路」。 4.2.2 提过路由控制的概念,这里把它落到表上:表项、匹配、下一跳。
一、路由表里记了什么
一条路由表项只有四个关键字段:
| 字段 | 含义 | 例子 |
|---|---|---|
| 目的网络 | 网络地址加掩码 | 192.168.3.0/24 |
| 下一跳 | 交给谁 | 192.168.3.1 |
| 出接口 | 从哪个网卡发 | WLAN |
| 度量值 | 哪条更优 | 越小越优先 |
第一行是这张表的灵魂:它记的是「一段」,所以一个 /24 只用一行就能覆盖 254 台主机。 如果按主机记,全球几十亿台设备就要几十亿行——这张表根本存不下,也查不动。 第三行的「出接口」常被忽略:下一跳是「给谁」,出接口是「从哪儿给」。 在同一条链路上,下一跳和出接口是一一对应的;但在有多条链路的路由器上,两者要分别指定。
二、匹配规则:最长前缀优先
同一个目的地可能同时命中好几条路由,这时选「掩码最长」的那条——因为它描述得最具体。
| 路由 | 能命中的目的地 | 优先级 |
|---|---|---|
| 0.0.0.0/0 | 全部 | 最低 |
| 10.0.0.0/8 | 10 开头的全部 | 中 |
| 10.1.0.0/16 | 10.1 开头的全部 | 高 |
| 10.1.2.3/32 | 只有这一台 | 最高 |
四行同时存在时,去 10.1.2.3 会走最后一行,去 10.1.9.9 走第二行,去 10.2.3.4 走第一行。 这就是「越具体越优先」的实际样子。 最后一行那种 /32 叫「主机路由」:它只圈一台机器,用来「临时给某台设备指一条特殊的路」。 加一条主机路由不影响别的流量,这是运维里最常用的「精准手术」。
三、直接交付与间接交付
同一个网段内的目的地,不用问网关: 自己发 ARP 问「这个 IP 是谁的 MAC」,然后直接把帧发过去。 这叫「直接交付」。 跨网段才把包交给下一跳,由它继续往下转,这叫「间接交付」。
| 目的地 | 怎么发 | 要不要网关 |
|---|---|---|
| 192.168.3.20(同网段) | ARP 找 MAC 直接发 | 不要 |
| 8.8.8.8(跨网段) | 发给 192.168.3.1 | 要 |
判断「是不是同网段」靠的是自己的掩码: 本机 192.168.3.152/24,掩码算出网段是 192.168.3.0/24,所以 192.168.3.x 都算同网段。 换个掩码,判断结果就变了——这也是「掩码配错就连不上」的原因。
四、表是谁填进去的
两种来源,界限很清楚:
| 方式 | 谁负责 | 适用场景 |
|---|---|---|
| 静态路由 | 人手工写 | 条目少、要精确控制 |
| 动态路由 | 路由协议自动算 | 条目多、会变化 |
动态路由的三种常见协议:RIP 按「跳数」算、OSPF 按「链路代价」算、BGP 按「策略」算。 前两个用在「一个组织内部」,BGP 用在「运营商之间」。 家里的路由器其实也用动态路由(DHCP 会顺带下发默认路由), 只是你感觉不到——插上网线就能上网,背后就是表被填好了。
五、动手 Demo:一条路由覆盖一整段,不覆盖一台
先算「一段前缀能圈多大」,再看本机真实的四条路由。 注意第四列:按主机记要十亿条,按 /24 记只要几百万条。
hosts = 10 ** 9
for p in (0, 8, 16, 20, 24, 32):
n = 2 ** (32 - p)
need = max(1, -(-hosts // max(n - 2, 1)))
print('/%-3d %12d 1/%-12d %d' % (p, n, 2 ** p, need))
实跑输出:
--------------------------------------------------------------------
一条路由覆盖一整段,不覆盖一台
--------------------------------------------------------------------
**路由表的每一条记的是「一段地址」**——**网络地址加掩码,就圈定了一段连续的范围。**
**所以表的大小取决于「段有多少」,不取决于「主机有多少」。**
**先看一段前缀能圈多大**(第四列按「10 亿台主机」估算条数):
前缀 覆盖地址数 占全部地址 覆盖 10 亿台要几条
------------------------------------------------------------
/0 4294967296 1/1 1
/8 16777216 1/256 60
/16 65536 1/65536 15260
/20 4096 1/1048576 244260
/24 256 1/16777216 3937008
/32 1 1/4294967296 1000000000
**第一行和最后一行的差距就是路由表存在的理由**:**/0 一条顶全部,/32 一条只管一台。**
**所以「上网」这件事,本机路由表里通常只有三五条**——**一段内网、一条默认路由,就够了。**
**看本机真实的表**:
目的网段 下一跳 地址数 作用
---------------------------------------------------------------------
0.0.0.0/0 192.168.3.1 4294967296 默认路由,兜底
192.168.3.0/24 直接交付 256 本网段,不用网关
127.0.0.0/8 本机 16777216 回环
192.168.3.152/32 本机 1 自己的地址
**第二行那句「直接交付」很关键**:
**同一个网段内的目的地不用问网关,自己发 ARP 找对方的 MAC 就行。**
**只有跨网段才把包交给下一跳**——**这就是「一条路由」和「一次转发」的区别。**
**最后说清「主机路由」**:**掩码 32 位全 1,只圈一台,用来「专门给某台机器指一条路」。**
**它在匹配时优先级最高**(最长前缀优先),**所以「临时改一台机器的出口」不用动别的条目。**
第一行 /0 的「1 条」和最后一行 /32 的「10 亿条」是同一个问题的两端:
一条路由覆盖得越宽,表就越小,但越不精确。
真实网络是「两种都要」——骨干用 /8 到 /16 的粗粒度,接入层用 /24 的细粒度。
第二张表里 192.168.3.152/32 这条容易让人困惑:「自己的地址为什么也要一条路由?」
因为发给自己的包不该出门——这条 /32 把它指回本机,等于「照镜子」。
127.0.0.0/8 那条更极端:整段 1600 多万个地址都指回本机,
所以 ping 127.0.0.1 永远通,哪怕网线拔了。
这也是排查「协议栈有没有坏」的最快办法。
30 秒实验
- 算一下:一条 /20 的路由能覆盖多少台可用主机?
- 想一下:为什么「主机路由」要放在最前面匹配?
- 想一下:掩码配错为什么会导致「同网段也连不上」?
常见误区
- 以为「路由表里每个 IP 都有一条」。 只记网段,一台主机一条的叫「主机路由」,是特例。
- 以为「默认路由优先级最高」。 它最低,任何更具体的前缀都会盖过它。
- 以为「下一跳就是最终目的地」。 只是一站,下一跳可能还要再转好几手。
自测三问(点开对答案)
1. 一条路由表项最少要记哪几样? —— **目的网络(地址加掩码)、下一跳、出接口**,再加上度量值用来比较优劣。 2. 同一个目的地命中多条路由时选哪条? —— **掩码最长的那条**,因为它的描述最具体。 3. 什么是「直接交付」? —— **目的地和自己同网段**,直接发 ARP 找 MAC 发过去,不经过网关。下一节讲「表太长了怎么办」:把多条合成一条。
- ☐ (本节完,下一节 4.4.2 路由控制表的聚合)