Implementing STP Root Guard and Loop Guard
These two are optional features we can configure with Spanning-Tree. They are mutually exclusive: we configure one or the other, but you cannot configure both of them at the same time on the same interface. Where and how should we configure them? Let's take a look.
STP Root Guard
Let's start with Root Guard, and the topology:

For the sake of the simplicity we only use a single VLAN (VLAN 1), and we lower the priority of SW1 to make it the Root Bidge:
SW1(config)#spanning-tree vlan 1 priority 4096
Now all ports on SW1 are designated:
SW1#show spanning-tree
VLAN0001
Spanning tree enabled protocol ieee
Root ID Priority 4097
Address 5254.0012.6b86
This bridge is the root
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Bridge ID Priority 4097 (priority 4096 sys-id-ext 1)
Address 5254.0012.6b86
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Aging Time 300 sec
Interface Role Sts Cost Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
Gi0/0 Desg FWD 4 128.1 P2p
Gi0/1 Desg FWD 4 128.2 P2p
Gi0/2 Desg FWD 4 128.3 P2p
Gi0/3 Desg FWD 4 128.4 P2p
SW2 and SW3 both chooses its G0/0 interface as their Root port facing the Root Bridge.
Let's say we manage the network in the blue box, and we want the Root Bridge to be in our network. But what happens if a customer connects a switch with a lower priority (or with the same priority but lower base MAC address) than the current Root Bridge to our switch? That switch becomes the Root Bridge, and that can have undesirable consequences: some ports will be blocking which should be in the forwarding state, and traffic might flow through the rogue switch if it has multiple links connected to the service provider network. So Root Guard can help to prevent a rogue switch from becoming the Root Bridge.
We configure Root Guard on interfaces where we don't want to receive superior BPDUs (BPDUs with lower priority than the current Root Bridge), i.e. we never want these ports to be Root ports. This way we can protect our L2 network. So we configure this on the customer facing interfaces where we don't want superior BPDUs to appear: that's G0/2 on SW2 and G0/2 on SW3:
SW2(config)#int g0/2
SW2(config-if)#spanning-tree guard ?
loop Set guard mode to loop guard on interface
none Set guard mode to none
root Set guard mode to root guard on interface
SW2(config-if)#spanning-tree guard root
*Jun 23 06:57:02.132: %SPANTREE-2-ROOTGUARD_CONFIG_CHANGE: Root guard enabled on port GigabitEthernet0/2.
Similarly on SW3:SW3(config)#int g0/2
SW3(config-if)#spanning-tree guard root
Now let's lower the bridge priority of SW4 to 0, and make it the Root Bridge:
SW4(config)#spanning-tree vlan 1 priority 0
SW4 is now sending superior BPDU with a priority of 0 (the current Root Bridge which is SW1 has a bridge priority of 4096):

The moment SW2 receives SW4's superior BPDU, it blocks the port:*Jun 23 07:18:54.024: STP: VLAN0001 heard root 1-5254.0012.9926 on Gi0/2
*Jun 23 07:18:54.024: supersedes 4097-5254.0012.6b86
*Jun 23 07:18:54.024: %SPANTREE-2-ROOTGUARD_BLOCK: Root guard blocking port GigabitEthernet0/2 on VLAN0001.
*Jun 23 07:18:54.025: STP: VLAN0001 sent Topology Change Notice on Gi0/0
*Jun 23 07:18:54.025: STP[1]: Generating TC trap for port GigabitEthernet0/2
*Jun 23 07:18:54.026: STP: VLAN0001 Gi0/2 -> blocking
*Jun 23 07:18:56.032: STP: VLAN0001 heard root 1-5254.0012.9926 on Gi0/2
*Jun 23 07:18:56.032: supersedes 4097-5254.0012.6b86
The Root Bridge is still SW1, SW2 turn this port into a Root-Inconsistent state, and it remains in this state as long as SW2 receives BPDUs with lower Bridge Priority than the current Root Bridge (SW1). Now SW2 is unable to forward frames on this port:
SW2#show spanning-tree
VLAN0001
Spanning tree enabled protocol ieee
Root ID Priority 4097
Address 5254.0012.6b86
Cost 4
Port 1 (GigabitEthernet0/0)
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Bridge ID Priority 32769 (priority 32768 sys-id-ext 1)
Address 5254.000b.24ab
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Aging Time 300 sec
Interface Role Sts Cost Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
Gi0/0 Root FWD 4 128.1 P2p
Gi0/1 Desg FWD 4 128.2 P2p
Gi0/2 Desg BKN*4 128.3 P2p *ROOT_Inc
Gi0/3 Desg FWD 4 128.4 P2p
Let's change back the priority on SW4 to the default of 32768:
SW4(config)#spanning-tree vlan 1 priority 32768
SW2 waits for the Max Age timer (20 sec) to expire and automatically recovers from the Root Inconsistent state:
*Jun 23 07:19:46.074: STP: VLAN0001 heard root 1-5254.0012.9926 on Gi0/2
*Jun 23 07:19:46.074: supersedes 4097-5254.0012.6b86
*Jun 23 07:19:48.077: STP: VLAN0001 heard root 32769-5254.0012.9926 on Gi0/2
*Jun 23 07:20:06.074: %SPANTREE-2-ROOTGUARD_UNBLOCK: Root guard unblocking port GigabitEthernet0/2 on VLAN0001.
*Jun 23 07:20:06.074: STP: VLAN0001 Gi0/2 -> listening
*Jun 23 07:20:06.081: STP: VLAN0001 heard root 32769-5254.0012.9926 on Gi0/2
*Jun 23 07:20:06.084: STP: VLAN0001 Topology Change rcvd on Gi0/2
*Jun 23 07:20:06.084: STP: VLAN0001 sent Topology Change Notice on Gi0/0
*Jun 23 07:20:21.075: STP: VLAN0001 Gi0/2 -> learning
*Jun 23 07:20:36.074: STP[1]: Generating TC trap for port GigabitEthernet0/2
*Jun 23 07:20:36.075: STP: VLAN0001 sent Topology Change Notice on Gi0/0
*Jun 23 07:20:36.075: STP: VLAN0001 Gi0/2 -> forwarding
After going through the Listening and Learning states it eventually moves to the Forwarding state (after 2*15 sec Forward Delay Timer, we use the Classic STP here, not Rapid STP). So to summarize: we configure Root Guard on ports which we don't want to turn into Root ports and we don't want to accept superior BPDUs on these ports. Use this feature to ensure that the L2 topology stays consistent, and the switch remains the Root Bridge which was intended to be.
Now let's take a look at Loop Guard.
STP Loop Guard
We configure Loop Guard on NON-Designated ports (i.e. ports in the blocking state) which we don't want to become designated.

