STP拓扑计算
网络中所有的设备使能STP协议后,每一台设备都认为自己是根桥。此时,每台设备仅仅收发配置BPDU,而不转发用户流量,所有的端口都处于Listening状态。所有设备通过交换配置BPDU后,进行选举工作,选出根桥、根端口和指定端口。
BPDU报文的交互过程
如图9-8所示,用{}标注的四元组表示了由根桥ID(图中以S1_MAC和S2_MAC代表两台设备的BID)、累计根路径开销、发送者BID、发送端口PID构成的有序组。配置BPDU会按照Hello Timer规定的时间间隔来发送。
STP算法实现的基本过程
初始状态
由于每个桥都认为自己是根桥,所以在每个端口所发出的BPDU中,根桥字段都是用各自的BID,Root Path Cost字段是累计的到根桥的开销,发送者BID是自己的BID,端口PID是发送该BPDU端口的端口ID。
选择根桥
网络初始化时,网络中所有的STP设备都认为自己是“根桥”,根桥ID为自身的设备ID。通过交换配置消息,设备之间比较根桥ID,网络中根桥ID最小的设备被选为根桥。
选择根端口和指定端口
根端口和指定端口的选择过程如表9-8所示。
表9-8 根端口和指定端口的选择过程步骤
过程
1
非根桥设备将接收最优配置消息(最优配置消息的选择过程如表9-9所示)的那个端口定为根端口
2
设备根据根端口的配置消息和根端口的路径开销,为每个端口计算一个指定端口配置消息:
- 根桥ID替换为根端口的配置消息的根桥ID;
- 根路径开销替换为根端口配置消息的根路径开销加上根端口对应的路径开销;
- 发送者BID替换为自身设备的ID;
- 发送端口PID替换为自身端口ID。
3
设备将计算出的配置消息与角色待定端口自己的配置消息进行比较:
- 如果计算出的配置消息更优,则该端口被确定为指定端口,其配置消息也被计算出的配置消息替换,并周期性地向外发送;
- 如果该端口自己的配置消息更优,则不更新该端口的配置消息并将该端口阻塞。该端口将不再转发数据,且只接收不发送配置消息。
STP算法实现举例
一旦根桥、根端口和指定端口选举成功,整个树形拓扑就建立完毕了。下面结合例子说明STP算法实现的具体过程。
如图9-9所示,DeviceA、DeviceB和DeviceC的优先级分别为0、1和2,DeviceA与DeviceB之间、DeviceA与DeviceC之间以及DeviceB与DeviceC之间链路的路径开销分别为5、10和4。
各设备的初始状态
各设备的初始状态如表9-10所示。
各设备的比较过程及结果
各设备的比较过程及结果如表9-11所示。
表9-11 STP拓扑计算过程及结果设备
比较过程
比较后端口的配置消息
DeviceA
- Port A1收到Port B1的配置消息{1,0,1,Port B1},发现自己的配置消息{0,0,0,Port A1}更优,于是将其丢弃。
- Port A2收到Port C1的配置消息{2,0,2,Port C1},发现自己的配置消息{0,0,0,Port A2}更优,于是将其丢弃。
- DeviceA发现自己各端口的配置消息中的根桥和指定桥都是自己,于是认为自己就是根桥,各端口的配置消息都不作任何修改,此后便周期性地向外发送配置消息。
- Port A1:{0,0,0,Port A1}
- Port A2:{0,0,0,Port A2}
DeviceB
- Port B1收到Port A1的配置消息{0,0,0,Port A1},发现其比自己的配置消息{1,0,1,Port B1}更优,于是更新自己的配置消息。
- Port B2收到Port C2的配置消息{2,0,2,Port C2},发现自己的配置消息{1,0,1,Port B2}更优,于是将其丢弃。
- Port B1:{0,0,0,Port A1}
- Port B2:{1,0,1,Port B2}
- DeviceB比较自己各端口的配置消息,发现Port B1的配置消息最优,于是该端口被确定为根端口,其配置消息不变。
- DeviceB根据根端口的配置消息和路径开销,为Port B2计算出指定端口的配置消息{0,5,1,Port B2},然后与Port B2本身的配置消息{1,0,1,Port B2}进行比较,发现计算出的配置消息更优,于是Port B2被确定为指定端口,其配置消息也被替换为计算出的配置消息,并周期性地向外发送。
- 根端口Port B1:{0,0,0,Port A1}
- 指定端口Port B2:{0,5,1,Port B2}
DeviceC
- Port C1收到Port A2的配置消息{0,0,0,Port A2},发现其比自己的配置消息{2,0,2,Port C1}更优,于是更新自己的配置消息。
- Port C2收到Port B2更新前的配置消息{1,0,1,Port B2},发现其比自己的配置消息{2,0,2,Port C2}更优,于是更新自己的配置消息。
- Port C1:{0,0,0,Port A2}
- Port C2:{1,0,1,Port B2}
- DeviceC比较自己各端口的配置消息,发现Port C1的配置消息最优,于是该端口被确定为根端口,其配置消息不变。
- DeviceC根据根端口的配置消息和路径开销,为Port C2计算出指定端口的配置消息{0,10,2,Port C2},然后与Port C2本身的配置消息{1,0,1,Port B2}进行比较,发现计算出的配置消息更优,于是Port C2被确定为指定端口,其配置消息也被替换为计算出的配置消息。
- 根端口Port C1:{0,0,0,Port A2}
- 指定端口Port C2:{0,10,2,Port C2}
- Port C2收到Port B2更新后的配置消息{0,5,1,Port B2},发现其比自己的配置消息{0,10,2,Port C2}更优,于是更新自己的配置消息。
- Port C1收到Port A2周期性发来的配置消息{0,0,0,Port A2},发现其与自己的配置消息一样,于是将其丢弃。
- Port C1:{0,0,0,Port A2}
- Port C2:{0,5,1,Port B2}
- DeviceC比较Port C1的根路径开销10(收到的配置消息中的根路径开销0+本端口所在链路的路径开销10)与Port C2的根路径开销9(收到的配置消息中的根路径开销5+本端口所在链路的路径开销4),发现后者更小,因此Port C2的配置消息更优,于是Port C2被确定为根端口,其配置消息不变。
- DeviceC根据根端口的配置消息和路径开销,为Port C1计算出指定端口的配置消息{0,9,2,Port C1},然后与Port C1本身的配置消息{0,0,0,Port A2}进行比较,发现本身的配置消息更优,于是Port C1被阻塞,其配置消息不变。从此,Port C1不再转发数据,直至有触发生成树计算的新情况出现,譬如DeviceB与DeviceC之间的链路down掉。
- 阻塞端口Port C1:{0,0,0,Port A2}
- 根端口Port C2:{0,5,1,Port B2}
拓扑稳定后,根桥仍然按照Hello Timer规定的时间间隔发送配置BPDU报文,非根桥设备从根端口收到配置BPDU报文,通过指定端口转发。如果接收到的优先级比自己高的配置BPDU,则非根桥设备会根据收到的配置BPDU中携带的信息更新自己相应的端口存储的配置BPDU信息。
STP拓扑变化
STP拓扑变化处理过程如图9-10所示。
- 在网络拓扑发生变化后,下游设备会不间断地向上游设备发送TCN BPDU报文。
- 上游设备收到下游设备发来的TCN BPDU报文后,只有指定端口处理TCN BPDU报文。其它端口也有可能收到TCN BPDU报文,但不会处理。
- 上游设备会把配置BPDU报文中的Flags的TCA位设置1,然后发送给下游设备,告知下游设备停止发送TCN BPDU报文。
- 上游设备复制一份TCN BPDU报文,向根桥方向发送。
- 重复步骤1、2、3、4,直到根桥收到TCN BPDU报文。
- 根桥把配置BPDU报文中的Flags的TC和TCA位置1后发送,通知下游设备直接删除桥MAC地址表项。
- TCN BPDU报文主要用来向上游设备乃至根桥通知拓扑变化。
- 置位的TCA标记的配置BPDU报文主要是上游设备用来告知下游设备已经知道拓扑变化,通知下游设备停止发送TCN BPDU报文。
- 置位的TC标记的配置BPDU报文主要是上游设备用来告知下游设备拓扑发生变化,请下游设备直接删除桥MAC地址表项,从而达到快速收敛的目的。