Understanding Spanning-Tree Loopguard

Introduction

 

The spanning-tree loopguard feature is used to stop bridging loops caused by unidirectional links.  If you are not aware, a unidirectional link is a link that is only functioning in one direction.  Think about a fiber link between two switches.  One wire transmits and the other receives.  If there is bad hardware, or something physically happens to one of the wires in the pair, one switch could send frames but not be able to receive them or visa versa.  Situations like that are very dangerous in a layer two looped environment and can cause bridging loops.  Loopguard aims to solve that problem

Note, loopguard does not prevent unidirectional links or do anything about the unidirectional link itself.  Loopguard just tweaks spanning-tree to adjust to a situation where a unidirectional link is present.  Another feature known as UDLD (unidirectional link detection) can actually detect the unidirectional link at layer 1 and take action by errdisabling the link.  However, if UDLD is not enabled and a unidirectional link is present in a looped layer 2 network, loopguard can help mitigate a bridging loop by jumping into action.

 

Unidirectional Link – No Loopguard

 

Before we can understand what loopguard does, we need to understand STP as it is out of the box.  Let’s check out our diagram for today

 


 

 

In this case, Cat1 is the root bridge of our spanning-tree.  Through the normal STP convergence process, Cat2 ends up with Fa0/19 in the blocking state because it is not a root or designated port.  If you know your STP you will remember that on any given segment, the switch with the designated port on that segment will send BPDUs on to the segment and the switch that does not have the designated port on the segment hears those BPDUs.  That means in our scenario, Cat3 will be sending BPDUs to Cat2.  More technically, since we are running PVSTP+ here, Cat3 actually relays BPDUs sent down from the root bridge.

Now, imagine we have a unidirectional link between Cat2 and Cat3 such that Cat2 is not receiving data but it is sending data.  Cat2 still believes the link to be up/up but it is not able to receive BPDUs.  Normally what will happen is this:  After Cat2 notices it has not received any BPDUs on Fa0/19 for max_age (20 seconds by default) it will transition to the listening, learning and finally forwarding states.  It does this because from Cat2’s perspective there is no longer a loop to prevent against since it is not receiving BPDU’s from the designated port on the segment.  When Cat2 goes into forwarding, it actually creates a bridging loop because at that point both Cat2 and Cat3 Fa0/19 are forwarding which means every port in our looped topology is forwarding.  Never a good thing!!!  A situation like that could easily bring a network down, so Cisco came up with loopguard.

 

Unidirectional Link – Loopguard

 

So how does loopguard prevent this catastrophe?  Simply put, if a port enabled with loopguard stops hearing BPDUs from the designated port on the segment, instead of transitioning into forwarding, it goes into the loop inconsistent state.  Loop inconsistent is basically blocking, and no traffic gets forwarded.  Once the port detects BPDUs again, it automatically recovers by moving back into blocking.  In this example, if Cat2 Fa0/19 had loopguard on, once it stopped receiving BPDUs from Cat3, it would move Fa0/19 into loop inconsistent instead of moving to forwarding and causing a bridging loop.

 

Configuring Loopguard

 

Loopguard is pretty simple to configure.  You can do it globally with the spanning-tree loopguard default command, or per interface with the spanning-tree guard loop command. Let’s give it a try.  We will configure loopguard on Cat2 Fa0/19.  If you are configuring this in a real network, you generally want it enabled on any port that is non-designated in your topology.

interface FastEthernet0/19
 spanning-tree guard loop
!
Cat2#show spanning-tree int fa0/19 detail
 Port 19 (FastEthernet0/19) of VLAN0001 is alternate blocking
   Port path cost 19, Port priority 128, Port Identifier 128.19.
   Designated root has priority 24577, address 0018.1820.2700
   Designated bridge has priority 28673, address 000d.bc91.7900
   Designated port id is 128.19, designated path cost 19
   Timers: message age 2, forward delay 0, hold 0
   Number of transitions to forwarding state: 0
   Link type is point-to-point by default
   Loop guard is enabled on the port
   BPDU: sent 2, received 796

