Advanced STP Features: PortFast, BPDU Guard, and BPDU FilterAdvanced STP features is perhaps one of the most commonly misunderstood topics in any Cisco certification level studies. From what I have found, the features are somewhat unclearly documented and some information available out there is even plain wrong. This post describes the operation of PortFast, BPDU guard, and BPDU filter in detail.

 

PortFast

 

The PortFast feature was originally developed to overcome a situation where a PC was unable to obtain a DHCP address due to the port failing to transition into the forwarding state in time. This results from STP going through the listening and learning states, which would normally take 30 seconds. The PortFast feature allows the port to enter the forwarding state immediately, bypassing the listening and learning states. Because the purpose of PortFast is to minimize the time a port must wait for STP to converge by skipping important transitional states, it should be configured only on edge ports connecting to end devices. If PortFast is enabled on an interface connecting to another switch, a temporary STP loop could be created. This is potentially detrimental to the network. IOS will actually issue a warning about this when PortFast is enabled.

 

There is much misinformation about the operational details of PortFast circulating throughout the Internet. One of the most common misconceptions is that PortFast effectively disables STP, and  BPDUs are no longer sent or received on the port. Everything about this statement is wrong. Not only does a PortFast-enabled port transmit BPDUs, but the operational PortFast status is actually dependent on incoming BPDUs. If the port receives BPDUs, the PortFast feature is disabled. Now, it is important to understand the difference between the administrative and operational state of PortFast. The administrative state refers to what is configured on the device, and the operational state defines whether the feature is actually enabled or disabled. There are basically two ways to enable PortFast: globally (spanning-tree portfast default) or per interface (spanning-tree portfast). Both commands enable PortFast on operational access ports. For example, a port that is administratively configured to negotiate a trunk but failed to do so would operate in access mode.

 

Let’s look at this on the command line. A PC is connected to S1 on Eth0/2. The port is configured in dynamic desirable mode and PortFast is configured on the interface. This is the administrative state. S1 will fail to establish a trunk with the PC, so the port will revert to access mode and PortFast will be enabled. This is the operational state.

 

S1#show run interface eth0/2

interface Ethernet0/2   

switchport mode dynamic desirable

spanning-tree portfast 

 

S1#show interface eth0/2 switchport                                           

Name: Et0/2

Switchport: Enabled

Administrative Mode: dynamic desirable                                         

Operational Mode: static access

 

S1#show spanning-tree interface eth0/2 portfast                               

VLAN0001            enabled  

 

 

What about the BPDUs? Are they still sent out? Let’s find out.

 

S1#show spanning-tree interface eth0/2 detail | include BPDU                                     

  BPDU: sent 580, received 0

 

Clearly, the port is still sending BPDUs. STP is up and running.

 

 

What if I temporarily plug a root switch to the port instead? The port will receive incoming BPDUs and the PortFast feature is effectively disabled.

 

S1#show spanning-tree interface eth0/2 detail | include BPDU

BPDU: sent 724, received 10   

 

S1#show spanning-tree interface eth0/2 portfast                               

VLAN0001            disabled

 

 

The PC is connected back to S1 Eth0/2 again. What happens if I explicitly configure the interface to operate as a trunk? The PortFast feature will no longer be in effect.

 

S1#show run interface eth0/2

interface Ethernet0/2               

switchport trunk encapsulation dot1q                                         

switchport mode trunk

spanning-tree portfast 

 

S1#show interface eth0/2 switchport               

Name: Et0/2

Switchport: Enabled

Administrative Mode: trunk

Operational Mode: trunk

 

S1#show spanning-tree interface eth0/2 portfast

VLAN0001            disabled

 

 

There is an additional interface-level command, spanning-tree portfast trunk, which enables PortFast on trunk ports. The documentation is slightly misleading in this regard. The documentation says, "This command enables PortFast on the interface even while in the trunk mode," and later states, "This command allows you to configure PortFast on trunk ports." The first statement is accurate. The second statement could be interpreted as enabling PortFast only on trunk ports, which is not true. In fact, that would be impossible. There is no configuration command to enable PortFast solely on operational trunk ports.

 

