Saturday, July 13, 2013

Optimizing and Protecting Spanning Tree – Lab Testing

Unfortunately the equipment I was using didn’t support PVST+ (Sup2Ts in 6503 Catalyst Switches), so I skipped testing UplinkFast and BackboneFast as these are incorporated in 802.1w (RSTP) and 802.1s (MSTP, which is basically an extension of RSTP).

BPDU Guard

image

For this test, SwitchD will be treated as a Rogue Switch being attached to the network.  Initially, SwitchC’s port 2/1 is configured as an access port with only PortFast enabled.

  1. 1. Disconnect link between SwitchC and SwitchD
  2. 2. Configure SwitchC port 2/1 as an access port in VLAN 10 with PortFast enabled.
  3. 3. Configure SwitchD port 2/1 as an access port in VLAN 10. Configure the priority on VLAN 10 to be 0.
  4. 4. Reconnect link between SwitchC and SwitchD and check topology for VLAN 10. SwitchD should be the root for VLAN 10.
  5. 5. Disconnect link between SwitchC and SwitchD
  6. 6. Enable BPDU Guard on Switch C port 2/1
  7. 7. Reconnect link between SwitchC and SwitchD. SwitchC port 2/1 should move to an err-disable state. Verify with sh interfaces status err-disabled. Verify SwitchD is no longer the root for VLAN 10.

*Jul  5 22:02:06.023: %SPANTREE-2-BLOCK_BPDUGUARD: Received BPDU on port GigabitEthernet2/1 with BPDU Guard enabled. Disabling port.
*Jul  5 22:02:06.023: %PM-4-ERR_DISABLE: bpduguard error detected on Gi2/1, putting Gi2/1 in err-disable state

SwitchC#show interfaces status err-disabled

Port            Name               Status            Reason
Gi2/1           SWITCHD_2/1        err-disabled      bpduguard

BPDU Filtering

image

  1. Run packet capture. Verify BPDUs are seen.
  2. Configure SwitchC port 2/1 with BPDU Filter.
  3. Run packet capture. Verify no BPDUs are seen.
  4. Verify SwitchD sees itself as the root bridge for all VLANs.
  5. Remove BPDU Filter from SwitchC port2/1. Verify BPDUs are seen again.
  6. Disconnect link between SwitchC and SwitchD.
  7. Configure SwitchC port 2/1 as access port in VLAN 1 with PortFast enabled.
  8. Configure SwitchD port 2/1 as access port in VLAN 1 with BPDU Filter enabled. Verify SwitchC sees this as an Edge port.
  9. Enable BPDU Filter globally on edge ports on SwitchC. Verify no BPDUs are seen in packet capture.
  10. Disable BPDU Filter on SwitchD port 2/1. Verify switch C port 2/1 disables BPDU Filter with sh spanning-tree int gig 2/1 detail and BPDUs are seen again in packet capture.

Root Guard

Oh man, this one was a doozy.  After some digging and posting on forums, there are definitely some differences in opinion.  I saw references stating that Root Guard should be placed on all non-root ports – basically anywhere you wouldn’t expect to see the root bridge.  The CCNP SWITCH Official Cert Guide (OCG) however stated that current design practices are to place Root Guard only on access ports.  After my research and testing, I would say – it depends.

image

SwitchD will again be a Rogue Switch

  1. Disconnect link between SwitchC and SwitchD
  2. Configure SwitchD with a priority of 0 for all VLANs.
  3. Reconnect link between SwitchC and SwitchD. Verify SwitchD is the root for all VLANs.
  4. Disconnect link between SwitchC and SwitchD.
  5. Configure Root Guard on SwitchA ports 1/1 and 5/4.
  6. Reconnect link between SwitchC and SwitchD. Verify SwitchA places ports 1/1 and 5/4 in root-inconsistent state with sh spanning-tree inconsistentports. Verify Switch B and SwitchC sees SwitchD as the root for all VLANs.

