路由器多出来的能力只有一条:把一段网络接到另一段网络。 查路由表的规则叫「最长前缀优先」,没有例外。
1.9.4 的交换机「只看 MAC、只管一段」,路由器往上走了一层。 这一节要把「最长前缀」这条规则记牢,排障时第一个用到它。
一、它比交换机多做了什么
四件事,前三件交换机都不做:
| 动作 | 交换机 | 路由器 |
|---|---|---|
| 看 IP 头 | 不看 | 看 |
| 改帧头 | 不改 | 每一跳都改 MAC |
| TTL 减一 | 不做 | 必做 |
| 选路 | 不需要 | 查路由表 |
第二行是「链路层只管一段」的直接结果:
路由器把包从一段送到另一段,帧头的 MAC 必须换成新一段的。
所以跨网段抓包时,你会看到同样的 IP 包被装进不同的帧里——
这不是重复抓包,是同一份数据换了外衣。
第三行那个 TTL 是防环的:每过一个路由器减一,减到 0 就丢弃并回一个 ICMP 超时。
这就是 traceroute 的原理——故意发 TTL 很小的包,看每一跳是谁回的错。
没有 TTL,一次路由环路就能让网络彻底瘫痪。
二、最长前缀优先
路由表里可能有多条都「匹配」,规则是选前缀最长的:
| 条目 | 前缀长度 | 含义 |
|---|---|---|
| 0.0.0.0/0 | 0 | 默认路由(兜底) |
| 192.168.0.0/16 | 16 | 整个 192.168 段 |
| 192.168.3.0/24 | 24 | 本网段 |
| 192.168.3.128/25 | 25 | 本网段后半 |
查三个地址就明白这条规则:
| 目的地址 | 命中条目 | 前缀 |
|---|---|---|
| 192.168.3.200 | 192.168.3.128/25 | 25 |
| 192.168.3.10 | 192.168.3.0/24 | 24 |
| 8.8.8.8 | 0.0.0.0/0 | 0 |
第一行那个地址同时匹配四条,最后选了 /25——因为前缀最长、最具体。 「越长越具体」这件事保证了「更细的配置能覆盖更笼统的配置」, 所以你可以只给某一小段单独指定下一跳。 第三行那个 8.8.8.8 只匹配默认路由:默认路由就是「谁都匹配不上时兜底」的那一条。 排障时如果发现流量走了错的路,第一件事就是查有没有更长的前缀—— 多一条 /32 的主机路由,就能让整段流量改道。
三、路由器与三层交换机
功能重叠,位置不同:
| 对比项 | 路由器 | 三层交换机 |
|---|---|---|
| 转发方式 | 软件查表 | 硬件 ASIC |
| 端口 | 少而贵 | 多而便宜 |
| 功能 | NAT、防火墙、VPN | 以转发为主 |
| 典型位置 | 出口、跨地域 | 机房内部 |
第一行决定了两者的性能差:软件转发要经过 CPU 与内存,硬件转发走专用芯片, 所以三层交换机在局域网内部能跑到线速,路由器往往跑不到。 但路由器的强项在「功能多」——NAT、策略路由、VPN 这些都要改包,硬件做不了。 第四行是选型的实际依据: 机房内部要的是「快、便宜、口多」→ 三层交换机;出口要的是「功能全、能改包」→ 路由器。 今天很多设备两者兼有,但「快」与「功能全」在硬件上是矛盾的,所以分工还是存在。 别忘了 1.8.2 那条:大网络要三层到边缘, 因为二层只能靠泛洪与学习,扩展性差——这就是三层交换机在机房里普及的根本原因。
四、动手 Demo:路由器查表,查的是「最长前缀」
建一张有四条目的路由表,拿三个地址去查。 重点是第一个地址同时匹配四条,最后选了谁。
def n(s):
return sum(int(x) << (8 * (3 - i))
for i, x in enumerate(s.split('.')))
table = [('0.0.0.0', 0, '默认路由'),
('192.168.0.0', 16, '整个 192.168 段'),
('192.168.3.0', 24, '本网段'),
('192.168.3.128', 25, '本网段后半')]
for ip in ('192.168.3.200', '192.168.3.10', '8.8.8.8'):
best, blen = None, -1
for net, plen, note in table:
m = ((1 << plen) - 1) << (32 - plen) if plen else 0
if (n(ip) & m) == (n(net) & m) and plen > blen:
best, blen = (net, plen, note), plen
print('%-16s → %-18s /%-3d %s'
% (ip, best[0], best[1], best[2]))
实跑输出:
--------------------------------------------------------------------
路由器查表,查的是「最长前缀」
--------------------------------------------------------------------
**路由表里可能有多条都「匹配」的条目**,规则是选前缀最长的那条。
假设表里有这四条:
条目 前缀长度 含义
--------------------------------------------------
0.0.0.0/0 0 默认路由
192.168.0.0/16 16 整个 192.168 段
192.168.3.0/24 24 本网段
192.168.3.128/25 25 本网段后半
现在查三个地址:
目的地址 命中条目 前缀 为什么
-----------------------------------------------------------
192.168.3.200 192.168.3.128/25 25 本网段后半
192.168.3.10 192.168.3.0/24 24 本网段
8.8.8.8 0.0.0.0/0 0 默认路由
**第一行那个 192.168.3.200 同时匹配四条**,最后选了 /25——**因为前缀最长,最具体。**
**第三行那个 8.8.8.8 只匹配默认路由**——**这就是「默认路由」的作用:谁都匹配不上时兜底。**
**「最长前缀优先」是路由表的核心规则,没有例外**:**它保证了「更具体的配置能覆盖更笼统的配置」。**
**排障时如果发现流量走了错的路,第一件事就是查有没有更长的前缀。**
三个地址分别命中 /25、/24、/0:第一个同时匹配四条,取最长;第三个只匹配默认路由。 注意 /0 那一条的掩码是全 0,所以它与任何地址做按位与都得 0, 这就是「谁都匹配」的数学表达。 默认路由不是特殊语法,就是前缀长度 0。 「最长前缀优先」是路由表的核心规则,没有例外:它保证了「更具体的配置能覆盖更笼统的配置」。 所以想给某台机器单独改道,加一条 /32 的主机路由就行。
30 秒实验
- 加一条
192.168.3.200/32指向别的地方,看第一个地址的查询结果变不变。 - 把
192.168.3.0/24删掉,看192.168.3.10会命中哪一条。 - 想一下:默认路由和「静态路由」是什么关系?
常见误区
- 以为路由器只看目的 IP。 它还要看路由表、TTL、分片标志,而且每一跳都要改帧头。
- 以为多条匹配时「随便选一条」。 必须选前缀最长的,这条规则没有例外。
- 以为三层交换机就是「更快的路由器」。 它是「功能更少的硬件转发设备」,NAT、 VPN 这类要改包的功能它做不了。
自测三问(点开对答案)
1. 路由器比交换机多做了哪几件事? —— **看 IP 头、改帧头(每跳换 MAC)、TTL 减一、查路由表选路。**这四件交换机一件都不做。 2. 「最长前缀优先」保证了什么? —— **更具体的配置能覆盖更笼统的配置。**所以加一条 /32 主机路由就能让某台机器单独改道。 3. TTL 是干什么用的?traceroute 怎么利用它? —— **防环**:每过一个路由器减一,到 0 就丢弃并回 ICMP 超时。 traceroute 故意发 TTL 很小的包,靠谁回的错来定位每一跳。下一节讲四到七层交换机——它不看 MAC、不看 IP,看的是「内容」。
- ☐ (本节完,下一节 1.9.6 4~7层交换机)