S1(config)#interface eth0/2

S1(config-if)#no spanning-tree portfast

S1(config-if)#spanning-tree portfast trunk   

 

S1#show interface eth0/2 switchport

Name: Et0/2

Switchport: Enabled

Administrative Mode: trunk

Operational Mode: trunk

 

S1#show spanning-tree interface eth0/2 portfast                               

VLAN0001            enabled

 

 

If the interface is changed to access mode, the PortFast feature will still be enabled.

 

S1#show run interface eth0/2

interface Ethernet0/2

switchport mode access

spanning-tree portfast trunk 

 

S1#show interface eth0/2 switchport       

Name: Et0/2

Switchport: Enabled                                                           

Administrative Mode: static access                     

Operational Mode: static access   

 

S1#show spanning-tree interface eth0/2 portfast   

VLAN0001            enabled

 

 

Faster STP convergence is perhaps the main but not the only benefit of the PortFast feature. The switch never generates a TCN when the link status of a PortFast enabled port changes. In very large (and flat) networks, a point can be reached where the network is in a constant state of topology change. This can lead to major problems like excessive unicast flooding, which can slow down the network significantly. That is why it is important to correctly implement PortFast in your network.

 

 

BPDU Guard


BPDU guard prevents a port from receiving BPDUs. If the port still receives a BPDU, it is put in the error-disabled state as a protective measure. Much like the PortFast feature, BPDU Guard has two configuration options: globally (spanning-tree portfast bpduguard default) and per interface (spanning-tree bpduguard enable). As you might guess from the command syntax, if configured globally, BPDU Guard is dependent on the operational PortFast state. It does not matter how PortFast was configured; as long as it is enabled, BPDU Guard will be in effect. The per interface configuration unconditionally enables BPDU Guard on the port, independent of PortFast or access/trunk mode.

 

Let’s jump to the command line and see this behavior in action. Switches S1 (root) and S2 are directly connected on Eth0/0 on both ends. Let’s verify that the global command has no effect unless coupled with operational PortFast. The interfaces are configured in access mode, BPDU Guard is enabled globally, and PortFast is not set. The configuration is identical on both switches.

 

S2#show interface eth0/0 switchport     

Name: Et0/0

Switchport: Enabled                                                         

Administrative Mode: static access                   

Operational Mode: static access


S2#show spanning-tree interface eth0/0 portfast                             

VLAN0001            disabled


S2(config)#spanning-tree portfast bpduguard default

S2#show spanning-tree summary                                                 

Switch is in pvst mode                                                       

Root bridge for: none                                                     

Extended system ID          is enabled                                 

Portfast Default            is disabled                                       

PortFast BPDU Guard Default  is enabled

                                       

As you can see, BPDU Guard is enabled globally. Viewing only this command output can easily lead to wrong conclusions because you might expect the port to be err-disabled after receiving BPDUs. However, BPDUs are received, but the port is still forwarding. The PortFast feature is not enabled, so BPDU Guard never kicks in to err-disable the port.


S2#show spanning-tree interface eth0/0 detail | include BPDU                   

  BPDU: sent 0, received 136    

 

S2#show spanning-tree interface eth0/0 portfast                               

VLAN0001            disabled

 

S2#show spanning-tree | begin Interface           

Interface          Role Sts Cost      Prio.Nbr Type                           

------------------- ---- --- --------- -------- ------

Et0/0              Root FWD 100      128.1    Shr

 


Let’s activate PortFast globally on S1.

 

S1(config)#spanning-tree portfast default

 

S1#show spanning-tree summary                                                 

Switch is in pvst mode                                                         

Root bridge for: VLAN0001                                                     

Extended system ID          is enabled   

Portfast Default            is enabled                                       

PortFast BPDU Guard Default  is enabled                                       

 

S1#show spanning-tree interface eth0/0 portfast   

VLAN0001            enabled

 

S1#show spanning-tree | begin Interface                                   


Interface          Role Sts Cost      Prio.Nbr Type     