*Jul 8 21:22:41.903: %SPANTREE-2-ROOTGUARD_CONFIG_CHANGE: Root guard enabled on port TenGigabitEthernet1/1.
*Jul 8 21:24:06.319: %SPANTREE-2-ROOTGUARD_BLOCK: Root guard blocking port TenGigabitEthernet1/1 on VLAN0001

SwitchA#sh spanning-tree inconsistentports
Name Interface Inconsistency
-------------------- ---------------------- ------------------
VLAN0001 TenGigabitEthernet1/1 Root Inconsistent
VLAN0001 TenGigabitEthernet5/4 Root Inconsistent
VLAN0010 TenGigabitEthernet1/1 Root Inconsistent
VLAN0010 TenGigabitEthernet5/4 Root Inconsistent
VLAN0020 TenGigabitEthernet1/1 Root Inconsistent
VLAN0020 TenGigabitEthernet5/4 Root Inconsistent
Number of inconsistent ports (segments) in the system : 6

  1. Disconnect link between SwitchC and SwitchD.
  2. Configure Root Guard on all ports you wouldn’t expect to see superior BPDUs on.
    1. SwitchB port 1/1, SwitchC port 2/1
  3. Reconnect link between SwitchC and SwitchD. Verify SwitchC places port 2/1 into root-inconsistent state. Verify SwitchA and SwitchB ports do not change.
  4. Disconnect the link between SwitchA and SwitchB. Verify SwitchB becomes isolated due to its only remaining link being placed into a root-inconsistent state.

What I discovered from this was that Root Guard worked like a charm but in one specific scenario it’s not so great.  When a link failure occurs between what would be the two distros, the only remaining path that can be utilized for convergence can’t be used because when the superior BPDUs from root hit the remaining switch uplinks that have Root Guard configured, Root Guard triggers and the ports are put into root-inconsistent, effectively breaking the network.  So this led me to believe that really, Root Guard should be kept to access ports as described in the CCNP SWITCH OCG.

I decided to run a second, more realistic type of environment to really test this out.  I set up a pair of distro switches and access switches, and setup HSRP on the distros as well as alternating odd and even VLAN traffic between them.  The first thing I learned was not to place Root Guard on the link between the two distros – that really screws things up.  Makes sense though – I was putting it on root ports for alternating VLANs.

image

1. Configure Root Guard on SwitchA and SwitchB ports 5/4 and 1/1-2. Note the resulting spanning tree topology and HSRP status

image

2. Remove Root Guard on SwitchA and SwitchB port 5/4. Note the resulting spanning tree topology and HSRP status

image

3. Disable link between SwitchA and SwitchB. Note the resulting spanning tree topology and HSRP status.

image 

4. Remove Root Guard from SwitchA and SwitchB ports 1/1-2. Note the resulting spanning tree topology and HSRP status.

image

To summarize all of this, it was the same story as the first test.  Root Guard works fine as long as the link between the two distros doesn’t go down.  Now, most folks run at least two links between distros so this should never happen, but for me personally, I’d avoid Root Guard on interswitch links unless a security requirement forced me to do so, or as was pointed out on a forum I frequent, a situation where you have a network you don’t control that connects to your network and that needs to participate in your STP topology.  In that case, just to protect yourself, Root Guard would be appropriate there.

But what is the point of having Root Guard on access ports if you have BPDU Guard to handle that?  Well, again – it depends.  It was said by one individual that if you have both of them enabled on an access port, Root Guard triggers before BPDU Guard.  This was eye-opening to me and sounded like a great idea.  That way you can tell if some generic switch got hooked up to the network or someone was REALLY dumb (or malicious) and hooked up a switch and attempted to hijack the current root bridge.  Turns out though that this must be code or platform specific, because I couldn’t get that to work on a 6503 with a Sup2T and 6848-GE-TX running 15.1.1.SY or a 3750X running 12.2.55.SE7.

SwitchC(config-if)#do sh run int gig 2/1
Building configuration...

