0%

STP802.1d简述

写在前面

本文旨在描述STP(802.1d)的一些基本概念,搞清楚其消除二层环路的原理,为后面的RSTP已经MSTP的学习做铺垫。STP是一个高度自动化的协议,一两条简单的命令就可以让其自动计算,链路故障时也可以自动恢复,但只有真正掌握其实现原理,才能在故障时进行修复,才能合理的使用其安全特性和优化特性。现有的STP有多个版本,包括标准STP(802.1d),快速RSTP(802.1w), 多实例MSTP(802.1s)。思科使用PVSTP(per-vlan stp)替代标准STP.

STP的作用

STP不仅仅是为了消除二层环路,其根本的作用是提供L2线路冗余的同时避免环路。二层环路会带来下面几个问题:

  1. 广播风暴
  2. 重复帧
  3. MAC地址跳跃

STP如何实现冗余及避免环路的

当有环的时候通过阻塞某些端口破坏环路,当线路挂掉的时候通过恢复之前阻塞的端口继续提供服务。要达到这样的效果,需要额外的检查,STP通过BPDU(bridge protocol data unit)来实现这种额外的检查。

这种检查的基本逻辑是,确定设备的角色,然后再确定设备上端口的角色,确定端口的状态,根据角色、状态这两个属性确定端口对报文的接收、发送、转发、学习、丢弃能力。

STP中的一些重要概念

BID

BID由优先级和参与STP计算的最小端口MAC地址组成,默认优先级是32768, 思科默认运行的PVSRT中会将vlan ID加到优先级中,所以它的默认优先级是32768+1

根桥

STP的目的是形成一颗以根桥为起点的无环树状结构,根桥是BID最小的网桥。

3中端口角色

端口角色 说明
root port(RP) 非根交换机到跟交换机cost最小的端口,上联根桥的端口
designated port(DP) 根桥和非根桥上都有,根桥的所有端口都是DP,连接下游的端口
Alternate port(AP) 剩下的端口都是AP,AP端口一般都处于blocking状态, 只接收BPDU,不做任何转发处理

5种端口状态

状态 说明
disabled 该状态下的端口没有激活,不参与STP的任何动作,不转发用户流量
blocking 只能接收BPDU
listening 该状态下的端口可以接收和发送BPDU,但不转发用户流量,不学习mac地址
learning 该状态下建立无环的转发表,不转发用户流量,学习mac地址
forwarding 接收和发送BPDU,也转发用户流量

四个计时器

STP很多工作的完成都依赖计时器,这些计时器可以保证拓扑进入无环状态才转发数据,链路故障时完成收敛,同时也是其收敛时间过长的原因。不同厂家在此都有一些优化策略。

计时器 说明
message age 每经过交换机relay一次加1秒,类似IP报文中的TTL,大于MAX_age后不处理,防止网络半径太大
max age 消息老化时间,默认20秒
hello time 发送两个消息之间的间隔,默认2秒
forward delag 控制listening和learning之间的状态切换延时,默认15秒

BPDU

BPDU是STP协议的核心,BPDU承载上述的某些参数,完成根桥的选举,端口的选举。BPDU报文字段如下:

protocol identical protocol version BPDU type flags root identifier root path cost bridge identifier port identifier message age max age hello time forward delay
ID为0 stp为0,rstp为2,mstp为3 0x00:配置BPDU,0x80:TCN BPDU,0x02:RST BPDU或MST BPDU 最高位为1表示TCA,最低位为1表示TC 根桥ID 发送桥到根桥的开销 sender BID sender PID 同上 同上 同上 同上

root past cost与带宽相关,一般ethernet(10M)的cost是100, 数值越小优先级越高。
port ID优先级.端口号组成,优先级默认为128, 如Eth0的port ID为128.1
这些参数可以在show spanning命令下看到。