------------------- ---- --- --------- -------- ----------

Et0/0              Desg FWD 100      128.1 Shr Edge       

 


Huh? Why is the port still forwarding even after the PortFast feature was just enabled? Why are there no log messages? The answer lies in normal STP operation. The switch is running PVST+, and only the root switch sends out BPDUs every Hello interval unless there is a topology change. Because S1 is the root switch and no events have occurred that would trigger S2 to send a TCN, S1 has not received any BPDUs.

 

S1#show spanning-tree interface eth0/0 detail | include BPDU|Bpdu             

  Bpdu guard is enabled by default                   

  BPDU: sent 631, received 0

 


Let's run the same command on S2.

 

S2(config)#spanning-tree portfast default

 


As soon as S2 received the next BPDU from S1, the port was err-disabled and error messages were displayed on the console.


*Mar  3 11:26:15.503: %SPANTREE-2-BLOCK_BPDUGUARD: Received BPDU on port Ethernet0/0 with BPDU Guard enabled. Disabling port.

*Mar  3 11:26:15.503: %PM-4-ERR_DISABLE: bpduguard error detected on Et0/0, putting Et0/0 in err-disable state

*Mar  3 11:26:16.504: %LINEPROTO-5-UPDOWN: Line protocol on Interface Ethernet0/0, changed state to down

*Mar  3 11:26:17.503: %LINK-3-UPDOWN: Interface Ethernet0/0, changed state to down

 

S2#show interface status err-disabled                                         

Port      Name    Status        Reason      Err-disabled Vlans

Et0/0              err-disabled  bpduguard

 

 

There are two ways to recover an err-disabled port, either by manually re-enabling with shutdown and no shutdown commands or by configuring automatic err-disable recovery with errdisable recovery cause bpduguard. The default recovery interval is 300 seconds but can be changed with the errdisable recovery interval <sec> command.


S2#show errdisable recovery                                                   

ErrDisable Reason           

Timer Status                                     

-----------------            --------------                                   

arp-inspection              Disabled                                         

bpduguard                    Enabled                                          

channel-misconfig (STP)      Disabled                                         


--- output omitted ---                                       

                                                                               

Timer interval: 300 seconds


Interfaces that will be enabled at the next timeout:                           


Interface      Errdisable reason      Time left(sec)                         

---------      -----------------      --------------                         

Et0/0                  bpduguard          275



Obviously, automatic recovery does not fix the root cause. After 300 seconds, the port would be re-enabled only for a short period of time before being err-disabled again when the next BPDU from the root switch is received.

 

Let’s quickly prove that the interface level BPDU Guard configuration is indeed independent of the operational PortFast or access/trunk state.

 

S2(config)#no spanning-tree portfast default

S2(config)#no spanning-tree portfast bpduguard default

S2(config)#interface Eth0/0

S2(config-if)#spanning-tree bpduguard enable

 

S2#show spanning-tree interface eth0/0 portfast                               

VLAN0001            disabled  

 

S2#show spanning-tree interface eth0/0 detail | include Bpdu|BPDU             

Bpdu guard is enabled                                                       

BPDU: sent 0, received 140

 


When the first BPDU is received, the interface is err-disabled.

 

*Mar  3 12:55:33.953: %SPANTREE-2-BLOCK_BPDUGUARD: Received BPDU on port Et0/0 with BPDU Guard enabled. Disabling port.

*Mar  3 12:55:33.953: %PM-4-ERR_DISABLE: bpduguard error detected on Et0/0, putting Et0/0 in err-disable state

*Mar  3 12:55:35.325: %LINK-3-UPDOWN: Interface Ethernet0/0, changed state to down

 

S2#show interface status err-disabled                                         

                                                                           

Port      Name    Status        Reason      Err-disabled Vlans                     

Et0/0            err-disabled  bpduguard

 


BPDU Filter

 

