Definitions
RSTP
An evolution of the original Spanning Tree Protocol which features increased convergence time. RSTP is designed to prevent loops from forming in a layer 2 network.
Introduction
Spanning Tree Protocol (STP) was originally developed to prevent the formation of loops in a network that has redundant layer 2 paths. Rapid Spanning Tree Protocol (RSTP) is an evolution of the same protocol that comes with an increase in convergence times and a change in the processing states.
Forming Loops
Because of the nature of switches when learning and flooding traffic, if you have redundant L2 paths throughout your network, you run the risk of creating a broadcast storm. Why is a broadcast storm so bad and why do we need spanning tree in place to protect our network?
When a broadcast message is sent from a client device, the switch receives the frame on its connected interface and sees the destination MAC of FF:FF:FF:FF:FF:FF. This special type of frame tells the switch that it needs to “flood” this frame to every member of the broadcast domain or VLAN.
This frame is then sent out of every interface except for the one it received the message on. For example, if our switch has two interfaces, ge-0/0/1 and ge-0/0/2, and our connected device is on interface ge-0/0/1, the message would only be sent out of interface ge-0/0/2.
Take a look at Figure 1 below and let’s paint the picture of our network; we’ve created a design with redundant L2 paths but we haven’t configured RSTP. In our scenario we are purposefully trying to create a loop so that our broadcast message will now makes its way across all of our interfaces. All our links are green as they are all capable of forwarding traffic.
We’ve created VLAN 10 and put our gateway on an upstream router. All switches downstream carry tagged traffic down to our access switch. Interface ge-0/0/3 connected to Server A on lab-access-switch-1 is configured as an untagged access port.

