Spanning-tree

You are currently browsing articles tagged Spanning-tree.

This topic seems to be coming up on the practice tests pretty frequently so it’s probably worth a quick review.  There are 4 types of spanning tree protection mechanisms that I want to cover, but let’s first look at a quick basic configuration…

image

Assuming that these switches were just ‘write erased’ (a new verb) and cabled in this manner, what would spanning tree look like?  Well, you should recall that spanning-tree likes configuration items that are lower.  Lower is better in spanning tree. 

Electing the root bridge – The switch with the lowest bridge ID becomes the root.  The bridge ID is a combination of the bridge priority and the bridge MAC address (Also the system ID extension, VLAN, but that’s the same per VLAN). 

Electing the root port – The root creates and sends hellos every 2 seconds.  Switches receive the hellos, update them with the appropriate information, and then forward them out all other ports.  The port that receives the hello with the lowest calculated cost to the root is the root port.

Electing the designated port – The switch that sends the hellos with the lowest advertised cost onto a segment.

So based on that information, and assuming that all of our ports are 10/100 Ethernet, we should be able to figure out what the topology is going to look like.  The cost of each interface should be 19 (Fast Ethernet cost) so let’s take a stab at what this topology will look like…

image

Picking the root here is a rather easy process.  All of the devices have the same priority so distro1 with the lowest MAC address wins the right to be the root.  Distro1 then begins forwarding hellos out of all of his ports.  The initial hellos will have a cost of 0.  Core will get the hello, add the cost of the ingress interface (19) to the hello and forward.  Distro2 will do the same thing.  Since both Core and Distro2 are receiving hellos with the same cost they need to fall back to the lowest bridge ID, followed by lowest port priority, followed by lowest forwarders port number.  In this case, the bridge ID of distro2 is lower than that of core so distro2 will win the designated router role for tat segment…

image

Taking a look at the spanning-tree output on the three switches we can see that we came to the correct conclusion…

image

image

image

Ok, so now we want to make the core the root bridge.  We can do this a couple of ways.  The main goal here is to make sure that the priority of the root bridge is the lowest…

image

Here we use the first method which is to ‘set’ the role of the bridge per VLAN.  In the first example, we set the bridge role to root primary.  This takes the current root bridge’s priority and subtracts 8192 from it.  If we use the secondary version of the command, it takes the current root bridge priority and subtracts 4096 from it.  In a stable topology (one that’s already configured) this would work out just fine.  However, if you set the primary on one switch, it’s just working off of the current root’s priority.  Let me show you what I mean…

image

Here I set the distro2 switch to be the vlan 1 root primary.  After things converge, I see that it is in fact the root of the spanning tree for vlan 1.  Now let’s go onto the core switch and manually change the priority…

As you can see, the core switch becomes the root.  The ‘spanning-tree vlan <vlan> root <primary|secondary>’ command only works of the existing settings.  That is, it’s a sort of macro that actually does the math and converts the ‘primary’ piece of the command to a hard number it puts in the config.  This is why I prefer actually setting the priority to using these commands.

image

Ok, so now we have the topology in place that I actually wanted to use in this post (took me a while to get there huh?).

image

Now let’s take a look at the spanning tree protection mechanisms that I wanted to talk about…

Root Guard
Root guard examines BPDUs that are heard through a particular interface and checks to make sure that they aren’t lower than the switches BPDU.  If it does hear a superior BPDU, the switch will put the port into a ‘root inconsistent’ state which prevents the port from passing traffic.  This prevents an unwanted port from becoming the root port on a switch.  If the condition clears, the superior BPDUs stop coming, the port is returned to it’s normal state.  As far as I can tell, the current recommendation is to enable this on access ports. 

It’s important to note here that it has to hear a BPDU that’s superior to the local switches BPDU.  NOT that of the roots.  For instance, if you enabled it on distro2’s port to the core switch that interface would go into the root inconsistent state.

Let’s take a look at a quick example…

image

Here we enable it on a single port on disto1.  Then we plug in the ‘user’ switch on that same port…

image

Any guesses on what will happen?

image

Nothing.  Why?  The BPDU the user switch is sending is not superior to the local distro1 switch.  See, you have to make some assumptions here.  If distro1 is NOT the root, then it’s BPDU is lower than the roots.  So as long as the new switch is not higher than the BPDU of distro1 (non-root) then everything is fine. 

So now let’s see what happens when we change the priority on the user switch to 0…

image