BPDU Filter prevents specified ports from sending or receiving BPDUs. Again, there are two methods to configure this feature: globally (spanning-tree portfast bpdufilter default) and per interface (spanning-tree bpdufilter enable). The interface configuration filters both incoming and outgoing BPDUs unconditionally – independent of the operational PortFast state or access/trunk mode. This is effectively the equivalent of turning off STP. This can be very dangerous because a permanent loop can easily be created. Interestingly enough, IOS does not display a warning message when this command is applied. Enabling PortFast on the wrong interface is not nearly as risky as BDPU Filter yet oddly IOS considers that significant enough to inform the administrator.

 

Let’s see this in action. Switches S1 (root) and S2 are connected with two links. Eth0/1 on S2 is blocking.

 

S1#show spanning-tree | begin Interface                                       

Interface          Role Sts Cost      Prio.Nbr Type                           

------------------- ---- --- --------- -------- --------

Et0/0              Desg FWD 100      128.1    Shr                           

Et0/1              Desg FWD 100      128.2    Shr       

 

 

S2#show spanning-tree | begin Interface                                       

Interface          Role Sts Cost      Prio.Nbr Type                           

------------------- ---- --- --------- -------- --------

Et0/0              Root FWD 100      128.1    Shr                           

Et0/1              Altn BLK 100      128.2    Shr     

 

 

What happens if BPDU Filter is enabled on S2?

 

S2(config)#interface range eth0/0 - 1                                                       

S2(config-if-range)#spanning-tree bpdufilter enable

 

 

S1#show spanning-tree                                                         

                                                                               

VLAN0001                                                                       

  Spanning tree enabled protocol ieee                                         

  Root ID    Priority    32769                                                 

            Address    aabb.cc00.1f00                                       

            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    aabb.cc00.1f00                                       

            Hello Time  2 sec  Max Age 20 sec  Forward Delay 15 sec         

            Aging Time  300 sec                                               

                                                                               

Interface          Role Sts Cost      Prio.Nbr Type                           

------------------- ---- --- --------- -------- -----------------------

Et0/0              Desg FWD 100      128.1    Shr                           

Et0/1              Desg FWD 100      128.2    Shr                           

 

 

S2#show spanning-tree                                                         

                                                                               

VLAN0001                                                                       

  Spanning tree enabled protocol ieee                                         

  Root ID    Priority    32769                                                 

            Address    aabb.cc00.2000                                       

            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    aabb.cc00.2000                                       

            Hello Time  2 sec  Max Age 20 sec  Forward Delay 15 sec         

            Aging Time  300 sec                                               

                                                                               

Interface          Role Sts Cost      Prio.Nbr Type                           

------------------- ---- --- --------- -------- -----------------------

Et0/0              Desg FWD 100      128.1    Shr                           

Et0/1              Desg FWD 100      128.2    Shr                         

 

 

Both switches now think they are the root and all interfaces are forwarding. BPDUs are not sent or received on S2.

                                                                                                                               

S2#show spanning-tree interface eth0/0 detail | include Bpdu|BPDU             

  Bpdu filter is enabled                                                     

  BPDU: sent 0, received 0

 

S2#show spanning-tree interface eth0/1 detail | include Bpdu|BPDU             

  Bpdu filter is enabled                                                     

  BPDU: sent 0, received 0

 

 

Take a look at the bandwidth utilization. That's a lot of packets.

 

S2#show interface eth0/0                                                       

Ethernet0/0 is up, line protocol is up (connected)                                             

  30 second input rate 12481000 bits/sec, 20262 packets/sec                   

  30 second output rate 12482000 bits/sec, 20264 packets/sec                                                    


S2#show interface eth0/1                                                       

Ethernet0/1 is up, line protocol is up (connected)                                             

  30 second input rate 12477000 bits/sec, 20256 packets/sec                   

  30 second output rate 12474000 bits/sec, 20250 packets/sec                   

 


This is an emulated lab running on IOL. Besides these two switches, there are no other devices and no other traffic. You can imagine how this configuration could quickly crash your network. Exercise extreme caution with this command.

 

