📚 第一章 网络基础知识
📄 一句话概括

路由器多出来的能力只有一条:把一段网络接到另一段网络。 查路由表的规则叫「最长前缀优先」,没有例外。

📝 本节和前面几节的关系

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

  1. 加一条 192.168.3.200/32 指向别的地方,看第一个地址的查询结果变不变。
  2. 把 192.168.3.0/24 删掉,看 192.168.3.10 会命中哪一条。
  3. 想一下:默认路由和「静态路由」是什么关系?

常见误区

  1. 以为路由器只看目的 IP。 它还要看路由表、TTL、分片标志,而且每一跳都要改帧头。
  2. 以为多条匹配时「随便选一条」。 必须选前缀最长的,这条规则没有例外。
  3. 以为三层交换机就是「更快的路由器」。 它是「功能更少的硬件转发设备」,NAT、 VPN 这类要改包的功能它做不了。
自测三问(点开对答案) 1. 路由器比交换机多做了哪几件事? —— **看 IP 头、改帧头(每跳换 MAC)、TTL 减一、查路由表选路。**这四件交换机一件都不做。 2. 「最长前缀优先」保证了什么? —— **更具体的配置能覆盖更笼统的配置。**所以加一条 /32 主机路由就能让某台机器单独改道。 3. TTL 是干什么用的?traceroute 怎么利用它? —— **防环**:每过一个路由器减一,到 0 就丢弃并回 ICMP 超时。 traceroute 故意发 TTL 很小的包,靠谁回的错来定位每一跳。

下一节讲四到七层交换机——它不看 MAC、不看 IP,看的是「内容」。

相关笔记