根桥的选举,端口角色的选举,本质就是不同设备BPDU的对比,不同端口收到的BPDU的选举。这里介绍一个概念superior BPDU. superior BPDU满足如下条件:

  1. BID最优
  2. 如果条件1一致,root past cost最优的为superior BPDU
  3. 如果条件1,2一致,sender BID最优的为superior BPDU
  4. 如果1,2,3一致,sender PID最优的为superior BPDU
  5. 如果1,2,3,4一致,receiver PID最优的为superior BPDU
    STP中涉及到参数比较的都是数值越小优先级越高,BID和PID类似,都是先比较优先级,如果优先级一致,再比较mac地址或端口号。与之相对不满足上述条件的则成为inferior BPDU

此外需要知道一个细节,端口会存储最近收到的superior BPDU(加上该端口的cost),并对他进行老化,老化时间为max_age-message_age。典型场景是AP收不到superior BPDU, 20秒后老化变成DP,这样可以保证超时信息从拓扑中移除。只有RP和AP上会存储superior BPDU, DP只负责转发。

STP的选举流程

  1. 根桥的选举
    刚开始时,所有的交换机认为自己是根桥,所有端口都是DP(listening),将root idbridge id字段都填充自己的BID向外发送(组播),经过一段时间收敛后,BID最优的被选成根桥。本质就是不同交换机之间BPDU的比较,根桥的BPDU为superior BPDU.根桥选定之后,只有根桥向外发送配置BPDU,其它交换机只负责接收和转发,端口都是DP(listening).
    如图所示,S1的BID优先级最小,选举成为根桥。

  2. 根端口的选举
    在成环的拓扑中,非根桥会从多个端口收到根桥发来的BPDU,从这些BPDU中选出superior BPDU作为根端口。
    如图所示,以S3为例,会从eth0,eth2,eth3三个端口收到根桥发来的BPDU,eth3收到的是S2中继的BPDU,cost值大,而eth0和eth2收到的BPDU的cost为0, 所以在eth0和eth2之间选。sender BID都是S1,看PID,S3上eth0收到的是S1上eth1发出,PID小(优先级一样,看端口号), 所以S3上eth0是RP。换言之,S3的3个端口收到的BPDU中,eth0收到的是superior BPDU。

  3. 指定端口的选举
    根桥上的所有端口都是DP,对于非根桥设备,除RP外,将端口收到的BPDU与发出的BPDU对比,superior BPDU的作为DP,inferior BPDU则作为AP.
    任一链路中肯定有一个DP,如图所示,以S2为例,eth0是RP,剩下eth2进行DP选举,eth2中继eth0收到的BPDU给S3的eth3(发出的BPDU),S3的eth3中继eth0收到的BPDU给S2的eth2(收到的BPDU),cost一致,比较sender BID,两者优先级一致,但S2的MAC更小,所以S2的eth2是DP, 同理,S3的eth3是AP。换言之,S2的eth2发出的BPDU相较于收到的BPDU是superior BPDU。

选举完成之后,DP和RP经过listening和learning的时延后进入forwarding状态,AP则处于blocking状态,破除拓扑的环路。根桥周期向外发送配置BPDU,非根桥从RP接收superior BPDU,加上RP的cost,将bridge ID字段改成自己的,从DP向外中继该BPDU(源MAC改成DP的MAC).

STP收敛场景描述

只有当RP挂点后才有收敛的意义(链路必定有一端是RP)。交换机通过两种方式可以感知到线路故障。

直接感知

链路物理上是直连的。这种场景下又可以分两种情况。

交换机上没有存储BPDU的端口

当交换机感知到端口down掉后,会立马清除该端口上存储的BPDU, 如果没有其它存储BPDU的端口,那么该交换机就会宣告自己是新的根桥,并将自己的配置BPDU向外发送,由于真实根桥依然存在,其它交换机收到的是inferior BPDU, 不会对其做任何处理,直至收到inferior BPDU的端口超时。

如STP选举流程中的图示,当S2的eth0端口down掉之后,S2认为自己是根桥,通过eth2给S3的eth3发送inferior BPDU(TC置位),S3的eth3一直收不到superior BPDU,最终会超时(20秒),之后变成DP(经过listening,learning的30秒时延后变成forwarding状态,通过RP发送TCN),并立即向S2中继superior BPDU,S2收到之后知道根桥的存在,停止发送BPDU,并将eth2选举成RP(原则上应该经历listening,learning再转成forwarding,思科上直接变成forwarding,应该是做了优化),RP变成forwarding状态后发送TCN报文,所以收敛的总耗时接近50秒(超时没有算message_age).

