Spanning Tree Protocol (STP) 生成树协定

前言

Spanning Tree Protocol (STP) 是一款 Layer 2 的 Protocol,一般在 Switch 上执行,主要目的是防止 Switch 在接驳时产生 Switching Loop。STP 是在学习网络知识中一个重要的课题,必需深入了解其运作原理和操作流程。

Broadcast Storm

为什麽需要 STP 呢?请看看以下例子:

stp

假设 C1 要传送资料给 C2,但 C1 的 ARP Table 里没有 C2 的 MAC Address,因此 C1 送出一个 Broadcast ARP Request 想找 C2 的 MAC Address。这个 Broadcast 送到 SW1,由於 SW1 在 Fa0/3 收到 Broadcast,所以它会把 Broadcast 经由 Fa0/1 和 Fa0/2 送出去。同样地,SW2 在 Fa0/1 收到後会在 Fa0/2 送出去,而 SW3 在 Fa0/2 收到後,就在 Fa0/1 和 Fa0/3 送出去,於是 SW2 和 SW1 又收到来自 SW3 的 Broadcast,然後它们也照样在另一个出口送出,於是 Broadcast 不会停止地重覆输送,这就称为 Broadcast Storm,会造成 Switching Loop 的问题。

解决 Broadcast Storm 的方法是把网络中其中一条连线断开,阻止 Broadcast 在网络上游花园。问题是究竟断开那一条连线好呢?各个 Switch 应该要有一致的共识,所以就有了 STP 这个机制,让所有 Switch 沟通一下那些 port 要传送资料,那些 port 应该休息不要传送资料。

PVST+

PVST+ (Per VLAN Spanning Tree Plus) 是 Cisco Switch 预设的 STP 设定,透过 PVST+,Switch 可以建立一个 Loop-free (没有 Loop) 的 topology。各 Switch 会按程序完成以下步骤:

  1. 在整个网络里选举一只 Root Switch
  2. 除了 Root Switch 外的其他各 Switch 都选择一个 Root Port
  3. 所有网段选择一个 Designated Port
  4. 把没成为 Root Port 或 Designated Port 的 Port 成为 Non-Desiganted Port,这些 Port 会被 Blocking 去防止 Loop

Step 1: 选举 Root Switch

stp

PVST+ 会选 Switch Priority (或称 Bridge Priority) 最小的 Switch 来成为 Root Switch,所以第一步要学习的是如何找出和计算 Switch 的 Priority。PVST+ 计算 Switch Priority 的公式是 Priority 值 + VLAN Number,Priority 值是可以设定的,预设值是 32768。每一个 VLAN 里面的 Priority 可以各不相同,这就是所谓 Per VLAN STP 的精神,每一个 VLAN 都拥有属於自己的 STP Topology。请看以下例子。

在 SW1 输入 show spanning-tree 指令,请暂时跳过 Root ID 部份,先看 Bridge ID。Bridge ID 是本机的 Bridge 资料,可见本机的 Switch Priority 是 32769 (预设值 32768 + VLAN 1)。