The global configuration is more intricate. Similar to the BPDU Guard feature, the global BPDU Filter is enabled on interfaces in operational PortFast state. In global mode, the switch does not filter incoming BPDUs, but most (though not all) outgoing BPDUs are filtered. When a port comes up, 11 BPDUs are sent out. If BPDUs are received, the PortFast and BPDU Filter features are disabled.

 

Let’s see how this works. Both interfaces on S1 have been configured with interface BPDU Filter. Both interfaces on S2 have spanning-tree portfast trunk configured so that PortFast will be operational no matter what, and BPDU Filter is enabled globally.

 

S1#show spanning-tree interface eth0/0 detail | include Bpdu|BPDU             

  Bpdu filter is enabled                                                     

  BPDU: sent 0, received 0                                                   

                                                                         

S1#show spanning-tree interface eth0/1 detail | include Bpdu|BPDU             

  Bpdu filter is enabled                                                      

  BPDU: sent 0, received 0

 

 

S2#show spanning-tree summary                                                 

Switch is in pvst mode                                                         

Root bridge for: VLAN0001                                                     

Extended system ID          is enabled                                       

Portfast Default            is disabled

PortFast BPDU Guard Default  is disabled                                       

Portfast BPDU Filter Default is enabled

 

 

The ports send 11 BPDUs and then stop.

 

S2#show spanning-tree interface eth0/0 detail | include Bpdu|BPDU             

  Bpdu filter is enabled by default                                           

  BPDU: sent 11, received 0                                                  

 

S2#show spanning-tree interface eth0/1 detail | include Bpdu|BPDU             

  Bpdu filter is enabled by default                                           

  BPDU: sent 11, received 0

 

 

Note what happens on S2 when the interface BPDU Filter is disabled on S1.

 

S1(config)#interface range eth0/0 - 1

S1(config-if-range)#no spanning-tree bpdufilter enable


S2#debug spanning-tree events

*Mar  3 15:01:09.027: STP: VLAN0001 heard root 32769-aabb.cc00.1f00 on Et0/1   

*Mar  3 15:01:09.027:    supersedes 32769-aabb.cc00.2000                     

*Mar  3 15:01:09.027: STP: VLAN0001 new root is 32769, aabb.cc00.1f00 on port Et0/1, cost 100 *Mar  3 15:01:09.027: STP: VLAN0001 new root port Et0/0, cost 100             

*Mar  3 15:01:09.027: STP: VLAN0001 sent Topology Change Notice on Et0/0       

*Mar  3 15:01:09.027: STP[1]: Generating TC trap for port Ethernet0/1         

*Mar  3 15:01:09.027: STP: VLAN0001 Et0/1 -> blocking

 


S2 hears a superior BPDU, effectively disables BPDU Filter, and converts to normal STP operation. Eth0/0 becomes the root port and Eth0/1 is blocking.

 

S2#show spanning-tree | begin Interface                                       

Interface          Role Sts Cost      Prio.Nbr Type                           

------------------- ---- --- --------- -------- --------

Et0/0              Root FWD 100      128.1    Shr                           

Et0/1              Altn BLK 100      128.2    Shr

 

 

Summary


This blog discussed advanced STP features at length, but here are the main points I'd like you to take from it:

  • PortFast immediately moves the port into the forwarding state, bypassing listening and learning states.

  • A PortFast enabled port will continue to transmit BPDUs.

  • If a BPDU is received, PortFast is disabled.

  • The switch never generates a TCN when a PortFast enabled port goes up or down.

  • There is a difference between administrative and operational state.

  • The spanning-tree portfast trunk command enables PortFast on both access and trunk ports.

  • BPDU Guard and BPDU Filter global mode is dependent on operational PortFast.

  • BPDU Guard and BPDU Filter interface mode is unconditional.

  • Misconfigured BPDU Filter is much more dangerous than misconfigured PortFast, yet IOS does not generate a warning message about that.

  • PortFast can create a temporary loop of max. 2 seconds (default Hello interval) until the next BPDU is received and PortFast is disabled. BPDU Filter can create a permanent loop, because all BPDUs are ignored.

  • Remember the operation of STP - when BPDUs are sent and not sent.