Merge branch 'master' of github.com:mininet/mininet

This commit is contained in:
Brian O'Connor
2013-08-02 13:36:18 -07:00
6 changed files with 169 additions and 52 deletions
+6 -2
View File
@@ -11,6 +11,7 @@ nothing irreplaceable!
"""
from subprocess import Popen, PIPE
import time
from mininet.log import info
from mininet.term import cleanUpScreens
@@ -27,10 +28,13 @@ def cleanup():
info("*** Removing excess controllers/ofprotocols/ofdatapaths/pings/noxes"
"\n")
zombies = 'controller ofprotocol ofdatapath ping nox_core lt-nox_core '
zombies += 'ovs-openflowd ovs-controller udpbwtest mnexec'
zombies += 'ovs-openflowd ovs-controller udpbwtest mnexec ivs'
# Note: real zombie processes can't actually be killed, since they
# are already (un)dead. Then again,
# you can't connect to them either, so they're mostly harmless.
# Send SIGTERM first to give processes a chance to shutdown cleanly.
sh( 'killall ' + zombies + ' 2> /dev/null' )
time.sleep(1)
sh( 'killall -9 ' + zombies + ' 2> /dev/null' )
# And kill off sudo mnexec
@@ -49,7 +53,7 @@ def cleanup():
sh( 'dpctl deldp ' + dp )
info( "*** Removing OVS datapaths" )
dps = sh("ovs-vsctl list-br").split( '\n' )
dps = sh("ovs-vsctl --timeout=1 list-br").split( '\n' )
for dp in dps:
if dp:
sh( 'ovs-vsctl del-br ' + dp )
+58
View File
@@ -1026,6 +1026,64 @@ class OVSSwitch( Switch ):
OVSKernelSwitch = OVSSwitch
class IVSSwitch(Switch):
"""IVS virtual switch"""
def __init__( self, name, **kwargs ):
Switch.__init__( self, name, **kwargs )
@classmethod
def setup( cls ):
"Make sure IVS is installed"
pathCheck( 'ivs-ctl', 'ivs',
moduleName="Indigo Virtual Switch (projectfloodlight.org)" )
out, err, exitcode = errRun( 'ivs-ctl show' )
if exitcode:
error( out + err +
'ivs-ctl exited with code %d\n' % exitcode +
'*** The openvswitch kernel module might '
'not be loaded. Try modprobe openvswitch.\n' )
exit( 1 )
def start( self, controllers ):
"Start up a new IVS switch"
args = ['ivs']
args.extend( ['--name', self.name] )
args.extend( ['--dpid', self.dpid] )
args.extend( ['--verbose'] )
for intf in self.intfs.values():
if not intf.IP():
args.extend( ['-i', intf.name] )
for c in controllers:
args.extend( ['-c', '%s:%d' % (c.IP(), c.port)] )
if self.listenPort:
args.extend( ['--listen', '127.0.0.1:%i' % self.listenPort] )
logfile = '/tmp/ivs.%s.log' % self.name
self.cmd( ' '.join(args) + ' >' + logfile + ' 2>&1 </dev/null &' )
def stop( self ):
"Terminate IVS switch."
self.cmd( 'kill %ivs' )
self.deleteIntfs()
def attach( self, intf ):
"Connect a data port"
self.cmd( 'ivs-ctl', 'add-port', '--datapath', self.name, intf )
def detach( self, intf ):
"Disconnect a data port"
self.cmd( 'ivs-ctl', 'del-port', '--datapath', self.name, intf )
def dpctl( self, *args ):
"Run dpctl command"
if not self.listenPort:
return "can't run dpctl without passive listening port"
return self.cmd( 'ovs-ofctl ' + ' '.join( args ) +
' tcp:127.0.0.1:%i' % self.listenPort )
class Controller( Node ):
"""A Controller is a Node that is running (or has execed?) an
OpenFlow controller."""
+21 -10
View File
@@ -6,14 +6,12 @@
import unittest
from mininet.net import Mininet
from mininet.node import OVSKernelSwitch
from mininet.node import OVSKernelSwitch, UserSwitch, IVSSwitch
from mininet.node import CPULimitedHost
from mininet.link import TCLink
from mininet.topo import Topo
from mininet.log import setLogLevel
SWITCH = OVSKernelSwitch
# Number of hosts for each test
N = 2
@@ -32,14 +30,16 @@ class SingleSwitchOptionsTopo(Topo):
self.addLink(host, switch)
class testOptionsTopo( unittest.TestCase ):
"Verify ability to create networks with host and link options."
class testOptionsTopoCommon( object ):
"Verify ability to create networks with host and link options (common code)."
switchClass = None # overridden in subclasses
def runOptionsTopoTest( self, n, hopts=None, lopts=None ):
"Generic topology-with-options test runner."
mn = Mininet( topo=SingleSwitchOptionsTopo( n=n, hopts=hopts,
lopts=lopts ),
host=CPULimitedHost, link=TCLink )
host=CPULimitedHost, link=TCLink, switch=self.switchClass )
dropped = mn.run( mn.ping )
self.assertEqual( dropped, 0 )
@@ -58,7 +58,7 @@ class testOptionsTopo( unittest.TestCase ):
#self.runOptionsTopoTest( N, hopts=hopts )
mn = Mininet( SingleSwitchOptionsTopo( n=N, hopts=hopts ),
host=CPULimitedHost )
host=CPULimitedHost, switch=self.switchClass )
mn.start()
results = mn.runCpuLimitTest( cpu=CPU_FRACTION )
mn.stop()
@@ -73,7 +73,7 @@ class testOptionsTopo( unittest.TestCase ):
lopts = { 'bw': BW, 'use_htb': True }
# Also verify correctness of limit limitng within a bound.
mn = Mininet( SingleSwitchOptionsTopo( n=N, lopts=lopts ),
link=TCLink )
link=TCLink, switch=self.switchClass )
bw_strs = mn.run( mn.iperf )
for bw_str in bw_strs:
bw = float( bw_str.split(' ')[0] )
@@ -85,7 +85,7 @@ class testOptionsTopo( unittest.TestCase ):
DELAY_TOLERANCE = 0.8 # Delay fraction below which test should fail
lopts = { 'delay': '%sms' % DELAY_MS, 'use_htb': True }
mn = Mininet( SingleSwitchOptionsTopo( n=N, lopts=lopts ),
link=TCLink )
link=TCLink, switch=self.switchClass )
ping_delays = mn.run( mn.pingFull )
test_outputs = ping_delays[0]
# Ignore unused variables below
@@ -105,7 +105,7 @@ class testOptionsTopo( unittest.TestCase ):
REPS = 1
lopts = { 'loss': LOSS_PERCENT, 'use_htb': True }
mn = Mininet( topo=SingleSwitchOptionsTopo( n=N, lopts=lopts ),
host=CPULimitedHost, link=TCLink )
host=CPULimitedHost, link=TCLink, switch=self.switchClass )
# Drops are probabilistic, but the chance of no dropped packets is
# 1 in 100 million with 4 hops for a link w/99% loss.
dropped_total = 0
@@ -121,6 +121,17 @@ class testOptionsTopo( unittest.TestCase ):
hopts = { 'cpu': 0.5 / N }
self.runOptionsTopoTest( N, hopts=hopts, lopts=lopts )
class testOptionsTopoOVSKernel( testOptionsTopoCommon, unittest.TestCase ):
"Verify ability to create networks with host and link options (OVS kernel switch)."
switchClass = OVSKernelSwitch
class testOptionsTopoIVS( testOptionsTopoCommon, unittest.TestCase ):
"Verify ability to create networks with host and link options (IVS switch)."
switchClass = IVSSwitch
class testOptionsTopoUserspace( testOptionsTopoCommon, unittest.TestCase ):
"Verify ability to create networks with host and link options (Userspace switch)."
switchClass = UserSwitch
if __name__ == '__main__':
setLogLevel( 'warning' )
+44 -23
View File
@@ -7,42 +7,63 @@ import unittest
from mininet.net import Mininet
from mininet.node import Host, Controller
from mininet.node import UserSwitch, OVSKernelSwitch
from mininet.node import UserSwitch, OVSKernelSwitch, IVSSwitch
from mininet.topo import SingleSwitchTopo, LinearTopo
from mininet.log import setLogLevel
SWITCHES = { 'user': UserSwitch,
'ovsk': OVSKernelSwitch,
}
class testSingleSwitchCommon( object ):
"Test ping with single switch topology (common code)."
class testSingleSwitch( unittest.TestCase ):
"For each datapath type, test ping with single switch topologies."
switchClass = None # overridden in subclasses
def testMinimal( self ):
"Ping test with both datapaths on minimal topology"
for switch in SWITCHES.values():
mn = Mininet( SingleSwitchTopo(), switch, Host, Controller )
dropped = mn.run( mn.ping )
self.assertEqual( dropped, 0 )
"Ping test on minimal topology"
mn = Mininet( SingleSwitchTopo(), self.switchClass, Host, Controller )
dropped = mn.run( mn.ping )
self.assertEqual( dropped, 0 )
def testSingle5( self ):
"Ping test with both datapaths on 5-host single-switch topology"
for switch in SWITCHES.values():
mn = Mininet( SingleSwitchTopo( k=5 ), switch, Host, Controller )
dropped = mn.run( mn.ping )
self.assertEqual( dropped, 0 )
"Ping test on 5-host single-switch topology"
mn = Mininet( SingleSwitchTopo( k=5 ), self.switchClass, Host, Controller )
dropped = mn.run( mn.ping )
self.assertEqual( dropped, 0 )
class testSingleSwitchOVSKernel( testSingleSwitchCommon, unittest.TestCase ):
"Test ping with single switch topology (OVS kernel switch)."
switchClass = OVSKernelSwitch
class testSingleSwitchIVS( testSingleSwitchCommon, unittest.TestCase ):
"Test ping with single switch topology (IVS switch)."
switchClass = IVSSwitch
class testSingleSwitchUserspace( testSingleSwitchCommon, unittest.TestCase ):
"Test ping with single switch topology (Userspace switch)."
switchClass = UserSwitch
class testLinear( unittest.TestCase ):
"For each datapath type, test all-pairs ping with LinearNet."
class testLinearCommon( object ):
"Test all-pairs ping with LinearNet (common code)."
switchClass = None # overridden in subclasses
def testLinear5( self ):
"Ping test with both datapaths on a 5-switch topology"
for switch in SWITCHES.values():
mn = Mininet( LinearTopo( k=5 ), switch, Host, Controller )
dropped = mn.run( mn.ping )
self.assertEqual( dropped, 0 )
"Ping test on a 5-switch topology"
mn = Mininet( LinearTopo( k=5 ), self.switchClass, Host, Controller )
dropped = mn.run( mn.ping )
self.assertEqual( dropped, 0 )
class testLinearOVSKernel( testLinearCommon, unittest.TestCase ):
"Test all-pairs ping with LinearNet (OVS kernel switch)."
switchClass = OVSKernelSwitch
class testLinearIVS( testLinearCommon, unittest.TestCase ):
"Test all-pairs ping with LinearNet (IVS switch)."
switchClass = IVSSwitch
class testLinearUserspace( testLinearCommon, unittest.TestCase ):
"Test all-pairs ping with LinearNet (Userspace switch)."
switchClass = UserSwitch
if __name__ == '__main__':