交换机上有存储BPDU的端口

同上,如果交换机上有其它存储BPDU的端口,那么会在这些端口中选出superior BPDU的端口作为新的RP。

如STP选举流程中的图示,当S3的eth0端口down掉之后,S3会在eth2和eth3之间选举出新的RP,很明显eth2上市superior BPDU,eth2成为RP,经过listening和learning之后变成forwarding,并发送TCN报文。收敛时间是30秒。

间接感知

链路物理上是非直连的,比如中间链路中间有个hub。这种情况下只能等待BPDU报文超时触发。之后的处理流程和直接感知一致,需要加上额外的20秒BPDU报文超时时间。

STP拓扑变化带来的问题

L2依据Mac地址表进行转发,拓扑变换可能导致Mac地址表失效. 当stp收敛之后,虽然会重新学习到正确的mac地址,但是会耗费相当多的时间,特别是当某条mac地址不存在或超时时间恰好是最大值(默认300秒). 为此,当拓扑变化时,通过TCN BPDU通知根桥,根桥通过TCN ACK BPDU通知所有交换机,收到此报文的交换机将mac地址表超时改成forward_time,发送TCN BPDU的交换机收到ACK后会停止发送TCN.

缩短mac地址的老化时间会使拓扑不稳定,会存在泛洪流量,当大量拓扑发生改变时,这种情况是很危险的。RSTP中也有这个问题。

STP收敛的几个优化配置

思科设备上提供了几种优化配置来减少收敛时间, 降低不必要的mac地址表刷新。

portfast在edge port上开启,当端口状态发生变化时,不会发送TCN BPDU,避免刷新MAC地址表,端口可以直接从block状态变成forwarding状态,不需要等待30秒。开启命令如下

1
Switch(config-if)#spanning-tree portfast edge	 // 在eth2上开启portfast

如上图,在eth2上开启portfast后,eth2会直接变成forwarding状态,并且不会发送TCN报文。

uplinkfast当RP失效后,AP跳过listening和learning的30秒,直接变成RP的forwarding状态, 开启命令如下:

1
Switch(config)#spanning-tree uplinkfast		// 全局开启uplinkfast

如上图,shutdown S3上的RP eth0, eth1会从AP直接变成RP的forwarding状态。
注意,配置uplinkfast后,交换机优先级会调整32768+4096(不会选成根桥),端口cost会增加3000(不会选成DP)

backbonefastAP端口收到inferior BPDU后ignore,直到max_age超时后变成DP,耗时20秒,开启backbonefast后,不用等到超时,AP直接变成DP,开启命令如下:

1
Switch(config)#spanning-tree backbonefast		// 需要在所有交换机上开启才生效,原理上应该只需要在收到inferior BPDU的switch上开启就行,模拟器bug?

如上图,S2的eth0 down掉后,认为自己是根桥向S3发送inferior BPDU,正常情况下S3忽略,直到eth1超时变成DP(20秒), 然后S3向S2转发superior BPDU,eth1再经过listening和learning的30秒时延后进入forwarding状态,完成收敛。开启backbonefast后,eth1不用等待20秒超时,直接变成DP,然后再经过30秒状态变化后进入forwarding,收敛时间由50秒变成30秒。
很多文档中有direct和indirect的区分,其实没啥必要,命令行中也没体现,直接分析错误场景,分析BPDU的比较即可。

几种安全机制

BPDU gard/filter如果端口使能BPDU gard,当端口收到BPDU时将端口down掉(error disable)。应该在所有的access端口使能,即只有交换机互联的端口跑STP。可以避免交换机attacks(攻击者伪装成根交换机监听流量)和incident(非 STP/RSTP 感知交换机插入网络导致环路)。

1
2
Switch(config-if)#spanning-tree bpduguard enable		// 端口下开启bpduguard,收到bpdu将端口errordisable
Switch(config-if)#spanning-tree bpdufilter enable // 不shutdown端口,只是ignore收到的bpdu,其它流量正常转发,在AP上开启,BPDU超时后会变成DP,形成环路