Skip to content

STP、RSTP 与 MSTP ​

标签
基本功/网络
字数
6508 字
阅读时间
27 分钟

同一条技术线演进的三代二层防环协议。三代之间的关系是继承加改造,不是互相替代的三种方案:

协议标准出现时间解决的问题
STP802.1D1985 起二层环路
RSTP802.1w2001STP 收敛太慢(30~50 秒)
MSTP802.1s2002全网一棵树导致冗余链路闲置

后来 802.1D-2004 把 802.1w 合并了进去,所以今天说「跑 802.1D」通常指的就是 RSTP。

[[12-交换机与路由器:两种转发机制]] §1.5 讲过 STP 的基础机制,这篇展开三代协议的全部细节。

1. 二层为什么需要防环 ​

1.1 三类故障 ​

三台交换机两两相连形成三角形,一台机器发出广播帧:

T=0   SW1 收到 → 从另外两个口各发一份 → SW2、SW3 各收到一份
T=1   SW2 收到 → 除入端口外泛洪 → 发回 SW1,同时发给 SW3
      SW3 收到 → 除入端口外泛洪 → 发回 SW1,同时发给 SW2
T=2   SW2 又收到(来自 SW3)→ 再泛洪;SW3 同理

T=1 那一行是分水岭:两台交换机各自收到的那份被互相转发了一遍,于是每绕一圈帧数翻倍。

绕圈数环上的帧数
12
101024
20一百多万

以交换机微秒级的转发速度,几秒内就能打满链路带宽与 CPU。这是广播风暴。

连带两个后果:

故障机制
MAC 表震荡(MAC flapping)同一个源 MAC 从两个端口轮流进来,表项被反复改写,CPU 全花在写表上
重复帧同一个广播帧在环里绕,接收方收到多份

1.2 三层为什么没这个问题 ​

三层有 TTL——每经一跳减一,减到 0 丢弃。二层帧里没有任何字段会随转发递减,所以环里的帧不会自己消失。

这个差异决定了两种截然不同的解法:

三层二层
环路的处理被动兜底:让包自己耗尽主动预防:转发前就断环
手段TTL生成树协议
代价环路期间包被丢弃冗余链路必须闲置

2. STP(IEEE 802.1D) ​

2.1 核心思路 ​

所有交换机协商出一个共识——哪些端口转发,哪些闲着。闲着的端口保留物理连接但不转发用户数据帧,于是「环」在逻辑上消失。

「闲着」不等于「断开」:

阻塞端口仍然做阻塞端口不做
收发 BPDU不转发用户数据帧
听拓扑变化不学习源 MAC

心跳还在,所以活跃链路一断,它立刻接手。

2.2 BPDU ​

交换机之间的对话靠 BPDU(Bridge Protocol Data Unit),默认每 2 秒一次(hello-time),发往链路协议专用组播地址 01:80:C2:00:00:00——交换机不转发这类帧,只在本机处理。

字段作用
协议 ID / 版本标识这是 STP 报文
BPDU 类型配置 BPDU 或 TCN BPDU
标志802.1D 只定义两位:TC(拓扑变化)与 TCA(TC 确认)
根桥 ID发送方认为的根桥
到根桥的路径开销从这里到根桥要花多少
发送方桥 ID我是谁
发送方端口 ID从哪个口发的
消息寿命 / 最大寿命防止 BPDU 无限转发的计时字段

「发送方认为的根桥」是协议的精髓:每台交换机启动时都以为自己是根桥(BPDU 里填自己),收到别人的 BPDU 一比较——发现对方报的根桥更优就改认对方,并把更新后的信息往下游传。这个过程就是收敛。

根桥持续每 2 秒发一次;非根交换机收到后把自己的开销加上再往下传,所以从根桥往外,BPDU 里的开销递增。

2.3 选举四步 ​

步骤选什么判据数量
1根桥BID 最小全网一台
2根端口(RP)到根桥路径开销最小每台非根交换机一个
3指定端口(DP)该链路上到根桥开销最小的一端每条链路一个
4落选的——全部阻塞

BID(Bridge ID,8 字节) = 桥优先级(2 字节)+ 交换机 MAC(6 字节)。先比优先级,小的赢;相同则比 MAC。

优先级默认 32768,只能取 4096 的倍数(0、4096、8192…)。所以只要把核心交换机配成 4096,它必然当选。

