为了提高网络可靠性,交换网络中通常会使用冗余链路,冗余链路会给交换网络带来环路风险。生成树协议STP(Spanning Tree Protocol)就是在提高网络可靠性的同时,避免环路的种种问题。


二层环路的问题

  • 广播风暴

    对于BUM帧,交换机会执行无条件的泛洪,如果交换机网络中存在环路,这个帧会被无限转发,瞬间耗尽交换机的 CPU 和链路带宽。

  • 主机会收到重复的数据帧

    对于BUM帧,由于广播风暴的存在,网络中充斥着重复的广播帧。

    对于单播帧,原本的已知单播被“退化”成了未知单播,从而被泛洪。一是MAC表震荡,导致触发了保护机制删除了表项。二是由于链路拥塞,交换机收不到目标主机的回应导致表项无法老化删除。

  • MAC地址表震荡

    网络变得随机和不可预测。

补充1:BUM帧,即Broadcast (广播帧)、Unknown Unicast (未知单播帧)、Multicast (组播帧)。广播帧目标MAC为FF:FF:FF:FF:FF:FF;组播帧目标MAC最后一个字节最低位为1,在为开启IGMP Snooping(互联网组管理协议嗅探)等技术前,被当做广播帧处理;未知单播帧只指交换机MAC地址表查不到,执行和广播相同的操作。

补充2:交换机内部处理 MAC 表震荡时,会看到同一个源 MAC 在多个端口间快速迁移,并触发 MAC 地址漂移(MAC Flapping) 告警。为了保护硬件转发芯片,很多交换机有个默认动作:直接把那个反复震荡的 MAC 地址表项“冻结”甚至删除,直到震荡停止再重新学习。

生成树的构建过程

STP的作用:一是消除环路,通过阻断冗余链路来消除环路。二是链路备份,当活动路径发生故障时,激活备份链路。

image-20260705215101833

为什么STP大量使用“桥”术语,比如根桥(Root Bridge)、桥ID(Bridge ID)、桥协议数据单元(BPDU)?

STP 的原始标准 IEEE 802.1D 诞生于 1990 年。在那个年代,用来连接两个网段的网络设备就叫“网桥”,它通常是只有两个端口的“二层转发盒子”。 而我们今天熟悉的、有大量端口的交换机,在技术本质上就是多端口网桥。当 STP 协议被发明出来时,大家还没用上“交换机”这个词,所以整个协议的标准术语全用了“桥”。

Cisco AGS+,一个典型网桥。

Cisco AGS+

Kalpana EtherSwitch EPS-1500,最早的以太网交换机之一。

Kalpana EtherSwitch EPS-1500

BPDU

交换机之间通过 BPDU 报文交换生成树信息,里面包含:

  • Root ID —— 根桥 ID
  • Root Path Cost —— 发送者到根桥的路径开销
  • BID —— 发送BPDU的设备BID (4位优先级+12位系统ID扩展+48位交换机背板地址)
  • PID —— 发送BPDU的端口PID (4位优先级+12位端口编号)

Step 1 选举根桥

比较BID,先比较优先级,后比较MAC地址,越小越好。

默认优先级32768,可以手动配置为4096的倍数。

建议手动指定根桥,防止误接抢根,造成整个生成树重新生成。

1
2
stp root primary 等效于 stp priority 0
stp root secondary 等效于 stp priority 4096

Step 2 选举根端口

在非根桥设备上,选举离根桥最近的端口,简称RP,以下参数越小越好。

  1. 比较入方向的累计路径开销,即收到的 BPDU 中的根路径开销字段 + 本端口自己的端口开销。
  2. 比较发送者BID(如果两个以上的路径的累计路径开销相同)。
  3. 比较发送者PID(如果两个以上的端口连接到同一交换机)。
  4. 比较自身接口的PID (如果使用了HUB这种设备)。

Step 3 选举指定端口

Designated Port 简称DP

指定端口在每个链路(即冲突域)上选择,每段链路只会选择一个。

  1. 比较累计路径开销。
  2. 比较端口所在的交换机的BID。
  3. 比较端口的PID(如果使用了HUB这种设备)。

Step 4 阻塞非根&非指定端口

网络收敛后,只有指定端口和根端口可以转发数据。

其他端口在经典STP中被称为阻塞端口,Blocking Port,在RSTP中被称为预备端口,Alternate port,简称AP,被阻塞,不能转发数据,只能够从所连网段的指定交换机接收到BPDU报文,并以此来监视链路的状态。

