Fast Spanning Tree Protocol
Fast Spanning Tree Protocol has been introduced in vde networking to manage and detect loops and redundant links inside the network. The protocol is also responsible of network topology auto-reconfiguration when links or switches disappear or when a cycle is detected.
vde_switch management interface provides commands to manage and monitor Fast Spanning Tree Protocol status and parameters. In this part of the tutorial we'll analyze a network example with topology aspects managed by Fast Spanning Tree Protocol.
Contents |
Before continuing
In this tutorial we are going to use multiple vde_switches in the same hosting machine. To compare management output from multiple switches with simple shell scripts it is useful to enable unixterm to receive commands from standard input. This additional feature can be addedd to vde source tree with a little patch on unixterm source code. The patch can be downloaded here.
Here follows a quick example that shows how to apply the patch to vde source code tree.
$ bzcat unixterm_20070403.patch.bz2 | patch -p1 -d vde2-2.1.6 patching file unixterm/unixterm.c
Once the patch has been applied you need to recompile unixterm and substitute it with the new binary just compiled.
$ cd vde2-2.1.6/unixterm $ make $ mv unixterm `which unixterm`
The case study
We are going to analyze the virtual network shown in the figure here on the right: it is a network of four vde_switches completely-connected or, in other words, a network where each switch is connected to every other switch by a network link.
As can be seen there are several redundant links and several loops in this network. The role of Fast Spanning Tree Protocol is to compute a spanning tree for the network and to disable links that are not part of the tree.
In fact on switched ethernet network the presence of more than one open path at once result in several problems on the network: from CPU and bandwidth consumption caused by frames looping around, to failure of source-based location system used for frames routing at data link layer.
In the following subsection we are going to build the little network shown in the example to see its behavior step-by-step and to have a look to commands and configuration parameters provided by vde_switch management console.
Setting up the network
First of all we need to start four new vde_switches. This can be done with a simple one-line shell script. Parameters needed by vde_switch are the data socket path, the management socket path and the flag to tell him to run as a daemon.
$ for i in `seq 4`; do vde_switch -d -s /tmp/vde$i -M /tmp/mgmt$i; done $ ps x | grep vde_switch 1065 ? Ss 0:00 vde_switch -d -s /tmp/vde1 -M /tmp/mgmt1 1067 ? Ss 0:00 vde_switch -d -s /tmp/vde2 -M /tmp/mgmt2 1069 ? Ss 0:00 vde_switch -d -s /tmp/vde3 -M /tmp/mgmt3 1071 ? Ss 0:00 vde_switch -d -s /tmp/vde4 -M /tmp/mgmt4
Now that vde_switches are up and running we have to create new links between them.
In order to obtain the same configuration shown in the example without the need to specify additional parameters to vde_plug it is important to follow the right order while creating the links. Every time a virtual network device is plugged into a vde_switch the first available port is assigned to it, starting from port number one.
To create links for the example we use the simplest way to do it: a bi-directional pipe and two vde_plugs for each link.
$ dpipe vde_plug /tmp/vde1 = vde_plug /tmp/vde2 & $ dpipe vde_plug /tmp/vde1 = vde_plug /tmp/vde3 & $ dpipe vde_plug /tmp/vde1 = vde_plug /tmp/vde4 & $ dpipe vde_plug /tmp/vde2 = vde_plug /tmp/vde3 & $ dpipe vde_plug /tmp/vde2 = vde_plug /tmp/vde4 & $ dpipe vde_plug /tmp/vde3 = vde_plug /tmp/vde4 &
By default Fast Spanning Tree Protocol is not enabled at switch startup hence all created links are active. This results in multiple loops and multiple redundant links since all ports are enabled. As can be seen from output data given out by management console Fast Spanning Tree Protocol is disabled and all ports are marked as active.
$ for i in `seq 4`; do echo fstp/print | unixterm -i -s /tmp/mgmt$i; done /tmp/mgmt1: FST DATA VLAN 0000 ROOTSWITCH FSTP IS DISABLED /tmp/mgmt1: ++ root 80:00:00:ff:02:61:df:3b /tmp/mgmt1: ++ designated ff:ff:ff:ff:ff:ff:ff:ff /tmp/mgmt1: ++ rootport 0000 cost 0 age 21495 bonusport 0000 bonuscost 0 /tmp/mgmt1: -- Port 0001 tagged=0 portcost=20000000 role=Designated /tmp/mgmt1: -- Port 0002 tagged=0 portcost=20000000 role=Designated /tmp/mgmt1: -- Port 0003 tagged=0 portcost=20000000 role=Designated /tmp/mgmt2: FST DATA VLAN 0000 ROOTSWITCH FSTP IS DISABLED /tmp/mgmt2: ++ root 80:00:00:ff:0f:ba:e9:1a /tmp/mgmt2: ++ designated ff:ff:ff:ff:ff:ff:ff:ff /tmp/mgmt2: ++ rootport 0000 cost 0 age 21495 bonusport 0000 bonuscost 0 /tmp/mgmt2: -- Port 0001 tagged=0 portcost=20000000 role=Designated /tmp/mgmt2: -- Port 0002 tagged=0 portcost=20000000 role=Designated /tmp/mgmt2: -- Port 0003 tagged=0 portcost=20000000 role=Designated /tmp/mgmt3: FST DATA VLAN 0000 ROOTSWITCH FSTP IS DISABLED /tmp/mgmt3: ++ root 80:00:00:ff:e8:9b:68:26 /tmp/mgmt3: ++ designated ff:ff:ff:ff:ff:ff:ff:ff /tmp/mgmt3: ++ rootport 0000 cost 0 age 21495 bonusport 0000 bonuscost 0 /tmp/mgmt3: -- Port 0001 tagged=0 portcost=20000000 role=Designated /tmp/mgmt3: -- Port 0002 tagged=0 portcost=20000000 role=Designated /tmp/mgmt3: -- Port 0003 tagged=0 portcost=20000000 role=Designated /tmp/mgmt4: FST DATA VLAN 0000 ROOTSWITCH FSTP IS DISABLED /tmp/mgmt4: ++ root 80:00:00:ff:c8:97:58:52 /tmp/mgmt4: ++ designated ff:ff:ff:ff:ff:ff:ff:ff /tmp/mgmt4: ++ rootport 0000 cost 0 age 21495 bonusport 0000 bonuscost 0 /tmp/mgmt4: -- Port 0001 tagged=0 portcost=20000000 role=Designated /tmp/mgmt4: -- Port 0002 tagged=0 portcost=20000000 role=Designated /tmp/mgmt4: -- Port 0003 tagged=0 portcost=20000000 role=Designated
In such a situation if data is injected into the network it starts looping around generating a lot of useless traffic and saturating cpu usage. This happens because the traditional source-based location system for switched ethernet networks fails to work correctly. Troubles with location system can be advised looking at vde_switch logging output in syslog.
Here is a little snapshot of what happens when connecting a vde_plug2tap to the network.
Mar 7 15:04:48 balaton vde_switch[2323]: VDE_SWITCH started Mar 7 15:04:48 balaton vde_switch[2325]: VDE_SWITCH started Mar 7 15:04:48 balaton vde_switch[2327]: VDE_SWITCH started Mar 7 15:04:48 balaton vde_switch[2329]: VDE_SWITCH started Mar 7 15:12:37 balaton vde_plug2tap[2412]: VDE_PLUG2TAP started Mar 7 15:13:37 balaton vde_switch[2326]: MAC 2a:93:e5:15:4e:b9 moved from port 1 to port 2 Mar 7 15:13:37 balaton vde_switch[2328]: MAC 2a:93:e5:15:4e:b9 moved from port 2 to port 1 Mar 7 15:13:37 balaton vde_switch[2328]: MAC 2a:93:e5:15:4e:b9 moved from port 2 to port 1 Mar 7 15:13:37 balaton vde_switch[2328]: MAC 2a:93:e5:15:4e:b9 moved from port 2 to port 3 Mar 7 15:13:37 balaton vde_switch[2330]: MAC 2a:93:e5:15:4e:b9 moved from port 3 to port 1 Mar 7 15:13:37 balaton vde_switch[2326]: MAC 2a:93:e5:15:4e:b9 moved from port 1 to port 3 Mar 7 15:13:37 balaton vde_switch[2330]: MAC 2a:93:e5:15:4e:b9 moved from port 3 to port 2
Starting Fast Spanning Tree Protocol
Although it is possible to enable Fast Spanning Tree Protocol while starting vde_switches it is also possible to manage its status at run-time via vde_switch management console. Fast Spanning Tree Protocol can be enabled on each active switch with this command:
$ for i in `seq 4`; do echo fstp/setfstp 1 | ./unixterm -i -s /tmp/mgmt$i; done
Ports status with Fast Spanning Tree Protocol.
/tmp/mgmt1: FST DATA VLAN 0000 /tmp/mgmt1: ++ root 80:00:00:ff:03:41:d9:1a /tmp/mgmt1: ++ designated 80:00:00:ff:03:41:d9:1a /tmp/mgmt1: ++ rootport 0001 cost 20000000 age 0 bonusport 0000 bonuscost 0 /tmp/mgmt1: -- Port 0001 tagged=0 portcost=20000000 role=Root /tmp/mgmt1: -- Port 0002 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt1: -- Port 0003 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt2: FST DATA VLAN 0000 /tmp/mgmt2: ++ root 80:00:00:ff:03:41:d9:1a /tmp/mgmt2: ++ designated 80:00:00:ff:03:41:d9:1a /tmp/mgmt2: ++ rootport 0002 cost 20000000 age 0 bonusport 0000 bonuscost 0 /tmp/mgmt2: -- Port 0001 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt2: -- Port 0002 tagged=0 portcost=20000000 role=Root /tmp/mgmt2: -- Port 0003 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt3: FST DATA VLAN 0000 ROOTSWITCH /tmp/mgmt3: ++ root 80:00:00:ff:03:41:d9:1a /tmp/mgmt3: ++ designated ff:ff:ff:ff:ff:ff:ff:ff /tmp/mgmt3: ++ rootport 0000 cost 0 age 8542 bonusport 0000 bonuscost 0 /tmp/mgmt3: -- Port 0001 tagged=0 portcost=20000000 role=Designated /tmp/mgmt3: -- Port 0002 tagged=0 portcost=20000000 role=Designated /tmp/mgmt3: -- Port 0003 tagged=0 portcost=20000000 role=Designated /tmp/mgmt4: FST DATA VLAN 0000 /tmp/mgmt4: ++ root 80:00:00:ff:03:41:d9:1a /tmp/mgmt4: ++ designated 80:00:00:ff:03:41:d9:1a /tmp/mgmt4: ++ rootport 0002 cost 20000000 age 1 bonusport 0000 bonuscost 0 /tmp/mgmt4: -- Port 0001 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt4: -- Port 0002 tagged=0 portcost=20000000 role=Root /tmp/mgmt4: -- Port 0003 tagged=0 portcost=20000000 role=Alternate/Backup
- Switch vde3 has been elected as rootswitch, all its ports have been configured as Designated. Their role is to deliver data to all other LAN segments.
- Switches vde1, vde2 and vde4 have been configured as leafs of the Spanning Tree, keeping active only links directly connected to rootswitch vde3. Ports connected to these links have been configured as Root ports.
- Every other port that is not part of the Spanning Tree have been configured as Alternate/Backup and so they are kept disabled until something happens, like topology changes or switch/link failure.
It is possible to simulate a link failure choosing a link and shutting down vde_plugs associated with it. Let's see what happens such a failure takes place.
Link failure simulation
In this example we want to simulate a failure on link between vde3 and vde4. First of all we have to search right vde_plugs that are endpoints of the selected link. To do this we have to look at ports status on switches vde3 and vde4.
$ echo port/allprint | unixterm -i -s /tmp/mgmt3 Port 0001 untagged_vlan=0000 ACTIVE - Unnamed Allocatable -- endpoint ID 0006 module unix prog : vde_plug: user=render PID=2621 192.168.0.1 37484 22 ... Port 0002 untagged_vlan=0000 ACTIVE - Unnamed Allocatable -- endpoint ID 0008 module unix prog : vde_plug: user=render PID=2628 192.168.0.1 37484 22 ... Port 0003 untagged_vlan=0000 ACTIVE - Unnamed Allocatable -- endpoint ID 0010 module unix prog : vde_plug: user=render PID=2625 192.168.0.1 37484 22 ...
We are going to kill the vde_plug connected to port 3, its pid is PID=2625. In the same way we look for pid of the vde_plug connected to port 3 on the vde4 switch. Note that part of the output has been omitted to fit the page width.
$ echo port/allprint | unixterm -i -s /tmp/mgmt4 Port 0001 untagged_vlan=0000 ACTIVE - Unnamed Allocatable -- endpoint ID 0006 module unix prog : vde_plug: user=render PID=2623 192.168.0.1 37484 22 ... Port 0002 untagged_vlan=0000 ACTIVE - Unnamed Allocatable -- endpoint ID 0008 module unix prog : vde_plug: user=render PID=2629 192.168.0.1 37484 22 ... Port 0003 untagged_vlan=0000 ACTIVE - Unnamed Allocatable -- endpoint ID 0010 module unix prog : vde_plug: user=render PID=2627 192.168.0.1 37484 22 ...
The other pid we were looking for is PID=2627. Now we can simulate the link failure by killing only one of these processes (the other will terminate because of a signal generated by termination of bi-directional pipe to which it was connected to).
$ kill -9 2625
Now Fast Spanning Tree Protocol converges rapidly to a new stable topology loop-free. Here is the new status of the network after link failure and auto-reconfiguration.
$ for i in `seq 4`; do echo fstp/print | unixterm -i -s /tmp/mgmt$i; done /tmp/mgmt1: FST DATA VLAN 0000 /tmp/mgmt1: ++ root 80:00:00:ff:57:53:46:13 /tmp/mgmt1: ++ designated 80:00:00:ff:57:53:46:13 /tmp/mgmt1: ++ rootport 0003 cost 20000000 age 1 bonusport 0000 bonuscost 0 /tmp/mgmt1: -- Port 0001 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt1: -- Port 0002 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt1: -- Port 0003 tagged=0 portcost=20000000 role=Root /tmp/mgmt2: FST DATA VLAN 0000 /tmp/mgmt2: ++ root 80:00:00:ff:57:53:46:13 /tmp/mgmt2: ++ designated 80:00:00:ff:57:53:46:13 /tmp/mgmt2: ++ rootport 0002 cost 20000000 age 1 bonusport 0000 bonuscost 0 /tmp/mgmt2: -- Port 0001 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt2: -- Port 0002 tagged=0 portcost=20000000 role=Root /tmp/mgmt2: -- Port 0003 tagged=0 portcost=20000000 role=Designated /tmp/mgmt3: FST DATA VLAN 0000 ROOTSWITCH /tmp/mgmt3: ++ root 80:00:00:ff:57:53:46:13 /tmp/mgmt3: ++ designated ff:ff:ff:ff:ff:ff:ff:ff /tmp/mgmt3: ++ rootport 0000 cost 0 age 2011 bonusport 0000 bonuscost 0 /tmp/mgmt3: -- Port 0001 tagged=0 portcost=20000000 role=Designated /tmp/mgmt3: -- Port 0002 tagged=0 portcost=20000000 role=Designated /tmp/mgmt4: FST DATA VLAN 0000 /tmp/mgmt4: ++ root 80:00:00:ff:57:53:46:13 /tmp/mgmt4: ++ designated 80:00:00:ff:80:38:d5:63 /tmp/mgmt4: ++ rootport 0002 cost 40000000 age 2 bonusport 0000 bonuscost 0 /tmp/mgmt4: -- Port 0001 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt4: -- Port 0002 tagged=0 portcost=20000000 role=Root
- Switch vde4 has been isolated from the rest of the network so the Spanning Tree have to be recalculated.
- After disappearing of direct link between vde3 and vde4 the temporary disabled link between vde2 and vde4 have been re-activated.
- Rootswitch is the same as before.
- Now switch vde4 can reach rootswitch passing through switch vde2.
This simple example shows how Fast Spanning Tree Protocol behaves when failures on links happen. By default the Fast Spanning Tree Protocol decides itself how to rebuild the spanning tree when failures or topology changes take place basing its choices on ports cost.
By default each port of a switch has the same cost, but it is possible (for each VLAN) to specify a bonus cost to a port that will be called bonus port. A bonus port is different from the others because from its standard cost is subtracted a bonus cost defined by the user. Let's see an example of how bonus ports work.
Bonus ports
We use again the network of previous example. This time, before starting Fast Spanning Tree Protocol we are going to configure bonus ports and bonus costs for each vde_switch, in order to influence spanning tree creation.
In a completely connected network like this where every link have the same weight the most reasonable way to build a spanning tree is to choose a root switch and then keep enabled only links that connect each other switch directly to the root. When virtual switches are distributed also in reality could be useful to assign priority to some predefined links in order to get better performance.
Like shown in the figure on the right we are going to set bonus ports and costs to give greater priority to links between vde3, vde4 and vde1. Let's see how to do it in practice.
Once switches and links have been created we have to define bonus ports and costs like shown in the last figure. Starting from switch vde1, we set port 1 as bonusport with bonuscost 19000000 for the only available VLAN 0.
$ echo fstp/bonus 0 1 19000000 | unixterm -i -s /tmp/mgmt1. $ echo fstp/print | unixterm -i -s /tmp/mgmt1 /tmp/mgmt1: FST DATA VLAN 0000 ROOTSWITCH FSTP IS DISABLED /tmp/mgmt1: ++ root 80:00:00:ff:ee:34:a5:69 /tmp/mgmt1: ++ designated ff:ff:ff:ff:ff:ff:ff:ff /tmp/mgmt1: ++ rootport 0000 cost 0 age 250 bonusport 0001 bonuscost 19000000 /tmp/mgmt1: -- Port 0001 tagged=0 portcost=20000000 role=Designated /tmp/mgmt1: -- Port 0002 tagged=0 portcost=20000000 role=Designated /tmp/mgmt1: -- Port 0003 tagged=0 portcost=20000000 role=Designated
In vde3 we set port 1 as bonusport with bonuscost 15000000.
$ echo fstp/bonus 0 1 15000000 | unixterm -i -s /tmp/mgmt3 $ echo fstp/print | unixterm -i -s /tmp/mgmt3 /tmp/mgmt3: FST DATA VLAN 0000 ROOTSWITCH FSTP IS DISABLED /tmp/mgmt3: ++ root 80:00:00:ff:ad:e2:f2:73 /tmp/mgmt3: ++ designated ff:ff:ff:ff:ff:ff:ff:ff /tmp/mgmt3: ++ rootport 0000 cost 0 age 455 bonusport 0001 bonuscost 15000000 /tmp/mgmt3: -- Port 0001 tagged=0 portcost=20000000 role=Designated /tmp/mgmt3: -- Port 0002 tagged=0 portcost=20000000 role=Designated /tmp/mgmt3: -- Port 0003 tagged=0 portcost=20000000 role=Designated
Finally we set port 1 of vde4 switch as bonusport with bonuscost 15000000.
$ echo fstp/bonus 0 1 15000000 | unixterm -i -s /tmp/mgmt4 $ echo fstp/print | unixterm -i -s /tmp/mgmt4 /tmp/mgmt4: FST DATA VLAN 0000 ROOTSWITCH FSTP IS DISABLED /tmp/mgmt4: ++ root 80:00:00:ff:df:43:ac:60 /tmp/mgmt4: ++ designated ff:ff:ff:ff:ff:ff:ff:ff /tmp/mgmt4: ++ rootport 0000 cost 0 age 576 bonusport 0001 bonuscost 15000000 /tmp/mgmt4: -- Port 0001 tagged=0 portcost=20000000 role=Designated /tmp/mgmt4: -- Port 0002 tagged=0 portcost=20000000 role=Designated /tmp/mgmt4: -- Port 0003 tagged=0 portcost=20000000 role=Designated
Now it is possible to start Fast Spanning Tree Protocol on all switches and then see what happens.
$ for i in `seq 4`; do echo fstp/setfstp 1 | unixterm -i -s /tmp/mgmt$i; done $ for i in `seq 4`; do echo fstp/print | unixterm -i -s /tmp/mgmt$i; done /tmp/mgmt1: FST DATA VLAN 0000 /tmp/mgmt1: ++ root 80:00:00:ff:a2:6a:6e:44 /tmp/mgmt1: ++ designated 80:00:00:ff:a2:6a:6e:44 /tmp/mgmt1: ++ rootport 0001 cost 1000000 age 2 bonusport 0001 bonuscost 19000000 /tmp/mgmt1: -- Port 0001 tagged=0 portcost=20000000 role=Root /tmp/mgmt1: -- Port 0002 tagged=0 portcost=20000000 role=Designated /tmp/mgmt1: -- Port 0003 tagged=0 portcost=20000000 role=Designated /tmp/mgmt2: FST DATA VLAN 0000 ROOTSWITCH /tmp/mgmt2: ++ root 80:00:00:ff:a2:6a:6e:44 /tmp/mgmt2: ++ designated ff:ff:ff:ff:ff:ff:ff:ff /tmp/mgmt2: ++ rootport 0000 cost 0 age 719 bonusport 0000 bonuscost 0 /tmp/mgmt2: -- Port 0001 tagged=0 portcost=20000000 role=Designated /tmp/mgmt2: -- Port 0002 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt2: -- Port 0003 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt3: FST DATA VLAN 0000 /tmp/mgmt3: ++ root 80:00:00:ff:a2:6a:6e:44 /tmp/mgmt3: ++ designated 80:00:00:ff:ee:34:a5:69 /tmp/mgmt3: ++ rootport 0001 cost 6000000 age 3 bonusport 0001 bonuscost 15000000 /tmp/mgmt3: -- Port 0001 tagged=0 portcost=20000000 role=Root /tmp/mgmt3: -- Port 0002 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt3: -- Port 0003 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt4: FST DATA VLAN 0000 /tmp/mgmt4: ++ root 80:00:00:ff:a2:6a:6e:44 /tmp/mgmt4: ++ designated 80:00:00:ff:ee:34:a5:69 /tmp/mgmt4: ++ rootport 0001 cost 6000000 age 3 bonusport 0001 bonuscost 15000000 /tmp/mgmt4: -- Port 0001 tagged=0 portcost=20000000 role=Root /tmp/mgmt4: -- Port 0002 tagged=0 portcost=20000000 role=Alternate/Backup /tmp/mgmt4: -- Port 0003 tagged=0 portcost=20000000 role=Alternate/Backup