这一步是「根桥不是核心交换机」这类故障的根源——默认全为 32768,于是比 MAC,谁小谁当,等于随机。

选举过程本身就是一轮 BPDU 的交换与比较:

收敛之后,每台非根交换机再按「到根桥开销最小」选出自己的根端口,每条链路上再按同样判据选出指定端口。

2.4 路径开销 ​

开销按带宽折算,交换机把沿途各端口开销累加:

链路带宽经典 STP(802.1D)RSTP(802.1w)
10 Mbps1002000000
100 Mbps19200000
1 Gbps420000
10 Gbps22000

两套数值的来源不同:经典 STP 用 16 位字段,RSTP 改用 32 位以便表达万兆以上的差异。

「到根桥的开销」= 沿途所有出端口开销之和。环里开销大的那条链路,会有一端被判为阻塞。

2.5 端口状态与 30 秒的由来 ​

状态持续收 BPDU学 MAC转发数据
Disabled——否否否
Blocking——是否否
Listening15 秒是否否
Learning15 秒是是否
Forwarding——是是是

从不转发到转发最少等 30 秒(Listening 15 + Learning 15),全程通常 30~50 秒。

为什么要等:拓扑变化时新 BPDU 要一层层传到全网,传播本身需要时间。端口若立刻转发,在「有人还以为旧拓扑有效」的窗口里会形成临时环路。这 30 秒是用一个保守的等待窗口覆盖信息传播的最坏延迟。

Learning 阶段专门用来提前学 MAC——先建立转发表、再转发数据,减少开始转发瞬间的泛洪。

2.6 拓扑变化通知 ​

链路断了,下游怎么通知根桥?靠 TCN BPDU:

1. 发现变化的交换机 → 从根端口向上游发 TCN
2. 上游继续向上转发 → 一直到根桥
3. 根桥 → 回带 TCA 标志的 BPDU 确认
4. 根桥 → 向下游广播带 TC 位的 BPDU
5. 所有交换机把 MAC 表老化时间从 300 秒缩短到 forward delay(15 秒)

第 5 步是关键:拓扑变了,原有「MAC → 端口」映射可能已失效,不清理就会继续往旧端口发。缩短老化时间让收敛更快。

传播路径是「先向上报到根桥,再由根桥向下广播」:

这个「先上后下」的结构正是 RSTP 要改掉的地方——通知根桥这一段在链路长时延迟明显,RSTP 改由发起者自己泛洪。

2.7 四个局限 ​

局限后果
依赖定时器收敛慢,最坏 50 秒
只有一棵树冗余链路全部闲置,花钱买的带宽用不上
拓扑变化要先通知根桥通知链路长,慢
链路断开也算拓扑变化触发不必要的全网刷新

这四条正好是 RSTP 与 MSTP 各自的改进目标。

3. RSTP(IEEE 802.1w) ​

RSTP 的计算规则与 STP 完全相同(桥/端口优先级用法没变),改的是达到该拓扑的步骤。

3.1 端口角色与状态解耦 ​

这是 RSTP 的设计核心。它把角色(这个端口在拓扑里干什么)与状态(当前转不转发)拆成两个独立变量:

角色含义
Root收到最佳 BPDU 的端口,到根桥最近
Designated能向所在网段发送最佳 BPDU 的端口
Alternate从另一个网桥收到更优 BPDU 而被阻塞,提供通往根桥的替代路径
Backup从同一个网桥收到更优 BPDU 而被阻塞,提供同一网段的冗余

802.1D 的「阻塞端口」在 RSTP 里被拆成 Alternate 与 Backup 两个角色。这个区分不是新发明——Cisco 的 UplinkFast 早就在内部做了同样的区分,RSTP 把它标准化了。

角色与状态可以不一致:一个端口可以同时是 Designated 且 Discarding——这表示它正在向「指定转发」过渡的短暂瞬间。

状态从 5 个压到 3 个:

802.1DRSTP在活动拓扑中学 MAC
DisabledDiscarding否否
BlockingDiscarding否否
ListeningDiscarding是否
LearningLearning是是
ForwardingForwarding是是

3.2 提议-同意握手 ​

RSTP 快速收敛的核心机制,完全不依赖定时器:

1. 指定端口处于 Discarding 或 Learning 时,发出的 BPDU 置 proposal 位
   (只有这两种状态下才置)