端口状态转换

为了防止临时环路,在定义了端口角色的基础上,还定义了端口状态。

端口状态 行为 解释
Disabled 禁用状态 不处理BPDU,也不转发用户流量 比如端口状态是down
Blocking 阻塞状态 接收BPDU,不能转发。 阻塞端口的长期工作形态
Listening 侦听状态 收发BPDU,不学习MAC,不转发用户流量 DP和RP的临时状态,15s确保全网选举一致,防止临时环路
Learning 学习状态 收发BPDU,学习MAC,不转发用户流量 在无环拓扑上预建MAC表,减少转发初期的未知单播泛洪,经15秒后进入Forwarding
Forwarding 转发状态 收发BPDU,学习MAC,转发用户流量 DP和RP最终正常工作状态

端口状态转换

这是华为的图:

image-20260706205729200

Learning状态存在的原因:

一是减少未知单播泛洪。在转发前,完成MAC表的构建,收到数据即刻开始转发,尽可能减少未知单播泛洪。

二是构建无环MAC表。不开启STP的时候,端口直接学习MAC地址;开启STP后,在了解网络的拓扑环境(那个端口被阻塞了)后,在Learning状态可以建立无环的MAC表。

Listening状态存在的原因:

防止临时环路。确保网络中的所有交换机都完成了选举,这个时候只做一件事,处理BPDU报文,使得整个网络达成一致。如果没有这个状态,尽管最终还是会完成选举,但是已经产生的错误MAC表项,只能等老化时间结束后才能消除。

Blocking状态存在的原因:

一是物理环路需要逻辑断开。这也是使用STP去解决二层环路的目的。

二是需要作为充当备份。在收不到BPDU时候,触发重新选举。

是阻塞端口的长期工作状态,或者说是备用端口的最终状态。

BPDU

BPDU字段含义

image-20260706225716152

字段 含义 典型值
PID 协议ID 0,表示使用的是 IEEE 802.1D 生成树协议。
PVI 协议版本ID STP 为0,RSTP 为2,MSTP 为3。
BPDU Type BPDU类型 配置 BPDU——0x00 | TCN BPDU——0x80。
Flags 标志 TC | TCA
Root ID 根桥ID 根桥的优先级和MAC地址组成
RPC 根路径开销 到根桥的最短路径开销。
Bridge ID 指定桥ID 指定桥的优先级和MAC地址组成。
Port ID 指定端口ID 指定端口的优先级和端口号组成。
Message Age 配置BPDU在网络中传播的生存期。 根桥始发为0,每经过一台设备+1,超过20时候丢弃。
Max Age 配置BPDU在设备中的最大生存期。 20s
Hello Time 配置BPDU发送的周期 2s
Fwd Delay 端口状态迁移的延时 15s

TCN-BPDU

配置BPDU —-> 只有DP会发送,RP和AP只能被动接收,RP可以修改并转发。用于生成树的选举、周期性的维护。

TCN-BPDU —-> 只有在拓扑变化时RP才会发送,实现全网所有设备清空MAC地址表。

几个名词:

TCN:Topology Change Notification 拓扑变化通知(TCN-BPDU,一个独立短小的报文)

TCA:Topology Change Acknowledgment 拓扑变化确认(配置BPDU的标志位)

TC:Topology Change 拓扑变更(配置BPDU的标志位)

image-20260706232710105

使用TCN-BPDU的原因是:为了解决错误的MAC表项只能等老化时间结束才能改变

如果生成树拓扑发生变化,交换机转发数据的路径也会随着发生改变,此时MAC地址表中未及时老化掉的表项会导致数据转发错误,因此在拓扑发生变化后需要及时清空MAC地址表项。

拓扑改变导致MAC地址表错误

网络中的某个交换机检测到以下两点,即表明拓扑改变

  • 阻塞端口进入Forwarding状态
  • 处于Forwarding状态的RP或者DP端口进入Blocking状态

此后

  1. RP逐级发送TCN-BPDU,2s发一次
  2. 上游交换机立刻回传TCA置位的配置BPDU,然后使用RP向上发送TCN-BPDU
  3. 根桥收到后,向全网泛洪TC置位的配置BPDU,共发送35s,收到此消息的交换机,会将老化时间改为Fwd Delay(15s)。

一个典型的例子是:image-20260707001157266