📚 第四章 IP协议
📄 一句话概括

路由表记的是「网络」,不是「主机」,一条记录能覆盖一整段地址。 查表的规则是「最长前缀优先」,越具体的路由越先被选中。

📝 本节和前面几节的关系

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 秒实验

  1. 算一下:一条 /20 的路由能覆盖多少台可用主机?
  2. 想一下:为什么「主机路由」要放在最前面匹配?
  3. 想一下:掩码配错为什么会导致「同网段也连不上」?

常见误区

  1. 以为「路由表里每个 IP 都有一条」。 只记网段,一台主机一条的叫「主机路由」,是特例。
  2. 以为「默认路由优先级最高」。 它最低,任何更具体的前缀都会盖过它。
  3. 以为「下一跳就是最终目的地」。 只是一站,下一跳可能还要再转好几手。
自测三问(点开对答案) 1. 一条路由表项最少要记哪几样? —— **目的网络(地址加掩码)、下一跳、出接口**,再加上度量值用来比较优劣。 2. 同一个目的地命中多条路由时选哪条? —— **掩码最长的那条**,因为它的描述最具体。 3. 什么是「直接交付」? —— **目的地和自己同网段**,直接发 ARP 找 MAC 发过去,不经过网关。

下一节讲「表太长了怎么办」:把多条合成一条。

相关笔记