2. 对端收到更优信息 → 立即把该端口定为新根端口
   → 启动 sync,检查自己所有端口是否与新信息同步
3. 端口「in-sync」的两个条件(满足其一):
   · 该端口处于阻塞状态(稳定拓扑中就是 Discarding)
   · 该端口是边缘端口
4. 为让所有端口 in-sync,只需把不满足条件的端口置为 Discarding
5. 同步完成后,解除对新根端口的阻塞,回一个 agreement 消息
   (agreement 是 proposal BPDU 的副本,只是把 proposal 位换成 agreement 位)
6. 收到 agreement → 端口立即转发

与 STP 的根本区别就在「立即」:802.1D 要等两个 forward-delay(2 × 15 = 30 秒),RSTP 靠握手波沿网络快速传播,几百毫秒内完成。

这张图里没有出现任何定时器——收敛速度由握手在网络中的传播速度决定,与链路跳数成正比,与 forward-delay 无关。

回退机制:指定端口发出 proposal 后若没等到 agreement,会退回传统的 Listening → Learning 序列。这发生在对端不支持 RSTP,或对端端口处于阻塞状态时。

Cisco 的一个增强:sync 时只把原来的根端口置为 Discarding,而不是把所有非边缘端口都置一遍。常见重收敛场景因此少做几次阻塞操作。

3.3 边缘端口与链路类型 ​

边缘端口(对应 Cisco 的 PortFast):直连终端设备的端口不会形成环路,直接进入转发,跳过 Listening 与 Learning。

特性行为
链路切换时不产生拓扑变化(终端设备不会转发 BPDU)
一旦收到 BPDU立即失去边缘端口身份,变回普通生成树端口
配合 BPDU Guard收到 BPDU 直接关闭端口(防私接交换机)

链路类型决定能否快速收敛:

双工模式链路类型能否快速过渡
全双工点对点能
半双工共享(Shared)不能

这个推断是自动的,可被显式配置覆盖。半双工端口只能跑传统收敛,这是排查「为什么这个口收敛慢」时的第一个检查点。

3.4 拓扑变化机制的差异 ​

802.1DRSTP
谁发起传播只有根桥发起者自己
是否要先通知根桥是否
专门的 TCN 报文有无(直接用带 TC 位的 BPDU)
什么算拓扑变化端口 up/down 都算只有非边缘端口进入转发才算
刷新范围全网发起者 + 下游

RSTP 的关键改动:

  1. 一步式进程:检测到变化的网桥自己把信息泛洪出去,不等根桥。省掉了「通知根桥」这一整段延迟。
  2. 连通性丢失不算拓扑变化——802.1D 里端口转入阻塞会产生 TC,RSTP 不产生。理由是:链路断了本身不需要刷新 MAC 表,只有新路径可能改变转发方向时才需要。
  3. TC While 计时器:值为两倍的 hello-time(默认 4 秒)。在它运行期间,端口发出的 BPDU 都带 TC 位,同时刷新关联的 MAC 表项。

结果:几秒内(hello-time 的少量倍数)整个网络的 MAC 表大部分被刷新。

代价:可能造成更多临时泛洪。用短暂的泛洪换取「不留陈旧信息」,这个取舍在快速收敛场景下是划算的。

3.5 BPDU 作为保活机制 ​

处理方式的两点变化:

802.1DRSTP
发送时机只中继根桥的 BPDU每个 hello-time 都自己发,即使没从根桥收到
信息老化等 max_age(20 秒)连续丢 3 个 hello 即认为邻居失联

RSTP 的 BPDU 承担了保活职责——漏掉连续 3 个 BPDU(默认 6 秒)就判定失去连通性,比等 max_age 的 20 秒快得多。

接受较差 BPDU:网桥从指定/根桥收到较差信息时立即接受并替换先前的信息。这是 Cisco BackboneFast 的核心机制,RSTP 原生内置。

3.6 与旧式网桥的兼容 ​

RSTP 能和老 STP 互操作,但与旧式网桥交互时会丧失快速收敛优势。

机制是迁移延迟计时器:

参数值
Migration Delay3 秒
模式切换响应时间最多两倍 hello-time

端口 up 时启动 Migration Delay,在此期间锁定当前模式。到期后,端口适应它收到的下一个 BPDU 所对应的模式。若因 BPDU 导致模式改变,计时器重启,以限制切换频率。