Let’s go through the steps that lead to a storm one-by-one:
- Server A is connected to our switch at ge-0/0/3. The interface is brought up and connected to our network on VLAN 10.
- A broadcast message is sent in the form of an ARP request by Server A through its interface nic1 and to our access switch on ge-0/0/3.
- The access switch floods this message out of all its interfaces, except ge-0/0/3 as that is the originating interface, including interfaces ge-0/0/1 and ge-0/0/2.
- Our two distribution switches receive the broadcast frame on their ge-0/0/1 interfaces and flood the frames out of their respective ge-0/0/0 interfaces.
Here’s where things get interesting:
- Our core switch now receives duplicate frames on its ge-0/0/1 and ge-0/0/2 interfaces. The frame received on ge-0/0/1 is flooded to ge-0/0/0 and ge-0/0/2 and the frame received on ge-0/0/2 is flooded to ge-0/0/0 and ge-0/0/1.
- Those same frames are now received at our distribution switches over the ge-0/0/0 interfaces and flooded back down the ge-0/0/1 interfaces where they are received by our access switch and our loop is now complete.
So what’s the issue with a broadcast storm?
Well unlike layer 3 packets that have a default TTL (Windows 128 & Linux/Junos 64), L2 frames do not have any TTL, so these frames will loop endlessly. Ultimately this ends with our devices resources being consumed until the network is overwhelmed completely or the physical path is broken.
Another side-effect of a broadcast storm is MAC table instability. When Server A is first connected without our loop in place, our access switch learns the MAC address of the connected device as it processes frames originating from that device.
The switch’s corresponding MAC table is updated and it knows it can reach our Server A over interface ge-0/0/3.
routing-table@lab-access-switch-1> show ethernet-switching table
Ethernet switching table : 1 entries, 1 learned
Routing instance : default-switch
Vlan MAC MAC Logical
name address flags interface
vid10 50:00:00:09:00:00 D ge-0/0/3.0
And now we’ll take a look at the learned MACs and the expected outcome:
routing-table@lab-access-switch-1> show ethernet-switching mac-learning-log
Sun Apr 26 14:57:54 vlan_name vid10+10 mac 50:00:00:09:00:00 was learned on ge-0/0/3.0 with flags: 0x2001f
Let’s run those same two outputs after we’ve created our loop:
routing-table@lab-access-switch-1> show ethernet-switching table
Ethernet switching table : 1 entries, 1 learned
Routing instance : default-switch
Vlan MAC MAC Logical
name address flags interface
vid10 50:00:00:09:00:00 D ge-0/0/1.0
Our interface has now changed to ge-0/0/1. This is because the frame was sent to the agg switch and looped back around so our switch thinks its learning the same MAC over its upstream interface. The MAC table is updated accordingly because it thinks the frame came from a device elsewhere.
What’s the issue with this? Well when the switch receives traffic destined to the MAC of our server, it doesn’t know what interface to send the frames out of, resulting in partial or complete traffic loss.
Let’s take a another look at the learning log below. These messages tell us what MAC addresses are being learnt and where.
routing-table@lab-access-switch-1> show ethernet-switching mac-learning-log
Sun Apr 26 15:22:08 vlan_name vid10+10 mac 50:00:00:09:00:00 was moved from ge-0/0/0.0 to ge-0/0/1.0 with flags: 0x2101f
Sun Apr 26 15:22:08 vlan_name vid10+10 mac 50:00:00:09:00:00 was moved from ge-0/0/1.0 to ge-0/0/0.0 with flags: 0x2101f
Sun Apr 26 15:22:08 vlan_name vid10+10 mac 50:00:00:09:00:00 was moved from ge-0/0/0.0 to ge-0/0/1.0 with flags: 0x2101f
Sun Apr 26 15:22:08 vlan_name vid10+10 mac 50:00:00:09:00:00 was moved from ge-0/0/1.0 to ge-0/0/0.0 with flags: 0x2101f
Sun Apr 26 15:22:08 vlan_name vid10+10 mac 50:00:00:09:00:00 was moved from ge-0/0/0.0 to ge-0/0/1.0 with flags: 0x2101f
Sun Apr 26 15:22:08 vlan_name vid10+10 mac 50:00:00:09:00:00 was moved from ge-0/0/1.0 to ge-0/0/0.0 with flags: 0x2101f
The output is abbreviated but look at how quickly we learn the same MAC over different interfaces. In less than a single second, our Server A MAC has been learnt on ge-0/0/0 and ge-0/0/1 multiple times. All of this forwarding, learning, and re-learning is how our resource exhaustion comes about.
So, how can we design our network with redundant paths to our core without running the risk of bringing down our network?
Spanning Tree!
The Root Bridge
Spanning tree creates a “tree” topology of the entire L2 network with a single best path to the “Root Bridge”.
The root bridge is an elected switch within this tree topology that dictates the best path through the network and is the reference point for all other switches. You can have multiple root bridges in your network depending on the design. If you have isolated L2 networks, have routers or firewalls servicing certain traffic paths, or multiple data centers then you will likely have multiple. It is best practice to place your root bridge as close as possible to the gateways for your network and it should be your most capable switch.
The root bridge is named so because it is placed at the base or root of our logical tree with all other switches (branches) expanding outward from it. A trees branches never loop around and join together.
RSTP works by placing these participating interfaces into a blocking/discarding state that have the potential to create a loop. Imagine if two branches grew outward from our hypothetical tree and joined at each end, spanning tree would detect this new loop and “cut” the branches at the loop.
Back to our lab now, let’s re-create our loop, but this time we’ll enable spanning tree across all of our devices with some default configuration before establishing our physical connections.
set protocols rstp interface all
How has our environment reacted? Let’s go switch-by-switch and see what we can understand based on our new topology.
routing-table@lab-access-switch-1> show ethernet-switching table
Ethernet switching table : 1 entries, 1 learned
Routing instance : default-switch
Vlan MAC MAC Logical
name address flags interface
vid10 50:00:00:09:00:00 D ge-0/0/3.0
routing-table@lab-access-switch-1> clear ethernet-switching table
routing-table@lab-access-switch-1> show ethernet-switching mac-learning-log
Sun May 10 12:27:21 vlan_name vid10+10 mac 50:00:00:09:00:00 was deleted from ge-0/0/3.0 with flags: 0x181080
Sun May 10 12:27:23 vlan_name vid10+10 mac 50:00:00:09:00:00 was learned on ge-0/0/3.0 with flags: 0x2001f
We’ve cleared our MAC table and re-learnt the address of Server A and it stays on the ge-0/0/3 interface as expected, there is no table instability anymore.
Let’s now find our recently elected root-bridge if we leave all defaults to Junos:
routing-table@lab-root-bridge-1> show spanning-tree interface
Spanning tree interface parameters for instance 0
Interface Port ID Designated Designated Port State Role
port ID bridge ID Cost
ge-0/0/0 128:490 128:490 32768.2c6bf584d1d0 20000 FWD DESG
ge-0/0/1 128:491 128:493 32768.2c6bf56cbed0 20000 FWD ROOT
ge-0/0/2 128:492 128:493 32768.2c6bf59317d0 20000 BLK ALT
routing-table@lab-agg-switch-1> show spanning-tree interface
Spanning tree interface parameters for instance 0
Interface Port ID Designated Designated Port State Role
port ID bridge ID Cost
ge-0/0/1 128:490 128:490 32768.2c6bf53c6dd0 20000 FWD ROOT
ge-0/0/0 128:493 128:493 32768.2c6bf56cbed0 20000 FWD DESG
routing-table@lab-agg-switch-2> show spanning-tree interface
Spanning tree interface parameters for instance 0
Interface Port ID Designated Designated Port State Role
port ID bridge ID Cost
ge-0/0/1 128:490 128:491 32768.2c6bf53c6dd0 20000 FWD ROOT
ge-0/0/0 128:493 128:493 32768.2c6bf59317d0 20000 FWD DESG
routing-table@lab-access-switch-1> show spanning-tree interface
Spanning tree interface parameters for instance 0
Interface Port ID Designated Designated Port State Role
port ID bridge ID Cost
ge-0/0/0 128:490 128:490 32768.2c6bf53c6dd0 20000 FWD DESG
ge-0/0/1 128:491 128:491 32768.2c6bf53c6dd0 20000 FWD DESG
ge-0/0/3 128:492 128:492 32768.2c6bf53c6dd0 20000 FWD DESG
If we take a careful look at the output of our switches here we find out two things:
- What ports are being blocked that would form our loop, and;
- What switch has been elected our root bridge
We can tell both of these things by the “state” and “roles”of our interfaces.
The root bridge will always have all of its interfaces placed into the “Forwarding” state and the “Designated” role. Whereas our other switches will have interfaces in various other states depending on connectivity.
We know that by looking at our output, lab-access-switch-1 has been made the root bridge because all of its interfaces are in the forwarding state. Another way to take a look at this would be by running the following command on any of the switches:
routing-table@lab-agg-switch-1> show spanning-tree bridge
STP bridge parameters
Routing instance name : GLOBAL
Context ID : 0
Enabled protocol : RSTP
Root ID : 32768.2c:6b:f5:3c:6d:d0
Root cost : 20000
Root port : ge-0/0/1
Hello time : 2 seconds
Maximum age : 20 seconds
Forward delay : 15 seconds
Message age : 1
Number of topology changes : 2
Time since last topology change : 288 seconds
Local parameters
Bridge ID : 32768.2c:6b:f5:6c:be:d0
Extended system ID : 0
routing-table@lab-access-switch-1> show spanning-tree bridge
STP bridge parameters
Routing instance name : GLOBAL
Context ID : 0
Enabled protocol : RSTP
Root ID : 32768.2c:6b:f5:3c:6d:d0
Hello time : 2 seconds
Maximum age : 20 seconds
Forward delay : 15 seconds
Message age : 0
Number of topology changes : 1
Time since last topology change : 157 seconds
Local parameters
Bridge ID : 32768.2c:6b:f5:3c:6d:d0
Extended system ID : 0
On our agg switch the global and local bridge are different, whereas on our access switch they are the same.
Let’s take a look at our new network with RSTP enabled showing our green links as our forwarding interfaces, and red links as our interfaces that have been placed in a blocking state:

In our default spanning tree topology, a root bridge is elected based on the lowest numerical mac address. What you’ll notice is that the MAC address assigned as the Bridge ID is not any physical or virtual interface on the device. For the purposes of spanning tree, Junos will use the same chassis MAC of the device and change the last octets so that it is unique, this is only used for spanning tree purposes. You can find the chassis MAC by running:
routing-table@lab-access-switch-1> show chassis mac-addresses
MAC address information:
Public base address 2c:6b:f5:3c:66:00
Public count 1984
Private base address 2c:6b:f5:3c:6d:c0
Private count 64
This election process is a result of the default configuration, all we did here was enable RSTP on all interfaces with no custom configuration. After we’ve safely enabled RSTP and avoided a storm, we now want fine-tune our network and make our root bridge the switch named lab-root-bridge-1. This is our more powerful datacenter class switch closest to our gateways.
Looking at the output above, we know what our root bridge is based on the defined MAC address, but what is the value 32768 in front of it? This is the default bridge priority. The bridge priority is the first thing considered in the spanning tree bridge election process. Because 32768 is the default for all switches, our election process was left to the lowest MAC address, and it actually picked the switch we would least like to be the root. It is furthest from our gateways AND the least-powerful switch in our datacenter. So how do we change this and make our switch closest to the router our root bridge?
Here’s our output from our intended root bridge before we make our changes:
routing-table@lab-root-bridge-1> show spanning-tree interface
Spanning tree interface parameters for instance 0
Interface Port ID Designated Designated Port State Role
port ID bridge ID Cost
ge-0/0/0 128:490 128:490 32768.2c6bf584d1d0 20000 FWD DESG
ge-0/0/1 128:491 128:490 32768.2c6bf56cbed0 20000 FWD ROOT
ge-0/0/2 128:492 128:490 32768.2c6bf59317d0 20000 BLK ALT
routing-table@lab-root-bridge-1> show spanning-tree bridge
STP bridge parameters
Routing instance name : GLOBAL
Context ID : 0
Enabled protocol : RSTP
Root ID : 32768.2c:6b:f5:3c:6d:d0
Root cost : 40000
Root port : ge-0/0/1
Hello time : 2 seconds
Maximum age : 20 seconds
Forward delay : 15 seconds
Message age : 2
Number of topology changes : 5
Time since last topology change : 16 seconds
Local parameters
Bridge ID : 32768.2c:6b:f5:84:d1:d0
Extended system ID : 0
Let’s make our changes:
routing-table@lab-root-bridge-1> configure
Entering configuration mode
[edit]
andrew-lab@lab-root-bridge-1# set protocols rstp bridge-priority 8k
[edit]
andrew-lab@lab-root-bridge-1# commit and-quit
commit complete
Exiting configuration mode
and now let’s look at our output:
routing-table@lab-root-bridge-1> show spanning-tree interface
Spanning tree interface parameters for instance 0
Interface Port ID Designated Designated Port State Role
port ID bridge ID Cost
ge-0/0/0 128:490 128:490 8192.2c6bf584d1d0 20000 FWD DESG
ge-0/0/1 128:491 128:491 8192.2c6bf584d1d0 20000 FWD DESG
ge-0/0/2 128:492 128:492 8192.2c6bf584d1d0 20000 FWD DESG
routing-table@lab-root-bridge-1> show spanning-tree bridge
STP bridge parameters
Routing instance name : GLOBAL
Context ID : 0
Enabled protocol : RSTP
Root ID : 8192.2c:6b:f5:84:d1:d0
Hello time : 2 seconds
Maximum age : 20 seconds
Forward delay : 15 seconds
Message age : 0
Number of topology changes : 6
Time since last topology change : 7 seconds
Local parameters
Bridge ID : 8192.2c:6b:f5:84:d1:d0
Extended system ID : 0
What’s changed?
Well all of our interfaces are now in the designated state, and our global and local bridges are the same.
Our core switch is now the root bridge. Let’s validate on our access switch:
routing-table@lab-access-switch-1> show spanning-tree interface
Spanning tree interface parameters for instance 0
Interface Port ID Designated Designated Port State Role
port ID bridge ID Cost
ge-0/0/0 128:490 128:491 32768.2c6bf56cbed0 20000 FWD ROOT
ge-0/0/1 128:491 128:491 32768.2c6bf59317d0 20000 BLK ALT
ge-0/0/3 128:492 128:492 32768.2c6bf53c6dd0 20000 FWD DESG
routing-table@lab-access-switch-1> show spanning-tree bridge
STP bridge parameters
Routing instance name : GLOBAL
Context ID : 0
Enabled protocol : RSTP
Root ID : 8192.2c:6b:f5:84:d1:d0
Root cost : 40000
Root port : ge-0/0/0
Hello time : 2 seconds
Maximum age : 20 seconds
Forward delay : 15 seconds
Message age : 2
Number of topology changes : 3
Time since last topology change : 327 seconds
Local parameters
Bridge ID : 32768.2c:6b:f5:3c:6d:d0
Extended system ID : 0
Here’s our new network:

The bridge priority is a definable attribute that can be set within the range of 0 through 61440.
You want to set your bridge priority low enough that it cannot be superseded by another new switch that is installed in the network, but not low enough so that it can never be changed in the event of a hardware refresh for example. It can only be set in increments of 4096. Junos will accept the value in the format of <value>k for example. I configured 8k.
The introduction of a new member to the spanning tree topology or root bridge will trigger the reevaluation of the entire topology, and depending on the complexity of your environment, you want it to remain as predictable as possible. Defined attributes are always better than leaving things to default. The defaults will work, but they may not always be ideal as we witnessed in our environment. Our core switch may have 10GbE interfaces and our access switch only 1GbE interfaces, if we have a 10GbE interface shut off upstream then we’re wasting resources.
With the topology change, interfaces that were once previously in the discarding state may now be forwarding and interfaces that were once previously forwarding may now be in the discarding state. We haven’t yet touched on what that means for our network and the main difference between classic STP and rapid STP.
Port Cost
We’ve influenced our root bridge and placed it as close as possible to our core router in the network, that’s great. We’ve also stopped the formation of a loop and cleaned up our network. But now we want to influence the interfaces used as the root port on our access switch. We can do that by modifying the port cost of an interface.
All interfaces have default port costs that are linked to their speed. We mentioned above we want to utilize as many high speed links as possible and RSTP has that ability to identify these links and make sure that they’re not placed in a blocking state and less preferred to our lower speed links. It’s unlikely you will need to modify the default port cost because you will always want to prefer the high speed links over others, and RSTP does a good job of that, but if you do then modifying the port cost is the best method.
Looking at the table below you can see the RSTP costs on the right. Aggregated interfaces also have their own costs when interfaces are grouped together.

