dump file for network 1
dump file for network2
dump file used for improvement of network 1
dump file used for improvement of network 2
UML switches can be created as a switch or a hub. Which do you need to use for sniffing and why?
We need hub here, as switch will not forward Ethernet frames to certain ports according to the filter rule learned during the learning state. Sniffer can only capture the Ethernet frames for other nodes when they are on the same collision domain. In this case, we are taking a look at STP which work on Ethernet level, so hub should be the only choice.
Download the Ubuntu package and install the files in your UML filesystem as per usual.
Please see the work log.
Can you think of reasons not to use the Busybox version of brctl?
The reason is simple, busybox version of brctl miss some functions. The normal brctl provides the following function
vic@umlubuntu:~/uml$ brctl --help Usage: brctl [commands] commands: addbr <bridge> add bridge delbr <bridge> delete bridge addif <bridge> <device> add interface to bridge delif <bridge> <device> delete interface from bridge setageing <bridge> <time> set ageing time setbridgeprio <bridge> <prio> set bridge priority setfd <bridge> <time> set bridge forward delay sethello <bridge> <time> set hello time setmaxage <bridge> <time> set max message age setpathcost <bridge> <port> <cost> set path cost setportprio <bridge> <port> <prio> set port priority show show a list of bridges showmacs <bridge> show a list of mac addrs showstp <bridge> show bridge stp info stp <bridge> {on|off} turn stp on/off
Provide and investigate the reasoning behind each of the following items. Also explain any choices you made in the process.
- To be able to analyze the collected data, we need to be able to put it into a timeline.
- We need to see all the relevant packets produced by the Spanning Tree Protocol. That means that irrelevant packets can be left out, though your
should carefully decide what they are.
- We need to be able to see the content of the STP packets. tcpdump can show that in a nice format so be sure to look into that.
- We need to be able to see what (sub)network the packet was retrieved from.
The order in which the nodes send/receive the packet is very important. They have influence on the procedure and the convergence time of the network. The t family of tcpdump can help us
-t Don't print a timestamp on each dump line. -tt Print an unformatted timestamp on each dump line. -ttt Print a delta (micro-second resolution) between current and pre‐ vious line on each dump line. -tttt Print a timestamp in default format proceeded by date on each dump line. -ttttt Print a delta (micro-second resolution) between current and first line on each dump line.
We can use filters to ensure that only the relevant packets are captured, like protocol = stp, and so on. However, I did not apply any filter in the tcpdump. There are two reasons for that
- simplify the scripts: I do not have to let tcpdump use different filter in every different assignment where different packets have to be captured.
- I have more complete capture file, every packet is captured, to play with later with either tcpdump itself or wireshark (GUI tool).
There are parameters we can define in tcpdump to let it present us with some more human-friendly packet contents. Like -v -vv -x -xx. The v family, present more verbose output includes more fields and the x family gives out also the packet content instead of only the header.
-v When parsing and printing, produce (slightly more) verbose out‐ put. For example, the time to live, identification, total length and options in an IP packet are printed. Also enables additional packet integrity checks such as verifying the IP and ICMP header checksum. When writing to a file with the -w option, report, every 10 sec‐ onds, the number of packets captured. -vv Even more verbose output. For example, additional fields are printed from NFS reply packets, and SMB packets are fully decoded. -x When parsing and printing, in addition to printing the headers of each packet, print the data of each packet (minus its link level header) in hex. The smaller of the entire packet or snaplen bytes will be printed. Note that this is the entire link-layer packet, so for link layers that pad (e.g. Ethernet), the padding bytes will also be printed when the higher layer packet is shorter than the required padding. -xx When parsing and printing, in addition to printing the headers of each packet, print the data of each packet, including its link level header, in hex.
I “mark” the packets with bridges' IDs and their ports IDs. Like, for example
bridge 1: AA:BB:CC:DD:01:AA - port 1 AA:BB:CC:DD:01:01 - port 2 AA:BB:CC:DD:01:02 bridge 2: AA:BB:CC:DD:02:AA - port 1 AA:BB:CC:DD:02:01 - port 2 AA:BB:CC:DD:02:02 - port 3 AA:BB:CC:DD:02:03
In this way, I can easily see in the dump file where the specific packet come from. The host and rcS scripts have to be adapted to the change as well.
+ change in host file. It will accept manual MAC addresses assignment. + <code bash> bridge) macbr=$4 macif1=$5 sw1=$6 #hostname=$macbr if [ -z "$7" ]; then #echo "screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ r umlid=$hostname role=$role hostname=$hostname eth0=daemon,,unix,$home/switch/$sw1.ctl macbr=$macbr macif1=$macif1 sw1=$sw1" screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ r umlid=$hostname hostname=$hostname role=$role eth0=daemon,,unix,$switchhome/$sw1.ctl macbr=$macbr macif1=$macif1 sw1=$sw1 else macif2=$7 sw2=$8 if [ -z "$9" ]; then #echo "screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ r umlid=$hostname hostname=$hostname role=$role eth0=daemon,,unix,$home/switch/$sw1 eth1=daemon,,unix,$home/switch/$sw2 macbr=$macbr macif1=$macif1 sw1=$sw1 macif2=$macif2 sw2=$sw2" screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ r umlid=$hostname hostname=$hostname role=$role eth0=daemon,,unix,$switchhome/$sw1.ctl eth1=daemon,,unix,$switchhome/$sw2.ctl macbr=$macbr macif1=$macif1 sw1=$sw1 macif2=$macif2 sw2=$sw2 else macif3=$9 sw3=$10 #echo "screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ r umlid=$hostname hostname=$hostname role=$role eth0=daemon,,unix,$switchhome/$sw1.ctl eth1=daemon,,unix,$switchhome/$sw2.ctl eth2=daemon,,unix,$switchhome/$sw3.ctl macbr=$macbr macif1=$macif1 sw1=$sw1 macif2=$macif2 sw2=$sw2 macif3=$macif3 sw3=$sw3" screen -d -m -S $hostname linux.uml rootfstype=hostfs rootflags=$home/ r umlid=$hostname hostname=$hostname role=$role eth0=daemon,,unix,$switchhome/$sw1.ctl eth1=daemon,,unix,$switchhome/$sw2.ctl eth2=daemon,,unix,$switchhome/$sw3.ctl macbr=$macbr macif1=$macif1 sw1=$sw1 macif2=$macif2 sw2=$sw2 macif3=$macif3 sw3=$sw3 fi fi echo "bridge $hostname started" ;;
</code>
+ change in rcS on UML instances. It will change the MAC address of each interface of each bridge accordingly (AA:BB:CC:DD:<Bridge ID>:<port ID>). And assign MAC address (AA:BB:CC:DD:<Bridge ID>:AA) to bridge. + <code bash>
bridge)
echo "bridge: $hostname" mount -t hostfs none /lib/modules/ -o /usr/lib/uml/modules modprobe llc modprobe stp modprobe bridge
#add br and interfaces
/bin/brctl addbr $hostname ifconfig $hostname hw ether $macbr
if [ ! -z $macif1 ]; then ifconfig eth0 hw ether $macif1 up /bin/brctl addif $hostname eth0 fi if [ ! -z $macif2 ]; then ifconfig eth1 hw ether $macif2 up /bin/brctl addif $hostname eth1 fi if [ ! -z $macif3 ]; then ifconfig eth2 hw ether $macif3 up /bin/brctl addif $hostname eth2 fi
/bin/brctl stp $hostname on ifconfig $hostname up echo "INFO: bridge $hostname activated" ;;
</code>
Witnessing the start-up
Describe in detail (i.e. your own words, not verbatim dumps) what packets are sent, when and why.
What parameters are used in the packets and what are the set to (timing parameters in the BPDU packets etcetera. . . )?
Does the witnessed behaviour of the protocol deviate in any way from the official specification?
<hi #808000>Improvement</hi> Yes. The strange issue I saw is that when there is no change on the network, the TC bit will all of sudden be set. and last for about 36 seconds. Please see the following packets.
179 28.210945 aa:bb:cc:dd:01:01 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8001 18 28.217348 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 180 30.213560 aa:bb:cc:dd:01:01 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8001 19 30.220059 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 . . 35 62.213755 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 197 64.209801 aa:bb:cc:dd:01:01 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8001
This situation happen more than one time, please see the packets below
320 318.064784 aa:bb:cc:dd:02:01 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:02:aa Cost = 0 Port = 0x8001 151 318.071218 aa:bb:cc:dd:02:02 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:02:aa Cost = 0 Port = 0x8002 . . 162 340.070109 aa:bb:cc:dd:02:02 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:02:aa Cost = 0 Port = 0x8002
The TC bit does not get cleared after packet 162 at 340 second. But my capture file stopped here. This is more likely to be a implementation error in the software.
Below the read out of tcpdump of the captured packets with option xx and vv
21:48:35.148686 STP 802.1d, Config, Flags [none], bridge-id 8000.aa:bb:cc:dd:01:aa.8001, length 35 message-age 0.00s, max-age 20.00s, hello-time 2.00s, forwarding-delay 15.00s root-id 8000.aa:bb:cc:dd:01:aa, root-pathcost 0 0x0000: 0180 c200 0000 aabb ccdd 0101 0026 4242 0x0010: 0300 0000 0000 8000 aabb ccdd 01aa 0000 0x0020: 0000 8000 aabb ccdd 01aa 8001 0000 1400 0x0030: 0200 0f00
It is possible to do the full analysis by using tcpdump, but it is just so much easier if we use Wireshark a GUI tool with lots of easy to use built in functions, like merge the dump file, make time line and sort according to different fields.
Network 1
The following image shows how the tree look like after the convergence. Bridge1 is elected as the root bridge. And both port 1 of the other two bridges are used as root port, and both port 2 are blocked.
The result of my STP caculation:
+ Bridge 1: by running brctl showstp br1 + <code bash>
/ # brctl showstp br1 br1 bridge id 8000.aabbccdd01aa designated root 8000.aabbccdd01aa root port 0 path cost 0 max age 20.00 bridge max age 20.00 hello time 2.00 bridge hello time 2.00 forward delay 15.00 bridge forward delay 15.00 ageing time 300.00 hello timer 1.23 tcn timer 0.00 topology change timer 0.00 gc timer 15.23 flags
eth0 (1) port id 8001 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 0.00 designated port 8001 forward delay timer 0.00 designated cost 0 hold timer 0.23 flags
eth1 (2) port id 8002 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 0.00 designated port 8002 forward delay timer 0.00 designated cost 0 hold timer 0.23 flags </code>
+ Bridge 2: by running brctl showstp br2 + <code bash>
/ # brctl showstp br2 br2 bridge id 8000.aabbccdd02aa designated root 8000.aabbccdd01aa root port 1 path cost 100 max age 20.00 bridge max age 20.00 hello time 2.00 bridge hello time 2.00 forward delay 15.00 bridge forward delay 15.00 ageing time 300.00 hello timer 0.00 tcn timer 0.00 topology change timer 0.00 gc timer 9.96 flags
eth0 (1) port id 8001 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 19.84 designated port 8001 forward delay timer 0.00 designated cost 0 hold timer 0.00 flags
eth1 (2) port id 8002 state blocking designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 19.84 designated port 8002 forward delay timer 0.00 designated cost 0 hold timer 0.00 flags
</code>
+ Bridge 3: by running brctl showstp br3 + <code bash>
/ # brctl showstp br3 br3 bridge id 8000.aabbccdd03aa designated root 8000.aabbccdd01aa root port 1 path cost 100 max age 20.00 bridge max age 20.00 hello time 2.00 bridge hello time 2.00 forward delay 15.00 bridge forward delay 15.00 ageing time 300.00 hello timer 0.00 tcn timer 0.00 topology change timer 0.00 gc timer 12.84 flags
eth0 (1) port id 8001 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 18.77 designated port 8001 forward delay timer 0.00 designated cost 0 hold timer 0.00 flags
eth1 (2) port id 8002 state blocking designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 18.77 designated port 8002 forward delay timer 0.00 designated cost 0 hold timer 0.00 flags </code>
Now we take a closer look into the captured file.
Below are the first 6 packets I got from the capture. Every bridge start by announcing themselves as the root, on all the ports, however with one exception which is the port 2 of bridge 2, as it may has heard of bridge 1 earlier than announcing itself as root, it starts broadcast bridge1 as the root and give cost of 100.
#bridge 3 1 0.000000 aa:bb:cc:dd:03:01 Spanning-tree-(for-bridges)_00 STP Conf. Root = 32768/0/aa:bb:cc:dd:03:aa Cost = 0 Port = 0x8001 4 0.010066 aa:bb:cc:dd:03:02 Spanning-tree-(for-bridges)_00 STP Conf. Root = 32768/0/aa:bb:cc:dd:03:aa Cost = 0 Port = 0x8002 #bridge 1 2 0.000208 aa:bb:cc:dd:01:01 Spanning-tree-(for-bridges)_00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8001 5 0.010070 aa:bb:cc:dd:01:02 Spanning-tree-(for-bridges)_00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 #bridge 2 3 0.000632 aa:bb:cc:dd:02:01 Spanning-tree-(for-bridges)_00 STP Conf. Root = 32768/0/aa:bb:cc:dd:02:aa Cost = 0 Port = 0x8001 6 0.011331 aa:bb:cc:dd:02:02 Spanning-tree-(for-bridges)_00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8002
The BPDUs are flooded to Spanning-tree-(for-bridges)_00 (01:80:c2:00:00:00), so every STP talking bridge should receive them. In this case, bridge3 boot up quickly and start the STP election first by broadcast itself as the root on both of his port. The port 1 of bridge 1 start in between and broadcast also itself as the root on both of its port.
Bridge2 starts latest among the three. Its port1 is broadcasting itself as the root, but port2 is broadcasting bridge1 as the root bridge, as it may has received the earlier sent BPDU by others (bridge1 and/or bridge3). Since every bridge is using the same priority (32768), which is also broadcast in the BPDU, we do need the tie breaker here. The MAC address is therefor used. That's why finally bridge1 is elected as the root with lowest MAC address (aa:bb:cc:dd:01:aa).
The BPDUs are sent in the interval of 2 seconds through out the whole procedure. However, after the election, only the root bridge will keep sending out BPDUs. Others only listen.
All the ports enter listening mode first, after the root bridge is elected, they will enter learning port. Then after the forwarding delay (15 seconds) they enter the forward mode.
Many parameters are sent in the BPDU packets
- source (MAC of originating ports) and destination (01:80:c2:00:00:00 STP bridge) addresses
- BPDU flag
- TCN (topology change)
- TCA (acknowledge of TCN)
- BPDU type (configuration, TCN, TCA)
- root id (root brdige id)
- bridge id (bridge's own id)
- cost (cost to root)
- port id (originating port)
- bridge priority (32768)
- message age (start with 0)
- max age (20)
- Hello time (2)
- forward delay (15)
What happens if the topology changes?
Depending on the role of the down port of bridge, the STP will behave differently. If it is not a port on the root bridge, the bridge will just unblock the formerly blocked port and the network flow will not be disturbed. But in case of a root port or root bridge down, the topology of the whole network will be changed, hence a TCN will be triggered and acknowledged by others.
What happens if you disturb the network by shutting down the root bridge?
<hi #808000>Improvement: Does the witnessed behaviour of the protocol deviate in any way from the official specification?</hi>
I did not notice any abnormal behavior in the log nor on the bridges. The STP on each bridge just behave like described in the book and slides of Karst.
Explore as many possibilities for situations that could/should/may give rise to problems as can be imagined (i.e. more than one), describe them and then test them.
I turn off STP on bridge1 (root). So a new election is needed. However, it will not happen until the max age (20 seconds) is reached. We can see this clearly from the capture below
126 118.339826 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 127 138.334867 aa:bb:cc:dd:03:01 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:03:aa Cost = 0 Port = 0x8001 128 138.334869 aa:bb:cc:dd:02:01 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:02:aa Cost = 0 Port = 0x8001 129 138.335206 aa:bb:cc:dd:03:01 01:80:c2:00:00:00 STP Topology Change Notification
<hi #808000>Improvement</hi>
Bridge2 is elected as the new root bridge, as it has lowest bridge ID (MAC address) and port 1 and 2 of it are serving as the DP.
br2 bridge id 8000.aabbccdd02aa designated root 8000.aabbccdd02aa root port 0 path cost 0 max age 20.00 bridge max age 20.00 hello time 2.00 bridge hello time 2.00 forward delay 15.00 bridge forward delay 15.00 ageing time 300.00 hello timer 1.87 tcn timer 0.00 topology change timer 0.00 gc timer 7.87 flags eth0 (1) port id 8001 state forwarding designated root 8000.aabbccdd02aa path cost 100 designated bridge 8000.aabbccdd02aa message age timer 0.00 designated port 8001 forward delay timer 0.00 designated cost 0 hold timer 0.87 flags eth1 (2) port id 8002 state forwarding designated root 8000.aabbccdd02aa path cost 100 designated bridge 8000.aabbccdd02aa message age timer 0.00 designated port 8002 forward delay timer 0.00 designated cost 0 hold timer 0.87 flags
bridge3 port 1 is the root port for bridge3. It has lower port ID (0x8001), so it preferred over port2 (0x8002)
/ # brctl showstp br3 br3 bridge id 8000.aabbccdd03aa designated root 8000.aabbccdd02aa root port 1 path cost 100 max age 20.00 bridge max age 20.00 hello time 2.00 bridge hello time 2.00 forward delay 15.00 bridge forward delay 15.00 ageing time 300.00 hello timer 0.00 tcn timer 0.00 topology change timer 0.00 gc timer 3.86 flags eth0 (1) port id 8001 state forwarding designated root 8000.aabbccdd02aa path cost 100 designated bridge 8000.aabbccdd02aa message age timer 19.71 designated port 8001 forward delay timer 0.00 designated cost 0 hold timer 0.00 flags eth1 (2) port id 8002 state blocking designated root 8000.aabbccdd02aa path cost 100 designated bridge 8000.aabbccdd02aa message age timer 19.71 designated port 8002 forward delay timer 0.00 designated cost 0 hold timer 0.00 flags
BPDU number 126 (time 118), we still have bridge 1 as the root and the root is then brought down by me. BPDU number 127 (time 138, which is 20 seconds later), bridge 3 reached max age and start sending out BPDU to announce that there is a topological change and itself should be the new root. In BPDU 128 (time 138), bridge 2 does the same. A new election hence should be started. Probably, in this round bridge2 will become the new root, due to the lower bridge id. At almost the same time, bridge 3 send out the TCN to yield that there is a change on topology.
As shown below,
129 138.335206 aa:bb:cc:dd:03:01 01:80:c2:00:00:00 STP Topology Change Notification 136 138.346604 aa:bb:cc:dd:03:01 01:80:c2:00:00:00 STP Topology Change Notification 137 139.421463 aa:bb:cc:dd:02:01 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:02:aa Cost = 0 Port = 0x8001 138 139.432378 aa:bb:cc:dd:02:01 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:02:aa Cost = 0 Port = 0x8001
The TCN is sent in a very high frequency. Same goes with the TCA. As each of the TCN will be acknowledged by a TCA. The TCA is a normal looking BPDU packet with only the BPDU flag TCA bit set while TCN is a packet in different form. It is a packet without content and only has the BPDU type set to 0x80. Interesting enough, if we do not look at the content and TC flag of TCA, we will have the flag of TCA also as 0x80.
Now bridge2 takes over the role as root bridge. And broadcast in every 2 seconds the BPDU.
investigate more cases
- Turn back on the bridge 1
In the same network, I turn on the previously turned off bridge1. It starts broadcasting BPDU to announce itself as the root. And amazingly enough, in such a huge change of topology. There is no TCN nor TC flag. Both bridge2 and 3 will quietly accept it and use bridge1 as the root again.
184 185.325847 aa:bb:cc:dd:01:01 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8001 185 185.336085 aa:bb:cc:dd:02:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8002 186 185.336599 aa:bb:cc:dd:03:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8002 187 185.336928 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 188 186.322706 aa:bb:cc:dd:01:01 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8001 189 186.333423 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002
<hi #808000>Improvement</hi>
126 118.339826 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002
This is the last BPDU from previous root bridge 1 at time 118 second.
172 172.427118 aa:bb:cc:dd:02:01 01:80:c2:00:00:00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:02:aa Cost = 0 Port = 0x8001 173 174.414214 aa:bb:cc:dd:02:01 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:02:aa Cost = 0 Port = 0x8001
This 172 packet is the last packet from new root bridge 2 with TC set. After that it broadcasts normal 2 second's BPDU.
184 185.325847 aa:bb:cc:dd:01:01 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8001
This is the first packet from re-turn on bridge1 at time 185 second.
Next all the bridges just send BPDU to compete for the root role
185 185.336085 aa:bb:cc:dd:02:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8002 186 185.336599 aa:bb:cc:dd:03:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8002 187 185.336928 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 188 186.322706 aa:bb:cc:dd:01:01 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8001 189 186.333423 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002
No TC, no TCN, no TCA. Only the down of the root bridge will be notified via TCN and TC. The join of a “better” root is not notified via these packets. A new election just happen and every other bridges follow quietly.
network 2
Result of STP calculation
+ Bridge 1 (root) + <code bash>
/ # brctl showstp br1 br1 bridge id 8000.aabbccdd01aa designated root 8000.aabbccdd01aa root port 0 path cost 0 max age 20.00 bridge max age 20.00 hello time 2.00 bridge hello time 2.00 forward delay 15.00 bridge forward delay 15.00 ageing time 300.00 hello timer 1.72 tcn timer 0.00 topology change timer 4.84 gc timer 1.72 flags TOPOLOGY_CHANGE TOPOLOGY_CHANGE_DETECTED
eth0 (1) port id 8001 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 0.00 designated port 8001 forward delay timer 0.00 designated cost 0 hold timer 0.72 flags
eth1 (2) port id 8002 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 0.00 designated port 8002 forward delay timer 0.00 designated cost 0 hold timer 0.72 flags
eth2 (3) port id 8003 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 0.00 designated port 8003 forward delay timer 0.00 designated cost 0 hold timer 0.72 flags </code>
+ Bridge 2 + <code bash>
/ # brctl showstp br2 br2 bridge id 8000.aabbccdd02aa designated root 8000.aabbccdd01aa root port 2 path cost 100 max age 20.00 bridge max age 20.00 hello time 2.00 bridge hello time 2.00 forward delay 15.00 bridge forward delay 15.00 ageing time 300.00 hello timer 0.00 tcn timer 0.00 topology change timer 0.00 gc timer 15.04 flags
eth0 (1) port id 8001 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd02aa message age timer 0.00 designated port 8001 forward delay timer 0.00 designated cost 100 hold timer 1.04 flags
eth1 (2) port id 8002 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 19.92 designated port 8002 forward delay timer 0.00 designated cost 0 hold timer 0.00 flags
eth2 (3) port id 8003 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd02aa message age timer 0.00 designated port 8003 forward delay timer 0.00 designated cost 100 hold timer 1.04 flags </code>
+ Bridge 3 + <code bash>
/ # brctl showstp br3 br3 bridge id 8000.aabbccdd03aa designated root 8000.aabbccdd01aa root port 3 path cost 100 max age 20.00 bridge max age 20.00 hello time 2.00 bridge hello time 2.00 forward delay 15.00 bridge forward delay 15.00 ageing time 300.00 hello timer 0.00 tcn timer 0.00 topology change timer 0.00 gc timer 6.92 flags
eth0 (1) port id 8001 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd03aa message age timer 0.00 designated port 8001 forward delay timer 0.00 designated cost 100 hold timer 0.92 flags
eth1 (2) port id 8002 state blocking designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd02aa message age timer 19.92 designated port 8003 forward delay timer 0.00 designated cost 100 hold timer 0.00 flags
eth2 (3) port id 8003 state forwarding designated root 8000.aabbccdd01aa path cost 100 designated bridge 8000.aabbccdd01aa message age timer 19.93 designated port 8003 forward delay timer 0.00 designated cost 0 hold timer 0.00 flags </code>
This is a more complicated setting than network 1, in the sense that not only bridge 1 (root) is sending period BPDU but also bridge 2 is sending BPDU on port 3 (connected to bridge3) with weight 100, to tell bridge 3 that it has a route to root bridge with cost 100.
1 0.000000 aa:bb:cc:dd:03:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:03:aa Cost = 0 Port = 0x8002 2 0.000455 aa:bb:cc:dd:02:03 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:02:aa Cost = 0 Port = 0x8003 3 0.074078 aa:bb:cc:dd:03:03 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:03:aa Cost = 0 Port = 0x8003 4 0.074313 aa:bb:cc:dd:01:03 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8003 5 0.140022 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 6 0.991514 aa:bb:cc:dd:03:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8002 7 1.066574 aa:bb:cc:dd:01:03 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8003 8 1.113405 aa:bb:cc:dd:02:03 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8003 9 2.033120 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 10 2.068905 aa:bb:cc:dd:01:03 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8003 11 2.116324 aa:bb:cc:dd:02:03 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8003 12 3.993914 aa:bb:cc:dd:02:03 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8003 13 4.031611 aa:bb:cc:dd:01:02 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 14 4.068319 aa:bb:cc:dd:01:03 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8003 15 5.998564 aa:bb:cc:dd:02:03 01:80:c2:00:00:00 STP Conf. Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8003
Only the first 12 BPDUs are related to the root election. The later three (13 to 15) are period BPDUs. Two sent by root bridge with cost 0, and one sent by port 3 of bridge 2, which is connected to the blocking port of bridge 3. This shows that even if the port is in the state of blocking it is still taking part in the STP and listening to BPDUs.
If I turn off the port 3 on bridge 3 which is the root port for it, port 2 will immediately be put into listening state. And send out BPDU to announce itself as root. Only after the first receipt of the root BPDU, it will use the lower root id bridge as the root. Port two will then be put into learning mode, after 15 seconds' forward delay, it will be in forwarding state.
If I shutdown the root bridge in this setting, it does not make too much sense, as there is no fault tolerance in the network. If any one of the bridge, it will break the current network setting and leave us with a totally different two bridge network. The reachability of the hosts is gone. However, let's suppose the root bridge 1 is down. Then host1 will be disconnected from the rest of the network, and bridge 2 will be the new root.
Analyse both networks using the above approach.
<hi #808000>You can turn off individual ports on the bridges. In that case there is fault tolerance! Network 2 needs more work (more tests)</hi>
I will first turn off one of the ports on root bridge, in this case bridge1 port 2. As there is no more direct link to root from bridge 2, bridge2's port to port 1 on root should be blocked, however, since the connected root port is down, it will not receive BPDU, so it will not be put into block mode, rather it will stay in the forwarding mode broadcast BPDU to the UML hub. Its port to bridge3 should be left untouched in forwarding state. Port on bridge3 to bridge2 become DP, the other one should become RP. Let's see if it works as expected.
port 2 on root brdige1 is down, below is the message on bridge2
br2: neighbor 8000.aa:bb:cc:dd:01:aa lost on port 2(eth1) br2: topology change detected, propagating
Next, the previously blocked port of bridge3 will be bring up. And there is TCN generated to announce the change of topology as we can see from the message below.
br3: port 3(eth2) entering learning state br3: topology change detected, sending tcn bpdu
So everything works as expected. In a triangle topology even one port is down does not take down the whole network. We can conclude certain level of fault tolerance. But not as high as in network 1.
Next, I bring back the disabled port on root, wait till the network re-convergence. Then try to disable a port on bridge3's RP. Just to see how smooth the switch of port state can be. And how fast it can be.
turn down the interface on bridge3 to root bridge 1
/ # ifconfig eth2 down br3: port 3(eth2) entering disabled state br3: port 2(eth1) entering listening state
immediately, the previously blocked port 2 enter listening state. Same time, the TCNs are sent from two bridges
182 115.006268 aa:bb:cc:dd:02:02 Spanning-tree-(for-bridges)_00 STP Topology Change Notification 183 115.040180 aa:bb:cc:dd:03:02 Spanning-tree-(for-bridges)_00 STP Topology Change Notification
bridge3 is the the place where the change occurs, but maybe it is too busy with the change, bridge2 is just a tiny bit faster in sending out the TCN.
186 116.415578 aa:bb:cc:dd:01:03 Spanning-tree-(for-bridges)_00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8003 187 116.589078 aa:bb:cc:dd:01:02 Spanning-tree-(for-bridges)_00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 188 116.653639 aa:bb:cc:dd:02:03 Spanning-tree-(for-bridges)_00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8003
The the patent of the repetation of the BPDUs goes back to normal. bridge1 is still the root, so both of its ports are sending out BPDUs. And bridge2 port 3 became DP for bridge3, and sending out BPDU. Its port 2 is the RP. bridge3's port 2 is disabled. And port3 is used as RP.
The switch is real fast and smooth, from the above packets we can calcute that the total process of switching takes only around 1.5 seconds. It is the full convergence time, if we look at the packets below, the time of convergence should be reduced to half a second
184 115.588295 aa:bb:cc:dd:01:02 Spanning-tree-(for-bridges)_00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 0 Port = 0x8002 BPDU flags: 0x81 (Topology Change Acknowledgment, Topology Change) 185 115.652761 aa:bb:cc:dd:02:03 Spanning-tree-(for-bridges)_00 STP Conf. TC + Root = 32768/0/aa:bb:cc:dd:01:aa Cost = 100 Port = 0x8003 BPDU flags: 0x81 (Topology Change Acknowledgment, Topology Change)
Make a thorough comparison between the analyses of both networks.
Are the observations the same for both networks? What, if any, are the differences?
network 1 is smaller in size but complicated topology wise due to the loops created by the connections to the switches. It probably takes more CPU cycles from the bridge to run STP algorithm.
<hi #808000>Improvement: why netowrk 1 take more CPU cycles on STP</hi>
There are 3 portential loops in first network: bridge 1 and 2, bridge 1 and 3, bridge 2 and 3. There are even more combinations with up/down ports to form more complicated issues. However, in network2, there is max one physical loop as it is a triangle. STP is the protocol created with loop emission as goal, it will have to work harder within a heavy loop environment.
But network 1 comes with more fault tolerance than network 2. there are three redundant links between hosts. Any two bridges can be down, and at most 4 connections can be down, as long as the broken links comes in pairs. In network 2, with only one bridge down the host connected to it will be inaccessible.
STP is not sticky and deterministic. If the election criteria keeps the same, like bridge id, port id and etc, the root bridge will always be the same one. Even after it went down for a while, after it came back online, it will take over the root role smoothly.