OK, so we have enabled loopguard. Now, how do we see if this works?  Fortunately, no hardware in my lab is broken…so a true unidirectional link is out of the question.  What if we just shut down the link between Cat1 and Cat3 instead?  Since Cat1 is the root bridge, Cat3 won’t be able to receive BPDUs and by that logic should not relay any down to Cat2.  Once Cat2 stops receiving BPDUs after max_age it should go into loop inconsistent instead of forwarding, right?  Let’s go with that for a second.  We will enable debug spanning-tree events on both Cat2 and Cat3 so we can see precisely what is happening when we shutdown Fa0/21 on Cat3

Cat3#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
Cat3(config)#int fa0/21
Cat3(config-if)#shutdown
Cat3(config-if)#
*Mar  1 01:04:48.059: STP: VLAN0001 we are the spanning tree root
*Mar  1 01:05:07.655: STP: VLAN0001 heard root 24577-0018.1820.2700 on Fa0/19
*Mar  1 01:05:07.655:     supersedes 28673-000d.bc91.7900
*Mar  1 01:05:07.655: STP: VLAN0001 new root is 24577, 0018.1820.2700 on port Fa0/19, cost 38
*Mar  1 01:05:07.655: STP: VLAN0001 sent Topology Change Notice on Fa0/19

Cat3#show spanning-tree int fa0/19

Vlan                Role Sts Cost      Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
VLAN0001            Root FWD 19        128.19   P2p
Cat2#debug spanning-tree events
Spanning Tree event debugging is on

*Mar  1 01:05:00.979: STP: VLAN0001 heard root 28673-000d.bc91.7900 on Fa0/19
*Mar  1 01:05:02.431: STP: VLAN0001 heard root 28673-000d.bc91.7900 on Fa0/19
*Mar  1 01:05:04.431: STP: VLAN0001 heard root 28673-000d.bc91.7900 on Fa0/19
*Mar  1 01:05:06.431: STP: VLAN0001 heard root 28673-000d.bc91.7900 on Fa0/19
*Mar  1 01:05:08.431: STP: VLAN0001 heard root 28673-000d.bc91.7900 on Fa0/19
*Mar  1 01:05:10.431: STP: VLAN0001 heard root 28673-000d.bc91.7900 on Fa0/19
*Mar  1 01:05:12.431: STP: VLAN0001 heard root 28673-000d.bc91.7900 on Fa0/19
*Mar  1 01:05:14.431: STP: VLAN0001 heard root 28673-000d.bc91.7900 on Fa0/19
*Mar  1 01:05:16.431: STP: VLAN0001 heard root 28673-000d.bc91.7900 on Fa0/19
*Mar  1 01:05:18.431: STP: VLAN0001 heard root 28673-000d.bc91.7900 on Fa0/19
*Mar  1 01:05:18.979: STP: VLAN0001 Fa0/19 -> listening
*Mar  1 01:05:20.031: STP: VLAN0001 Topology Change rcvd on Fa0/19
*Mar  1 01:05:20.031: STP: VLAN0001 sent Topology Change Notice on Fa0/23
*Mar  1 01:05:33.979: STP: VLAN0001 Fa0/19 -> learning
*Mar  1 01:05:48.979: STP: VLAN0001 sent Topology Change Notice on Fa0/23
*Mar  1 01:05:48.979: STP: VLAN0001 Fa0/19 -> forwarding

Cat2#show spanning-tree int fa0/19

Vlan                Role Sts Cost      Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
VLAN0001            Desg FWD 19        128.19   P2p