Current configuration : 155 bytes
!
interface GigabitEthernet2/1
description SWITCHD_2/1
switchport
switchport mode access
spanning-tree bpduguard enable
spanning-tree guard root
end

SwitchC(config)#int gig 2/1
SwitchC(config-if)#shut
SwitchC(config-if)#no shut
SwitchC(config-if)#
*Jul 12 21:51:26.969: RSTP(1): initializing port Gi2/1
*Jul 12 21:51:26.969: RSTP(1): Gi2/1 is now designated
*Jul 12 21:51:26.973: RSTP(1): transmitting a proposal on Gi2/1
*Jul 12 21:51:26.973: RSTP[1]: Gi2/1 state change completed. New state is [blocking]
*Jul 12 21:51:27.873: %SPANTREE-2-BLOCK_BPDUGUARD: Received BPDU on port GigabitEthernet2/1 with BPDU Guard enabled. Disabling port.
SwitchC(config-if)#
*Jul 12 21:51:27.873: %PM-4-ERR_DISABLE: bpduguard error detected on Gi2/1, putting Gi2/1 in err-disable state
SwitchC(config-if)#no spann
SwitchC(config-if)#no spanning-tree bpduguar
SwitchC(config-if)#no spanning-tree bpduguard
SwitchC(config-if)#shut
SwitchC(config-if)#no shut
SwitchC(config-if)#
*Jul 12 21:51:52.577: RSTP(1): initializing port Gi2/1
*Jul 12 21:51:52.577: RSTP(1): Gi2/1 is now designated
*Jul 12 21:51:52.581: RSTP(1): transmitting a proposal on Gi2/1
*Jul 12 21:51:52.581: RSTP[1]: Gi2/1 state change completed. New state is [blocking]
SwitchC(config-if)#
*Jul 12 21:51:52.601: %SPANTREE-2-ROOTGUARD_BLOCK: Root guard blocking port GigabitEthernet2/1 on VLAN0001.
SwitchC(config-if)#
SwitchC#

 

3750A#sh run int gig 2/0/1
Building configuration...

Current configuration : 139 bytes
!
interface GigabitEthernet2/0/1
description 3750B
switchport mode access
spanning-tree bpduguard enable
spanning-tree guard root
end

3750A(config)#int gig 2/0/1
3750A(config-if)#shut
3750A(config-if)#no shut
3750A(config-if)#
*Mar  1 00:05:39.914: setting bridge id (which=3) prio 32769 prio cfg 32768 sysid 1 (on) id 8001.7081.05a2.ed80
*Mar  1 00:05:39.914: set portid: VLAN0001 Gi2/0/1: new port id 8037
*Mar  1 00:05:39.914: STP: VLAN0001 Gi2/0/1 -> listening
*Mar  1 00:05:41.877: %SPANTREE-2-BLOCK_BPDUGUARD: Received BPDU on port Gi2/0/1 with BPDU Guard enabled. Disabling port.
*Mar  1 00:05:41.877: %PM-4-ERR_DISABLE: bpduguard error detected on Gi2/0/1, putting Gi2/0/1 in err-disable state
3750A(config-if)#int gig 2/0/1
3750A(config-if)#no spanning
3750A(config-if)#no spanning-tree bpduguard
3750A(config-if)#shut
3750A(config-if)#no shut
3750A(config-if)#
*Mar  1 00:06:05.399: setting bridge id (which=3) prio 32769 prio cfg 32768 sysid 1 (on) id 8001.7081.05a2.ed80
*Mar  1 00:06:05.399: set portid: VLAN0001 Gi2/0/1: new port id 8037
*Mar  1 00:06:05.399: STP: VLAN0001 Gi2/0/1 -> listening
*Mar  1 00:06:07.395: %LINK-3-UPDOWN: Interface GigabitEthernet2/0/1, changed state to up
*Mar  1 00:06:07.404: STP: VLAN0001 heard root     1-c84c.75a6.fa80 on Gi2/0/1
*Mar  1 00:06:07.404:     supersedes 32769-7081.05a2.ed80
*Mar  1 00:06:07.404: %SPANTREE-2-ROOTGUARD_BLOCK: Root guard blocking port GigabitEthernet2/0/1 on VLAN0001.