In our lab all of our links are 1GbE so we have a default port cost of 20,000:
routing-table@lab-access-switch-1> show spanning-tree interface
Spanning tree interface parameters for instance 0
Interface Port ID Designated Designated Port State Role
port ID bridge ID Cost
ge-0/0/0 128:490 128:491 32768.2c6bf56cbed0 20000 FWD ROOT
ge-0/0/1 128:491 128:491 32768.2c6bf59317d0 20000 BLK ALT
ge-0/0/3 128:492 128:492 32768.2c6bf53c6dd0 20000 FWD DESG
ge-0/0/1 is still in the blocking state but what if we want to make it our root port and put ge-0/0/0 into a blocking state?
routing-table@lab-access-switch-1> edit
Entering configuration mode
[edit]
routing-table@lab-access-switch-1# edit protocols rstp
[edit protocols rstp]
routing-table@lab-access-switch-1# set interface ge-0/0/1 cost 10000
[edit protocols rstp]
routing-table@lab-access-switch-1# commit and-quit
commit complete
Exiting configuration mode
routing-table@lab-access-switch-1> show spanning-tree interface
Spanning tree interface parameters for instance 0
Interface Port ID Designated Designated Port State Role
port ID bridge ID Cost
ge-0/0/0 128:490 128:491 32768.2c6bf56cbed0 20000 BLK ALT
ge-0/0/1 128:491 128:491 32768.2c6bf59317d0 10000 FWD ROOT
ge-0/0/3 128:492 128:492 32768.2c6bf53c6dd0 20000 FWD DESG
BPDUs, States, and Roles
BPDUs
So far we’ve looked at the election process and the purpose of spanning tree in the network and how it works, but we also introduced new concepts that have yet to be explained and how it all works.
All of this information is communicated between switches through the sending and receiving of Bridge Protocol Data Units or BPDUs. BPDUs are sent by all switches in RSTP.
These special messages are sent by switches and contain all of the information we’ve configured above, interfaces, priorities, and costs. This is how devices in our switched LAN learn so quickly and respond to our configured changes. When we changed our bridge priority to prefer our root bridge, that switch sent a BPDU with its new priority to let every other device downstream know about the update.
Classic STP was dependent on a timer-based mechanism to determine interface state transitions, whereas RSTP now has a hello-based mechanism. What does that mean?
Take a look at the bolded output below:
routing-table@lab-access-switch-1> show spanning-tree bridge detail
STP bridge parameters
Routing instance name : GLOBAL
Context ID : 0
Enabled protocol : RSTP
Root ID : 8192.2c:6b:f5:84:d1:d0
Root cost : 30000
Root port : ge-0/0/1
Hello time : 2 seconds
Maximum age : 20 seconds
Forward delay : 15 seconds
Message age : 2
Number of topology changes : 4
Time since last topology change : 2136 seconds
Local parameters
Bridge ID : 32768.2c:6b:f5:3c:6d:d0
Extended system ID : 0
Hello time : 2 seconds
Maximum age : 20 seconds
Forward delay : 15 seconds
Path cost method : 32 bit
We’re going to introduce BPDU hello, max age, and forwarding delay timers. These are all Juniper defaults:
- Hello time – This is the frequency in which BPDUs are sent by the root bridge.
- Maximum age – The amount of time that a switch will consider BPDUs received from other devices as valid before considering the device dead.
- Forward delay – The time spent in the listening and learning states before a port will transition into the forwarding state (we’ll touch on states next).
The max age and forwarding delay timers are carried over from the original iteration of the protocol since RSTP is backwards compatible and you may still have a need to configure it if there are older devices in the network.
A switch will send BPDUs every two seconds by default and will consider a neighbor dead if it does not receive a BPDU from that device three consecutive times, or 6 seconds total. Here’s our first difference, a topological change is detected within 6 seconds and our network can adjust rapidly.
Scenario
A root bridge fails and goes into an offline state, its physical neighbor detects the link failure and becomes the new root bridge based on having the next lowest bridge priority and immediately sends updated BPDUs. In RSTP, the other downstream switches receiving this updated BPDU will immediately update their own tables OR these neighbors will acknowledge that they have not received a BPDU within the configured time and their own sent BPDUs will be used in the conversation to determine the new root bridge. RSTP reconvergence is complete within 6 seconds, oftentimes quicker because of the upstream link failure triggering the new election process.
This is why RSTP is much preferred to the original STP and where you see the difference with the max age and forward delay timers. In STP also only the root bridge would send BPDUs and the other members would relay and propagate those BPDUs, in RSTP all switches are sending BPDUs. The defaults are 20 and 15 seconds respectively so devices would wait for 20 seconds before they announced a neighbor as dead, and then the switch interface would spend 15 seconds each in the listening and learning states before forwarding traffic. So if you had an interface in a blocking state then that interface would need to wait at minimum 50 seconds before it could forward traffic again.
If you are running exclusively RSTP then you do not need to worry about the max age or forward delay timers.
States
Because we are discussing RSTP rather than STP, we’ll focus on the changes rather than an in-depth explanation of the original protocol from the beginning. We mentioned the change in processing states earlier on, traditional STP has 5 whereas RSTP now has 3:
| STP States | RSTP States |
| Disabled | Discarding |
| Blocking | Discarding |
| Listening | Discarding |
| Learning | Learning |
| Forwarding | Forwarding |
The old states of Disabled, Blocking, and Listening have been replaced with Discarding whereas Learning and Forwarding have remained the same. We are now down to 3 total states instead of 5.
- Discarding – The interface is disabled/blocked and will discard all incoming BPDUs along with all frames as well as learned MAC addresses.
- Learning – The interface is preparing to become active and forward frames across the network but is examining incoming frames to determine its place in the topology. This is an in-between state.
- Forwarding – The interfaces are active and available to forward frames across the network.
Roles
Along with states, spanning tree also introduces the idea of roles. Roles determine how the interface participates in spanning tree.
- Root port – This is the interface closest to our designated root bridge in terms of path cost. Root ports are always in the forwarding state.
- Designated port – These interfaces forward traffic away from the root bridge towards another spanning tree member or end device. The root bridge in the topology has all of its ports in the designated role. Designated ports are always in the forwarding state.
- Alternate port – These interfaces provide an alternative path toward the root bridge if the root port fails for any reason. Alternate ports are always in the discarding/blocking state but will immediately take over from the root port if that interface fails.
- Backup port – These interfaces provide backup paths toward other members of the spanning tree if the designated port fails for any reason. A backup port will only exist in spanning tree if there are redundant designated links. Backup ports are always in the discarding/blocking state but will immediately take over from the designated port if that interface fails.
States and Roles Overview
| RSTP States | RSTP Roles |
| Discarding | Alternate and Backup Ports |
| Forwarding | Root and Designated Ports |
In our lab we currently have interfaces in only root, designated, and alternate roles.
Edge v Non-Edge Ports
In RSTP we can speed convergence up for certain interfaces even faster with the introduction of edge and non-edge ports. Edge ports are interfaces that we do not expect to receive BPDUs on such as end servers, PCs, VoIP phones, etc. Edge ports skip the learning phase completely and move directly to forwarding. Non-edge ports are those where we expect to connect to another switching device.
I’ve taken our RSTP configuration back to its original state with the all interfaces set command so we can see how our interfaces are classified by default.
routing-table@lab-access-switch-1> show configuration protocols rstp | display set
set protocols rstp interface all
routing-table@lab-access-switch-1> show spanning-tree interface detail
Spanning tree interface parameters for instance 0
Interface name : ge-0/0/0
Port identifier : 128.490
Designated port ID : 128.491
Port cost : 20000
Port state : Forwarding
Designated bridge ID : 16384.2c:6b:f5:6c:be:d0
Port role : Root
Link type : Pt-Pt/NONEDGE
Boundary port : NA
Interface name : ge-0/0/1
Port identifier : 128.491
Designated port ID : 128.491
Port cost : 20000
Port state : Blocking
Designated bridge ID : 20480.2c:6b:f5:93:17:d0
Port role : Alternate
Link type : Pt-Pt/NONEDGE
Boundary port : NA
Interface name : ge-0/0/3
Port identifier : 128.492
Designated port ID : 128.492
Port cost : 20000
Port state : Forwarding
Designated bridge ID : 32768.2c:6b:f5:3c:6d:d0
Port role : Designated
Link type : Pt-Pt/EDGE
Boundary port : NA
ge-0/0/0 and ge-0/0/1 are our uplinks to the network and ge-0/0/3 is our server downlink, you can see only ge-0/0/3 is classified as an edge port. This is because this interface hasn’t received any BPDUs, if it did it would transition automatically to a non-edge port. Our interfaces have been classified appropriately but we should specify accordingly:
routing-table@lab-access-switch-1# set protocols rstp interface ge-0/0/0 mode point-to-point
[edit]
routing-table@lab-access-switch-1# set protocols rstp interface ge-0/0/1 mode point-to-point
[edit]
routing-table@lab-access-switch-1# set protocols rstp interface ge-0/0/3 edge
[edit]
routing-table@lab-access-switch-1# commit and-quit
commit complete
Exiting configuration mode
routing-table@lab-access-switch-1> show configuration protocols rstp | display set
set protocols rstp interface ge-0/0/0 mode point-to-point
set protocols rstp interface ge-0/0/1 mode point-to-point
set protocols rstp interface ge-0/0/3 edge
This is great but we shouldn’t implicitly trust edge ports, you might be a network administrator for a large campus where an end-user brings a switch from home and plugs it into a port originally designed for a PC with bridge priority of 0 which immediately changes your network topology. For this potential behavior, we can configure the following:
routing-table@lab-access-switch-1# set protocols rstp bpdu-block-on-edge
This command will block an interface if it receives a BPDU when it is not expected. Let’s disconnect our server and connect a switch with a priority of 0 and see what happens:
routing-table@lab-access-switch-1> show interfaces ge-0/0/3 | match error
Link-level type: Ethernet, MTU: 1514, LAN-PHY mode, Speed: 1000mbps, BPDU Error: Detected, Loop Detect PDU Error: None, Ethernet-Switching Error: None, Remote Bounce: None,
MAC-REWRITE Error: None, Loopback: Disabled, Source filtering: Disabled, Flow control: Enabled, Auto-negotiation: Enabled, Remote fault: Online, Media type: Fiber
Bit errors 0
Errored blocks 0
routing-table@lab-access-switch-1> show log messages| match bpdu
Aug 15 16:33:38 lab-access-switch-1 l2cpd[6767]: L2CPD_RECEIVE_BPDU_BLOCK_ENABLED: BPDU_PROTECT: Interface ge-0/0/3 is DOWN: BPDU error detected
We can see a BPDU has been detected on our server facing interface and the port has been shut down.
The end user has been warned and the switch now disconnected. Let’s see what the interface looks like now
routing-table@lab-access-switch-1> show spanning-tree interface
Spanning tree interface parameters for instance 0
Interface Port ID Designated Designated Port State Role
port ID bridge ID Cost
ge-0/0/0 128:490 128:491 32768.2c6bf56cbed0 20000 FWD ROOT
ge-0/0/1 128:491 128:491 32768.2c6bf59317d0 20000 BLK ALT
ge-0/0/3 128:492 128:492 32768.2c6bf53c6dd0 20000 BLK DIS (Bpdu-Incon)
Unless you specify a manual timeout, this interface is going to remain in a blocked state
routing-table@lab-access-switch-1> show interfaces ge-0/0/3 | match error
Link-level type: Ethernet, MTU: 1514, LAN-PHY mode, Speed: 1000mbps, BPDU Error: Detected, Loop Detect PDU Error: None, Ethernet-Switching Error: None, Remote Bounce: None,
MAC-REWRITE Error: None, Loopback: Disabled, Source filtering: Disabled, Flow control: Enabled, Auto-negotiation: Enabled, Remote fault: Online, Media type: Fiber
Bit errors 0
Errored blocks 0
routing-table@lab-access-switch-1> clear error bpdu interface ge-0/0/3
routing-table@lab-access-switch-1> show interfaces ge-0/0/3 | match error
Link-level type: Ethernet, MTU: 1514, LAN-PHY mode, Speed: 1000mbps, BPDU Error: None, Loop Detect PDU Error: None, Ethernet-Switching Error: None, Remote Bounce: None,
MAC-REWRITE Error: None, Loopback: Disabled, Source filtering: Disabled, Flow control: Enabled, Auto-negotiation: Enabled, Remote fault: Online, Media type: Fiber
Bit errors 0
Errored blocks 0
You can clear the interface using this command:
clear ethernet-switching recovery-timeout interface <Interface-name>
To wrap up there are a few more useful commands you can find to tailor your network:
set protocols rstp interface <interface> no-root-port
You may configure this when you want a switch to participate in RSTP but don’t want it to become the root bridge, and:
set protocols rstp interface <interface> bpdu-timeout-action <alarm | block>
The first command is considered root protection while the second is considered loop protection. You cannot configure both at the same time. Configuring loop protection stops an interface from entering the forwarding state in error if it has not received a BPDU for some time and re-opens a looped path.
That’s all!
Documentation Links and KBs
https://www.ieee802.org/1/pages/802.1Q-2014.html
https://datatracker.ietf.org/doc/html/rfc2878
https://supportportal.juniper.net/s/article/Interface-down-due-to-BPDU-Error