0%

信息时代的背面 02|二层环路为什么会瘫痪整个网络

信息时代的背面 02|二层环路为什么会瘫痪整个网络

《信息时代的背面》系列每期拆解一个“粗看都对”的网络常识。本期是第 02 期,上一期讲了三层交换机如何靠目的 MAC 判定是否路由。

为了提高可靠性,网络中经常会部署冗余链路:两台设备之间多拉一根线,或者多台设备互相连接,这样某条链路断了,流量还能走另一条。但冗余链路也带来了一个风险:环路。

所谓环路,就是报文从一台设备出发,经过几台设备转发,又回到了这台设备,然后继续被转发出去,在网络中不停地“绕圈”。

环路既可能出现在二层网络中,比如交换机之间的连线形成了一个环;也可能出现在三层网络中,比如两台路由器的路由配置错误,互相把报文指向对方。

这两种环路的表现差别很大:

  • 三层环路发生时,通常只是去往某个网段的流量不通。在主机上 ping 目的地址,会收到“TTL 超时”的提示,网络的其他部分照常工作。
  • 二层环路发生时,整个 VLAN 甚至整个网络可能在几秒内瘫痪:交换机端口指示灯快速闪烁,设备无法登录管理,大量用户无法上网。

同样是环路,为什么二层环路能瘫痪整个网络,三层环路却通常只影响部分流量?

很多人会把原因归结为“二层网络里广播多、流量大”。广播多确实是二层环路的现象之一,但它不是根本原因。

真正的区别在于:三层环路中的报文绕一定次数后会自己消失,而二层环路中的帧永远不会消失。同样是在环路里绕圈,一个能停下来,一个停不下来,答案就在报文头里。


一、核心判据:报文头里有没有 TTL

两种环路后果不同,根本原因在于:

IP 报文头有 TTL 字段,每经过一台三层设备减 1,减到 0 就被丢弃;以太网帧头没有类似的字段,交换机二层转发时也不修改帧。

所以,三层环路中的报文寿命有限,绕一定次数后必然消失;二层环路中的帧没有任何机制让它消失,会一直循环下去。

二、判据为什么成立

2.1 TTL 字段的作用

TTL 是 Time To Live 的缩写,意思是“生存时间”。它是 IPv4 报文头中的一个 8 位字段,取值范围是 0 到 255。(IPv6 中对应的字段叫 Hop Limit,作用相同。)

虽然名字叫“时间”,但实际使用中它表示的是报文最多还能经过几台三层设备:

  • 主机发出报文时,会给 TTL 设一个初始值。常见的初始值有 64(多数 Linux 系统)、128(Windows 系统)和 255(很多网络设备)。
  • 报文每经过一台路由器或三层交换机,TTL 减 1。
  • 如果 TTL 减到 0,这台设备就丢弃报文,并向报文的源地址发送一条 ICMP 超时消息,告诉对方“报文在路上过期了”。

TTL 的设计目的,就是防止报文因为路由错误在网络里无限转发。

2.2 以太网帧头里没有生存时间字段

再看以太网帧头的结构:

以太网帧头只有四部分:目的 MAC、源 MAC、可选的 VLAN Tag,以及表示上层协议类型的类型字段。其中没有任何字段可以用来限制帧被转发的次数。

为什么以太网当初不设计这样的字段?这和以太网的起源有关。

早期的以太网是一根共享的同轴电缆,所有主机都连在这根电缆上,一台主机发出的帧,其他主机直接就能收到,帧根本不经过“转发”,自然也就不需要限制转发次数。

后来出现了网桥和交换机,它们的设计原则是对主机“透明”:主机不需要知道交换机的存在,交换机也不修改经过的帧。

为了避免环路,以太网另外引入了 STP(生成树协议),通过阻塞冗余链路,保证网络中任意两点之间只有一条路径。换句话说,以太网防环靠的是“不让环路出现”,而不是“让环路中的帧自动消失”。

2.3 与第 01 期的结论对应