具体场景:A、B 跑 RSTP 的链路上接入一台老式 STP 网桥 C。C 忽略 RSTP BPDU(RSTP 用的是 type 2, version 2,旧式网桥会直接丢弃),认为网段上没别人,开始发较差的老格式 BPDU。A 收到后最多两倍 hello-time 内切换为 802.1D 模式。

一个已知局限:C 被移除后,A 在该端口上仍跑 STP 模式(它不知道 C 已经走了),需要手动干预重启该端口的协议检测。

3.7 三代收敛时间对比 ​

场景802.1D802.1w
端口 up 到转发(边缘端口)30 秒立即
直连链路故障切换30 秒以上几百毫秒
间接链路故障50 秒几百毫秒
点对点链路拓扑变化30 秒秒级

RSTP 原生的特性对应着 Cisco 三件套:

Cisco 专有RSTP 中的对应
PortFast边缘端口
UplinkFastAlternate 端口直接顶上,原生内置、自动启用
BackboneFast接受较差 BPDU

4. MSTP(IEEE 802.1s) ​

4.1 为什么需要多实例 ​

STP 与 RSTP 全网只有一棵树,意味着:

  • 所有 VLAN 共用同一条活跃路径;
  • 其余冗余链路全部闲置。

这在多 VLAN 场景下浪费严重。MSTP 的思路是按 VLAN 分组,每组一棵独立的树:

实例 1(VLAN 1-10)  → 活跃路径走链路 A
实例 2(VLAN 11-20) → 活跃路径走链路 B

两条链路都在用,冗余链路从「闲置」变成负载分担。

4.2 Region 与三个属性 ​

MSTP 把交换机划分为 Region(域)。同一个 Region 内的交换机必须配置完全一致的三个属性:

属性作用
Region 名标识符
修订号(revision)版本标识
VLAN 到实例的映射哪个 VLAN 属于哪个实例

三个属性里任何一个不匹配,端口就被标记为「边界端口」——两台交换机不属于同一个 Region。

这个设计的意图是:Region 内部是「自己人」,可以用同一套 VLAN 映射;Region 之间只当成一台大交换机来对待,不需要知道对方内部的实例细节。

4.3 IST / CST / CIST ​

三个容易混的概念,用「范围」来区分最清楚:

概念范围作用
IST(Internal Spanning Tree)Region 内部就是实例 0,保留用于与其他 STP 和其他 Region 交互
CST(Common Spanning Tree)Region 之间把所有 Region 视为一台「大网桥」,它们之间形成的那棵树
CIST(Common and Internal ST)全网CST 与各 Region 内 IST 的合集,是全网唯一的树

层级关系:

CIST(全网唯一的树)
 ├─ CST:Region 与 Region 之间
 └─ IST:每个 Region 内部(= 实例 0)
      └─ MSTI 1~15:Region 内部额外的实例

4.4 边界端口的行为 ​

这是 MSTP 最关键的一条约束:

为保证无环,所有边界端口的转发/阻塞状态必须与 IST 的状态一致。

含义是:MSTI(实例 1~15)只在 Region 内部起作用。跨 Region 的路径由 IST/CST 唯一决定,不受各 Region 内部实例划分的影响。

所以 MSTP 的负载分担只在 Region 内部有效。如果两台交换机不在同一个 Region(三个属性有差异),它们的多条链路就只会有一条活跃——等于退化成 RSTP。

4.5 实例数与限制 ​

项值
实例 0IST,保留,不可改用途
实例 1 ~ 15只在 MST Region 内部有效
默认映射所有 VLAN 默认映射到实例 0

只支持 16 个实例(0 + 15)——这是 MSTP 的重要约束。VLAN 数量可以几千,但实例只有 16 个。实务上通常按「业务大类」分组,比如「生产 / 办公 / 测试」各一个实例,而不是每个 VLAN 一个。

4.6 配置要点 ​

MSTP 的配置有三个容易踩的坑:

坑后果
三个属性不一致边界端口产生,Region 被拆分,跨 Region 退化成单路径
改配置后没提交部分厂商的实现需要显式 commit,未提交的改动不生效
实例映射改了但没同步改全网不同交换机的映射不一致 → 直接拆出多个 Region

排查时先确认 Region 是否统一——这是 MSTP 类问题的第一步:

