生成树技术的背景
如下图所示的交换网络,要让三个二层交换机可以相互通信的话,则至少需要如下图所示的连接。
但是如果SW3和SW2之间的连接故障了,则SW1和SW3之间通信就断开了,因此这个网络不够健壮。
为了减少单链路故障,提升网络的健壮性、增加网络的冗余性。交换网络中通常会增加冗余链路,比如将SW1和SW3之间也增加一条链路,如下图所示:
但是这又会引入二层环路。二层环路的危害是非常大的,会引发包括广播风暴、设备MAC地址表紊乱、以及MAC地址漂移等在内的一系列问题,严重时由环路引发的广播风暴更有可能耗尽链路带宽,或者使设备的CPU利用率急剧攀升并导致其无法正常工作,最终造成网络瘫痪。
有没有一种技术能够既增加网络的可靠性,又不引入二层环路呢?生成树技术就是这种技术。
如下图所示,当在交换网络中部署了生成树技术(Spanning-tree Protocol, STP)后,如果发现网络有环路,那么STP能够自动的阻塞(Block)特定的某个端口,从而打破环路。比如在下面的交换网络中,发现存在环路,则阻塞SW1中和SW2连接的端口,这样就破环了。并且当网络出现变动时,比如SW1和SW3之间的链路故障了,那么就会将SW1中和SW2连接的端口去除阻塞,因此能够适应网络的拓扑变化,实现链路冗余。
生成树技术有以下两个作用:
- 消除二层环路:通过阻塞冗余链路消除网络中可能出现的二层环路。
- 链路备份:当活动链路发生故障时,激活冗余备份链路,及时恢复网络的连通性。
与众多协议的发展过程一样,生成树协议也是随着网络的发展而不断更新的,从最初的IEEE 802.1D中定义的STP到IEEE 802.1W中定义的快速生成树协议RSTP(Rapid Spanning Tree Protocol),再到最新的IEEE 802.1S中定义的多生成树协议MSTP(Multiple Spanning Tree Protocol)。本文所讲的即是802.1D,即STP。
STP的工作原理用一句话讲就是:通过在交换机之间交换BPDU消息发现环路,并有选择地阻塞某些端口,最终将环路网络修剪成无环路的树型网络结构。
怎么将有环的网络修剪成无环的树型网络是本文的学习重点,也是STP的工作机制。
基本概念
-
桥ID(Bridge Indentification):每一台运行STP的交换机都拥有一个唯一的桥ID(也称交换机ID,就是交换机的一个身份证)。桥ID一共8个字节(共64bit),由16bit的桥优先级(Bridge Priority)和48bit的桥MAC地址组成,其中桥优先级占据桥ID的高16bit,而MAC地址占据其余的48bit。
- 桥优先级的范围是0~65536,默认优先级是32768,可以修改,但必须是4096的倍数。值越小,优先级越大。
-
根桥(Root Bridge):STP的根桥是这棵树的树根。网络中拥有最小桥ID的交换机将成为根桥,在比较桥ID时,首先比的是桥优先级,桥优先级的值最小的交换机将胜出成为根桥,如果桥优先级相等,那么MAC地址最小的交换机将成为根桥。
-
STP的路径开销(Path Cost):路径开销用于衡量路径的优劣,STP中链路开销与链路带宽成反比。
-
根路径开销(Root Path Cost, RPC):到达根桥的的路径开销。
-
端口ID(Port Identification)(或者称 接口ID):端口ID用于在一个网桥中唯一地标识一个端口。端口ID由端口优先级和端口编号构成。端口优先级的范围:0~240,且是16的倍数,默认为128。
SPT的工作过程
STP通过4个步骤来保证网络中不存在二层环路:
-
在交换网络中选举一个根桥(Root Bridge, RB)。STP的正常工作依赖于该协议所使用的报文的正常交互,这种报文就是BPDU(Bridge Protocol Data Unit,网桥协议数据单元),BPDU包含着几个重要的数据,这些数据是STP进行无环拓扑计算的关键。
选举原则:选择BridgeID最小的交换机称为根交换机。
根桥的地位是具有可抢占性的。
-
在每个非根桥上选举一个根端口(Root Port, RP):在一个交换网络中,除了根桥之外的其他交换机都是非根桥,STP将为每个非根桥选举一个根端口,所谓根端口,实际上是非根桥上所有端口中收到最优BPDU的接口,可以简单地将其理解为交换机在STP树上"朝向"根桥的端口。非根桥可能会有一个或多个端口接入同一个交换网络,STP将在这些端口之中选举一个(而且只会选一个)根端口(根端口收消息)。
选举原则:
- 首先比较根桥,根桥最小的成为根端口(由于在第1步已经选择出根桥了,所以根桥应该会相同,即这一步比较不出来)。
- 然后比较根路径开销。根路径开销最小的端口成为该非根桥的根端口。
- 如果根路径开销相同,则比较链路对端的网桥ID,对端网桥ID最小的称为根端口。
- 如果对端网桥ID相同,则比较对端端口ID,对端端口ID最小的成为根端口。
-
在每条链路上选举一个指定端口(Designated Port, DP):STP将在每个网段中选举一个指定端口,这个端口是该网段内所有端口中到达根桥的最优端口。此外,指定端口还负责向该网段发送BPDU。
选举原则:
-
所在网桥到根的路径开销最小。由于根桥的所有端口到自己的路径开销是0,所以根桥的所有端口都是指定端口。
-
如果到根桥的路径开销相同,则比较本端网桥的桥ID,桥ID最小的成为指定端口。
-
如果本端网桥的桥ID都相同(在实际情况中,一般不会出现,除非错连),则比较本端端口ID。端口ID最小的成为指定端口。
-
-
阻塞非指定端口,打破二层环路。经STP计算后,如果交换机的某个(或者某些)端口既不是根端口又不是指定端口,我们称这种端口为非指定端口,那么该端口将会被STP阻塞。
STP工作过程举例:
以下图网络为例,假设所有设备都开启了STP协议。
(1)选举根桥。初始情况下,所有的交换机都认为自己是根桥,于是都向网络中泛洪BPDU消息,在各自发送的BPDU中,都会有自己认为的根桥ID,显然,在初始情况下,填的根桥ID都是自己的桥ID。当BPDU消息到达对端之后,根据根桥的选举原则:选择BridgeID最小的交换机称为根交换机。很显然,在上面的网络中,三台交换机的桥优先级相同,都是32768,因此比较MAC地址,MAC地址最小的成为根桥,因此,SW1成为根桥。
(2)在每个非根桥上选举一个根端口。由于SW1是根桥,因此需要在SW2和SW3中各自选择出一个根端口。在SW2上,有port1和port2两个端口。根据根端口选举原则一:首先比较根桥,根桥最小的成为根端口。由于根桥都是SW1,因此原则一选不出来,接着是原则二:比较根路径开销。很显然SW2的port1到根桥的开销比SW2的port2到根桥的开销更小,因此在SW2上,port1是根端口。按照同样的选举原则,选举出SW3的port1是SW3的根端口。
通过上面的两个步骤,根桥以及根端口已经选举出来了,如下图所示:
(3)在每条链路上选举一个指定端口。这里总共有三条链路:SW1的port2和SW3的port1之间的链路、SW1的port1和SW2的port1之间的链路、SW2的port2和SW3的port2之间的链路。由于根桥的所有端口都是指定端口,因此,SW1的port2和SW3的port1之间的链路中,SW1的port2是指定端口。SW1的port1和SW2的port1之间的链路中,SW1的port1是指定端口。现在,还剩下SW2的port2和SW3的port2之间的链路。根据指定端口选举原则一:所在网桥到根的路径开销最小。SW2的port2所在的网桥SW2到根桥的路径开销要比SW3的port2所在的网桥SW3到根桥的路径开销要小,因此SW2的port2成为指定端口。
(4)阻塞非指定端口。如果交换机的某个(或者某些)端口既不是根端口又不是指定端口,我们称这种端口为非指定端口,那么该端口将会被STP阻塞。从上面的网络中看,SW3的port2端口既不是根端口,也不是指定端口,因此它是非指定端口,需要阻塞它。通过阻塞它,打破了原来网络中的环路。
上面是STP的一个整体工作过程,如果只想有一个大概的了解,那接下来的内容可以跳过了。下面的内容是更加详细的解说上面的过程。
STP的BPDU报文
在一个交换网络中,STP能够正常工作的基本前提是BPDU的正常交互。BPDU即网桥协议数据单元(Bridge Protocol Data Unit)。
STP的BPDU有两种类型:配置BPDU(Configuration BPDU)及TCN BPDU(Topology Change Notification BPDU)。两种BPDU各有各的用途。BPDU载荷被直接封装在以太网数据帧中,数据帧的目的MAC地址是组播MAC地址:0180-c200-0000。
BPDU消息的格式如下:
配置BPDU
配置BPDU是STP进行拓扑计算的关键。在交换网络的初始化过程中,每台交换机都从自己激活了STP的接口向外发送配置BPDU。当STP收敛完成后,只有根桥才会周期性地发送配置BPDU(缺省时,以2s为周期发送配置BPDU),而非根桥则会在自己的根接口上收到上游发送过来的配置BPDU,并立即被触发而产生自己的配置BPDU,然后从自己的指定接口发送出去。这一过程看起来就像是根桥发出的配置BPDU逐跳地“经过”了其他的交换机。
配置BPDU的报文格式如下:
+--------------------------------+
| DMAC |
+--------------------------------+
| SMAC |
+--------------------------------+
| Length |
+--------------------------------+
| LLC header |
+--------------------------------+-----------------------
| Protocol Identifier | ^
+--------------------------------+ |
| Protocol Version Identifier | |
+--------------------------------+ |
| BPDU Type | |
+--------------------------------+ |
| Flags | |
+--------------------------------+ |
| Root Identifier | |
+--------------------------------+ |
| Root Path Cost | |
+--------------------------------+ |
| Bridge Identifier | |
+--------------------------------+ |
| Port Identifier | |
+--------------------------------+ |
| Message Age | |
+--------------------------------+ BPDU
| Max Age | payload
+--------------------------------+ |
| Hello Time | |
+--------------------------------+ |
| Forward Delay | |
+--------------------------------+---------- |
各个字段解释如下:
字节数 | 字段 | 描述 |
---|---|---|
6 | DMAC | 目的MAC地址,该字段标识帧的接收者,是一个固定的组播地址:0180-c200-0000 |
6 | SMAC | 源MAC地址,即发送该BPDU消息的桥MAC地址。 |
2 | Length(帧长) | 指后续数据的字节长度,但不包括FCS字段。 |
3 | LLC | 一个固定的链路头 |
2 | 协议ID(Protocol Identifier) | 该字段的值总为0 |
1 | 协议版本ID( Protocol Version Identifier) | 对于STP而言,该字段的值总为0x00。(RSTP为0x02,MSTP为0x03) |
1 | BPDU类型(BPDU Type) | 本BPDU的类型。 - 若值为0x00,则表示本报文为STP的配置BPDU; - 若值为0x80,则本报文为STP的TCN BPDU - 若值为0x02,则表示为RST BPDU(Rapid Spanning-Tree BPDU)或者MST BPDU(Multiple Spanning-Tree BPDU) |
1 | 标志(Flag) | 对于STP而言,该字段(共8bit)用于网络拓扑变化标志。STP只使用了该字段的最高及最低两个比特位,最低位是TC(Topology Change, 拓扑变更)标志,最高位是TCA(Topology Change Acknowledgment,拓扑变更确认)标志 |
8 | 根桥ID(Root Identifier) | 发送本BPDU消息的交换机所认为的根桥的桥ID |
4 | 根路径开销(Root Path Cost) | 发送本BPDU消息的交换机到达根桥的STP路径开销,也就是根桥路径开销 |
8 | 网桥ID(Bridge Identifier) | 发送本BPDU的交换机的桥ID |
2 | 端口ID(Port Identifier) | 发送本BPDU的端口的端口ID |
2 | 消息寿命(Message age) | 该BPDU的消息年龄,以秒为单位。本BPDU的寿命。在根桥所发送的BPDU中。该字段值为0,此后BPDU每经过一个交换设备,该字段值增加1,因此实际上这个字段指示的是BPDU所经过的交换设备的个数。 |
2 | 最大寿命(Max age) | 消息老化年龄,以秒为单位,超时则认为到根交换机的链路故障。也被称为老化时间,缺省为20s。 |
2 | Hello时间(Hello time) | BPDU的发送时间间隔,缺省为2s |
2 | 转发延迟(Forward Delay) | 接口在侦听和学习状态所停留的时间,缺省为15s。 |
TCN BPDU
TCN BPDU的格式非常简单,只有"协议ID"、"协议版本号ID"以及"BPDU类型"三个字段,并且"BPDU类型"字段的值为0x80。TCN BPDU用于在网络拓扑发生变化时向根桥通知变化的发生。
+--------------------------------+
| DMAC |
+--------------------------------+
| SMAC |
+--------------------------------+
| Length |
+--------------------------------+
| LLC header |
+--------------------------------+-----------------------
| Protocol Identifier | ^
+--------------------------------+ |
| Protocol Version Identifier | |
+--------------------------------+ BPDU
| BPDU Type | payload
+--------------------------------+ |
配置BPDU的比较原则
在配置BPDU中,有四个字段非常关键,它们是“根桥ID”、“RPC”、“网桥ID”以及“接口ID”,这四个字段便是交换机进行配置BPDU比较的关键内容。
STP按照如下顺序选择最优的配置BPDU。
-
最小的根桥ID
- 桥ID一共8个字节,由2个字节的优先级和6个字节的MAC地址构成
-
最小的RPC
- 从根桥上发送的Path Cost一定是0(在实际中,可以看这个字段来判断哪个是根桥)。
-
最小的网桥ID
-
最小的接口ID
- 接口ID(2字节)=接口优先级(1字节)+接口编号(1字节)
- 缺省优先级为128,范围0-255,越小越优
- 接口ID(2字节)=接口优先级(1字节)+接口编号(1字节)
在这四条原则中(每条原则都对应配置BPDU中的相应字段),第一条原则主要用于在网络中选举根桥,后面的原则主要用于选举根接口及指定接口。
配置BPDU的交互过程
下面的过程将看到STP是如何通过配置BPDU消息来工作的(怎么通过配置BPDU消息,来破环):
(1)初始情况下,SW1和SW2都认为自己是根桥,因此在它们各自发送的BPDU中,”根桥ID”字段均填写的是自己的桥ID,而”RPC”字段则填写的是0。根桥发出的BPDU的RPC始终为0。“网桥ID”字段填写的是该BPDU发送者的桥ID,而“接口ID”字段则填写的是发送该BPDU的接口的接口ID。
SW1和SW2都将收到对方发送过来的BPDU并开始进行BPDU的比较——将对方的BPDU与自己接口上的BPDU进行比较,按照“最小的根桥ID、最小的RPC、最小的网桥ID、最小的接口ID”的比较原则进行比较。实际上,在第一个原则(最小的根桥ID)的比较中,SW2便已经判断出对方发送的BPDU要比本地的更优。现在SW2接受了SW1为根桥的事实,而SW1则认定自己是根桥,它将忽略SW2发送的BPDU,并继续周期性的从自己的接口发送BPDU。
(2)接下来,SW2将开始根接口选举。由于SW2在GE0/0/3及GE0/0/4接口上收到的BPDU都比自己本地的BPDU更优,因此它使用对方的BPDU更新自己本地的BPDU。然后SW2将比较自己所有接口上的BPDU,拥有最优BPDU的接口将成为其根接口。
对于SW2,在GE0/0/3及GE0/0/4接口上保存的这两个BPDU,它们的“根桥ID”字段是相同的,而它通过这两个接口达到根桥的RPC又都是20000。另外,这两个BPDU的“网桥ID”字段也相同,因此SW2将比较这两个BPDU的“接口ID”字段。由于在GE0/0/3接口上到达的BPDU是由SW1的GE0/0/1接口发出,而在GE0/0/4接口上到达的BPDU是由SW1的GE0/0/2接口发出。接口ID由两部分构成:接口优先级和接口编号,接口优先级的值最小的将胜出,而如果接口优先级都相等,则接口编号最小的将胜出。因此,GE0/0/3接口上到达的BPDU更优,因此GE0/0/3接口将成为SW2的根接口。
(3)SW2的根接口选举出来后,它使用当前在根接口上保存的最优BPDU为其他接口计算BPDU。以SW2为其GE0/0/4接口计算的BPDU为例:
1、在“根桥ID”字段中写入最优BPDU中的根桥ID,也就是SW1的桥ID。
2、在“RPC”字段中写入最优BPDU中的RPC与根接口(GE0/0/3)的Cost之和,也就是20000。
3、在“网桥ID”字段中写入本设备的桥ID,也就是SW2的桥ID。
4、在“接口ID”字段中写入本接口的ID,也就是GE0/0/4接口的ID。
完成上述操作后,SW2将其为GE0/0/4计算出的BPDU与该接口当前保存的BPDU进行比较,很明显当前保存的BPDU更优,于是SW2将该接口认定为非指定接口。SW2继续在GE0/0/4接口上保存SW1发送的BPDU,并且持续侦听该BPDU。
(4)SW2的GE0/0/4接口将被阻塞,从而网络中的二层环路被打破。
STP接口状态
STP除了定义接口角色外(根端口和指定端口),还定义了接口状态。STP主要有以下5种状态:
状态名称 | 状态描述 |
---|---|
禁用(Disable) | 该接口不能收发BPDU,也不能收发业务数据帧,例如接口为down |
阻塞(Blocking) | 该接口被STP阻塞。处于阻塞状态的接口不能发送BPDU,但是会持续侦听BPDU,而且不能收发业务数据帧,也不会进行MAC地址学习。如果max age(默认20s)计时器到期时该接口仍没有收到BPDU则切换到Listening状态。 |
侦听(Listening) | 当接口处于该状态时,表明STP初步认定该接口为根接口或指定接口,但接口依然处于STP计算的过程中,此时接口可以收发BPDU,但是不能收发业务数据帧,也不会进行MAC地址学习。在Listening状态停留15s后,进入Learning状态。 |
学习(Learning) | 当接口处于该状态时,会侦听业务数据帧(但是不能转发业务数据帧),并且在收到业务数据帧后进行MAC地址学习。在Learning状态停留15s后(为了学习到MAC地址),进入Forwarding状态。 |
转发(Forwarding) | 处于该状态的接口可以正常地收发业务数据帧,也会进行BPDU处理。接口的角色需是根接口或指定接口才能进入转发状态 |
当交换机的一个接口被激活后,该接口将从禁用状态自动进入阻塞状态。处于阻塞状态的接口如果被交换机选举为根接口或者指定接口,那么它将从阻塞状态进入侦听状态,并且在侦听状态停留15s(转发延迟时间)。为什么接口不允许从阻塞状态直接进入转发状态,而要先进入侦听状态呢?设想一下,在STP的收敛过程中,BPDU泛洪到全网是需要一定时间的,STP完成全网拓扑计算同样需要时间,因此接口在侦听状态停留的这15s将给予STP充分的时间进行全网拓扑计算,避免网络中出现临时的环路。在侦听状态停留15s后,如果该接口依然是根接口或指定接口,那么它将进入学习状态,并且在该状态下也停留15s(转发延迟时间)。由于此时交换机在接口上并未学习到任何MAC地址,因此如果接口从侦听状态立即进入转发状态的话,就有可能在短时间内导致网络中出现不必要的数据帧泛洪现象。所以,STP规定接口从侦听状态进入学习状态后,也需停留15s,在这段时间内交换机会在该接口持续侦听业务数据帧并学习MAC地址,为进入转发状态做好准备。
STP拓扑变更的触发条件
从上面知道,STP的BPDU消息分为配置BPDU和TCN BPDU消息。通过配置BPDU消息,STP能够将二层网络中的环路破除。
那TCN BPDU消息的功能呢?TCN BPDU用于在网络拓扑发生变化时向根桥通知变化的发生。
那产生TCN BPDU的条件是什么呢?
当拓扑发生变化后,STP是否产生TCN BPDU,要根据以下两个标准来判定:
(1)网桥至少有一个指定端口,并且某端口从其他状态(Blocking、Listening、Learning)转移到Forwarding状态。
(2)某端口从Forwarding、Learning、Listening状态转移到Blocking状态。
当以上两个条件至少满足一个时,STP交换机就会触发TCN BPDU。
STP拓扑变更机制
(1)STP拓扑变更过程如下图所示,当某个拓扑感知到有拓扑变化时,会产生一个TCN BPDU消息并从该交换机的根端口发送出去(因为根端口是朝着根桥的方向),发送给它的上游交换机。该交换机会一直发送,直到上游交换机回复它TCA置位的配置BPDU消息为止。(下图的步骤1、2)
(2)上游交换机收到TCN BPDU消息后,将回复一个TCA标志位置1的配置BPDU消息给它的下游交换机。并且继续向该交换机的上游继续发送TCN BPDU消息以及等待该交换机上游的TCA 置位的配置BPDU消息.该报文UI一跳一跳地向上游传递,直至抵达根桥 (下图的步骤3、4、5)
(3)根桥收到TCN BPDU消息后,意识到网络中拓扑发生了变化,因此它需要将该变化通知到全网。它将向网络中泛洪TC置1的配置BPDU消息。网络中的交换机收到该配置BPDU后,会立即将其MAC地址表的老化时间从原有的值(一般默认是300s)调整为一个较小的值(该值等于转发延迟时间,默认15s),使MAC地址表能够尽快的刷新。
STP中的三个定时器
STP中,定义了三个重要的定时器,分别是:
- Hello Timer(Hello 时间):STP交换机发送BPDU的时间间隔(默认值为2s)。当网络拓扑稳定之后,该计时器的修改只有在根桥修改才有效。根桥会在之后发出的BPDU中填充适当的字段以向其他非根桥传递该计时器修改信息。但当拓扑变化之后,TCN BPDU的发送不受这个计时器的管理。
- Forward Delay(转发延迟):运行了STP的接口从侦听(Listening)状态进入学习(Learning)状态,或者从学习(Learning)状态进入转发(Forwarding)状态的延迟时间,缺省为15s。为了避免在生成树收敛过程中网络中可能出现的临时环路,或者短暂的数据帧泛洪现象,STP定义了侦听以及学习这两种接口状态,并要求接口从阻塞状态进入转发状态前必须先经历这两个状态,而且分别在这两个状态各停留一个转发延迟时间。因此,对于STP而言,一个被阻塞的接口被选举为根接口或者指定接口后,进入转发状态之前至少需要经历30s的时间。
- Max Age(最大生存时间):BPDU消息存活的最大时间(默认值为20s)。如果某接口一直没有收到上游发送的BPDU消息,并且超过了Max Age,那么该接口保存的BPDU消息将被老化,此时该设备会重新进行根接口的选举。
STP协议的不足
- 收敛时间慢。STP从初始化状态到完全收敛至少需要经历30s(两个转发延迟时间)。
- 当交换机的某个接口连接终端用户时,也需要等待至少30秒才能进入转发状态。这其实是没必要的,因为连接终端的接口肯定不会有环。
- STP的拓扑变更机制复杂,效率低效。STP的拓扑变更机制是:先由变更点朝根桥方向发送TCN消息,收到该消息的上游交换机就会回复TCA消息进行确认,最后TCN消息到达根桥后,再由根桥发送TC消息通知设备删除桥MAC地址表项,机制复杂,效率低下。
- 端口角色过少。当前STP的端口角色有指定端口、根端口。当根端口或指定端口故障后,需要从交换机其他端口中重新选举并且需要等待计时器超时后才能进入转发状态。
- 端口状态过于复杂。从用户使用的角度看,STP的Disable、Blocking、Listening的端口状态对应的行为都相同,但是呈现出不同的状态,反而增加了使用难度。
STP端口状态 | 端口状态对应的行为 |
---|---|
Disabled | 不转发用户流量也不学习MAC地址 |
Blocking | 不转发用户流量也不学习MAC地址 |
Listening | 不转发用户流量也不学习MAC地址 |
Learning | 不转发用户流量但学习MAC地址 |
Forwarding | 既转发用户流量也学习MAC地址 |
正因为上述的缺点,所以在实际网络中,STP协议一般用的很少。实际上,很多企业的交换机运行的是MSTP。
参考文献:《HCNP路由交换学习指南》