Loopguard did NOT kick in on Cat2 at all!!! You see, when the Cat1-Cat3 link went down, Cat3 lost it’s root port.  Because of that, Cat3 will freak out and immediately declare himself the root bridge.  Cat2 will get those “inferior” BPDU’s.  Cat2 will ignore them for max_age and then go into listening, learning, forwarding just as before.  At that point, Cat3 will learn it is not the real root by receiving superior BPDUs from Cat1 through Cat2 and adjust it’s root port to be Fa0/19. Cat2 will move Fa0/19 to be the DP and at that point there is no physical loop in the network and we are converged.

Why didn’t loop guard kick in?  When Cat2 sees the “crazy” BPDUs coming down from Cat3 claiming to be the root bridge, it knows something is up.  The only reason that Cat3 would all the sudden start claiming to be the root bridge is if Cat3 had a direct link failure and lost it’s root port.  More technically speaking, Cat2 did indeed stop receiving BPDU’s but it did so after it already received inferior BPDUs from Cat3.  Because of that, Cat2 knows there is a legitimate failure, and it actually NEEDS to transition Fa0/19 into forwarding.  Otherwise, Cat3 would never have a legitimate path back to the root bridge during the failure. The above example is just STP doing what it does best.

So, to test this feature we need to somehow simulate a unidirectional link. hmmmmm….how can we keep all the links up/up but prevent Cat2 from receiving BPDUs from Cat3?  BPDUfilter.  We can configure BPDUfilter on Cat3 fa0/19.  That will prevent Cat3 from sending BPDUs on that interface.  From Cat2’s perspective, the link is still fine, but all the sudden it stops receiving BPDUs.  When that happens, loopguard should kick in for us.  Let’s give this a try.  First, we’ll bring up Cat3 Fa0/21 and get back to our starting point

Cat3(config)#int fa0/21
Cat3(config-if)#do no deb all
All possible debugging has been turned off

Cat3(config-if)#do sh span vlan 1 | b Interface
Interface           Role Sts Cost      Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
Fa0/19              Desg FWD 19        128.19   P2p
Fa0/21              Root FWD 19        128.21   P2p
Cat2#show spanning-tree vlan 1 | b Interface
Interface           Role Sts Cost      Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
Fa0/19              Altn BLK 19        128.19   P2p
Fa0/23              Root FWD 19        128.23   P2p

Ok, cool we are back to square one. Now, we will simulate our unidirectional link by configuring BPDUfilter on Cat3 Fa0/19.

Cat3(config-if)#int fa0/19
Cat3(config-if)#spanning-tree bpdufilter enable

After a few seconds, Cat2 notices the BPDU’s have gone missing from the designated port on Cat3 and loopguard kicks in to do its thing!

Cat2#
*Mar 1 01:15:34.471: %SPANTREE-2-LOOPGUARD_BLOCK: Loop guard blocking port FastEthernet0/19 on VLAN0001.
Cat2#
Cat2#show span int fa0/19

Vlan                Role Sts Cost      Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
VLAN0001            Desg BKN*19        128.19   P2p *LOOP_Inc

Let’s fix our “unidirectional link” now and whack BPDUfilter on Cat3. This should automatically restore things for us on Cat2. We’ll watch debug spanning-tree events on Cat2 while it converges…

Cat3(config-if)#no spanning-tree bpdufilter enable

Cat2#
*Mar 1 01:17:59.867: %SPANTREE-2-LOOPGUARD_UNBLOCK: Loop guard unblocking port FastEthernet0/19 on VLAN0001.
Cat2#
*Mar 1 01:17:59.871: STP: VLAN0001 Fa0/19 -> listening
*Mar 1 01:17:59.871: STP: VLAN0001 Fa0/19 -> blocking
Cat2#show span int fa0/19

Vlan Role Sts Cost Prio.Nbr Type
——————- —- — ——— ——– ——————————–
VLAN0001 Altn BLK 19 128.19 P2p

Back in business!!! Thats it for today everybody.  Have a great Labor Day weekend if you are in the USA!

 

30 Comments

Leave a Reply