4 Test bandwidth (using iperf) on linear networks of varying size,
5 using both kernel and user datapaths.
7 We construct a network of N hosts and N-1 switches, connected as follows:
9 h1 <-> s1 <-> s2 .. sN-1
13 WARNING: by default, the reference controller only supports 16
14 switches, so this test WILL NOT WORK unless you have recompiled
15 your controller to support 100 switches (or more.)
17 In addition to testing the bandwidth across varying numbers
18 of switches, this example demonstrates:
20 - creating a custom topology, LinearTestTopo
21 - using the ping() and iperf() tests from Mininet()
22 - testing both the kernel and user switches
27 from mininet.net import Mininet
28 from mininet.node import UserSwitch, OVSKernelSwitch, Controller
29 from mininet.topo import Topo
30 from mininet.log import lg, info
31 from mininet.util import irange, quietRun
32 from mininet.link import TCLink
33 from functools import partial
36 flush = sys.stdout.flush
38 class LinearTestTopo( Topo ):
39 "Topology for a string of N hosts and N-1 switches."
41 def build( self, N, **params ):
42 # Create switches and hosts
43 hosts = [ self.addHost( 'h%s' % h )
44 for h in irange( 1, N ) ]
45 switches = [ self.addSwitch( 's%s' % s )
46 for s in irange( 1, N - 1 ) ]
50 for switch in switches:
52 self.addLink( last, switch )
56 self.addLink( hosts[ 0 ], switches[ 0 ] )
57 for host, switch in zip( hosts[ 1: ], switches ):
58 self.addLink( host, switch )
61 def linearBandwidthTest( lengths ):
63 "Check bandwidth at various lengths along a switch chain."
66 switchCount = max( lengths )
67 hostCount = switchCount + 1
69 switches = { 'reference user': UserSwitch,
70 'Open vSwitch kernel': OVSKernelSwitch }
72 # UserSwitch is horribly slow with recent kernels.
73 # We can reinstate it once its performance is fixed
74 del switches[ 'reference user' ]
76 topo = LinearTestTopo( hostCount )
79 output = quietRun( 'sysctl -w net.ipv4.tcp_congestion_control=reno' )
80 assert 'reno' in output
82 for datapath in switches.keys():
83 info( "*** testing", datapath, "datapath\n" )
84 Switch = switches[ datapath ]
85 results[ datapath ] = []
86 link = partial( TCLink, delay='2ms', bw=10 )
87 net = Mininet( topo=topo, switch=Switch,
88 controller=Controller, waitConnected=True,
91 info( "*** testing basic connectivity\n" )
93 net.ping( [ net.hosts[ 0 ], net.hosts[ n ] ] )
94 info( "*** testing bandwidth\n" )
96 src, dst = net.hosts[ 0 ], net.hosts[ n ]
97 # Try to prime the pump to reduce PACKET_INs during test
98 # since the reference controller is reactive
99 src.cmd( 'telnet', dst.IP(), '5001' )
100 info( "testing", src.name, "<->", dst.name, '\n' )
101 # serverbw = received; _clientbw = buffered
102 serverbw, _clientbw = net.iperf( [ src, dst ], seconds=10 )
103 info( serverbw, '\n' )
105 results[ datapath ] += [ ( n, serverbw ) ]
108 for datapath in switches.keys():
109 info( "\n*** Linear network results for", datapath, "datapath:\n" )
110 result = results[ datapath ]
111 info( "SwitchCount\tiperf Results\n" )
112 for switchCount, serverbw in result:
113 info( switchCount, '\t\t' )
114 info( serverbw, '\n' )
118 if __name__ == '__main__':
119 lg.setLogLevel( 'info' )
120 sizes = [ 1, 10, 20, 40, 60, 80 ]
121 info( "*** Running linearBandwidthTest", sizes, '\n' )
122 linearBandwidthTest( sizes )