Skip to content

Instantly share code, notes, and snippets.

@lantz
Last active December 30, 2023 14:26
Show Gist options
  • Save lantz/7853026 to your computer and use it in GitHub Desktop.
Save lantz/7853026 to your computer and use it in GitHub Desktop.
(Evil) Spanning Tree Protocol (STP) using Open vSwitch
#!/usr/bin/python
"""
OVS Bridge with Spanning Tree Protocol
Note: STP bridges don't start forwarding until
after STP has converged, which can take a while!
See below for a command to wait until STP is up.
Example:
mn -v output --custom torus2.py --switch ovs-stp --topo torus,3,3
mininet> sh time bash -c 'while ! ovs-ofctl show s1x1 | grep FORWARD; do sleep 1; done'
...
0.01user 0.13system 0:28.22elapsed 0%CPU (0avgtext+0avgdata 1828maxresident)k
0inputs+0outputs (0major+36846minor)pagefaults 0swaps
mininet> pingall
*** Ping: testing ping reachability
h1x1 -> h1x2 h1x3 h2x1 h2x2 h2x3 h3x1 h3x2 h3x3
...
"""
from mininet.node import OVSSwitch
class OVSBridgeSTP( OVSSwitch ):
"""Open vSwitch Ethernet bridge with Spanning Tree Protocol
rooted at the first bridge that is created"""
prio = 1000
def start( self, *args, **kwargs ):
OVSSwitch.start( self, *args, **kwargs )
OVSBridgeSTP.prio += 1
self.cmd( 'ovs-vsctl set-fail-mode', self, 'standalone' )
self.cmd( 'ovs-vsctl set-controller', self )
self.cmd( 'ovs-vsctl set Bridge', self,
'stp_enable=true',
'other_config:stp-priority=%d' % OVSBridgeSTP.prio )
switches = { 'ovs-stp': OVSBridgeSTP }
#!/usr/bin/python
from mininet.net import Mininet
from mininet.topo import Topo
from mininet.node import OVSSwitch
"""
This example shows how to create a rich topology
(2-d torus) and then remove most of its benefits
by using OVS bridges with STP turned on.
Note: STP bridges don't start forwarding until
after STP has converged, which can take a while.
See below for a command to wait until STP is up.
Example:
mn -v output --custom torus-stp.py --switch ovs-stp --topo torus,3,3
mininet> sh time bash -c 'while ! ovs-ofctl show s1x1 | grep FORWARD; do sleep 1; done'
...
0.01user 0.13system 0:28.22elapsed 0%CPU (0avgtext+0avgdata 1828maxresident)k
0inputs+0outputs (0major+36846minor)pagefaults 0swaps
mininet> pingall
*** Ping: testing ping reachability
h1x1 -> h1x2 h1x3 h2x1 h2x2 h2x3 h3x1 h3x2 h3x3
...
"""
class OVSBridgeSTP( OVSSwitch ):
"""Open vSwitch Ethernet bridge with Spanning Tree Protocol
rooted at the first bridge that is created"""
prio = 1000
def start( self, *args, **kwargs ):
OVSSwitch.start( self, *args, **kwargs )
OVSBridgeSTP.prio += 1
self.cmd( 'ovs-vsctl set-fail-mode', self, 'standalone' )
self.cmd( 'ovs-vsctl set-controller', self )
self.cmd( 'ovs-vsctl set Bridge', self,
'stp_enable=true',
'other_config:stp-priority=%d' % OVSBridgeSTP.prio )
switches = { 'ovs-stp': OVSBridgeSTP }
class TorusTopo( Topo ):
"Torus topology"
def __init__( self, x, y, *args, **kwargs ):
Topo.__init__( self, *args, **kwargs )
if x < 3 or y < 3:
raise Exception( 'Please use 3x3 or greater for compatibility '
'with Mininet 2.1.0' )
hosts, switches, dpid = {}, {}, 0
# Create and wire interior
for i in range( 0, x ):
for j in range( 0, y ):
loc = '%dx%d' % ( i + 1, j + 1 )
# dpid cannot be zero for OVS
dpid = ( i + 1 ) * 256 + ( j + 1 )
switch = switches[ i, j ] = self.addSwitch(
's' + loc, dpid='%016x' % dpid )
host = hosts[ i, j ] = self.addHost( 'h' + loc )
self.addLink( host, switch )
# Connect switches
for i in range( 0, x ):
for j in range( 0, y ):
sw1 = switches[ i, j ]
sw2 = switches[ i, ( j + 1 ) % y ]
sw3 = switches[ ( i + 1 ) % x, j ]
self.addLink( sw1, sw2 )
self.addLink( sw1, sw3 )
topos = { 'torus': TorusTopo }
#!/usr/bin/python
from mininet.topo import Topo
class TorusTopo( Topo ):
"""2-D Torus topology
WARNING: this topology has LOOPS and WILL NOT WORK
with the default controller or any Ethernet bridge
without STP turned on"""
def __init__( self, x, y, *args, **kwargs ):
Topo.__init__( self, *args, **kwargs )
if x < 3 or y < 3:
raise Exception( 'Please use 3x3 or greater for compatibility '
'with Mininet 2.1.0' )
hosts, switches, dpid = {}, {}, 0
# Create and wire interior
for i in range( 0, x ):
for j in range( 0, y ):
loc = '%dx%d' % ( i + 1, j + 1 )
# dpid cannot be zero for OVS
dpid = ( i + 1 ) * 256 + ( j + 1 )
switch = switches[ i, j ] = self.addSwitch(
's' + loc, dpid='%016x' % dpid )
host = hosts[ i, j ] = self.addHost( 'h' + loc )
self.addLink( host, switch )
# Connect switches
for i in range( 0, x ):
for j in range( 0, y ):
sw1 = switches[ i, j ]
sw2 = switches[ i, ( j + 1 ) % y ]
sw3 = switches[ ( i + 1 ) % x, j ]
self.addLink( sw1, sw2 )
self.addLink( sw1, sw3 )
topos = { 'torus': TorusTopo }
@vipinkrathi
Copy link

hi lantz have you ever used clos network instead of torus
and can i use some other protocol then stp
can you please explain why you use stp

@devendra23
Copy link

Hello lantz,
mn -v output --custom torus-stp.py --switch ovs-stp --topo torus,3,3
this command gives me Exception: could not find custom file: torus-stp.py
Also is there a way i can modify the spanning tree python files ?

Copy link

ghost commented Sep 2, 2016

How much time does it take to converge after entering the command "sh time bash -c 'while ! ovs-ofctl show s1x1 | grep FORWARD; do sleep 1; done'"?
I waited for 20 minutes and nothing happened.
And how can i check which ports are root ports and which links are down?

@Herikurr
Copy link

Hello lantz,
i have similar problem with Raufoon, am i missing something?

@FlorianHeigl
Copy link

@raufoon @Herikurr The normal timer is 30s for STP or 50ms for RSTP. If you wait over a minute, it's somehow broken.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment