I'm trying to create a lab in GNS3 with docker containers to understand more about spanning-tree. My lab is very simple: there are two Linux/Alpine containers with two links connecting them:
-------- --------
| SW-1 | et2 -------------------------------- et2 | SW-2 |
| | et3 -------------------------------- et3 | |
-------- --------
Each has a bridge br0
configured with the following:
ifconfig eth2 down
ifconfig eth3 down
brctl addbr br0
brctl addif br0 eth2
brctl addif br0 eth3
brctl stp br0 on
ifconfig eth2 0.0.0.0 up
ifconfig eth3 0.0.0.0 up
ifconfig br0 up
The bridges are up, the modules are loaded and stp seems to be running fine in each host but they don't converge. All ports are kept forwarding and L2 pkts keep looping indefinitely:
# BOTH SW-1 and SW-2:
# lsmod | egrep -i 'bridge|stp'
bridge 352256 1 br_netfilter
stp 16384 1 bridge
llc 16384 2 bridge,stp
SW-1:
br0
bridge id 8000.8615aca70489
designated root 8000.8615aca70489 <<== SW-1 believes it is the root
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 0.36 tcn timer 0.00
topology change timer 0.00 gc timer 116.61
flags
eth3 (2)
port id 8002 state forwarding
designated root 8000.8615aca70489 path cost 100
designated bridge 8000.8615aca70489 message age timer 0.00
designated port 8002 forward delay timer 0.00
designated cost 0 hold timer 0.00
flags
eth2 (1)
port id 8001 state forwarding
designated root 8000.8615aca70489 path cost 100
designated bridge 8000.8615aca70489 message age timer 0.00
designated port 8001 forward delay timer 0.00
designated cost 0 hold timer 0.00
flags
SW-2:
br0
bridge id 8000.16d0f207e210
designated root 8000.16d0f207e210 <<== SW-2 believes it is the root
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 0.57 tcn timer 0.00
topology change timer 0.00 gc timer 116.61
flags
eth3 (2)
port id 8002 state forwarding
designated root 8000.16d0f207e210 path cost 100
designated bridge 8000.16d0f207e210 message age timer 0.00
designated port 8002 forward delay timer 0.00
designated cost 0 hold timer 0.00
flags
eth2 (1)
port id 8001 state forwarding
designated root 8000.16d0f207e210 path cost 100
designated bridge 8000.16d0f207e210 message age timer 0.00
designated port 8001 forward delay timer 0.00
designated cost 0 hold timer 0.00
flags
When I ran tcpdump
on eth2
and eth3
on both devices, I see the BPDUs being sent/received but, apparently, each device is ignoring the BDPU from the other (btw, load avg spikes up in my machine due to the loop) :
SW-1:
Spanning Tree Protocol
Protocol Identifier: Spanning Tree Protocol (0x0000)
Protocol Version Identifier: Spanning Tree (0)
BPDU Type: Configuration (0x00)
BPDU flags: 0x00
0... .... = Topology Change Acknowledgment: No
.... ...0 = Topology Change: No
Root Identifier: 32768 / 0 / 86:15:ac:a7:04:89
Root Bridge Priority: 32768
Root Bridge System ID Extension: 0
Root Bridge System ID: 86:15:ac:a7:04:89 (86:15:ac:a7:04:89)
Root Path Cost: 0
Bridge Identifier: 32768 / 0 / 86:15:ac:a7:04:89
Bridge Priority: 32768
Bridge System ID Extension: 0
Bridge System ID: 86:15:ac:a7:04:89 (86:15:ac:a7:04:89)
Port identifier: 0x8002
Message Age: 0
Max Age: 20
Hello Time: 2
Forward Delay: 15
SW-2:
Spanning Tree Protocol
Protocol Identifier: Spanning Tree Protocol (0x0000)
Protocol Version Identifier: Spanning Tree (0)
BPDU Type: Configuration (0x00)
BPDU flags: 0x00
0... .... = Topology Change Acknowledgment: No
.... ...0 = Topology Change: No
Root Identifier: 32768 / 0 / 16:d0:f2:07:e2:10
Root Bridge Priority: 32768
Root Bridge System ID Extension: 0
Root Bridge System ID: 16:d0:f2:07:e2:10 (16:d0:f2:07:e2:10)
Root Path Cost: 0
Bridge Identifier: 32768 / 0 / 16:d0:f2:07:e2:10
Bridge Priority: 32768
Bridge System ID Extension: 0
Bridge System ID: 16:d0:f2:07:e2:10 (16:d0:f2:07:e2:10)
Port identifier: 0x8002
Message Age: 0
Max Age: 20
Hello Time: 2
Forward Delay: 15
Each keep telling the other it is the Root bridge. It doesn't matter if I wait a few minutes. dmesg
shows nothing but:
[37533.507941] br0: received packet on eth2 with own address as source address (addr:86:15:ac:a7:04:89, vlan:0)
[37533.507942] br0: received packet on eth3 with own address as source address (addr:86:15:ac:a7:04:89, vlan:0)
AFAIK, bridges are not aware of VLANs. I tried anyway to set the the default_pvid
for this bridge to 0
but it made no difference. There are no ebtable
filters rule applied and I zeroed all files at /proc/sys/net/bridge/
too. I don't see a reason why the BPDUs are not consumed and the devices eventually converge.
I've tried the same experiment with just one link connecting the bridges (ie, no loops) and a host behind each connected to another interface, configured static IP addresses in the hosts and successfully pinged one another, ie, the bridges are switching the packets:
-------- --------
| SW-1 | et2 -------------------------------- et2 | SW-2 |
-------- --------
et1 et1
| |
host1 host2
I've also tried replacing the containers by openvswitch
and proprietary images and it worked fine. Any ideas?