交换机笔记(三)
冗余链路是网络的刚需——单根线断了业务就断。但前两篇说过,交换机对广播帧和未知帧的处理是泛洪,一旦链路成环,帧会在环上无限转圈。STP(Spanning Tree Protocol,生成树协议) 就是用来“既要冗余、又不能有环”的协议。这篇记录 802.1D 经典 STP 的完整工作过程。
一、环路的三大危害
先看没有 STP 时环路会发生什么。以太网帧里没有 TTL 字段,二层转发没有任何机制能阻止帧无限循环,这和 IP 层有本质区别。
- 广播风暴:一个广播帧进入环路,每台交换机都把它从除入端口外的所有端口发出去,帧在环上每转一圈就复制一份,几秒内链路带宽全部耗尽。
- MAC 地址表震荡:同一个源主机的帧从环的两个方向到达交换机,同一个 MAC 的表项在端口间来回跳动,正常转发被打乱。
- 重复帧:目的主机会收到大量相同的帧。
这三个症状里,广播风暴最致命——它不依赖任何触发流量之外的条件,自己就能滚雪球。
二、STP 的基本思想
STP 由 Radia Perlman 在 1985 年发明,1990 年被 IEEE 标准化为 802.1D。思路很朴素:物理上保留冗余链路,逻辑上阻塞掉多余的端口,让转发拓扑变成一棵树。树没有环。当活动链路故障时,再放开被阻塞的端口顶上。
所以 STP 的工作分两部分:选举出一套“无环拓扑”,以及故障时重新收敛。选举的核心是交换 BPDU(Bridge Protocol Data Unit) 报文。
三、选举过程
STP 的选举可以记成四步:一个根桥、每台非根桥一个根端口、每条链路一个指定端口、剩下的全部阻塞。
1. 选根桥:比 BID
每台交换机有一个 BID(Bridge ID,桥 ID),8 字节:
| 桥优先级 2B | 桥 MAC 地址 6B |BID 最小者成为根桥。先比优先级(默认 32768),相同再比 MAC 地址(小者优先)。
优先级可配范围是 0~61440,且必须是 4096 的整数倍。这个怪规矩的原因是:BID 的 2 字节优先级字段里,低 12 bit 被划给了“扩展系统 ID”(在思科 PVST+ 里放的就是 VLAN ID),能自由配的只剩高 4 bit,所以步长是 4096。
2. 每台非根桥选一个根端口
根端口(RP)是这台交换机“离根桥最近”的端口,即收到最优 BPDU 的端口。依次比较:
- 根路径开销(RPC):到达根桥的沿途入方向链路开销之和,小者优先;
- 上游交换机的 BID,小者优先;
- 上游端口 ID(PID = 端口优先级 + 端口号,优先级默认 128),小者优先。
路径开销由链路速率决定。不同年代的取值标准不同,这也是容易搞混的地方:
| 链路速率 | 802.1D-1998(短模式) | 802.1t(长模式,华为默认) |
|---|---|---|
| 10 Mbps | 100 | 2,000,000 |
| 100 Mbps | 19 | 200,000 |
| 1 Gbps | 4 | 20,000 |
| 10 Gbps | 2 | 2,000 |
| 100 Gbps | 放不下 | 200 |
1998 年的短模式开销是 16 bit,10G 已经给到 2,更高速率区分不开了;802.1t 把开销扩到 32 bit。华为设备默认按 dot1t 计算,可以用 stp pathcost-standard 切换,但整网必须统一,否则选路结果会乱。
3. 每条链路选一个指定端口
指定端口(DP)负责向所在网段转发 BPDU 和数据。每条链路上,哪个端口发出的 BPDU 最优(比较顺序同样是 RPC → BID → PID),哪个就是 DP,对端端口要么成为根端口,要么被阻塞。
根桥上的所有端口都是指定端口——它到任何网段的 RPC 都是 0,没人比得过。
4. 剩下的端口全部阻塞
既不是根端口也不是指定端口的端口进入阻塞状态:不转发数据、不学 MAC,但继续接收 BPDU——它得保持监听,随时准备在拓扑变化时顶上。
四、BPDU 报文
STP 的 BPDU 发往组播 MAC 01-80-C2-00-00-00,分两种:
| 类型 | 用途 |
|---|---|
| 配置 BPDU | 选举和维护拓扑,由根桥产生,其他桥从根端口收、从指定端口转发 |
| TCN BPDU | 拓扑变化通知,由检测到变化的桥向根桥方向发送 |
配置 BPDU 的关键字段:
| 字段 | 内容 |
|---|---|
| Protocol ID / Version / Type | 0x0000 / 0x00 / 0x00(配置 BPDU) |
| Flags | 只用两个 bit:TC(拓扑变化)和 TCA(变化确认) |
| Root ID | 根桥 BID |
| RPC | 发送方到根桥的路径开销 |
| Bridge ID / Port ID | 发送方 BID 和发送端口 PID |
| Message Age | BPDU 已经过的跳数,每过一台桥加 1 |
| Max Age | BPDU 最大存活时间,默认 20 秒 |
| Hello Time | 根桥发送 BPDU 的周期,默认 2 秒 |
| Forward Delay | 状态迁移等待时间,默认 15 秒 |
非根桥不是每台都自己发配置 BPDU,而是接力转发根桥的 BPDU;如果 Max Age(20 秒)内都没收到新的,就认为上游出了问题,重新选举。这套默认参数是按网络直径不超过 7 跳推导出来的,超过这个规模计时器就可能不够用。
过时结论:老资料常说“STP 网络直径不能超过 7 跳”。这个限制来自默认 Max Age 的推导假设,直径更大时 BPDU 的 Message Age 会提前超限。它说明默认计时器不是普适的,而不是协议本身画了条硬线——调整 Max Age 和 Forward Delay 可以放宽,但没人会这么做,因为 RSTP/MSTP 早已取代了这种调参玩法。
五、端口状态机与收敛时间
802.1D 的端口状态有五种:
| 状态 | 收发 BPDU | 学 MAC | 转发数据 |
|---|---|---|---|
| Disabled(禁用) | 否 | 否 | 否 |
| Blocking(阻塞) | 只收 | 否 | 否 |
| Listening(侦听) | 是 | 否 | 否 |
| Learning(学习) | 是 | 是 | 否 |
| Forwarding(转发) | 是 | 是 | 是 |
端口从阻塞到转发必须逐级走:Blocking → Listening → Learning → Forwarding,中间每级停留一个 Forward Delay(15 秒)。Listening 阶段完成选举,Learning 阶段先学 MAC 表——不经过学习直接转发会造成大面积泛洪。
收敛时间由此而来:
- 直连链路故障:根端口立刻感知,备用端口启用,2 个 Forward Delay = 30 秒。
- 间接链路故障:阻塞端口要等 Max Age(20 秒)超时才发现问题,再加 2 个 Forward Delay = 50 秒。
这就是“STP 收敛需要 30~50 秒”的出处。
六、拓扑变化的通知机制
拓扑稳定时,MAC 表项老化时间是 300 秒。拓扑一变,旧的 MAC 表立刻可能指向错误的端口,如果等 300 秒自然老化,很多流量会持续发错方向。802.1D 的处理流程:
- 检测到变化的交换机从根端口向上游发送 TCN BPDU;
- 上游交换机回一个 Flags 置了 TCA 的配置 BPDU 确认,然后继续从自己的根端口向上发 TCN,一路传到根桥;
- 根桥在之后 Max Age + Forward Delay(35 秒)内发出的配置 BPDU 里都置 TC 位;
- 全网收到 TC 后,把 MAC 表的老化时间临时缩短为 Forward Delay(15 秒),让旧表项快速失效。
代价也很明显:这 15 秒里大量表项被清掉,未知单播泛洪激增。拓扑频繁抖动的网络会陷入“清表—泛洪—再学习”的循环。
七、802.1D 的局限
- 慢:30~50 秒的收敛时间,语音、存储等业务无法接受。
- 只有一棵树:所有 VLAN 共用同一棵生成树,被阻塞的链路完全闲置。
- 被动等待多:靠计时器超时发现问题,靠逐级停留防环,都是拿时间换稳定。
这些局限正是 RSTP 和 MSTP 要解决的,下一篇展开。
八、小结
- 二层帧没有 TTL,环路会引发广播风暴、MAC 表震荡和重复帧,STP 用逻辑阻塞换取无环拓扑。
- 选举四步:BID 最小为根桥;每台非根桥按 RPC → 上游 BID → 上游 PID 选根端口;每条链路选指定端口;其余阻塞。
- 配置 BPDU 由根桥产生、全网接力;Hello 2 秒、Max Age 20 秒、Forward Delay 15 秒,默认参数按直径 7 跳推导。
- 收敛 30~50 秒来自 Max Age 等待加两级 Forward Delay;拓扑变化通过 TCN/TCA/TC 通知,全网把 MAC 老化缩到 15 秒。
注(2026 年补充):本文写于 2020 年,当时的说法是「STP 出自 802.1D」。802.1D-2004 已于 2021 年底被 IEEE 正式撤销,全部内容并入 802.1Q(现行版本 802.1Q-2022),生成树协议的家如今在 802.1Q 里。不过 802.1D 定义的这套选举规则没有任何失效——它仍是理解 RSTP/MSTP 的基础,30~50 秒的经典结论也是衡量后来协议进步幅度的标尺。