Instantly, the port on distro1 goes into root inconsistent.  We can see that in a couple of different outputs…

image

And when the priority changes back to normal, the port condition automatically restores to the normal forwarding state after going through the normal 802.1d port process…

image

BPDU Guard
BPDU guard is similar to root guard, but it’s more straight to the point.  If you have BPDU guard enabled on a switch, and you hear a BPDU, err-disable the port.  This condition can only be reversed by shutting and no-shutting the port to recover the err-disabled state.  The configuration is pretty straight forward…

image

Now if we plug the user switch back into that same port, we can see the action taken immediately…

image

So if you hear a BPDU, shutdown the port.  We can see this in a couple of different outputs…

image

BPDU Filter
Like the command suggests, BPDU filter prevents the port that the filter is configured on from sending BPDUs as well as disregards BPDUs that are coming into the port.  The configuration is pretty straight forward…

image

If we do the same test (plugging the user switch in distro1) we can see the results on each switch…

image

Dsitro1 puts the fa1/0/3 interface into the forwarding state after going through the normal STP port loading process..

image

And as you can see above, the user switch didn’t receive any BPDUs so it assume that it’s the root of it’s own STP domain. 

BPDU filter and guard in conjunction with portfast
I’m assuming that we all know what portfast is at this point.  But to summarize, it puts a interface into spanning-tree forwarding mode immediately.  Portfast can be enabled in two distinct ways.  The first is globally, and the second is by specific interface.  The key piece to understand is that they act differently based on the configuration. 

Global portfast puts access ports into the portfast state UNLESS they hear a BPDU.  If the port hears a BPDU, the port comes out of the portfast and goes through the normal listening, learning, forwarding spanning tree port process.  Interface portfast puts the port into an unconditional portfast mode.  BPDU or no BPDU, the port will always remain in portfast.

We can see the two different options in action below…

image

Above you can see what occurs when it’s configured globally.  The instant the port comes up and begins sending frames (BPDUs) the port loses it’s portfast status.  Now if we configure it on the interface…

image

We can see that despite receiving BPDUs, the port keeps it’s portfast status.  I bring this up because you can also configure the BPDU filter and guard functions globally on a switch.  These can be done via the following commands…

image

Note that these functions rely on portfast since it’s part of their configuration.  Keep this (any how portfast acts when it receives BPDUs) in mind when configuring the features.  For a deep dive on how these can interact check out Marko’s blog post on it here…

http://blog.ipexpert.com/2010/12/06/bpdu-filter-and-bpdu-guard/

Loop Guard
Loop guard is usually talked about in conjunction with UDLD.  The base premise of loop guard is that it prevents a port from transitioning from a blocking state to a forwarding state.  If you ran into a scenario where you had a link that failed in one direction.  The switch on the other end would no longer receive BPDUs and would believe that it should transition into forwarding mode.  This would cause a loop in the network.  If loop guard was turned on, instead of transitioning the port to forwarding, it would put the port in loop-inconsistent state.

Tags: ,

Ran into this at work the other day and it took me a second to remember what was going on.  Inconsistent ports are somewhat of an oddity.  Let’s take a quick look at an example…

image

So we have the possibility for a layer 2 loop here.  STP is going to kick in and figure out which one of these ports to block.  Let’s take a look and see what happens…

image

Not that interface Fa1/0/2 shows a status of ‘BKN’ and a type of ‘P2p *TYPE_Inc’.  If we take a look at the inconsistent ports in spanning-tree, we’ll see the port there as well…

image

Looking at the configuration of the Fa1/0/2 interfaces on both switches we can see that I have one end configured as a trunk, and the other end configured as a access port…

image

image

An unusual configuration I agree, but why wouldn’t this work?  The trunk has it’s native VLAN set to 10 and the other end is an access port in vlan 10.  The trunk port should send untagged frames on vlan 10 and when they end up on switch1 they should be put in vlan 10.  

Moreover, I could see this being an issue if one end had a spanning-tree type of ‘edge’ configured with portfast since we truly shouldn’t be seeing spanning-tree BPDUs on an access port, but in this case, the port types are both P2P.

So, I did some packet captures.  It looked like spanning-tree was sending 802.1Q tagged BPDUs on VLAN 1 as well as VLAN 10…

image

image

That would give merit to the error message I’m seeing on the switch about the port being ‘inconsistent’…

image

So this is sort of odd right?  Recall that the trunk had been configured with the native VLAN set to 10.  So why was it sending out spanning-tree messages with a DOT1Q header of VLAN 10?

