Munged mn and mnclean into mininet style.
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
'''Mininet runner
|
||||
|
||||
@author Brandon Heller (brandonh@stanford.edu)
|
||||
'''
|
||||
"""
|
||||
Mininet runner
|
||||
author: Brandon Heller (brandonh@stanford.edu)
|
||||
"""
|
||||
|
||||
from optparse import OptionParser
|
||||
import os.path
|
||||
@@ -10,9 +11,9 @@ import time
|
||||
|
||||
try:
|
||||
from ripcord.dctopo import TreeTopo, FatTreeTopo, VL2Topo
|
||||
USE_RIPCORD = True
|
||||
USERIPCORD = True
|
||||
except ImportError:
|
||||
USE_RIPCORD = False
|
||||
USERIPCORD = False
|
||||
|
||||
from mininet.log import lg, LEVELS
|
||||
from mininet.net import Mininet, init
|
||||
@@ -21,33 +22,33 @@ from mininet.node import RemoteController, UserSwitch, OVSKernelSwitch
|
||||
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
|
||||
|
||||
# built in topologies, created only when run
|
||||
TOPO_DEF = 'minimal'
|
||||
TOPODEF = 'minimal'
|
||||
TOPOS = { 'minimal': ( lambda: SingleSwitchTopo( k=2 ) ),
|
||||
'reversed': ( lambda: SingleSwitchReversedTopo( k=2 ) ),
|
||||
'single4': ( lambda: SingleSwitchTopo( k=4 ) ),
|
||||
'single100': ( lambda: SingleSwitchTopo( k=100 ) ),
|
||||
'linear2': ( lambda: LinearTopo( k=2 ) ),
|
||||
'linear100': ( lambda: LinearTopo( k=100 ) ) }
|
||||
if USE_RIPCORD:
|
||||
TOPOS_RIPCORD = {
|
||||
if USERIPCORD:
|
||||
TOPOSRIPCORD = {
|
||||
'tree16': ( lambda: TreeTopo( depth=3, fanout=4 ) ),
|
||||
'tree64': ( lambda: TreeTopo( depth=4, fanout=4 ) ),
|
||||
'tree1024': ( lambda: TreeTopo( depth=3, fanout=32 ) ),
|
||||
'fattree4': ( lambda: FatTreeTopo( k=4 ) ),
|
||||
'fattree6': ( lambda: FatTreeTopo( k=6 ) ),
|
||||
'vl2': ( lambda: VL2Topo( da=4, di=4 ) ),
|
||||
'vl2reduced': (lambda: VL2Topo(da = 4, di = 4, edge_down = 1))}
|
||||
TOPOS.update(TOPOS_RIPCORD)
|
||||
'vl2reduced': ( lambda: VL2Topo( da=4, di=4, edgeDown=1 ) ) }
|
||||
TOPOS.update( TOPOSRIPCORD )
|
||||
|
||||
SWITCH_DEF = 'kernel'
|
||||
SWITCHDEF = 'kernel'
|
||||
SWITCHES = { 'kernel': KernelSwitch,
|
||||
'user': UserSwitch,
|
||||
'ovsk': OVSKernelSwitch }
|
||||
|
||||
HOST_DEF = 'process'
|
||||
HOSTDEF = 'process'
|
||||
HOSTS = { 'process': Host }
|
||||
|
||||
CONTROLLER_DEF = 'ref'
|
||||
CONTROLLERDEF = 'ref'
|
||||
# a and b are the name and inNamespace params.
|
||||
CONTROLLERS = { 'ref': Controller,
|
||||
'nox_dump': lambda a, b: NOX( a, b, 'packetdump' ),
|
||||
@@ -56,51 +57,48 @@ CONTROLLERS = {'ref': Controller,
|
||||
'none': lambda a, b: None }
|
||||
|
||||
# optional tests to run
|
||||
TESTS = ['cli', 'build', 'ping_all', 'ping_pair', 'iperf', 'all', 'iperf_udp']
|
||||
TESTS = [ 'cli', 'build', 'ping_all', 'ping_pair', 'iperf', 'all',
|
||||
'iperf_udp' ]
|
||||
|
||||
|
||||
def add_dict_option(opts, choices_dict, default, name, help_str = None):
|
||||
'''Convenience function to add choices dicts to OptionParser.
|
||||
|
||||
@param opts OptionParser instance
|
||||
@param choices_dict dictionary of valid choices, must include default
|
||||
@param default default choice key
|
||||
@param name long option name
|
||||
@param help string
|
||||
'''
|
||||
if default not in choices_dict:
|
||||
def addDictOption( opts, choicesDict, default, name, helpStr=None ):
|
||||
"""Convenience function to add choices dicts to OptionParser.
|
||||
opts: OptionParser instance
|
||||
choicesDict: dictionary of valid choices, must include default
|
||||
default: default choice key
|
||||
name: long option name
|
||||
help: string"""
|
||||
if default not in choicesDict:
|
||||
raise Exception( 'Invalid default %s for choices dict: %s' %
|
||||
( default, name ) )
|
||||
if not help_str:
|
||||
help_str = '[' + ' '.join(choices_dict.keys()) + ']'
|
||||
if not helpStr:
|
||||
helpStr = '[' + ' '.join( choicesDict.keys() ) + ']'
|
||||
opts.add_option( '--' + name,
|
||||
type='choice',
|
||||
choices = choices_dict.keys(),
|
||||
choices=choicesDict.keys(),
|
||||
default = default,
|
||||
help = help_str)
|
||||
help = helpStr )
|
||||
|
||||
|
||||
class MininetRunner( object ):
|
||||
'''Build, setup, and run Mininet.'''
|
||||
"Build, setup, and run Mininet."
|
||||
|
||||
def __init__( self ):
|
||||
'''Init.'''
|
||||
"Init."
|
||||
self.options = None
|
||||
|
||||
self.parse_args()
|
||||
self.parseArgs()
|
||||
self.setup()
|
||||
self.begin()
|
||||
|
||||
def parse_args(self):
|
||||
'''Parse command-line args and return options object.
|
||||
|
||||
@return opts parse options dict
|
||||
'''
|
||||
def parseArgs( self ):
|
||||
"""Parse command-line args and return options object.
|
||||
returns: opts parse options dict"""
|
||||
opts = OptionParser()
|
||||
add_dict_option(opts, TOPOS, TOPO_DEF, 'topo')
|
||||
add_dict_option(opts, SWITCHES, SWITCH_DEF, 'switch')
|
||||
add_dict_option(opts, HOSTS, HOST_DEF, 'host')
|
||||
add_dict_option(opts, CONTROLLERS, CONTROLLER_DEF, 'controller')
|
||||
addDictOption( opts, TOPOS, TOPODEF, 'topo' )
|
||||
addDictOption( opts, SWITCHES, SWITCHDEF, 'switch' )
|
||||
addDictOption( opts, HOSTS, HOSTDEF, 'host' )
|
||||
addDictOption( opts, CONTROLLERS, CONTROLLERDEF, 'controller' )
|
||||
|
||||
opts.add_option( '--custom', type='string', default=None,
|
||||
help='read custom mininet from current dir' )
|
||||
@@ -127,7 +125,7 @@ class MininetRunner(object):
|
||||
self.options = opts.parse_args()[ 0 ]
|
||||
|
||||
def setup( self ):
|
||||
'''Setup and validate environment.'''
|
||||
"Setup and validate environment."
|
||||
|
||||
# set logging verbosity
|
||||
lg.setLogLevel( self.options.verbosity )
|
||||
@@ -136,8 +134,9 @@ class MininetRunner(object):
|
||||
init()
|
||||
|
||||
# check for invalid combinations
|
||||
if self.options.controller == 'ref' and \
|
||||
(('fattree' in self.options.topo) or ('vl2' in self.options.topo)):
|
||||
if ( self.options.controller == 'ref' and
|
||||
( ( 'fattree' in self.options.topo ) or
|
||||
( 'vl2' in self.options.topo ) ) ):
|
||||
raise Exception( 'multipath topos require multipath-capable '
|
||||
'controller.' )
|
||||
|
||||
@@ -147,7 +146,7 @@ class MininetRunner(object):
|
||||
self.options.custom )
|
||||
|
||||
def begin( self ):
|
||||
'''Create and run mininet.'''
|
||||
"Create and run mininet."
|
||||
|
||||
start = time.time()
|
||||
|
||||
@@ -157,20 +156,20 @@ class MininetRunner(object):
|
||||
controller = CONTROLLERS[ self.options.controller ]
|
||||
if self.options.controller == 'remote':
|
||||
controller = lambda a, b: RemoteController( a, b,
|
||||
ip_address = self.options.ip,
|
||||
ipAddress=self.options.ip,
|
||||
port=self.options.port )
|
||||
|
||||
controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
|
||||
in_namespace = self.options.in_namespace
|
||||
controllerParams = ControllerParams( 0x0a000000, 8 ) # 10.0.0.0/8
|
||||
inNamespace = self.options.inNamespace
|
||||
xterms = self.options.xterms
|
||||
mac = self.options.mac
|
||||
arp = self.options.arp
|
||||
mn = None
|
||||
if not self.options.custom:
|
||||
mn = Mininet(topo, switch, host, controller, controller_params,
|
||||
in_namespace = in_namespace,
|
||||
xterms = xterms, auto_set_macs = mac,
|
||||
auto_static_arp = arp)
|
||||
mn = Mininet( topo, switch, host, controller, controllerParams,
|
||||
inNamespace=inNamespace,
|
||||
xterms=xterms, autoSetMacs=mac,
|
||||
autoStaticArp=arp )
|
||||
else:
|
||||
globals_ = {}
|
||||
locals_ = {}
|
||||
|
||||
Executable → Regular
+3
-5
@@ -1,7 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
"""Mininet Cleanup
|
||||
|
||||
@author Bob Lantz (rlantz@cs.stanford.edu)
|
||||
"""
|
||||
Mininet Cleanup
|
||||
author: Bob Lantz (rlantz@cs.stanford.edu)
|
||||
|
||||
Unfortunately, Mininet and OpenFlow don't always clean up
|
||||
properly after themselves. Until they do (or until cleanup
|
||||
@@ -15,17 +16,14 @@ from subprocess import Popen, PIPE
|
||||
|
||||
from mininet.xterm import cleanUpScreens
|
||||
|
||||
|
||||
def sh( cmd ):
|
||||
"Print a command and send it to the shell"
|
||||
print cmd
|
||||
return Popen( [ '/bin/sh', '-c', cmd ], stdout=PIPE ).communicate()[ 0 ]
|
||||
|
||||
|
||||
def cleanup():
|
||||
"""Clean up junk which might be left over from old runs;
|
||||
do fast stuff before slow dp and link removal!"""
|
||||
|
||||
print "*** Removing excess controllers/ofprotocols/ofdatapaths/pings/noxes"
|
||||
zombies = 'controller ofprotocol ofdatapath ping nox_core lt-nox_core '
|
||||
zombies += 'udpbwtest'
|
||||
|
||||
Reference in New Issue
Block a user