Merge branch 'of1.0' into testing

Conflicts:

	bin/mn
	mininet/cli.py
	mininet/moduledeps.py
	mininet/node.py
	mininet/topo.py
	util/install.sh
This commit is contained in:
Bob Lantz
2010-10-17 17:23:23 -07:00
10 changed files with 505 additions and 113 deletions
+16 -1
View File
@@ -272,6 +272,20 @@ class CLI( Cmd ):
error( 'error reading file %s\n' % args[ 0 ] )
self.inputFile = None
def do_dpctl( self, line ):
"Run dpctl command on all switches."
args = line.split()
if len(args) == 0:
error( 'usage: dpctl command [arg1] [arg2] ...\n' )
return
if not self.mn.listenPort:
error( "can't run dpctl w/no passive listening port\n")
return
for sw in self.mn.switches:
output( '*** ' + sw.name + ' ' + ('-' * 72) + '\n' )
output( sw.cmd( 'dpctl ' + ' '.join(args) +
' tcp:127.0.0.1:%i' % sw.listenPort ) )
def default( self, line ):
"""Called on an input line when the command prefix is not recognized.
Overridden to run shell commands when a node is the first CLI argument.
@@ -314,7 +328,8 @@ class CLI( Cmd ):
while True:
try:
bothPoller.poll()
if self.inputFile:
# XXX BL: this doesn't quite do what we want.
if False and self.inputFile:
key = self.inputFile.read( 1 )
if key is not '':
node.write(key)
+11 -9
View File
@@ -37,7 +37,7 @@ def moduleDeps( subtract=None, add=None ):
info( '*** Removing ' + mod + '\n' )
rmmodOutput = rmmod( mod )
if rmmodOutput:
error( 'Error removing ' + mod + '\n%s' % rmmodOutput )
error( 'Error removing ' + mod + ': "%s">\n' % rmmodOutput )
exit( 1 )
if mod in lsmod():
error( 'Failed to remove ' + mod + '; still there!\n' )
@@ -47,20 +47,22 @@ def moduleDeps( subtract=None, add=None ):
info( '*** Loading ' + mod + '\n' )
modprobeOutput = modprobe( mod )
if modprobeOutput:
error( 'Error inserting ' + mod + ';\n See INSTALL.\n%s' %
modprobeOutput )
exit( 1 )
error( 'Error inserting ' + mod +
' - is it installed and available via modprobe?\n' +
'Error was: "%s"\n' % modprobeOutput )
if mod not in lsmod():
error( 'Failed to insert ' + mod + '\n' )
error( 'Failed to insert ' + mod + ' - quitting.\n' )
exit( 1 )
else:
debug( '*** ' + mod + ' already loaded\n' )
def pathCheck( *args ):
def pathCheck( *args, **kwargs ):
"Make sure each program in *args can be found in $PATH."
moduleName = kwargs.get( 'moduleName', 'it' )
for arg in args:
if not quietRun( 'which ' + arg ):
error( 'Cannot find required executable %s -'
' is it installed somewhere in your $PATH?\n(%s)\n' %
( arg, environ[ 'PATH' ] ) )
error( 'Cannot find required executable %s.\n' % arg +
'Please make sure that %s is installed ' % moduleName +
'and available in your $PATH:\n(%s)\n' % environ[ 'PATH' ] )
exit( 1 )
+20 -10
View File
@@ -94,7 +94,7 @@ from time import sleep
from mininet.cli import CLI
from mininet.log import info, error, debug, output
from mininet.node import Host, UserSwitch, KernelSwitch, Controller
from mininet.node import Host, UserSwitch, OVSKernelSwitch, Controller
from mininet.node import ControllerParams
from mininet.util import quietRun, fixLimits
from mininet.util import createLink, macColonHex, ipStr, ipParse
@@ -103,12 +103,12 @@ from mininet.term import cleanUpScreens, makeTerms
class Mininet( object ):
"Network emulation with hosts spawned in network namespaces."
def __init__( self, topo=None, switch=KernelSwitch, host=Host,
def __init__( self, topo=None, switch=OVSKernelSwitch, host=Host,
controller=Controller,
cparams=ControllerParams( '10.0.0.0', 8 ),
build=True, xterms=False, cleanup=False,
inNamespace=False,
autoSetMacs=False, autoStaticArp=False ):
autoSetMacs=False, autoStaticArp=False, listenPort=None ):
"""Create Mininet object.
topo: Topo (topology) object or None
switch: Switch class
@@ -120,7 +120,9 @@ class Mininet( object ):
cleanup: if build now, cleanup before creating?
inNamespace: spawn switches and controller in net namespaces?
autoSetMacs: set MAC addrs from topo?
autoStaticArp: set all-pairs static MAC addrs?"""
autoStaticArp: set all-pairs static MAC addrs?
listenPort: base listening port to open; will be incremented for
each additional switch in the net if inNamespace=False"""
self.switch = switch
self.host = host
self.controller = controller
@@ -131,6 +133,7 @@ class Mininet( object ):
self.cleanup = cleanup
self.autoSetMacs = autoSetMacs
self.autoStaticArp = autoStaticArp
self.listenPort = listenPort
self.hosts = []
self.switches = []
@@ -162,25 +165,32 @@ class Mininet( object ):
"""Add switch.
name: name of switch to add
mac: default MAC address for kernel/OVS switch intf 0
returns: added switch"""
returns: added switch
side effect: increments the listenPort member variable."""
if self.switch == UserSwitch:
sw = self.switch( name, defaultMAC=mac, defaultIP=ip,
inNamespace=self.inNamespace )
sw = self.switch( name, listenPort=self.listenPort,
defaultMAC=mac, defaultIP=ip, inNamespace=self.inNamespace )
else:
sw = self.switch( name, defaultMAC=mac, defaultIP=ip, dp=self.dps,
sw = self.switch( name, listenPort=self.listenPort,
defaultMAC=mac, defaultIP=ip, dp=self.dps,
inNamespace=self.inNamespace )
if not self.inNamespace and self.listenPort:
self.listenPort += 1
self.dps += 1
self.switches.append( sw )
self.nameToNode[ name ] = sw
return sw
def addController( self, name='c0', **kwargs ):
def addController( self, name='c0', controller=None, **kwargs ):
"""Add controller.
controller: Controller class"""
controller_new = self.controller( name, **kwargs )
if not controller:
controller = self.controller
controller_new = controller( name, **kwargs )
if controller_new: # allow controller-less setups
self.controllers.append( controller_new )
self.nameToNode[ name ] = controller_new
return controller_new
# Control network support:
#
+33 -18
View File
@@ -200,7 +200,6 @@ class Node( object ):
"""Monitor and return the output of a command.
Set self.waiting to False if command has completed.
timeoutms: timeout in ms or None to wait indefinitely."""
assert self.waiting
self.waitReadable( timeoutms )
data = self.read( 1024 )
# Look for PID
@@ -434,9 +433,19 @@ class Switch( Node ):
portBase = SWITCH_PORT_BASE # 0 for OF < 1.0, 1 for OF >= 1.0
def __init__( self, name, opts='', **kwargs):
def __init__( self, name, opts='', listenPort=None, **kwargs):
Node.__init__( self, name, **kwargs )
self.opts = opts
self.listenPort = listenPort
if self.listenPort:
self.opts += ' --listen=ptcp:%i ' % self.listenPort
def defaultIntf( self ):
"Return interface for HIGHEST port"
ports = self.intfs.keys()
if ports:
intf = self.intfs[ max( ports ) ]
return intf
def sendCmd( self, *cmd, **kwargs ):
"""Send command to Node.
@@ -455,12 +464,15 @@ class UserSwitch( Switch ):
"""Init.
name: name for the switch"""
Switch.__init__( self, name, **kwargs )
pathCheck( 'ofdatapath', 'ofprotocol' )
pathCheck( 'ofdatapath', 'ofprotocol',
moduleName='the OpenFlow reference user switch (openflow.org)' )
@staticmethod
def setup():
"Ensure any dependencies are loaded; if not, try to load them."
moduleDeps( add=TUN )
if not os.path.exists( '/dev/net/tun' ):
moduleDeps( add=TUN )
def start( self, controllers ):
"""Start OpenFlow reference user datapath.
@@ -478,7 +490,7 @@ class UserSwitch( Switch ):
if self.inNamespace:
intfs = intfs[ :-1 ]
self.cmd( 'ofdatapath -i ' + ','.join( intfs ) +
' punix:/tmp/' + self.name + mac_str +
' punix:/tmp/' + self.name + mac_str + ' --no-slicing ' +
' 1> ' + ofdlog + ' 2> ' + ofdlog + ' &' )
self.cmd( 'ofprotocol unix:/tmp/' + self.name +
' tcp:%s:%d' % ( controller.IP(), controller.port ) +
@@ -511,8 +523,10 @@ class KernelSwitch( Switch ):
@staticmethod
def setup():
"Ensure any dependencies are loaded; if not, try to load them."
moduleDeps( subtract = OVS_KMOD, add = OF_KMOD )
pathCheck( 'ofprotocol' )
pathCheck( 'ofprotocol',
moduleName='the OpenFlow reference kernel switch'
' (openflow.org) (NOTE: not available in OpenFlow 1.0!)' )
moduleDeps( subtract=OVS_KMOD, add=OF_KMOD )
def start( self, controllers ):
"Start up reference kernel datapath."
@@ -559,14 +573,15 @@ class OVSKernelSwitch( Switch ):
self.intf = self.dp
if self.inNamespace:
error( "OVSKernelSwitch currently only works"
" in the root namespace." )
" in the root namespace.\n" )
exit( 1 )
@staticmethod
def setup():
"Ensure any dependencies are loaded; if not, try to load them."
moduleDeps( subtract = OF_KMOD, add = OVS_KMOD )
pathCheck( 'ovs-dpctl', 'ovs-openflowd' )
pathCheck( 'ovs-dpctl', 'ovs-openflowd',
moduleName='Open vSwitch (openvswitch.org)')
moduleDeps( subtract=OF_KMOD, add=OVS_KMOD )
def start( self, controllers ):
"Start up kernel datapath."
@@ -607,10 +622,10 @@ class Controller( Node ):
"""A Controller is a Node that is running (or has execed?) an
OpenFlow controller."""
def __init__( self, name, inNamespace=False, controller='controller',
cargs='-v ptcp:', cdir=None, defaultIP="127.0.0.1",
def __init__( self, name, inNamespace=False, command='controller',
cargs='-v ptcp:%d', cdir=None, defaultIP="127.0.0.1",
port=6633 ):
self.controller = controller
self.command = command
self.cargs = cargs
self.cdir = cdir
self.port = port
@@ -620,17 +635,17 @@ class Controller( Node ):
def start( self ):
"""Start <controller> <args> on controller.
Log to /tmp/cN.log"""
pathCheck( self.controller )
pathCheck( self.command )
cout = '/tmp/' + self.name + '.log'
if self.cdir is not None:
self.cmd( 'cd ' + self.cdir )
self.cmd( self.controller + ' ' + self.cargs +
self.cmd( self.command + ' ' + self.cargs % self.port +
' 1>' + cout + ' 2>' + cout + '&' )
self.execed = False
def stop( self ):
"Stop controller."
self.cmd( 'kill %' + self.controller )
self.cmd( 'kill %' + self.command )
self.terminate()
def IP( self, intf=None ):
@@ -668,8 +683,8 @@ class NOX( Controller ):
noxCoreDir = os.environ[ 'NOX_CORE_DIR' ]
Controller.__init__( self, name,
controller=noxCoreDir + '/nox_core',
cargs='--libdir=/usr/local/lib -v -i ptcp: ' +
command=noxCoreDir + '/nox_core',
cargs='--libdir=/usr/local/lib -v -i ptcp:%s ' % self.port +
' '.join( noxArgs ),
cdir=noxCoreDir, **kwargs )