I could understand seeing the VLAN 1 BPDUs in a dot1q header, but why were the VLAN 10 BPDU’s showing up tagged?  I ran into some Cisco documentation that further confused me as I was trying to figure this out…

image

A quick post to networking-forum.com and mellowd was able to clear up the confusion for me.  He had ran into this during some of his testing and summed it up like this…

PVST BPDUs are always tagged, regardless of the native vlan.
The only untagged bpdus are 802.1d and MST bpdus, again regardless of native vlan

This makes sense.  If I change my spanning-tree mode to MST then the port inconsistency resolves itself. 

This introduces and important point about PVST. On trunk ports, PVST sends communication for each VLAN out bundled in a 802.1Q header with the appropriate VLAN header REGARDLESS of the native VLAN. If it did send the PVST info for the native VLAN untagged, then this configuration would (in my opinion) worked as I had initially expected. Please keep in mind that this wasn’t a real scenario, there was more gear and more complicated configuration in play for the problem that spawned this post. In the real world, two ends of a port should be configured identically in scenarios like this one.

Tags:

It should be obvious by now that there are really two types of spanning-tree topologies.  One where all switches run a single spanning-tree instance (common spanning-tree) and one where a switch can run one instance per VLAN (per-VLAN spanning-tree).  MST makes a happy compromise by allowing you to group VLANs together under one spanning-tree instance.  That is, VLANs 10 through 20 can run one instance and VLANs 30 through 40 could run another.  We haven’t really talked much about the per-VLAN configuration but I’m not going to dwell on it since it’s pretty easy to configure (spanning-tree vlan <vlan number> <spanning-tree command>). 

MST groups VLANs together by instance.  An instance is the group of VLANs that will run under that particular spanning-tree.  MST also uses the concept of regions.  A region is group of MST switches that share the same configuration information.  The configuration information that has to match is…

-Configuration Name
-Revision Number
-The VLAN to instance mappings

If some of these items don’t match, the the two switches can’t be in the same region. 

MST can be rather easy to understand, or very very very complicated.  If all of the switches are running MST, it’s pretty easy to get.  If you are matching a MST boundary up to a non-MST boundary, things get complicated and there are a lot of design considerations.  That being said, we are only going to talk about a basic MST configuration in this post.

In this code snippet, we create 5 VLANs, and map them to two different instances on the switch…

Switch2(config)#vlan 10
Switch2(config-vlan)#
name users0
Switch2(config-vlan)#vlan 11
Switch2(config-vlan)#
name users1
Switch2(config-vlan)#vlan 12
Switch2(config-vlan)#name users2
Switch2(config-vlan)#vlan 13
Switch2(config-vlan)#
name users3
Switch2(config-vlan)#
Switch2(config-vlan)#
vlan 20
Switch2(config-vlan)#name prod0
Switch2(config-vlan)#
vlan 21
Switch2(config-vlan)#
name prod1
Switch2(config-vlan)#
Switch2(config-vlan)#
spanning-tree mst config
Switch2(config-mst)#
revision 1
Switch2(config-mst)#
instance 1 vlan 10-13
Switch2(config-mst)#instance 2 vlan 20-21

Switch2(config-mst)#show pending
Pending MST configuration
Name      []
Revision  1     Instances configured 3

Instance  Vlans mapped
——–  ———————————————————————
0         1-9,14-19,22-4094
1         10-13
2         20-21
——————————————————————————-
Switch2(config-mst)#
?
  abort         Exit region configuration mode, aborting changes
  exit          Exit region configuration mode, applying changes
  instance      Map vlans to an MST instance
  name          Set configuration name
  no            Negate a command or set its defaults
  private-vlan  Set private-vlan synchronization
  revision      Set configuration revision number
  show          Display region configurations

Switch2(config-mst)#

About half way down you can see that I issue the ‘show pending’ command.  In MST the changes aren’t applied until you exit the MST configuration mode.  If you don’t want to apply the changes, you can type the abort command to exit without applying. 

You’ll also note that by default all VLANs belong to instance 0.  You can see that I mapped certain VLANs in instance 1 and 2 and the remainder of the VLANs are left in instance 0.  Instance 0 is referred to as the IST or Internal spanning tree or sometimes referred to as MSTI0.  This instance has some special use cases but are too deep for us to cover in this intro post.

I’m hoping I might have more time later to come back to MST but for now I’ll have to leave it at this (I’m on a tight schedule!).

Tags: ,

« Older entries