The G0/1 interface of SW3 is blocking (it has the Alternating role). If it stops receiving BPDUs from SW2 it'll turn into the forwarding state (after listening and learning). This can happen because of unidirectional link failure (i.e. a single fiber optics breaks instead of both) or some software failure which prevents SW2 to send BPDUs but the link in the other direction is still functional. In this case both G0/1 on SW3 and G0/1 on SW2 would be designated ports and turn into the forwarding state which could cause loops.
So let's configure Loop Guard on G0/1 interface of SW3:
SW3(config)#int g0/1
SW3(config-if)#spanning-tree guard loop
To simulate an unidirectional link failure, on SW2 I enable bpdufilter to turn off sending BPDUs:
SW2(config)#int g0/1
SW2(config-if)#spanning-tree bpdufilter enable
The moment I do this SW3 doesn't receive BPDUs from SW2 anymore, and we receive the following Syslog message:
*Jun 23 08:01:41.595: %SPANTREE-2-LOOPGUARD_BLOCK: Loop guard blocking port GigabitEthernet0/1 on VLAN0001.
The port has been put in Loop Inconsistent state, and it won't be transitioning into the forwarding state, and forward any traffic, the port is now effectively blocked:
SW3(config-if)#do show spanning-tree
VLAN0001
Spanning tree enabled protocol ieee
Root ID Priority 4097
Address 5254.0012.6b86
Cost 4
Port 1 (GigabitEthernet0/0)
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Bridge ID Priority 32769 (priority 32768 sys-id-ext 1)
Address 5254.000e.d572
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Aging Time 300 sec
Interface Role Sts Cost Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
Gi0/0 Root FWD 4 128.1 P2p
Gi0/1 Desg BKN*4 128.2 P2p *LOOP_Inc
Gi0/2 Desg FWD 4 128.3 P2p
Gi0/3 Desg FWD 4 128.4 P2p
If I turn off bpdufilter on SW2, and SW2 starts sending BPDUs again:
SW2(config-if)#spanning-tree bpdufilter disable
SW3 automatically recovers and, and unblocks the port:
*Jun 23 08:03:18.653: %SPANTREE-2-LOOPGUARD_UNBLOCK: Loop guard unblocking port GigabitEthernet0/1 on VLAN0001.
*Jun 23 08:03:18.653: STP: VLAN0001 Gi0/1 -> listening
*Jun 23 08:03:18.653: STP: VLAN0001 Gi0/1 -> blocking
And the port moves back to the Alternating role, into the Blocking state:
SW3(config-if)#do show spanning-tree
VLAN0001
Spanning tree enabled protocol ieee
Root ID Priority 4097
Address 5254.0012.6b86
Cost 4
Port 1 (GigabitEthernet0/0)
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Bridge ID Priority 32769 (priority 32768 sys-id-ext 1)
Address 5254.000e.d572
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Aging Time 300 sec
Interface Role Sts Cost Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
Gi0/0 Root FWD 4 128.1 P2p
Gi0/1 Altn BLK 4 128.2 P2p
Gi0/2 Desg FWD 4 128.3 P2p
Gi0/3 Desg FWD 4 128.4 P2p
To summarize: Loop Guard helps preventing Layer 2 loops, if a port stops receiving BPDUs because of unidirectional link failure. We can also configure it globally with the spanning-tree loopguard default
command to enable Loop Guard on all ports.