Merge branch 'master' of github.com:mininet/mininet
This commit is contained in:
@@ -26,7 +26,7 @@ from mininet.log import lg, LEVELS, info, debug, error
|
||||
from mininet.net import Mininet, MininetWithControlNet, VERSION
|
||||
from mininet.node import ( Host, CPULimitedHost, Controller, OVSController,
|
||||
NOX, RemoteController, UserSwitch, OVSKernelSwitch,
|
||||
OVSLegacyKernelSwitch )
|
||||
OVSLegacyKernelSwitch, IVSSwitch )
|
||||
from mininet.link import Link, TCLink
|
||||
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
|
||||
from mininet.topolib import TreeTopo
|
||||
@@ -45,7 +45,8 @@ TOPOS = { 'minimal': lambda: SingleSwitchTopo( k=2 ),
|
||||
SWITCHDEF = 'ovsk'
|
||||
SWITCHES = { 'user': UserSwitch,
|
||||
'ovsk': OVSKernelSwitch,
|
||||
'ovsl': OVSLegacyKernelSwitch }
|
||||
'ovsl': OVSLegacyKernelSwitch,
|
||||
'ivs': IVSSwitch }
|
||||
|
||||
HOSTDEF = 'proc'
|
||||
HOSTS = { 'proc': Host,
|
||||
|
||||
+6
-2
@@ -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 )
|
||||
|
||||
@@ -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
@@ -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
@@ -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__':
|
||||
|
||||
+37
-15
@@ -84,10 +84,9 @@ OVS_RELEASE=1.4.0
|
||||
OVS_PACKAGE_LOC=https://github.com/downloads/mininet/mininet
|
||||
OVS_BUILDSUFFIX=-ignore # was -2
|
||||
OVS_PACKAGE_NAME=ovs-$OVS_RELEASE-core-$DIST_LC-$RELEASE-$ARCH$OVS_BUILDSUFFIX.tar
|
||||
OVS_SRC=$BUILD_DIR/openvswitch
|
||||
OVS_TAG=v$OVS_RELEASE
|
||||
OVS_BUILD=$OVS_SRC/build-$KERNEL_NAME
|
||||
OVS_KMODS=($OVS_BUILD/datapath/linux/{openvswitch_mod.ko,brcompat_mod.ko})
|
||||
|
||||
IVS_TAG=v0.3
|
||||
|
||||
# Command-line versions overrides that simplify custom VM creation
|
||||
# To use, pass in the vars on the cmd line before install.sh, e.g.
|
||||
@@ -95,6 +94,7 @@ OVS_KMODS=($OVS_BUILD/datapath/linux/{openvswitch_mod.ko,brcompat_mod.ko})
|
||||
WS_DISSECTOR_REV=${WS_DISSECTOR_REV:-""}
|
||||
OF13_SWITCH_REV=${OF13_SWITCH_REV:-""}
|
||||
|
||||
|
||||
function kernel {
|
||||
echo "Install Mininet-compatible kernel if necessary"
|
||||
sudo apt-get update
|
||||
@@ -287,6 +287,10 @@ function wireshark {
|
||||
function ovs {
|
||||
echo "Installing Open vSwitch..."
|
||||
|
||||
OVS_SRC=$BUILD_DIR/openvswitch
|
||||
OVS_BUILD=$OVS_SRC/build-$KERNEL_NAME
|
||||
OVS_KMODS=($OVS_BUILD/datapath/linux/{openvswitch_mod.ko,brcompat_mod.ko})
|
||||
|
||||
# Required for module build/dkms install
|
||||
$install $KERNEL_HEADERS
|
||||
|
||||
@@ -399,6 +403,22 @@ function remove_ovs {
|
||||
echo "Done removing OVS"
|
||||
}
|
||||
|
||||
function ivs {
|
||||
echo "Installing Indigo Virtual Switch..."
|
||||
|
||||
IVS_SRC=$BUILD_DIR/ivs
|
||||
|
||||
# Install dependencies
|
||||
$install git pkg-config gcc make libnl-3-dev libnl-route-3-dev libnl-genl-3-dev
|
||||
|
||||
# Install IVS from source
|
||||
cd $BUILD_DIR
|
||||
git clone git://github.com/floodlight/ivs $IVS_SRC -b $IVS_TAG --recursive
|
||||
cd $IVS_SRC
|
||||
make
|
||||
sudo make install
|
||||
}
|
||||
|
||||
# Install NOX with tutorial files
|
||||
function nox {
|
||||
echo "Installing NOX w/tutorial files..."
|
||||
@@ -640,7 +660,7 @@ function vm_clean {
|
||||
}
|
||||
|
||||
function usage {
|
||||
printf '\nUsage: %s [-abcdfhkmnprtvwx03]\n\n' $(basename $0) >&2
|
||||
printf '\nUsage: %s [-abcdfhikmnprtvwx03]\n\n' $(basename $0) >&2
|
||||
|
||||
printf 'This install script attempts to install useful packages\n' >&2
|
||||
printf 'for Mininet. It should (hopefully) work on Ubuntu 11.10+\n' >&2
|
||||
@@ -653,21 +673,22 @@ function usage {
|
||||
printf -- ' -b: install controller (B)enchmark (oflops)\n' >&2
|
||||
printf -- ' -c: (C)lean up after kernel install\n' >&2
|
||||
printf -- ' -d: (D)elete some sensitive files from a VM image\n' >&2
|
||||
printf -- ' -f: install open(F)low\n' >&2
|
||||
printf -- ' -e: install Mininet d(E)veloper dependencies\n' >&2
|
||||
printf -- ' -f: install Open(F)low\n' >&2
|
||||
printf -- ' -h: print this (H)elp message\n' >&2
|
||||
printf -- ' -i: install (I)ndigo Virtual Switch\n' >&2
|
||||
printf -- ' -k: install new (K)ernel\n' >&2
|
||||
printf -- ' -m: install Open vSwitch kernel (M)odule from source dir\n' >&2
|
||||
printf -- ' -n: install mini(N)et dependencies + core files\n' >&2
|
||||
printf -- ' -e: install mininet d(E)veloper dependencies\n' >&2
|
||||
printf -- ' -n: install Mini(N)et dependencies + core files\n' >&2
|
||||
printf -- ' -p: install (P)OX OpenFlow Controller\n' >&2
|
||||
printf -- ' -r: remove existing Open vSwitch packages\n' >&2
|
||||
printf -- ' -s <dir>: place dependency (S)ource/build trees in <dir>\n' >&2
|
||||
printf -- ' -t: complete o(T)her Mininet VM setup tasks\n' >&2
|
||||
printf -- ' -v: install open (V)switch\n' >&2
|
||||
printf -- ' -w: install OpenFlow (w)ireshark dissector\n' >&2
|
||||
printf -- ' -v: install Open (V)switch\n' >&2
|
||||
printf -- ' -w: install OpenFlow (W)ireshark dissector\n' >&2
|
||||
printf -- ' -x: install NO(X) Classic OpenFlow controller\n' >&2
|
||||
printf -- ' -0: (default) -0[fx] installs OpenFlow 1.0 versions\n' >&2
|
||||
printf -- ' -3: -3[fx] installs OpenFlow 1.3 versions\n' >&2
|
||||
printf -- ' -i < directory >: sets the (I)nstallation directory for Mininet dependencies\n' >&2
|
||||
exit 2
|
||||
}
|
||||
|
||||
@@ -677,25 +698,29 @@ if [ $# -eq 0 ]
|
||||
then
|
||||
all
|
||||
else
|
||||
while getopts 'abcdefhkmnprtvwx03i:' OPTION
|
||||
while getopts 'abcdefhikmnprs:tvwx03' OPTION
|
||||
do
|
||||
case $OPTION in
|
||||
a) all;;
|
||||
b) cbench;;
|
||||
c) kernel_clean;;
|
||||
d) vm_clean;;
|
||||
e) mn_dev;;
|
||||
f) case $OF_VERSION in
|
||||
1.0) of;;
|
||||
1.3) of13;;
|
||||
*) echo "Invalid OpenFlow version $OF_VERSION";;
|
||||
esac;;
|
||||
h) usage;;
|
||||
i) ivs;;
|
||||
k) kernel;;
|
||||
m) modprobe;;
|
||||
n) mn_deps;;
|
||||
e) mn_dev;;
|
||||
p) pox;;
|
||||
r) remove_ovs;;
|
||||
s) mkdir -p $OPTARG; # ensure the directory is created
|
||||
BUILD_DIR="$( cd -P "$OPTARG" && pwd )"; # get the full path
|
||||
echo "Dependency installation directory: $BUILD_DIR";;
|
||||
t) vm_other;;
|
||||
v) ovs;;
|
||||
w) wireshark;;
|
||||
@@ -706,9 +731,6 @@ else
|
||||
esac;;
|
||||
0) OF_VERSION=1.0;;
|
||||
3) OF_VERSION=1.3;;
|
||||
i) mkdir -p $OPTARG; # ensure the directory is created
|
||||
BUILD_DIR="$( cd -P "$OPTARG" && pwd )"; # get the full path of the directory
|
||||
echo "Dependency installation directory: $BUILD_DIR";;
|
||||
?) usage;;
|
||||
esac
|
||||
done
|
||||
|
||||
Reference in New Issue
Block a user