bash
# Cisco
show spanning-tree mst configuration        # 看三个属性
show spanning-tree mst 0                    # 看 IST 状态
show spanning-tree mst <实例号>              # 看具体实例

# Linux bridge(不支持 MSTP,只有单实例 STP)
cat /sys/class/net/br0/bridge/root_id
bridge link show

5. 三代对比 ​

维度STP(802.1D)RSTP(802.1w)MSTP(802.1s)
端口角色34(加 Alternate / Backup)4(继承 RSTP)
端口状态533
树的数量11每实例一棵(最多 16)
收敛时间30~50 秒几百毫秒几百毫秒
依赖定时器是否(握手取代)否
拓扑变化传播先通知根桥发起者自己泛洪同 RSTP
冗余链路利用闲置闲置可负载分担
与之交互——兼容 STP,但降速兼容 STP / RSTP,跨 Region 按 IST 处理
典型场景遗留设备单一 VLAN 或小规模多 VLAN 的园区网、数据中心接入

选择建议:

  • 新建园区网:直接上 MSTP。RSTP 只能利用一条路径,多 VLAN 场景浪费明显。
  • 单一 VLAN 或规模很小:RSTP 足够,MSTP 的 Region 管理反而是额外负担。
  • 有遗留设备:混合部署会拉低到最慢的那个,优先淘汰老设备。
  • 数据中心:不用 STP 家族作为主力,走 MLAG 或 VXLAN。

6. 替代方案 ​

STP 家族的核心代价是「用闲置换无环」——为断环必须阻塞链路,阻塞的就是白白闲置的带宽。三条绕开它的路子:

方案思路代价
MLAG / vPC把两台物理交换机当成一台逻辑设备,从根上不产生环需要特定硬件与配对配置
TRILL / SPB用类似三层路由的方式做二层转发,天然多路径生态没起来,部署少
VXLAN + EVPN用 overlay 封装绕过二层,底层走三层等价多路径复杂度高,需要支持 VTEP 的设备

数据中心现在基本不以 STP 为主力——要么 MLAG 消环,要么 VXLAN 绕开二层。STP 家族主要留在办公网与接入层这类对收敛不苛刻的场景。

7. 排查清单 ​

7.1 四个最常见的坑 ​

现象成因处置
根桥不是核心交换机默认优先级全为 32768 → 比 MAC → 谁小谁当,等于随机核心交换机显式配 priority 4096(或 0)
插了台家用路由器全网卡顿它发 BPDU 参与选举,或不参与导致临时环路接入端口配 BPDU Guard
收敛慢、中断 30 秒以上还在跑经典 STP,或端口是半双工(Shared)换 RSTP;检查双工模式
MSTP 只在部分链路负载分担Region 不统一,边界端口状态跟随 IST核对三个属性

7.2 命令行 ​

bash
# Cisco IOS
show spanning-tree                              # 本机端口角色与状态
show spanning-tree root                         # 根桥信息
show spanning-tree interface <端口>              # 单端口详情
show spanning-tree mst configuration            # MSTP 三个属性
show spanning-tree summary                      # 模式与统计

# Linux bridge(只支持单实例 STP/RSTP)
cat /sys/class/net/br0/bridge/root_id           # 根桥 ID
cat /sys/class/net/br0/bridge/root_path_cost    # 到根桥开销
bridge link show                                # 各端口状态

7.3 看输出时的三个判据 ​

看什么判据
根桥 ID是否等于核心交换机的 BID。不是就有问题
端口角色分布一个环里应该恰好有一个端口被阻塞。全转发 = 有环;多个阻塞 = 路径设计有问题
端口类型P2P 才能快速收敛;Shared 说明半双工,会退回慢收敛

7.4 三个典型误判 ​

误判实际情况
「有冗余链路就一定负载分担」只有 MSTP 且 Region 统一才分担;RSTP 下冗余链路 100% 闲置
「配了 PortFast 就安全」PortFast 只让端口快速转发,不防环。必须配 BPDU Guard
「show spanning-tree 显示 forwarding 就没问题」要连根桥是谁一起看。所有端口 forwarding 恰恰是环路的征兆

相关 ​

参考 ​

IEEE 802.1D / 802.1Q 是付费标准,本篇的机制与定时器数值对照 Cisco 官方公开文档;Linux bridge 的行为来自内核文档。

贡献者 ​

文件历史 ​