上一期我们讲过,三层交换机做两种转发时,对报文的处理方式不同:

  • 三层转发:重写源 MAC 和目的 MAC,TTL 减 1,重新计算校验和。
  • 二层转发:报文内容一个字节都不改。

这正是两种环路后果不同的原因。三层转发每经过一跳就“消耗”报文的一点寿命,二层转发则完全不会。

三、三层环路的过程

先看三层环路是怎么发生和结束的。

在基础环境的基础上,我们给 SW 增加一个上行出口路由器 R1。SW 和 R1 之间是一个互联网段:SW 的地址是 10.0.0.1,R1 的地址是 10.0.0.2。

两台设备上各配置了一条路由:

  • SW 上配置了默认路由,指向 R1。默认路由的意思是:目的地址匹配不到其他任何路由时,就交给 R1。
  • R1 上配置了一条汇总路由 192.168.0.0/16,指向 SW。汇总路由是用一条范围较大的路由代替多条具体路由,这里表示“所有 192.168 开头的地址都交给 SW”。

现在 PC1 访问 192.168.30.5,而这个网段在网络中并不存在:

  1. PC1 发出的报文 TTL 为 128(Windows 系统),到达 SW。
  2. SW 的路由表中只有 192.168.10.0/24 和 192.168.20.0/24 两个直连网段,都匹配不上,于是按默认路由交给 R1,TTL 减为 127。
  3. R1 查路由表,192.168.30.5 属于 192.168.0.0/16 的范围,于是交回 SW,TTL 减为 126。
  4. SW 再次按默认路由交给 R1……

报文就这样在 SW 和 R1 之间来回往返,每经过一次 TTL 减 1。大约往返 60 多次后,TTL 减到 0,报文被丢弃,PC1 收到一条 ICMP 超时消息。

如果此时在 PC1 上用 traceroute 跟踪路径,会看到 SW 和 R1 的地址交替出现,这是判断三层环路的典型现象。(这个例子同时涉及最长前缀匹配的原理,第 07 期会详细讲解。)

这次环路的影响范围是有限的:

  • 只有去往 192.168.30.0/24 这类“不存在网段”的报文会进入环路。
  • 每个报文最多往返几十到一百多次就会消失。
  • 其他正常流量不受影响。

四、二层环路的过程

再看二层环路。

在基础环境中,我们再增加两台接入交换机 SW2 和 SW3,它们各自通过一根线连到 SW 上。某天有人在 SW2 和 SW3 之间多接了一根线,三台交换机就形成了一个环。

为了说明问题,假设三台交换机都没有运行 STP。

4.1 广播帧永久循环

假设 PC1 要访问网关,先发出一个 ARP 请求。ARP 请求是广播帧,目的 MAC 是 ff:ff:ff:ff:ff:ff。交换机收到广播帧,会向同一 VLAN 内除入端口外的所有端口转发,这叫泛洪。

整个过程如下:

  1. SW 收到 PC1 的广播帧,向 SW2 和 SW3 方向各发一份。
  2. SW2 收到后,继续泛洪,其中一份发给 SW3。
  3. SW3 收到后,继续泛洪,其中一份又发回 SW。
  4. SW 收到后,又一次泛洪……

与此同时,另一个方向上也在发生同样的过程。于是,PC1 发出的一个广播帧,在环路里变成了两份沿相反方向永久循环的副本。

这里的关键在于,这两份副本永远不会消失。帧头里没有 TTL,每台交换机都原样转发,没有任何一个环节会把它丢掉。

还有两个因素让情况迅速恶化:

  • 新的广播不断加入。 网络中的主机随时都在发送广播,比如 ARP 请求、DHCP 请求等。每一个新的广播进入环路后都不会离开,环路里的帧只增不减。
  • 循环速度极快。 帧在交换机之间转发一圈只需要几微秒到几十微秒,一个广播帧每秒可以绕环路上万次,每绕一圈,环上每台交换机的所有端口都会再收到一份。

