- If there is a loop in the topology, the hosts cannot ping the others because https://github.com/mininet/mininet/wiki/FAQ#ethernet-loops
- Every time when I need to start mininet which supports a loop network, I have to add "--switch ovs,failMode=standalone,stp=1", it's so annoying.
- Every time when I try to start mininet with a custom topology, I have to add "--custum urfilename.py --topo urtopologyname", it's also annoying.
- Every time when I start mininet with spanning tree protocol enabled, I need to wait for a while to let STP converge. The only chance I could know whether it is converge is keep trying to pingall hosts.
- Although in https://github.com/mininet/mininet/wiki/FAQ#ethernet-loops a net.waitConnected() method is suggested, but this function seems doesn't work for me, and it doesn't work for a remote controller.
- I would like to write a python function to simplify these sh*ts, and construct a k=4 fat tree topology.
- To hard code a fat tree is exhausted, so the assignment also infer that "use 2-level for loops to construct it"
- SmallTreeTopo
class SmallTreeTopo(Topo):
host_list = []
switch_list = []
def __init__( self ):
# Initialize topology
Topo.__init__( self )
# Add hosts and switches---------------
host_P1_1 = self.addHost('10_0_0_2', ip='10.0.0.2')
host_P1_2 = self.addHost('10_0_0_3', ip='10.0.0.3')
host_P1_3 = self.addHost('10_0_1_2', ip='10.0.1.2')
host_P1_4 = self.addHost('10_0_1_3', ip='10.0.1.3')
self.host_list = ['10_0_0_2', '10_0_0_3', '10_0_1_2', '10_0_1_3']
# Switches
switch_E1_1 = self.addSwitch('10_0_0_1')
switch_E1_2 = self.addSwitch('10_0_1_1')
switch_A1_1 = self.addSwitch('10_0_2_1')
switch_A1_2 = self.addSwitch('10_0_3_1')
self.switch_list = ['10_0_0_1', '10_0_1_1', '10_0_2_1', '10_0_3_1']
# Add links ------------------------------
# POD 1: EDGE-HOSTS
self.addLink(switch_E1_1, host_P1_1)
self.addLink(switch_E1_1, host_P1_2)
self.addLink(switch_E1_2, host_P1_3)
self.addLink(switch_E1_2, host_P1_4)
# POD 1: AGGR-EDGE
self.addLink(switch_A1_1, switch_E1_1)
self.addLink(switch_A1_1, switch_E1_2)
self.addLink(switch_A1_2, switch_E1_1)
self.addLink(switch_A1_2, switch_E1_2)
- SmallTreeTopo is only "a pod" of a k=4 Fat Tree topology, so if someone try to add switches/hosts/links one by one, the file will be at least 4 times larger than this.- FatTreeTopo
class FatTreeTopo(Topo):
k = 4
host_list = []
switch_list = []
core_switch_object = []
aggr_switch_object = []
edge_switch_object = []
host_object = []
def __init__( self ):
"Create custom topo."
# Initialize topology
Topo.__init__( self )
# add switches and hosts
for i in range(self.k):
# add core switches
self.core_switch_object.append(self.addSwitch(
'10_%d_%d_%d' % (self.k, i/2+1, i%2+1)))
for j in range(self.k):
#add hosts
self.host_object.append(self.addHost(
'10_%d_%d_%d' % (i, j/2, j%2+2),
ip='10.%d.%d.%d' % (i, j/2, j%2+2)))
#add edge switches
if j < self.k:
self.edge_switch_object.append(self.addSwitch(
'10_%d_%d_1' % (i, j)))
#add aggr switches
else:
self.aggr_switch_object.append(self.addSwitch(
'10_%d_%d_1' % (i, j)))
self.host_list.extend(self.host_object)
self.switch_list.extend(self.core_switch_object)
self.switch_list.extend(self.aggr_switch_object)
self.switch_list.extend(self.edge_switch_object)
#add links
for switch in self.switch_list:
a, b, c, d = switch.split("_")
# core switches: connect to aggr switches
if int(b) == 4:
if int(c) == 1:
for i in range(4):
self.addLink(switch, "10_%d_2_1" % i)
elif int(c) == 2:
for i in range(4):
self.addLink(switch, "10_%d_3_1" % i)
# aggr switches: connect to edge switches
elif int(c) in (2, 3):
self.addLink(switch, "10_%d_0_1" % int(b))
self.addLink(switch, "10_%d_1_1" % int(b))
# edge switches: connect to hosts
elif int(d) == 1:
self.addLink(switch, "10_%d_%d_2" % (int(b), int(c)))
self.addLink(switch, "10_%d_%d_3" % (int(b), int(c)))
- Start mininet with this topology, and will see the following in the console.mininet@mininet-vm:~/cloudhw2$ sudo python mymininet.py -t fattree --stp *** Creating network *** Adding controller *** Adding hosts: 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 *** Adding switches: 10_0_0_1 10_0_1_1 10_0_2_1 10_0_3_1 10_1_0_1 10_1_1_1 10_1_2_1 10_1_3_1 10_2_0_1 10_2_1_1 10_2_2_1 10_2_3_1 10_3_0_1 10_3_1_1 10_3_2_1 10_3_3_1 10_4_1_1 10_4_1_2 10_4_2_1 10_4_2_2 *** Adding links: (10_0_0_1, 10_0_0_2) (10_0_0_1, 10_0_0_3) (10_0_1_1, 10_0_1_2) (10_0_1_1, 10_0_1_3) (10_0_2_1, 10_0_0_1) (10_0_2_1, 10_0_1_1) (10_0_3_1, 10_0_0_1) (10_0_3_1, 10_0_1_1) (10_1_0_1, 10_1_0_2) (10_1_0_1, 10_1_0_3) (10_1_1_1, 10_1_1_2) (10_1_1_1, 10_1_1_3) (10_1_2_1, 10_1_0_1) (10_1_2_1, 10_1_1_1) (10_1_3_1, 10_1_0_1) (10_1_3_1, 10_1_1_1) (10_2_0_1, 10_2_0_2) (10_2_0_1, 10_2_0_3) (10_2_1_1, 10_2_1_2) (10_2_1_1, 10_2_1_3) (10_2_2_1, 10_2_0_1) (10_2_2_1, 10_2_1_1) (10_2_3_1, 10_2_0_1) (10_2_3_1, 10_2_1_1) (10_3_0_1, 10_3_0_2) (10_3_0_1, 10_3_0_3) (10_3_1_1, 10_3_1_2) (10_3_1_1, 10_3_1_3) (10_3_2_1, 10_3_0_1) (10_3_2_1, 10_3_1_1) (10_3_3_1, 10_3_0_1) (10_3_3_1, 10_3_1_1) (10_4_1_1, 10_0_2_1) (10_4_1_1, 10_1_2_1) (10_4_1_1, 10_2_2_1) (10_4_1_1, 10_3_2_1) (10_4_1_2, 10_0_2_1) (10_4_1_2, 10_1_2_1) (10_4_1_2, 10_2_2_1) (10_4_1_2, 10_3_2_1) (10_4_2_1, 10_0_3_1) (10_4_2_1, 10_1_3_1) (10_4_2_1, 10_2_3_1) (10_4_2_1, 10_3_3_1) (10_4_2_2, 10_0_3_1) (10_4_2_2, 10_1_3_1) (10_4_2_2, 10_2_3_1) (10_4_2_2, 10_3_3_1) *** Configuring hosts 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 *** Starting controller c0 *** Starting 20 switches 10_0_0_1 10_0_1_1 10_0_2_1 10_0_3_1 10_1_0_1 10_1_1_1 10_1_2_1 10_1_3_1 10_2_0_1 10_2_1_1 10_2_2_1 10_2_3_1 10_3_0_1 10_3_1_1 10_3_2_1 10_3_3_1 10_4_1_1 10_4_1_2 10_4_2_1 10_4_2_2 ... *** Enabling STP 10_4_1_1 ... done 10_4_1_2 ... done 10_4_2_1 ... done 10_4_2_2 ... done 10_0_0_1 ... done 10_0_1_1 ... done 10_0_2_1 ... done 10_0_3_1 ... done 10_1_0_1 ... done 10_1_1_1 ... done 10_1_2_1 ... done 10_1_3_1 ... done 10_2_0_1 ... done 10_2_1_1 ... done 10_2_2_1 ... done 10_2_3_1 ... done 10_3_0_1 ... done 10_3_1_1 ... done 10_3_2_1 ... done 10_3_3_1 ... done Wait for STP converge ... Done! *** Starting CLI: mininet> pingall *** Ping: testing ping reachability 10_0_0_2 -> 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_0_0_3 -> 10_0_0_2 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_0_1_2 -> 10_0_0_2 10_0_0_3 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_0_1_3 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_1_0_2 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_1_0_3 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_1_1_2 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_1_1_3 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_2_0_2 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_2_0_3 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_2_1_2 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_2_1_3 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_3_0_2 10_3_0_3 10_3_1_2 10_3_1_3 10_3_0_2 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_3 10_3_1_2 10_3_1_3 10_3_0_3 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_1_2 10_3_1_3 10_3_1_2 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_3 10_3_1_3 -> 10_0_0_2 10_0_0_3 10_0_1_2 10_0_1_3 10_1_0_2 10_1_0_3 10_1_1_2 10_1_1_3 10_2_0_2 10_2_0_3 10_2_1_2 10_2_1_3 10_3_0_2 10_3_0_3 10_3_1_2 *** Results: 0% dropped (240/240 received) mininet> iperf *** Iperf: testing TCP bandwidth between 10_0_0_2 and 10_3_1_3 *** Results: ['14.9 Gbits/sec', '15.0 Gbits/sec'] mininet>- I have enabled stp in the main function and tried to write a small procedure to check the convergence of stp. As long as stp converges, pingall function works.
- The name of hosts and switches are assigned by their IP address(simply replace dots with "_"). The addressing method refers to http://ccr.sigcomm.org/online/files/p63-alfares.pdf
- Next step: Install RYU as controller!
can you show your mymininet.py file
回覆刪除