After some thought, while you may not be able to run both Root Guard and BPDU Guard on the same port (effectively), there may be a use case for one or the other.  Maybe you didn’t need such a hardcore mechanism like BPDU Guard that err-disables a port upon receipt of a BPDU, but you still wanted to protect yourself at least from hijacking of the root bridge.  This is where putting Root Guard on the access port makes sense instead of BPDU Guard.  Not as secure, I know, but it’s an option.

Loop Guard Testing

image

1. Enable BPDU Filter on SwitchB port 1/1. Verify SwitchC port 1/5 transitions to forwarding.

2. Hook up workstation to SwitchC port 2/2 and generate broadcast traffic. Verify broadcast storm ensues via Wireshark.

3. Disable BPDU Filter on SwitchB port 1/1. Verify SwitchC port 1/5 resumes ALT/BLK.

4. Configure Loop Guard on SwitchC port 1/5.

5. Enable BPDU Filter on SwitchB port 1/1. Verify SwitchC port 1/5 is placed in loop-inconsistent state with sh spanning-tree inconsistentports.

SwitchC#sh span vlan 1
VLAN0001
Spanning tree enabled protocol rstp
Root ID Priority 4096
Address 0017.0f61.5281
Cost 2
Port 4 (TenGigabitEthernet1/4)
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Bridge ID Priority 32769 (priority 32768 sys-id-ext 1)
Address 0013.5f1c.ca40
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Aging Time 480
Interface Role Sts Cost Prio.Nbr Type
------------------- ---- --- --------- -------- --------------------------------
Te1/4 Root FWD 2 128.4 P2p
Te1/5 Desg BKN*2 128.5 P2p *LOOP_Inc
Gi2/1 Desg FWD 4 128.129 P2p

SwitchC#sh spanning-tree inconsistentports
Name Interface Inconsistency
-------------------- ---------------------- ------------------
VLAN0001 TenGigabitEthernet1/5 Loop Inconsistent
VLAN0010 TenGigabitEthernet1/5 Loop Inconsistent
VLAN0020 TenGigabitEthernet1/5 Loop Inconsistent

6. Disable BPDU Filter on SwitchB port 1/1. Verify SwitchC port1/5 is recovered.

This test was pretty fun – I don’t think before now I had ever purposely induced a loop.  I knew it was working when I went to do a Wireshark Packet capture and within 3 seconds or so Wireshark was locked up and eating up almost 3Gb of my memory. :)

LoopWireshark

5 comments:

  1. True, Root Guard internal use is limited. And root guard towards a third party device... Well we never speak spanning tree with a third party. Each company has his own root bridge as far as I'm concerned.

    ReplyDelete
    Replies
    1. Yeah I would think that kind of situation would be rare if ever existent.

      Delete
  2. I would have thought that with RootGuard on the links between the core and the next layer was right - in your example if you were to lose the link between the cores you want one of the cores to remove itself, so it doesn't send traffic to the other core via a now oversubscribed link via a intermediate switch.

    ReplyDelete
    Replies
    1. You know what - I just whiteboarded this and I think you're right and I'm completely wrong. I think I may have not given enough weight to the fact that Root Guard places a port into a root inconsistent state, but only for that VLAN. I think this warrents a new blog article and revisiting - thanks!

      Delete
    2. Looks like I wasn't wrong. Check out my latest blog article where I revisted Root Guard.

      http://aspiringnetworker.blogspot.com/2013/10/spanning-tree-exercise-and-revisiting.html

      Root Guard between the core and the next layer is ok in some situations where you have a single spanning tree instance, but in the situation described here, it -will- break inter-VLAN communication.

      Delete