SW1#show spanning-tree
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    32769
              Address     0012.43bb.4340
              Cost        19
              Port        1 (FastEthernet0/1)
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    32769  (priority 32768 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
 
 <--Output Omitted-->

如果这只 Switch 有 VLAN20 又会怎样呢?建立 VLAN20 来试试看,VLAN20 的 Switch Priority = 32768 + 20 = 32788。所以,同一只 Switch 里面,不同 VLAN 的 Priority 是不相同的。

SW1(config)#vlan 20
 SW1(config-vlan)#end
 SW1#show spanning-tree
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    32769
              Address     0012.43bb.4340
              Cost        19
              Port        1 (FastEthernet0/1)
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    32769  (priority 32768 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
 
 <--Output Omitted-->
 
 
 VLAN0020
   Spanning tree enabled protocol ieee
   Root ID    Priority    32788
              Address     0014.f21e.4980
              This bridge is the root
              Hello Time   2 sec  Max Age 20 sec  Forward Delay
 
 Bridge ID    Priority    32788  (priority 32768 sys-id-ext 20)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300

<--Output Omitted-->

知道怎样找 Switch Priority 了,如果想改 Priority 要怎样做?一个简单指令便 OK!用 spanning-tree vlan <vlan no> priority <priority>,留意 priority 必需是 4096 的倍数,现在试把 VLAN1 的 priority 改为 36864,把 VLAN 20 的 Priority 改为 8192。

SW1(config)#spanning-tree vlan 1 priority ?
   <0-61440>  bridge priority in increments of 4096
 
 SW1(config)#spanning-tree vlan 1 priority 36864
 SW1(config)#spanning-tree vlan 20 priority 8192
 SW1(config)#end
 SW1#show spanning-tree
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    32769
              Address     0012.43bb.4340
              Cost        19
              Port        1 (FastEthernet0/1)
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    36865  (priority 36864 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
 
 <--Output Omitted-->
 
 
 VLAN0020
   Spanning tree enabled protocol ieee
   Root ID    Priority    8212
              Address     0014.f21e.4980
              This bridge is the root
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    8212   (priority 8192 sys-id-ext 20)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
 
 <--Output Omitted-->

看懂了 Switch Priority,现在正式开始谈谈 Root Switch 选举,原来 Switch Priority 最小的 Switch 会成为 Root Switch,如果 Priority 相同就选 MAC Address 最小的。现在到这 3 只 Switch 中看看 VLAN1 的 Priority 的情况。SW2 和 SW 3 的 Priority 都比较小,而 SW2 的 MAC Address 比 SW3 小,所以 SW2 成为 Root Switch。而且,在 SW2 见到一句很有霸气的讯息:This bridge is the root,明确表示 SW2 就是 Root Switch!

SW1#show spanning-tree vlan 1
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    32769
              Address     0012.43bb.4340
              Cost        19
              Port        1 (FastEthernet0/1)
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    36865  (priority 36864 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
 
 <--Output Omitted-->
SW2#show spanning-tree vlan 1
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    32769
              Address     0012.43bb.4340
              This bridge is the root
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    32769  (priority 32768 sys-id-ext 1)
              Address     0012.43bb.4340
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
 
 <--Output Omitted-->
SW3#show spanning-tree vlan 1
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    32769
              Address     0012.43bb.4340
              Cost        19
              Port        2 (FastEthernet0/2)
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    32769  (priority 32768 sys-id-ext 1)
              Address     0014.6999.0100
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300

<--Output Omitted-->

如果我们想 SW1 成为 Root Switch 呢?有两个方法,第一个方法是用 spanning-tree vlan <vlan no> priority <priority> 指令把 SW1 的 Priority 更改成更小的值。第二个方法是用 spanning-tree vlan 1 root primary 直接把 SW1 设定成 Root,其实这个指令也只是帮你把 Priority 调细而已。

SW1(config)#spanning-tree vlan 1 root primary
 SW1(config)#end
 SW1#show spanning-tree vlan 1
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    24577
              Address     0014.f21e.4980
              This bridge is the root
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    24577  (priority 24576 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 15
 
 <--Output Omitted-->

stp

所以,现在我们在 VLAN1 选择了 SW1 为 Root Switch。

Step 2: 选择 Root Port

然後,除了 Root Switch 外,每只 Switch 都会选择一个 Root Port,Root Port 是最「接近」Root Switch 的 Port,怎样计算最接近呢?Switch 会按 Interface 的 Bandwidth 来计算 Cost,不应该说计算,其实是死背的,请看下表:

Bandwidth (Mbps) 4 10 16 45 100 155 1000 10000
Cost 250 100 62 39 19 14 4 2

SW1

由於 SW1 自己本身是 Root Switch,因此不用选择 Root Port。

SW2

SW2 用 Fa0/1 要经过 1 条 100Mb Link (Cost: 19),而用 Fa0/2 要经过 2 条 100Mb Link (Cost = 19+19=38),因此 SW2 选用 Fa0/1 为 Root Port。

SW3

同样道理,SW3 用 Fa0/1 要经过 1 条 100Mb Link (Cost: 19),而用 Fa0/2 要经过 2 条 100Mb Link (Cost = 19+19=38),因此 SW3 选用 Fa0/1 为 Root Port。用 show spanning-tree 可以看到那个 Port 被定性为 Root Port。

SW2#show spanning-tree | begin Interface
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/1            Root FWD 19        128.1    P2p
 Fa0/2            Desg FWD 19        128.2    P2p
SW3#show spanning-tree  | begin Interface
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/1            Root FWD 19        128.1    P2p
 Fa0/2            Altn BLK 19        128.2    P2p

如果想强迫 SW2 的 Fa0/2 成为 Root Port 可以吗?我们可以用 Interface 指令 spanning-tree vlan <vlan no> cost <cost> 来增加 Fa0/1 的 Cost:

SW2(config)#int fastEthernet 0/1
 SW2(config-if)#spanning-tree vlan 1 cost 40
 SW2(config-if)#end
 SW2#show spanning-tree | begin Interface
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/1            Altn BLK 40        128.1    P2p
 Fa0/2            Root FWD 19        128.2    P2p

现在我们把更改 Cost 的指令移除,於是 Root Port 位置就如下图。

stp

Step 3: 选择 Designated Port 与 Non-Designated Port

每一段网段只容许一个 Port 成为 Designated Port,网段里面最接近 Root Switch (Cost 最少) 的 Port 成为 Designated Port。如果网段里只有两个 Port,在别无选择下,与 Root Port 相对的 Port 必然成为 Designated Port,因此 SW1 的 Fa0/1 与 Fa0/2 成为 Designated Port。问题在於 SW2 与 SW3 的连线,那一个 Port 成为 Designated Port 呢?在 Designated Port 的选择与选择 Root Switch 相似,同样用 Switch Priority 较小者成为 Designated Port,如果 Switch Priority 相同,则 MAC Address 较小者胜出。SW2 的 Priority 为 32769,SW3 的 Priority 也是 32769,不过 SW2 的 MAC Address 较小,因此 SW2 的 Fa0/2 成为 Designated Port,会传送讯息 (Forwarding) 而 SW3 的 Fa0/2 则会成为 Non-Designated Port,不传送也不接收讯息 (Blocking),这样就导绝了 Loop。Non-Designated Port 会被颢示为 Altn (Alternate Port) 或 Back (Backup Port),在传统的 STP 中并没分别,总之 State 都是 Blocking 就是了。

SW2#show spanning-tree
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    24577
              Address     0014.f21e.4980
              Cost        19
              Port        1 (FastEthernet0/1)
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    32769  (priority 32768 sys-id-ext 1)
              Address     0012.43bb.4340
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
 
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/1            Root FWD 19        128.1    P2p
 Fa0/2            Desg FWD 19        128.2    P2p
SW3#show spanning-tree
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    24577
              Address     0014.f21e.4980
              Cost        19
              Port        1 (FastEthernet0/1)
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    32769  (priority 32768 sys-id-ext 1)
              Address     0014.6999.0100
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
 
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/1            Root FWD 19        128.1    P2p
 Fa0/2            Altn BLK 19        128.2    P2p

stp

STP 的选举准则

透过上面的例子,我们知道要完成整个 STP 流程,中间经过几个选举,分别是选 Root Switch丶选 Root Port 和选 Designated Port。这几个选举的决择其实都源自是同一套准则如下:

准则 1:比 Bridge ID,小的胜出 (只有选 Root Switch 时使用)

所谓 Bridge ID 就是一串 16 Bits 的 Priority 和 48 Bits MAC Address 组成的值,由於 Priority 在前,MAC Address 在後,基本上 Priority 已可定胜负,除非 Priority 相同,则要看 MAC Address。在一只 Switch 之中,Priority 可人工调校,而 MAC Address 则不可改变。

准则 2:比 Root Cost ,小的胜出

在选择 Root Port 和 Designated Port 时,就要比 Root Cost。Root Cost 就是要到达 Root Switch 所需要的 Cost 总和,可以人工调校。

准则 3:比对方的 Bridge ID,小的胜出

如 Root Cost 相同的话,就要比对方的 Bridge ID。

准则 4:比对方的 Port ID,小的胜出

最後,会用 Port ID 来比较。Port ID 是一串 4 Bits 的 Priority 和 12 Bits Interface Number 所组成的值。由於 Priority 在前,一般用 Priority 已可定胜负,如果 Priority 相同,则要看 Interface Number,由於一只 Switch 上的 Interface Number 必然不同,所以准则 4 必可分出胜负。

现在我们用一个简单的网络,重新审视一下这 4 个准则。

stp

Step 1: 选举 Root Switch

准则 1:比 Bridge ID,小的胜出
准则 2:比 Root Cost,小的胜出
准则 3:比对方的 Bridge ID,小的胜出
准则 4:比对方的 Port ID,小的胜出

先看看两只 Switch 的 Priority 与 MAC Address:

SW1#show spanning-tree
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    32769
              Address     0012.43bb.4340
              Cost        19
              Port        1 (FastEthernet0/1)
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    32769  (priority 32768 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 15
SW2#show spanning-tree
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    32769
              Address     0012.43bb.4340
              This bridge is the root
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    32769  (priority 32768 sys-id-ext 1)
              Address     0012.43bb.4340
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 15

由於 Bridge ID 的 Priority 部份相同,因此比较 MAC Address,SW2 MAC Address 较小,因而胜出成为 Root Bridge。因为 MAC Address 不会相同,必能分胜负,因此 Root Switch 的选择透过准则 1 必可成功选出,不必到准则 2-4。

stp

Step 2: 选择 Root Port

准则 1:比 Bridge ID,小的胜出 (不用准则 1)
准则 2:比 Root Cost,小的胜出
准则 3:比对方的 Bridge ID,小的胜出
准则 4:比对方的 Port ID,小的胜出

准则 1:比 Bridge ID,小的胜出
准则 2:比 Root Cost,小的胜出
准则 3:比对方的 Bridge ID,小的胜出
准则 4:比对方的 Port ID,小的胜出

在预设的情况之下,SW1 的 Fa0/1 与 Fa0/2 Bandwidth 相同,因此 Cost 相同,无法用准则 2 分胜负。(当然,我们可以选择更改 Interface 的 Bandwdith,或使用 spanning-tree vlan <vlan no> cost <cost> 来调整 cost。)

准则 1:比 Bridge ID,小的胜出
准则 2:比 Root Cost,小的胜出
准则 3:比对方的 Bridge ID,小的胜出
准则 4:比对方的 Port ID,小的胜出

由於 SW1 的 Fa0/1 与 Fa0/2 都接上同一只 Switch,因此「对方的 Bridge ID」必然相同,所以准则 3 仍无法分胜负。

准则 1:比 Bridge ID,小的胜出
准则 2:比 Root Cost,小的胜出
准则 3:比对方的 Bridge ID,小的胜出
准则 4:比对方的 Port ID,小的胜出

从 SW2 可以查看 Fa0/5 和 Fa0/6 的 Port ID 分别是 128.5 和 128.6,由於 128.5 比较小,与其连接着的 SW1 的 Fa0/1 便成为 Root Port 了。由於 Interface Number 不能更改,因此准则 4 必能分胜负。

SW2#show spanning-tree | begin Interface
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/5            Desg FWD 19        128.5    P2p
 Fa0/6            Desg FWD 19        128.6    P2p
SW1#show spanning-tree | begin Interface
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/1            Root FWD 19        128.1    P2p
 Fa0/2            Altn BLK 19        128.2    P2p

如果想改变 Port Priority,可用 spanning-tree port-priority <priority>,例如试试把 SW2 的 Fa0/6 的 Port Priority 改为 64。

SW2(config)#interface fastEthernet 0/6
 SW2(config-if)#spanning-tree port-priority 64
SW2#show spanning-tree | begin Interface
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/5            Desg FWD 19        128.5    P2p
 Fa0/6            Desg FWD 19         64.6    P2p

於是 SW1 的 Fa0/2 成为 Root Port,因为准则 4,对方的 Port ID 比较小。

SW1#show spanning-tree | begin Interface
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/1            Altn BLK 19        128.1    P2p
 Fa0/2            Root FWD 19        128.2    P2p

stp

Step 3: 选择 Designated Port 与 Blocked Port

与 Root Port 相对的 Port 必然成为 Designated Port,因此 SW2 的 Fa0/6 顺理成章变成 Designated Port。问题在於 SW1 的 Fa0/1 与 SW2 的 Fa0/5 谁胜谁负?

准则 1:比 Bridge ID,小的胜出 (不用准则 1)
准则 2:比 Root Cost,小的胜出
准则 3:比对方的 Bridge ID,小的胜出
准则 4:比对方的 Port ID,小的胜出

准则 1:比 Bridge ID,小的胜出
准则 2:比 Root Cost,小的胜出
准则 3:比对方的 Bridge ID,小的胜出
准则 4:比对方的 Port ID,小的胜出

SW2 的 Root Cost 当然 比 SW1 小,所以 SW2 的 Fa0/5 胜出成为 Designated Port,而 SW1 的 Fa0/1 会成为 Non-Designated Port (Blocking)。(也有教学说 Root Switch 的 Port 必然是 Designated Port,记忆方法不同,道理相同。)

stp

BPDU

Bridge Protocol Data Unit (BPDU) 是 Switch 间用来传送 STP 资讯的 Frame,BPDU 里的资讯包括:Bridge ID丶Cost 和 Port ID 等。一个网络中应该只有 Root Switch 发放 BPDU,不过当任何一只 Switch 刚启动时,它都会认为自己是 Root Switch 而发放 BPDU,直至它收到一个包含 Bridge ID 较小的 BPDU (称为 Superior BPDU) 时,它才知道自己在 Root Switch 选举中落败了而停止发放 BPDU。

BPDU 预设每 2 秒发放一次,称为 BPDU Hello Time,而 Switch 接收到的 BPDU 只会被储存 20 秒 (Max-age),即是说如果 Switch 过了 20 秒也没有收到 BPDU,也没有在其他 Port 收到 BPDU 的话,就会判断 Root Switch 已经死了,它又会再次认定自己是 Root Switch,再次发放 BPDU 了。STP 还有另一个 Timer 称为 Forward Delay,是用作调校 Listening 和 Learning 状态的时间,关於 Listening 和 Learning 状态会在下一节说明。

如果想知道 Timer 的设定值,可以用 show spanning-tree vlan <vlan no> 指令。

SW1#show spanning-tree vlan 1
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    24577
              Address     0014.f21e.4980
              This bridge is the root
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    24577  (priority 24576 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
 
<--Output Omitted-->

更改这些 Timer 的指令如下:

SW1(config)#spanning-tree vlan 1 hello-time 4
 SW1(config)#spanning-tree vlan 1 max-age 26
 SW1(config)#spanning-tree vlan 1 forward-time 20
SW1#show spanning-tree vlan 1
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    24577
              Address     0014.f21e.4980
              This bridge is the root
              Hello Time   4 sec  Max Age 26 sec  Forward Delay 20 sec
 
   Bridge ID  Priority    24577  (priority 24576 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   4 sec  Max Age 26 sec  Forward Delay 20 sec
              Aging Time 300
 
<--Output Omitted-->

我们也可以叫 Switch 自动调整这 3 个 Timer,只要告诉 Root Switch 网络的 Diameter 是多少,所谓 Diameter 就是网络由一端去到另一端最远跳过多少只 Switch?即由一边去到另一边有多远?Switch 会按这个距离去设定 Timer:

SW1(config)#spanning-tree vlan 1 root primary diameter ?
   <2-7>  Maximum number of bridges between any two end nodes
 
 SW1(config)#spanning-tree vlan 1 root primary diameter 5
 SW1(config)#end
 SW1#show spanning-tree vlan 1
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    24577
              Address     0014.f21e.4980
              This bridge is the root
              Hello Time   2 sec  Max Age 16 sec  Forward Delay 12 sec
 
   Bridge ID  Priority    24577  (priority 24576 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 16 sec  Forward Delay 12 sec
              Aging Time 300

<--Output Omitted-->

由於更改 STP 的 Timer 有一定风险,如果设定值不理想会导致整个网络瘫痪,因此不建议更改,就算要更改都请尽量使用 Diameter 指令,这样可以使用 Cisco 的建议值,Diameter 与 Timer 的对照表如下:

Diameter 2 3 4 5 6 7
Hello Time 2 2 2 2 2 2
Max Age 10 12 14  16 18 20
Forward Delay 7 9 10 12 13 15

Port State

在 STP 中,一个 Port 由 Down 变成 Up,中间经历了几个状态,了解这些状态是学习 STP 重要的一环。

Disabled

Port 被 Shutdown 了,在这状态下该 Port 不会传送或接收任何 Frame。

Blocking

不会传送或接收 Data Frame,但仍会接收 BPDU,目的是 Blocking Port 有需要知道现时 Spanning Tree 的状态,当有需要时可以跳到 Listening。为了防止 Loop 发生,一只 Switch 启动时,所有 Port 都会先进入 Blocking。

Listening

当 Switch 知道某个 Port 需要启动时,就会把 Port 由 Blocking 转到 Listening,在这个状态下,Port 会传送及接收 BPDU,但仍不会传送 Data Frame,它会参与 Root Switch 选举丶Root Port 选举和 Designated Port 选举。这个状态会维持一个 Forward Delay 的时间 (预设 15 秒)。

Learning

如果一个 Port 在选举时成功成为 Root Port 或 Designated Port,它便会进入 Learning,Port 会收发 BPDU,而且会开始留意传过来的 Data Frame,把 MAC Address 记录到 MAC Address Table,但仍然不会传送 Data Frame,这样做的目的是希望这个 port 在开始工作之前,先尽量记录 MAC Address,免得稍後时间需要把 Frame Flood 到所有 Port 而制造不必要的 Traffic。这个状态会维持一个 Forward Delay 的时间 (预设 15 秒)。

Forwarding

最後,Port 会变成 Forwarding,会收发 BPDU,记录 MAC Address,也会传送 Data Frame。

状态 Disabled Blocking Listening Learning Forwarding
接收 BPDU NO YES YES YES YES
发送 BPDU NO NO YES  YES YES
Learn MAC Address NO NO NO YES YES
Forward Data Frame NO NO NO NO YES
维持时间 直至 no shutdown 直至 Topology 有转变 Forward Delay (预设 15 秒) Forward Delay (预设 15 秒) 直至 Shutdown 或不再成为 Root Port / Designated Port

如想观察 Port 状态的变化,可以使用 debug spanning-tree events

SW1#debug spanning-tree events
 Spanning Tree event debugging is on
 SW1#config terminal
 Enter configuration commands, one per line.  End with CNTL/Z.
 SW1(config)#int fastEthernet 0/1
 SW1(config-if)#shutdown
 SW1(config-if)#
 01:19:22: %LINK-5-CHANGED: Interface FastEthernet0/1, changed state to administr atively down
 01:19:22: STP: VLAN0001 Topology Change rcvd on Fa0/2
 01:19:23: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/1, chang ed state to down
 SW1(config-if)#no shutdown
 SW1(config-if)#
 01:19:29: %LINK-3-UPDOWN: Interface FastEthernet0/1, changed state to up
 01:19:32: set portid: VLAN0001 Fa0/1: new port id 8001
 01:19:32: STP: VLAN0001 Fa0/1 -> listening
 01:19:33: %LINEPROTO-5-UPDOWN: Line protocol on Interface FastEthernet0/1, chang ed state to up
 01:19:47: STP: VLAN0001 Fa0/1 -> learning
 01:20:02: STP: VLAN0001 Fa0/1 -> forwarding

Topology Change

当 STP 选好了 Root Switch丶Root Port 和 Designated Port 之後,就会进入收敛 (Convergence) 的状态,在此时,只要网络 Topology 没有改变,STP 就会很稳定地维持原状。不过世事无常,我们不时会在网络添置新的 Switch,又或者开关某些 Switch 都会令到网络 Topology 改变,当 Switch 发现网络 Topology 改变,就会向 Root Switch 发一个 Topology Change Notification (TCN) BPDUs,究竟怎样才算一个 Topology Change 呢?就是以下两个情况其中之一:

  1. 当一个 Port 转到 Forwarding 状态
  2. 当一个 Listening 或 Forwarding 的 Port 转到 Blocking 或 Disabled

当 root switch 收到 TCN 之後,会通知 STP 里面所有其他 Switch 有 Topology Change,其他 Switch 收到通知後就会把 MAC Address Table 的 timeout 时间由 300 秒改为 15 秒 (Forward Delay),这样做是因为基於 Topology 有改变,MAC Address Table 的纪录已经不可靠,因而缩短其保存时间,保证 MAC Address Table 尽快被更新,这状态会维持 35 秒 (Forward Delay + Max Age)。

PortFast

不过,这个 Topology Change 机制带来了一个问题,试想想如果在 Switch 插入一部 PC,PC 是不会改变 STP 的 Topology,可是插入 PC 时令 Port 转到 Forwarding 状态,又或者重新启动 PC 时,都会令 STP 以为有 Topology Change,而让整个 Network Switch 缩减 ARP Table Timeout 时间,这是多馀的。另一方面,插入 PC 的这个 Port 亦要经历 Blocking → Listening → Learning → Forwarding 的过程而等待 30 秒才能上线。为了解决这两个问题,Cisco 的 Switch 可以开启 PortFast,开启 PortFast 可以让 Port 在插入後跳过 Listening 和 Learning 而立刻转成 Forwarding。如果一个设成 PortFast 的 Port 收到 BPDU 的话 (即插入了 Switch) 就会依正常情序进入 Listening 和 Learning。

要启动 PortFast 有两个方法,可以在 Interface 用 spanning-tree portfast 指令:

SW1(config)#interface fastEthernet 0/1
 SW1(config-if)#spanning-tree portfast

又或者在 Global 用 spanning-tree portfast default 指令把所有 port 预设成 PortFast。

SW1(config)#spanning-tree portfast default

UplinkFast

接下来,我们讨论以下这个网络:

stp

图中 SW2 是 Root Switch,SW1 的 Fa0/2 是 Forwarding 而 Fa0/1 处於 Blocking 状态,当 Fa0/2 的 Link 因为某些原因而死掉,我们称之为 Directly Fail,SW1 会立刻进行 STP 计算,不过 Fa0/1 由 Blocking 转到 Forwarding 的状态需要 30 秒时间,而 30 秒等待时间对於一个网络来说可谓完全不能接受!而 Cisco 对此的解决方案为 UplinkFast。启动了 UplinkFast 的 Switch 会选 1 个 Blocking Port 设为 Standby 状态,当 Root Port 死掉时,Standby 的 Port 立刻转成 Forwarding,省掉 30 秒等候时间。

开启 UplinkFast 的指令为 spanning-tree uplinkfast。请注意,此指令不应在 Root Switch 执行。

SW1(config)#spanning-tree uplinkfast

输入此指令後,会发现 Switch priority 会被改成 49152,而所有 Port 的 Cost 都会被加 3000。

输入前:

SW1#show spanning-tree
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    32769
              Address     0012.43bb.4340
              Cost        19
              Port        1 (FastEthernet0/1)
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    32769  (priority 32768 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
 
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/1            Root FWD 19        128.1    P2p
 Fa0/2            Altn BLK 19        128.2    P2p

输入後:

SW1#show spanning-tree
 
 VLAN0001
   Spanning tree enabled protocol ieee
   Root ID    Priority    32769
              Address     0012.43bb.4340
              Cost        3019
              Port        1 (FastEthernet0/1)
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
 
   Bridge ID  Priority    49153  (priority 49152 sys-id-ext 1)
              Address     0014.f21e.4980
              Hello Time   2 sec  Max Age 20 sec  Forward Delay 15 sec
              Aging Time 300
   Uplinkfast enabled
 
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/1            Root FWD 3019      128.1    P2p
 Fa0/2            Altn BLK 3019      128.2    P2p

BackboneFast

Directly Fail 可用 UplinkFast 解决,现在讨论一下 Indirectly Fail 会出现什麽状况。

stp

上图中 SW1 是 Root Switch,SW2 的 Fa0/1 及 SW3 的 Fa0/1 是 Root Port,当 SW1 与 SW2 之间的连线中断,虽然 SW2 会察觉得到,但 SW3 是懵然不知的,它仍然等待接收由 SW1 传出经 SW2 传来的 BPDU,直至 20 秒 (Max Age) 过去了都收不到 BPDU 的话,SW3 才会把 BPDU 弃掉,然後选择把 Fa0/2 转成 Root Port,不过由 Blocking 至 Forwarding 又用了 30 秒,所以 SW1 要等待总共 50 秒 (20 + 30) 才能再次与 SW3 连上。如果任由这情况发生,网管人员的电话早已响过不停!Cisco 对此问题的解决方案就是 BackboneFast。

BackboneFast 想解决的问题在於那等待的 20 秒,如果 Switch 开启了 BackboneFast,当发现收不到 BPDU 时就会主动在 Root Port 发送一个 Root Link Query (RLQ),如果 Root Switch 收到的话就会回覆一个 RLQ reply,当发送 RLQ 的 Switch 收到 reply,即是说从 Root Port 仍然能够联络上 Root Switch 喔,刚才收不到 BPDU 可能只是少许的不稳定,它会继续相信这条 Path 能够去到 Root Switch。但是,如果发了 RLQ 又收不到 Reply 的话,证明这个 Root Port 真的去不到 Root Switch 了,它就会立刻进行 STP 运算来找另一条能去 Root Port 的 Path,这就省掉呆呆的等待 20 秒时间。如果配合 UplinkFast 使用的话,甚至可以无间断地跳转 Root Port。

要使用 BackboneFast,必需在所有 Switch 使用 spanning-tree backbonefast 指令。

SW1(config)#spanning-tree backbonefast

保护 STP Topology

当 STP Topology 设计好之後,应该加以保护,尤其 Root Switch 的角色不可被新加的 Switch 抢去,因为 STP Topology 的改变会导致 Port Up/Down,产生断线问题,而且会令 Frame 不是走最佳路径而出现 delay,所以加入新的 Switch 时要小心行事,留意 Switch Priority 的设定。不过,网络接头分布在各处,User 可能会插入一些未经授权的 Switch,网管人员又怎能看守着每一个 Port 呢?Cisco Switch 提供了几个方案让网管人员保护 STP。

Root Guard

Root Guard 可以保护 STP 免受 Switch Priority 小的 Switch 抢了 Root Switch 的位置。开启方法如下:

SW1(config)#int fastEthernet 0/8
 SW1(config-if)#spanning-tree guard root

当有一只 Switch Priority 比现时 Root Switch 小的 Switch 插入这个 Port,这个 Port 会处於 Root Inconsistent 的状态,它会被 Blocking 而不会传送或接收 Frame。

SW1#show spanning-tree inconsistentports
 
 Name                 Interface              Inconsistency
 -------------------- ---------------------- ------------------
 VLAN0001             FastEthernet0/8        Root Inconsistent
 
 Number of inconsistent ports (segments) in the system : 1
 
 SW1#show spanning-tree vlan 1 | begin Interface
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- --------------------------------
 Fa0/1            Desg FWD 19        128.1    P2p
 Fa0/8            Desg BKN*19        128.8    P2p *ROOT_Inc
 Gi0/1            Desg FWD 4         128.9    Edge P2p

BPDU Guard

如果嫌 Root Guard 也不够稳当,可以用 BPDU Guard。BPDU Guard 比 Root Guard 更严紧,只要收到 BPDU Message,无论它是否要成为 Root Switch,都立刻把此 Port 变成 Error Disable 关上。开启方法如下:

SW1(config)#int fastEthernet 0/7
 SW1(config-if)#spanning-tree bpduguard enable

当一只 Switch 插入,这个 Port 就被 Error Disable。

SW1#show interfaces fastEthernet 0/7
 FastEthernet0/7 is down, line protocol is down (err-disabled)
   Hardware is Fast Ethernet, address is 0014.f21e.4987 (bia 0014.f21e.4987)
   MTU 1500 bytes, BW 100000 Kbit, DLY 100 usec,
      reliability 255/255, txload 1/255, rxload 1/255

<--Output Omitted-->

解禁的方法是:先把 Switch 拔掉,然後把 Port shutdown 再 no shutdown。

SW1(config)#int fastEthernet 0/7
 SW1(config-if)#shutdown
 SW1(config-if)#no shutdown

BPDU Filtering

就算开启了 Root Guard 或者 BPDU Guard,Switch 仍然会在这个 Port 对外发送 BPDU Message,如果对方不是 Switch,发送 BPDU 是不必要的。BPDU Filtering 可以防止 Switch 对外发送 BPDU Message。BPDU Filtering 可以配合 PortFast 在 Global 启动,或者在 Interface 中启动。启动了 BPDU Filtering 後这个 Port 就不会再发送 BPDU Message。至於在这个 Port 收到 BPDU 的话则按情况作出不同处理:

如果是配合 PortFast 在 Global 启动的话,这个 Port 会依正常情序进行 STP,依次进入 Listening 丶 Learning 和 Forwarding 状态。配合 PortFast 启动方法如下:

SW1(config)#spanning-tree portfast bpdufilter default
 SW1(config)#interface GigabitEthernet0/6
 SW1(config-if)#spanning-tree portfast

如果是在 Interface 启动的话,这个 Port 会无视 BPDU Message。当这个 Port 变成 Forwarding 後就会有机会造成 Switch Loop,务必特别注意!

SW1(config)#int fastEthernet 0/6
 SW1(config-if)#spanning-tree bpdufilter enable

UDLD

一般网络线是有来有往的,即有传送 (transmit) 有接收 (receive),这叫做 bidirectional。但如果网络线有固障,发生单向传输 (unidirectional) 的问题,可能会导致 Port 接收不到 BPDU。试想想一个 Blocking Port 不断接收到 BPDU 而令自己维持在 Blocking 的状态,一旦发生 unidirectional 问题,令 Blocking Port 收不到 BPDU,过了 Max Age 20 秒之後,Blocking Port 就会尝试进入选举流程而最後变成 Forwarding,这就会造成 Switch Loop 问题。这程况最有可能发生在光纤线,Cisco 使用 Unidirectional Link Detection (UDLD) 来针对这个问题保护 STP。

当网络线的两端 Port 开启了 UDLD,Port 就会不断向对方发出检测,如果对方有回应,代表运作正常,但如果收不到对方回应,UDLD 就会因应两个不同的模式作出处理。

Normal Mode

在 Normal Mode 中,Port 不会被 Disable,但标记成 Undetermined State。
在 Global 把所有 Port 启动 UDLD Normal Mode:

SW1(config)#udld enable

或者在 Interface 为某个 Port 启动 UDLD Normal Mode:

SW1(config-if)#udld port

show udld 指令查看,udld 预设每 7 秒传送检测讯息,如果 5 秒内收不到回覆则判为 unidirectional:

SW1#show udld
 
 Interface Fa0/1
 ---
 Port enable administrative configuration setting: Enabled
 Port enable operational state: Enabled
 Current bidirectional state: Unknown
 Current operational state: Advertisement
 Message interval: 7
 Time out interval: 5
 No neighbor cache information stored
 
<--Output Omitted-->

Aggressive Mode

在 Aggressive Mode 中,Port 被变成 Error Disable。
在 Global 把所有 Port 启动成 UDLD Aggressive Mode:

SW1(config)#udld aggressive

或者在 Interface 为某个 Port 设定成 UDLD Aggressive Mode:

SW1(config-if)#udld port aggressive

用 show udld 指令查看可见 UDLD 正使用 Aggressive Mode:

SW1#show udld
 
 Interface Fa0/1
 ---
 Port enable administrative configuration setting: Enabled / in aggressive mode
 Port enable operational state: Enabled / in aggressive mode
 Current bidirectional state: Unknown
 Current operational state: Advertisement
 Message interval: 7
 Time out interval: 5
 No neighbor cache information stored

<--Output Omitted-->

Loop Guard

不过 UDLD 只能防止网络线出问题而导致的 Switching Loop,但收不到 BPDU 亦可能由其他问题引致,例如:Switch 硬件问题或 Switch 的 CPU Full Load 而处理不到 BPDU,另一个较保险的方法是使用 Loop Guard。如果 Port 开启了 Loop Guard,当它收不到 BPDU 超过 Max Age 的话就会被转成 Loop Inconsistent 状态,不能 Forward Traffic,避免发生 Switching Loop。

我们可以在 Global 把所有 Port 预设开启 Loop Guard:

SW1(config)#spanning-tree loopguard default

或者在 Interface 把某个 Port 开启 Loop Guard:

SW1(config-if)#spanning-tree guard loop

以下做一个简单实验,来验证 Loop Guard 的运作:

stp

上图中 SW2 为 Root Switch,在 SW1 把处於 Blocking 状态的 Fa0/1 开启 Loop Guard。

SW1(config)#int fastEthernet 0/1
 SW1(config-if)#spanning-tree guard loop

然後到 SW2 在 Fa0/5 开启 BPDU Filter,这样它就会停止发送 BPDU。

SW2(config)#int fastEthernet 0/5
 SW2(config-if)#spanning-tree bpdufilter enable

SW1 的 Fa0/1 因为过了 20 秒 (Max Age) 都收不到 BPDU,所以变成 Loop Inconsistent 状态。

SW1#show spanning-tree | begin Interface
 Interface        Role Sts Cost      Prio.Nbr Type
 ---------------- ---- --- --------- -------- ------------------------------
 Fa0/1            Desg BKN*20        128.1    P2p *LOOP_Inc
 Fa0/2            Root FWD 19        128.2    P2p

Coming Soon……

Per VLAN Load Balance
RSTP
MST

相關主題

发表回复

2021-07-22

Posted In: Layer 2 网络技术, menu-tall-3-zh-hans

Leave a Comment