在这个三角形环路中,每个广播帧“只”产生两份循环副本。如果某台交换机有更多条链路接入环路,每次泛洪还会复制出更多副本,增长会更快。

最终的结果是:链路带宽被循环的广播帧占满,正常业务流量无法传输。这就是广播风暴。

4.2 MAC 地址表漂移

除了广播风暴,二层环路还会破坏交换机的 MAC 地址表。

先解释一下 MAC 地址表:交换机收到帧时,会记录“这个源 MAC 是从哪个端口进来的”,形成一张 MAC 地址表。之后有帧要发往这个 MAC 时,交换机就查表,从对应端口发出去。

正常情况下,SW 从直连 PC1 的端口收到 PC1 的帧,于是记录:PC1 的 MAC 在连接 PC1 的端口上。

但在环路中,PC1 发出的广播帧会绕一圈回到 SW。这时 SW 是从连接 SW2 或 SW3 的端口收到这个帧的,帧的源 MAC 仍然是 PC1。于是 SW 会更新表项,认为 PC1 已经“搬到”了连接 SW2 的端口;过一会儿,另一份副本从 SW3 方向到达,SW 又把表项改成连接 SW3 的端口。

1
2
3
4
5
6
7
SW 的 MAC 地址表中,PC1(00:1b:21:3a:4f:10)的表项:

时刻 1: 出端口 = 连接 PC1 的端口 (正常学习)
时刻 2: 出端口 = 连接 SW2 的端口 (副本 A 绕回)
时刻 3: 出端口 = 连接 SW3 的端口 (副本 B 绕回)
时刻 4: 出端口 = 连接 SW2 的端口 (副本 A 再次绕回)
... 表项在多个端口之间反复变化

这种现象叫做 MAC 地址漂移。它的后果是:其他主机发给 PC1 的正常单播帧,会被 SW 发到 SW2 或 SW3 方向,而不是发给 PC1。即使链路带宽还没有被占满,通信也已经不正常了。

4.3 设备 CPU 负载升高

第 01 期 6.1 节讲过:交换机收到 ARP 请求这类广播帧时,除了在 VLAN 内泛洪,还会复制一份上送 CPU,因为三层接口本身也是这个广播域的成员,需要判断这个请求是不是在问自己。

在二层环路中,同一批广播帧每秒绕环上万次,每次经过 SW 都要上送一次 CPU。交换机 CPU 的处理能力远低于转发芯片,很快就会被占满,带来一系列连锁反应:

  • 设备无法通过网络登录管理,排查故障更加困难。
  • 设备需要处理的协议报文(如路由协议报文)来不及处理而被丢弃,导致路由中断等其他故障。
  • 连接在环路上的主机也会不停地收到大量广播,网卡和系统负载升高。

这就是为什么二层环路发生时,往往表现为“整个网络瘫痪”,而不只是某几台主机不通。

五、二层环路与三层环路对比

对比项 三层环路 二层环路
报文寿命 有限,TTL 减到 0 后丢弃 无限,帧头没有 TTL
进入环路的流量 去往特定网段的报文 广播帧、未知单播帧,以及受 MAC 漂移影响的单播帧
流量变化趋势 每个报文绕几十到一百多次后消失 只增不减,直到占满链路带宽
影响范围 通常只影响去往环路网段的流量 整个广播域,甚至整个网络
典型现象 ping 提示 TTL 超时;traceroute 中两台设备地址交替出现 端口指示灯快速闪烁;设备 CPU 占用率高;MAC 地址漂移;网络整体不可用
主要防护机制 路由协议自身的防环机制,TTL 作为最后保障 STP 等防环协议,阻止环路出现

六、特殊情况

6.1 三层环路同样会消耗带宽

三层环路的影响有限,但不等于没有影响。

TTL 初始值较大时,一个报文可以在环路中往返上百次,相当于这个报文占用的带宽被放大了上百倍。如果进入环路的流量本身就很大,例如有大量主机持续访问一个不存在的网段,环路所在的链路同样可能拥塞,进而影响经过这条链路的正常业务。

6.2 单播帧在二层环路中的表现

二层环路中,并不是所有帧都会循环:

  • 已知单播帧:交换机的 MAC 地址表中有目的 MAC 的正确表项时,帧会被直接转发到目的主机所在的端口,通常不会进入循环。
  • 未知单播帧:MAC 地址表中查不到目的 MAC 时,交换机会像处理广播一样泛洪,这类帧同样会在环路中循环。
  • 受 MAC 漂移影响的单播帧:表项被错误更新后,原本的已知单播帧可能被发往错误方向,甚至进入环路。

所以,环路刚形成时,部分单播业务可能暂时还能通信,但随着 MAC 漂移加剧和带宽被占满,最终都会受到影响。

6.3 环路不一定出现在核心交换机之间

提到二层环路,很多人会想到核心交换机之间的冗余链路配置错误。实际上,现网中很多环路出现在网络边缘,例如:

  • 一根网线两端插在同一台小交换机上。 办公室里常见的不可管理小交换机,通常不运行 STP。有人把一根网线的两端都插在它上面,这台小交换机内部就形成了环路,产生的广播风暴会通过上联链路扩散到整个 VLAN。
  • 主机网卡桥接。 一台主机有两块网卡,分别连到网络中的两个端口,如果主机上把两块网卡桥接在一起,就会在网络中形成一个经过这台主机的环路。

这类环路的位置通常比较隐蔽,排查时需要从网络边缘逐级定位。

七、二层环路的防护手段

既然以太网帧本身无法限制转发次数,防护的思路只能是:不让环路出现,或者在环路出现后尽快发现并切断。

7.1 STP:阻塞冗余链路

STP 是以太网防环的基础机制。运行 STP 的交换机之间会相互交换协议报文,计算出一个无环的转发路径,然后把多余的端口设为阻塞状态。阻塞端口不转发普通数据帧,从逻辑上切断了环路。

当正在使用的链路故障时,STP 会重新计算,把原来阻塞的端口打开,恢复连通。这样既消除了环路,又保留了链路冗余。

STP 具体如何决定阻塞哪个端口,我们在第 04 期详细讲解。

7.2 环路检测

一些交换机支持环路检测功能:交换机定期从端口发出专门的检测报文,如果这个报文又从自己的端口收了回来,就说明网络中存在环路。检测到环路后,交换机可以告警或关闭相应端口。

这个功能适合部署在连接终端、小交换机的接入端口上,用来发现 6.3 节提到的那类边缘环路。不同厂商对该功能的名称和实现细节有所不同。

7.3 广播风暴抑制

广播风暴抑制是在端口上限制广播帧的速率,超过阈值的广播帧直接丢弃。

需要注意的是,风暴抑制只能缓解广播风暴,不能消除环路。环路依然存在,MAC 漂移等问题依然会发生;而且阈值设置过低时,正常的广播(如 ARP 请求)也可能被误丢。所以它只能作为辅助手段,和 STP、环路检测配合使用。

八、总结

回到开头的问题:同样是环路,为什么二层环路能瘫痪整个网络,三层环路却通常只影响部分流量?

答案在于报文头里有没有 TTL。

IP 报文每经过一台三层设备,TTL 减 1,减到 0 就被丢弃,所以三层环路中的报文必然会消失,影响范围有限。以太网帧头没有生存时间字段,交换机二层转发时又不修改帧,所以环路中的广播帧会永久循环,并且不断累积,最终造成广播风暴、MAC 地址漂移和设备 CPU 过载。

这也解释了以太网的防环思路:既然无法让环路中的帧自动消失,就必须依靠 STP 等机制,从一开始就不让环路出现。


下期预告

很多人认为,Trunk 端口发出的报文都会带上 VLAN Tag。实际上,有一类报文从 Trunk 端口发出时是不带 Tag 的,而两端配置不一致时,还可能导致不同 VLAN 之间的流量串通。下一期《信息时代的背面 03》,讲 Trunk 端口什么时候带 Tag、什么时候不带。