Compare commits

..

1 Commits

Author SHA1 Message Date
Bob Lantz 8f8f304502 Add Natted() and natted() for easy natted topologies 2015-03-06 07:16:54 -08:00
17 changed files with 313 additions and 289 deletions
+2 -4
View File
@@ -29,16 +29,14 @@ Andrew Ferguson
Eder Leao Fernandes
Gregory Gee
Jon Hall
Roan Huang
Vitaly Ivanov
Babis Kaidos
Rich Lane
Rémy Léone
Zi Shen Lim
David Mahler
Murphy McCauley
José Pedro Oliveira
James Page
Rich Lane
Rémy Léone
Angad Singh
Piyush Srivastava
Ed Swierk
+1 -1
View File
@@ -2,7 +2,7 @@
Mininet Installation/Configuration Notes
----------------------------------------
Mininet 2.2.1
Mininet 2.2.1d1
---
The supported installation methods for Mininet are 1) using a
+2 -2
View File
@@ -1,6 +1,6 @@
Mininet 2.2.1 License
Mininet 2.2.1d1 License
Copyright (c) 2013-2015 Open Networking Laboratory
Copyright (c) 2013-2014 Open Networking Laboratory
Copyright (c) 2009-2012 Bob Lantz and The Board of Trustees of
The Leland Stanford Junior University
+43 -19
View File
@@ -3,7 +3,7 @@ Mininet: Rapid Prototyping for Software Defined Networks
*The best way to emulate almost any network on your laptop!*
Mininet 2.2.1
Mininet 2.2.1d1
### What is Mininet?
@@ -68,25 +68,44 @@ Mininet includes:
### New features in this release
This is primarily a performance improvement and bug fix release.
This release provides a number of bug fixes as well as
several new features, including:
- Batch startup has been implemented for Open vSwitch, improving
startup performance.
* Improved OpenFlow 1.3 support
- OVS patch links have been implemented via OVSLink and --link ovs
- `mn --switch ovs,protocols=openflow13` starts OVS in 1.3 mode
- `install.sh -w` installs a 1.3-compatible Wireshark dissector using
Loxigen
- `install.sh -y` installs the Ryu 1.3-compatible controller
Warning! These links have *serious limitations* compared to
virtual Ethernet pairs: they are not attached to real Linux
interfaces so you cannot use tcpdump or wireshark with them;
they also cannot be used in long chains - we don't recommend more
than 64 OVSLinks, for example --linear,64. However, they can offer
significantly better performance than veth pairs, for certain
configurations.
* A new `nodelib.py` node library, and new `Node` types including
`LinuxBridge`, `OVSBridge`, `LinuxRouter` (see `examples/`)
and `NAT`
- You can now easily install Mininet on a Raspberry Pi ;-)
* A `--nat` option which connects a Mininet network to your LAN using NAT
(For this to work correctly, Mininet's `--ipbase` subnet should not
overlap with any external or internet IP addresses you wish to use)
- Additional information for this release and previous releases
may be found in the release notes on docs.mininet.org
* An improved MiniEdit GUI (`examples/miniedit.py`) - thanks to
Gregory Gee
* Support for multiple `--custom` arguments to `mn`
* Experimental cluster support - consult the
[documentation](http://docs.mininet.org) for details -
as well as `examples/cluster.py` and an experimental `--cluster`
option for topologies built with the default `Host` and `OVSSwitch`
classes:
`mn --cluster localhost,server1,server2`
Note that examples contain experimental features which might
"graduate" into mainline Mininet in the future, but they should
not be considered a stable part of the Mininet API!
A number of bugs have also been fixed, most notably multiple link
support in `Topo()`. See github issues and the release notes on
the Mininet wiki for additional information.
### Installation
@@ -110,8 +129,6 @@ Mininet mailing list, `mininet-discuss` at:
### Join Us
Thanks again to all of the Mininet contributors!
Mininet is an open source project and is currently hosted
at <https://github.com/mininet>. You are encouraged to download
the code, examine it, modify it, and submit bug reports, bug fixes,
@@ -125,5 +142,12 @@ hard work that Mininet continues to grow and improve.
Best wishes, and we look forward to seeing what you can do with
Mininet to change the networking world!
Bob Lantz
Mininet Core Team
The Mininet Core Team:
* Bob Lantz
* Brian O'Connor
* Cody Burkard
Thanks again to all of the Mininet contributors, particularly Gregory
Gee for his work on MiniEdit.
+35 -33
View File
@@ -25,16 +25,15 @@ from mininet.cli import CLI
from mininet.log import lg, LEVELS, info, debug, warn, error
from mininet.net import Mininet, MininetWithControlNet, VERSION
from mininet.node import ( Host, CPULimitedHost, Controller, OVSController,
Ryu, NOX, RemoteController, findController,
DefaultController, NullController,
RYU, NOX, RemoteController, findController,
DefaultController,
UserSwitch, OVSSwitch, OVSBridge,
IVSSwitch )
OVSLegacyKernelSwitch, IVSSwitch )
from mininet.nodelib import LinuxBridge
from mininet.link import Link, TCLink, OVSLink
from mininet.topo import ( SingleSwitchTopo, LinearTopo,
SingleSwitchReversedTopo, MinimalTopo )
from mininet.topo import SingleSwitchTopo, LinearTopo, SingleSwitchReversedTopo
from mininet.topolib import TreeTopo, TorusTopo
from mininet.util import customClass, specialClass, splitArgs
from mininet.util import customConstructor, splitArgs
from mininet.util import buildTopo
from functools import partial
@@ -50,7 +49,7 @@ PLACEMENT = { 'block': SwitchBinPlacer, 'random': RandomPlacer }
# built in topologies, created only when run
TOPODEF = 'minimal'
TOPOS = { 'minimal': MinimalTopo,
TOPOS = { 'minimal': lambda: SingleSwitchTopo( k=2 ),
'linear': LinearTopo,
'reversed': SingleSwitchReversedTopo,
'single': SingleSwitchTopo,
@@ -63,24 +62,24 @@ SWITCHES = { 'user': UserSwitch,
'ovsbr' : OVSBridge,
# Keep ovsk for compatibility with 2.0
'ovsk': OVSSwitch,
'ovsl': OVSLegacyKernelSwitch,
'ivs': IVSSwitch,
'lxbr': LinuxBridge,
'default': OVSSwitch }
HOSTDEF = 'proc'
HOSTS = { 'proc': Host,
'rt': specialClass( CPULimitedHost, defaults=dict( sched='rt' ) ),
'cfs': specialClass( CPULimitedHost, defaults=dict( sched='cfs' ) ) }
'rt': partial( CPULimitedHost, sched='rt' ),
'cfs': partial( CPULimitedHost, sched='cfs' ) }
CONTROLLERDEF = 'default'
CONTROLLERS = { 'ref': Controller,
'ovsc': OVSController,
'nox': NOX,
'remote': RemoteController,
'ryu': Ryu,
'ryu': RYU,
'default': DefaultController, # Note: replaced below
'none': NullController }
'none': lambda name: None }
LINKDEF = 'default'
LINKS = { 'default': Link,
@@ -98,21 +97,24 @@ ALTSPELLING = { 'pingall': 'pingAll',
'iperfUDP': 'iperfUdp' }
def addDictOption( opts, choicesDict, default, name, **kwargs ):
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
kwargs: additional arguments to add_option"""
helpStr = ( '|'.join( sorted( choicesDict.keys() ) ) +
'[,param=value...]' )
helpList = [ '%s=%s' % ( k, v.__name__ )
for k, v in choicesDict.items() ]
helpStr += ' ' + ( ' '.join( helpList ) )
params = dict( type='string', default=default, help=helpStr )
params.update( **kwargs )
opts.add_option( '--' + name, **params )
help: string"""
if default not in choicesDict:
raise Exception( 'Invalid default %s for choices dict: %s' %
( default, name ) )
if not helpStr:
helpStr = ( '|'.join( sorted( choicesDict.keys() ) ) +
'[,param=value...]' )
opts.add_option( '--' + name,
type='string',
default = default,
help = helpStr )
def version( *_args ):
"Print Mininet version and exit"
@@ -197,7 +199,7 @@ class MininetRunner( object ):
opts = OptionParser( description=desc, usage=usage )
addDictOption( opts, SWITCHES, SWITCHDEF, 'switch' )
addDictOption( opts, HOSTS, HOSTDEF, 'host' )
addDictOption( opts, CONTROLLERS, [], 'controller', action='append' )
addDictOption( opts, CONTROLLERS, CONTROLLERDEF, 'controller' )
addDictOption( opts, LINKS, LINKDEF, 'link' )
addDictOption( opts, TOPOS, TOPODEF, 'topo' )
@@ -291,28 +293,28 @@ class MininetRunner( object ):
start = time.time()
if not self.options.controller:
if self.options.controller == 'default':
# Update default based on available controllers
CONTROLLERS[ 'default' ] = findController()
self.options.controller = [ 'default' ]
if not CONTROLLERS[ 'default' ]:
self.options.controller = [ 'none' ]
if CONTROLLERS[ 'default' ] is None:
if self.options.switch == 'default':
info( '*** No default OpenFlow controller found '
'for default switch!\n' )
info( '*** Falling back to OVS Bridge\n' )
self.options.switch = 'ovsbr'
elif self.options.switch not in ( 'ovsbr', 'lxbr' ):
self.options.controller = 'none'
elif self.options.switch in ( 'ovsbr', 'lxbr' ):
self.options.controller = 'none'
else:
raise Exception( "Could not find a default controller "
"for switch %s" %
self.options.switch )
topo = buildTopo( TOPOS, self.options.topo )
switch = customClass( SWITCHES, self.options.switch )
host = customClass( HOSTS, self.options.host )
controller = [ customClass( CONTROLLERS, c )
for c in self.options.controller ]
link = customClass( LINKS, self.options.link )
switch = customConstructor( SWITCHES, self.options.switch )
host = customConstructor( HOSTS, self.options.host )
controller = customConstructor( CONTROLLERS, self.options.controller )
link = customConstructor( LINKS, self.options.link )
if self.validate:
self.validate( self.options )
+2 -2
View File
@@ -49,7 +49,7 @@ from mininet.log import info, setLogLevel
from mininet.net import Mininet, VERSION
from mininet.util import netParse, ipAdd, quietRun
from mininet.util import buildTopo
from mininet.util import custom, customClass
from mininet.util import custom, customConstructor
from mininet.term import makeTerm, cleanUpScreens
from mininet.node import Controller, RemoteController, NOX, OVSController
from mininet.node import CPULimitedHost, Host, Node
@@ -3222,7 +3222,7 @@ class MiniEdit( Frame ):
return
self.newTopology()
topo = buildTopo( TOPOS, self.options.topo )
link = customClass( LINKS, self.options.link )
link = customConstructor( LINKS, self.options.link )
importNet = Mininet(topo=topo, build=False, link=link)
importNet.build()
+11 -36
View File
@@ -45,10 +45,6 @@ class CLI( Cmd ):
prompt = 'mininet> '
def __init__( self, mininet, stdin=sys.stdin, script=None ):
"""Start and run interactive or batch mode CLI
mininet: Mininet network object
stdin: standard input for CLI
script: script to run in batch mode"""
self.mn = mininet
# Local variable bindings for py command
self.locals = { 'net': mininet }
@@ -60,54 +56,33 @@ class CLI( Cmd ):
Cmd.__init__( self )
info( '*** Starting CLI:\n' )
if self.inputFile:
self.do_source( self.inputFile )
return
self.initReadline()
self.run()
readlineInited = False
@classmethod
def initReadline( cls ):
"Set up history if readline is available"
# Only set up readline once to prevent multiplying the history file
if cls.readlineInited:
return
cls.readlineInited = True
# Set up history if readline is available
try:
from readline import read_history_file, write_history_file
import readline
except ImportError:
pass
else:
history_path = os.path.expanduser( '~/.mininet_history' )
if os.path.isfile( history_path ):
read_history_file( history_path )
atexit.register( lambda: write_history_file( history_path ) )
history_path = os.path.expanduser('~/.mininet_history')
if os.path.isfile(history_path):
readline.read_history_file(history_path)
atexit.register(lambda: readline.write_history_file(history_path))
def run( self ):
"Run our cmdloop(), catching KeyboardInterrupt"
if self.inputFile:
self.do_source( self.inputFile )
return
while True:
try:
# Make sure no nodes are still waiting
for node in self.mn.values():
while node.waiting:
info( 'stopping', node, '\n' )
node.sendInt()
node.waitOutput()
if self.isatty():
quietRun( 'stty echo sane intr ^C' )
quietRun( 'stty echo sane intr "^C"' )
self.cmdloop()
break
except KeyboardInterrupt:
# Output a message - unless it's also interrupted
# pylint: disable=broad-except
try:
output( '\nInterrupt\n' )
except Exception:
pass
# pylint: enable=broad-except
output( '\nInterrupt\n' )
def emptyline( self ):
"Don't repeat last command when you hit return."
+2 -2
View File
@@ -108,7 +108,7 @@ from mininet.util import ( quietRun, fixLimits, numCores, ensureRoot,
from mininet.term import cleanUpScreens, makeTerms
# Mininet version: should be consistent with README and LICENSE
VERSION = "2.2.1"
VERSION = "2.2.1d1"
class Mininet( object ):
"Network emulation with hosts spawned in network namespaces."
@@ -402,7 +402,7 @@ class Mininet( object ):
if not isinstance( classes, list ):
classes = [ classes ]
for i, cls in enumerate( classes ):
# Allow Controller objects because nobody understands partial()
# Allow Controller objects because nobody understands currying
if isinstance( cls, Controller ):
self.addController( cls )
else:
+65 -33
View File
@@ -23,26 +23,20 @@ Switch: superclass for switch nodes.
UserSwitch: a switch using the user-space switch from the OpenFlow
reference implementation.
OVSSwitch: a switch using the Open vSwitch OpenFlow-compatible switch
KernelSwitch: a switch using the kernel switch from the OpenFlow reference
implementation.
OVSSwitch: a switch using the OpenVSwitch OpenFlow-compatible switch
implementation (openvswitch.org).
OVSBridge: an Ethernet bridge implemented using Open vSwitch.
Supports STP.
IVSSwitch: OpenFlow switch using the Indigo Virtual Switch.
Controller: superclass for OpenFlow controllers. The default controller
is controller(8) from the reference implementation.
OVSController: The test controller from Open vSwitch.
NOXController: a controller node using NOX (noxrepo.org).
Ryu: The Ryu controller (https://osrg.github.io/ryu/)
RemoteController: a remote controller node, which may use any
arbitrary OpenFlow-compatible controller, and which is not
created or managed by Mininet.
created or managed by mininet.
Future enhancements:
@@ -63,7 +57,7 @@ from time import sleep
from mininet.log import info, error, warn, debug
from mininet.util import ( quietRun, errRun, errFail, moveIntf, isShellBuiltin,
numCores, retry, mountCgroups )
from mininet.moduledeps import moduleDeps, pathCheck, TUN
from mininet.moduledeps import moduleDeps, pathCheck, OVS_KMOD, OF_KMOD, TUN
from mininet.link import Link, Intf, TCIntf, OVSIntf
from re import findall
from distutils.version import StrictVersion
@@ -513,13 +507,15 @@ class Node( object ):
mac: MAC address as string"""
return self.intf( intf ).setMAC( mac )
def setIP( self, ip, prefixLen=8, intf=None, **kwargs ):
def setIP( self, ip, prefixLen=8, intf=None ):
"""Set the IP address for an interface.
intf: intf or intf name
ip: IP address as a string
prefixLen: prefix length, e.g. 8 for /8 or 16M addrs
kwargs: any additional arguments for intf.setIP"""
return self.intf( intf ).setIP( ip, prefixLen, **kwargs )
prefixLen: prefix length, e.g. 8 for /8 or 16M addrs"""
# This should probably be rethought
if '/' not in ip:
ip = '%s/%s' % ( ip, prefixLen )
return self.intf( intf ).setIP( ip )
def IP( self, intf=None ):
"Return IP address of a node or specific interface."
@@ -901,12 +897,6 @@ class Switch( Node ):
debug( 'Assuming', repr( self ), 'is connected to a controller\n' )
return True
def stop( self, deleteIntfs=True ):
"""Stop switch
deleteIntfs: delete interfaces? (True)"""
if deleteIntfs:
self.deleteIntfs()
def __repr__( self ):
"More informative string representation"
intfs = ( ','.join( [ '%s:%s' % ( i.name, i.IP() )
@@ -1013,6 +1003,56 @@ class UserSwitch( Switch ):
self.cmd( 'kill %ofprotocol' )
super( UserSwitch, self ).stop( deleteIntfs )
class OVSLegacyKernelSwitch( Switch ):
"""Open VSwitch legacy kernel-space switch using ovs-openflowd.
Currently only works in the root namespace."""
def __init__( self, name, dp=None, **kwargs ):
"""Init.
name: name for switch
dp: netlink id (0, 1, 2, ...)
defaultMAC: default MAC as unsigned int; random value if None"""
Switch.__init__( self, name, **kwargs )
self.dp = dp if dp else self.name
self.intf = self.dp
if self.inNamespace:
error( "OVSKernelSwitch currently only works"
" in the root namespace.\n" )
exit( 1 )
@classmethod
def setup( cls ):
"Ensure any dependencies are loaded; if not, try to load them."
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."
ofplog = '/tmp/' + self.name + '-ofp.log'
# Delete local datapath if it exists;
# then create a new one monitoring the given interfaces
self.cmd( 'ovs-dpctl del-dp ' + self.dp )
self.cmd( 'ovs-dpctl add-dp ' + self.dp )
intfs = [ str( i ) for i in self.intfList() if not i.IP() ]
self.cmd( 'ovs-dpctl', 'add-if', self.dp, ' '.join( intfs ) )
# Run protocol daemon
clist = ','.join( [ 'tcp:%s:%d' % ( c.IP(), c.port )
for c in controllers ] )
self.cmd( 'ovs-openflowd ' + self.dp +
' ' + clist +
' --fail=secure ' + self.opts +
' --datapath-id=' + self.dpid +
' 1>' + ofplog + ' 2>' + ofplog + '&' )
self.execed = False
def stop( self, deleteIntfs=True ):
"""Terminate kernel datapath."
deleteIntfs: delete interfaces? (True)"""
quietRun( 'ovs-dpctl del-dp ' + self.dp )
self.cmd( 'kill %ovs-openflowd' )
super( OVSLegacyKernelSwitch, self ).stop( deleteIntfs )
class OVSSwitch( Switch ):
"Open vSwitch switch. Depends on ovs-vsctl."
@@ -1249,14 +1289,11 @@ OVSKernelSwitch = OVSSwitch
class OVSBridge( OVSSwitch ):
"OVSBridge is an OVSSwitch in standalone/bridge mode"
def __init__( self, *args, **kwargs ):
"""stp: enable Spanning Tree Protocol (False)
see OVSSwitch for other options"""
def __init__( self, args, **kwargs ):
kwargs.update( failMode='standalone' )
OVSSwitch.__init__( self, *args, **kwargs )
OVSSwitch.__init__( self, args, **kwargs )
def start( self, controllers ):
"Start bridge, ignoring controllers argument"
OVSSwitch.start( self, controllers=[] )
def connected( self ):
@@ -1451,7 +1488,7 @@ class NOX( Controller ):
cdir=noxCoreDir,
**kwargs )
class Ryu( Controller ):
class RYU( Controller ):
"Controller to run Ryu application"
def __init__( self, name, *ryuArgs, **kwargs ):
"""Init.
@@ -1473,7 +1510,6 @@ class Ryu( Controller ):
cdir=ryuCoreDir,
**kwargs )
class RemoteController( Controller ):
"Controller running outside of Mininet's control."
@@ -1517,7 +1553,3 @@ def DefaultController( name, controllers=DefaultControllers, **kwargs ):
if not controller:
raise Exception( 'Could not find a default OpenFlow controller' )
return controller( name, **kwargs )
def NullController( *_args, **_kwargs ):
"Nonexistent controller - simply returns None"
return None
+2 -3
View File
@@ -35,7 +35,7 @@ def tunnelX11( node, display=None):
"EXEC:'mnexec -a 1 socat STDIO %s'" % connection ]
return 'localhost:' + screen, node.popen( cmd )
def makeTerm( node, title='Node', term='xterm', display=None, cmd='bash'):
def makeTerm( node, title='Node', term='xterm', display=None ):
"""Create an X11 tunnel to the node and start up a terminal.
node: Node object
title: base title
@@ -54,8 +54,7 @@ def makeTerm( node, title='Node', term='xterm', display=None, cmd='bash'):
display, tunnel = tunnelX11( node, display )
if display is None:
return []
term = node.popen( cmds[ term ] +
[ display, '-e', 'env TERM=ansi %s' % cmd ] )
term = node.popen( cmds[ term ] + [ display, '-e', 'env TERM=ansi bash'] )
return [ tunnel, term ] if tunnel else [ term ]
def runX11( node, cmd ):
+8 -1
View File
@@ -8,7 +8,8 @@ import sys
from mininet.net import Mininet
from mininet.node import Host, Controller
from mininet.node import ( UserSwitch, OVSSwitch, IVSSwitch )
from mininet.node import ( UserSwitch, OVSSwitch, OVSLegacyKernelSwitch,
IVSSwitch )
from mininet.topo import Topo
from mininet.log import setLogLevel
from mininet.util import quietRun
@@ -80,6 +81,12 @@ class testSwitchOVSUser( TestSwitchDpidAssignmentOVS ):
"Test dpid assignnment of OVS User Switch."
switchClass = OVSUser
@unittest.skipUnless( quietRun( 'which ovs-openflowd' ),
'OVS Legacy Kernel switch is not installed' )
class testSwitchOVSLegacyKernel( TestSwitchDpidAssignmentOVS ):
"Test dpid assignnment of OVS Legacy Kernel Switch."
switchClass = OVSLegacyKernelSwitch
@unittest.skipUnless( quietRun( 'which ivs-ctl' ),
'IVS switch is not installed' )
class testSwitchIVS( TestSwitchDpidAssignmentOVS ):
-6
View File
@@ -318,12 +318,6 @@ class SingleSwitchReversedTopo( Topo ):
port1=0, port2=( k - h + 1 ) )
class MinimalTopo( SingleSwitchTopo ):
"Minimal topology with two hosts and one switch"
def build( self ):
return SingleSwitchTopo.build( self, k=2 )
class LinearTopo( Topo ):
"Linear topology of k switches, with n hosts per switch."
+28
View File
@@ -1,6 +1,7 @@
"Library of potentially useful topologies for Mininet"
from mininet.topo import Topo
from mininet.nodelib import NAT
from mininet.net import Mininet
# The build() method is expected to do this:
@@ -69,4 +70,31 @@ class TorusTopo( Topo ):
self.addLink( sw1, sw2 )
self.addLink( sw1, sw3 )
def Natted( topoClass ):
"Return a natted Topo class based on topoClass"
class NattedTopo( topoClass ):
"Customized topology with attached NAT"
def build( self, *args, **kwargs ):
"""Build topo with NAT attachment
natIP: local IP address of NAT node for routing ('10.0.0.254')
connect: switch to connect NAT node to ('s1')"""
self.natIP = kwargs.pop( 'natIP', '10.0.0.254')
self.connect = kwargs.pop( 'connect', 's1' )
self.hopts.update( defaultRoute='via ' + self.natIP )
super( NattedTopo, self ).build( *args, **kwargs )
nat1 = self.addNode( 'nat1', cls=NAT, ip=self.natIP,
inNamespace=False )
self.addLink( self.connect, nat1 )
return NattedTopo
def natted( topoClass, *args, **kwargs ):
"""Create and invoke natted version of topoClass
natIP: local IP address of NAT node for routing ('10.0.0.254')
connect: switch to connect NAT node to ('s1')
usage: topo = natted( TreeTopo, depth=2, fanout=2 )"""
topoClass = Natted( topoClass )
return topoClass( *args, **kwargs )
# pylint: enable=arguments-differ
+27 -39
View File
@@ -523,55 +523,43 @@ def splitArgs( argstr ):
kwargs[ key ] = makeNumeric( val )
return fn, args, kwargs
def customClass( classes, argStr ):
"""Return customized class based on argStr
The args and key/val pairs in argStr will be automatically applied
when the generated class is later used.
def customConstructor( constructors, argStr ):
"""Return custom constructor based on argStr
The args and key/val pairs in argsStr will be automatically applied
when the generated constructor is later used.
"""
cname, args, kwargs = splitArgs( argStr )
cls = classes.get( cname, None )
if not cls:
cname, newargs, kwargs = splitArgs( argStr )
constructor = constructors.get( cname, None )
if not constructor:
raise Exception( "error: %s is unknown - please specify one of %s" %
( cname, classes.keys() ) )
if not args and not kwargs:
return cls
( cname, constructors.keys() ) )
return specialClass( cls, append=args, defaults=kwargs )
if not newargs and not kwargs:
return constructor
def specialClass( cls, prepend=None, append=None,
defaults=None, override=None ):
"""Like functools.partial, but it returns a class
prepend: arguments to prepend to argument list
append: arguments to append to argument list
defaults: default values for keyword arguments
override: keyword arguments to override"""
if not isinstance( constructor, type ):
raise Exception( "error: invalid arguments %s" % argStr )
if prepend is None:
prepend = []
if append is None:
append = []
if defaults is None:
defaults = {}
if override is None:
override = {}
# Return a customized subclass
cls = constructor
class CustomClass( cls ):
"Customized subclass with preset args/params"
def __init__( self, *args, **params ):
newparams = defaults.copy()
newparams.update( params )
newparams.update( override )
cls.__init__( self, *( list( prepend ) + list( args ) +
list( append ) ),
**newparams )
"Customized subclass, useful for Node, Link, and other classes"
def __init__( self, name, *args, **params ):
params = params.copy()
params.update( kwargs )
if not newargs:
cls.__init__( self, name, *args, **params )
return
if args:
warn( 'warning: %s replacing %s with %s\n' %
( constructor, args, newargs ) )
cls.__init__( self, name, *newargs, **params )
CustomClass.__name__ = '%s%s' % ( cls.__name__, defaults )
CustomClass.__name__ = '%s%s' % ( cls.__name__, kwargs )
return CustomClass
def buildTopo( topos, topoStr ):
"""Create topology from string with format (object, arg1, arg2,...).
input topos is a dict of topo names to constructors, possibly w/args.
+24 -24
View File
@@ -25,20 +25,20 @@ clean=false
declare -a hosts=()
user=$(whoami)
SSHDIR=/tmp/mn/ssh
USERDIR=$HOME/.ssh
usage="./clustersetup.sh [ -p|h|c ] [ host1 ] [ host2 ] ...\n
USERDIR=/home/$user/.ssh
usage=$'./clustersetup.sh [ -p|h|c ] [ host1 ] [ host2 ] ...\n
Authenticate yourself and other cluster nodes to each other
via ssh for mininet cluster edition. By default, we use a
temporary ssh setup. An ssh directory is mounted over
$USERDIR on each machine in the cluster.
/home/user/.ssh on each machine in the cluster.
-h: display this help
-p: create a persistent ssh setup. This will add
new ssh keys and known_hosts to each nodes
$USERDIR directory
/home/user/.ssh directory
-c: method to clean up a temporary ssh setup.
Any hosts taken as arguments will be cleaned
"
'
persistentSetup() {
echo "***creating key pair"
@@ -74,40 +74,40 @@ tempSetup() {
echo "***creating temporary ssh directory"
mkdir -p $SSHDIR
echo "***creating key pair"
ssh-keygen -t rsa -C "Cluster_Edition_Key" -f $SSHDIR/id_rsa -N '' &> /dev/null
ssh-keygen -t rsa -C "Cluster_Edition_Key" -f /tmp/mn/ssh/id_rsa -N '' &> /dev/null
echo "***mounting temporary ssh directory"
sudo mount --bind $SSHDIR $USERDIR
sudo mount --bind $SSHDIR /home/$user/.ssh
cp $SSHDIR/id_rsa.pub $SSHDIR/authorized_keys
for host in $hosts; do
echo "***copying public key to $host"
ssh-copy-id $user@$host &> /dev/null
echo "***mounting remote temporary ssh directory for $host"
ssh -o ForwardAgent=yes $user@$host "
mkdir -p $SSHDIR
cp $USERDIR/authorized_keys $SSHDIR/authorized_keys
sudo mount --bind $SSHDIR $USERDIR"
echo "***copying key pair to $host"
scp $SSHDIR/{id_rsa,id_rsa.pub} $user@$host:$SSHDIR
done
for host in $hosts; do
echo "***copying public key to $host"
ssh-copy-id $user@$host &> /dev/null
echo "***mounting remote temporary ssh directory for $host"
ssh -o ForwardAgent=yes $user@$host "
mkdir -p /tmp/mn/ssh
cp /home/$user/.ssh/authorized_keys $SSHDIR/authorized_keys
sudo mount --bind $SSHDIR /home/$user/.ssh"
echo "***copying key pair to $host"
scp $SSHDIR/{id_rsa,id_rsa.pub} $user@$host:$SSHDIR
done
for host in $hosts; do
echo "***copying known_hosts to $host"
scp $SSHDIR/known_hosts $user@$host:$SSHDIR
done
for host in $hosts; do
echo "***copying known_hosts to $host"
scp $SSHDIR/known_hosts $user@$host:$SSHDIR
done
}
cleanup() {
for host in $hosts; do
echo "***cleaning up $host"
ssh $user@$host "sudo umount $USERDIR
ssh $user@$host "sudo umount /home/$user/.ssh
sudo rm -rf $SSHDIR"
done
echo "**unmounting local directories"
sudo umount $USERDIR
sudo umount /home/$user/.ssh
echo "***removing temporary ssh directory"
sudo rm -rf $SSHDIR
echo "done!"
+60 -83
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Mininet install script for Ubuntu (and Debian Wheezy+)
# Mininet install script for Ubuntu (and Debian Lenny)
# Brandon Heller (brandonh@stanford.edu)
# Fail on error
@@ -102,10 +102,7 @@ OF13_SWITCH_REV=${OF13_SWITCH_REV:-""}
function kernel {
echo "Install Mininet-compatible kernel if necessary"
sudo apt-get update
if ! $install linux-image-$KERNEL_NAME; then
echo "Could not install linux-image-$KERNEL_NAME"
echo "Skipping - assuming installed kernel is OK."
fi
$install linux-image-$KERNEL_NAME
}
function kernel_clean {
@@ -192,24 +189,17 @@ function of13 {
fi
# Install netbee
if [ "$DIST" = "Ubuntu" ] && version_ge $RELEASE 14.04; then
NBEESRC="nbeesrc-feb-24-2015"
NBEEDIR="netbee"
else
NBEESRC="nbeesrc-jan-10-2013"
NBEEDIR="nbeesrc-jan-10-2013"
fi
NBEESRC="nbeesrc-jan-10-2013"
NBEEURL=${NBEEURL:-http://www.nbee.org/download/}
wget -nc ${NBEEURL}${NBEESRC}.zip
unzip ${NBEESRC}.zip
cd ${NBEEDIR}/src
cd ${NBEESRC}/src
cmake .
make
cd $BUILD_DIR/
sudo cp ${NBEEDIR}/bin/libn*.so /usr/local/lib
sudo cp ${NBEESRC}/bin/libn*.so /usr/local/lib
sudo ldconfig
sudo cp -R ${NBEEDIR}/include/ /usr/
sudo cp -R ${NBEESRC}/include/ /usr/
# Resume the install:
cd $BUILD_DIR/ofsoftswitch13
@@ -268,63 +258,53 @@ function ubuntuOvs {
OVS_SRC=$BUILD_DIR/openvswitch
OVS_TARBALL_LOC=http://openvswitch.org/releases
if ! echo "$DIST" | egrep "Ubuntu|Debian" > /dev/null; then
echo "OS must be Ubuntu or Debian"
$cd BUILD_DIR
return
fi
if [ "$DIST" = "Ubuntu" ] && ! version_ge $RELEASE 12.04; then
echo "Ubuntu version must be >= 12.04"
cd $BUILD_DIR
return
fi
if [ "$DIST" = "Debian" ] && ! version_ge $RELEASE 7.0; then
echo "Debian version must be >= 7.0"
cd $BUILD_DIR
return
fi
if [ "$DIST" = "Ubuntu" ] && version_ge $RELEASE 12.04; then
rm -rf $OVS_SRC
mkdir -p $OVS_SRC
cd $OVS_SRC
rm -rf $OVS_SRC
mkdir -p $OVS_SRC
cd $OVS_SRC
if wget $OVS_TARBALL_LOC/openvswitch-$OVS_RELEASE.tar.gz 2> /dev/null; then
tar xzf openvswitch-$OVS_RELEASE.tar.gz
else
echo "Failed to find OVS at $OVS_TARBALL_LOC/openvswitch-$OVS_RELEASE.tar.gz"
cd $BUILD_DIR
return
fi
if wget $OVS_TARBALL_LOC/openvswitch-$OVS_RELEASE.tar.gz 2> /dev/null; then
tar xzf openvswitch-$OVS_RELEASE.tar.gz
# Remove any old packages
$remove openvswitch-common openvswitch-datapath-dkms openvswitch-controller \
openvswitch-pki openvswitch-switch
# Get build deps
$install build-essential fakeroot debhelper autoconf automake libssl-dev \
pkg-config bzip2 openssl python-all procps python-qt4 \
python-zopeinterface python-twisted-conch dkms
# Build OVS
cd $BUILD_DIR/openvswitch/openvswitch-$OVS_RELEASE
DEB_BUILD_OPTIONS='parallel=2 nocheck' fakeroot debian/rules binary
cd ..
$pkginst openvswitch-common_$OVS_RELEASE*.deb openvswitch-datapath-dkms_$OVS_RELEASE*.deb \
openvswitch-pki_$OVS_RELEASE*.deb openvswitch-switch_$OVS_RELEASE*.deb
if $pkginst openvswitch-controller_$OVS_RELEASE*.deb; then
echo "Ignoring error installing openvswitch-controller"
fi
modinfo openvswitch
sudo ovs-vsctl show
# Switch can run on its own, but
# Mininet should control the controller
# This appears to only be an issue on Ubuntu/Debian
if sudo service openvswitch-controller stop; then
echo "Stopped running controller"
fi
if [ -e /etc/init.d/openvswitch-controller ]; then
sudo update-rc.d openvswitch-controller disable
fi
else
echo "Failed to find OVS at $OVS_TARBALL_LOC/openvswitch-$OVS_RELEASE.tar.gz"
cd $BUILD_DIR
return
fi
# Remove any old packages
$remove openvswitch-common openvswitch-datapath-dkms openvswitch-controller \
openvswitch-pki openvswitch-switch
# Get build deps
$install build-essential fakeroot debhelper autoconf automake libssl-dev \
pkg-config bzip2 openssl python-all procps python-qt4 \
python-zopeinterface python-twisted-conch dkms
# Build OVS
cd $BUILD_DIR/openvswitch/openvswitch-$OVS_RELEASE
DEB_BUILD_OPTIONS='parallel=2 nocheck' fakeroot debian/rules binary
cd ..
$pkginst openvswitch-common_$OVS_RELEASE*.deb openvswitch-datapath-dkms_$OVS_RELEASE*.deb \
openvswitch-pki_$OVS_RELEASE*.deb openvswitch-switch_$OVS_RELEASE*.deb
if $pkginst openvswitch-controller_$OVS_RELEASE*.deb; then
echo "Ignoring error installing openvswitch-controller"
fi
modinfo openvswitch
sudo ovs-vsctl show
# Switch can run on its own, but
# Mininet should control the controller
# This appears to only be an issue on Ubuntu/Debian
if sudo service openvswitch-controller stop; then
echo "Stopped running controller"
fi
if [ -e /etc/init.d/openvswitch-controller ]; then
sudo update-rc.d openvswitch-controller disable
echo "Failed to install Open vSwitch. OS must be Ubuntu >= 12.04"
cd $BUILD_DIR
return
fi
}
@@ -339,17 +319,14 @@ function ovs {
return
fi
if [ "$DIST" = "Ubuntu" ] && ! version_ge $RELEASE 14.04; then
# Older Ubuntu versions need openvswitch-datapath/-dkms
# Manually installing openvswitch-datapath may be necessary
# for manually built kernel .debs using Debian's defective kernel
# packaging, which doesn't yield usable headers.
if ! dpkg --get-selections | grep openvswitch-datapath; then
# If you've already installed a datapath, assume you
# know what you're doing and don't need dkms datapath.
# Otherwise, install it.
$install openvswitch-datapath-dkms
fi
# Manually installing openvswitch-datapath may be necessary
# for manually built kernel .debs using Debian's defective kernel
# packaging, which doesn't yield usable headers.
if ! dpkg --get-selections | grep openvswitch-datapath; then
# If you've already installed a datapath, assume you
# know what you're doing and don't need dkms datapath.
# Otherwise, install it.
$install openvswitch-datapath-dkms
fi
$install openvswitch-switch
@@ -366,7 +343,7 @@ function ovs {
else
echo "Attempting to install openvswitch-testcontroller"
if ! $install openvswitch-testcontroller; then
echo "Failed - skipping openvswitch-testcontroller"
echo "Failed - giving up"
fi
fi
@@ -590,7 +567,7 @@ net.ipv6.conf.lo.disable_ipv6 = 1' | sudo tee -a /etc/sysctl.conf > /dev/null
# Since the above doesn't disable neighbor discovery, also do this:
if ! grep 'ipv6.disable' /etc/default/grub; then
sudo sed -i -e \
's/GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 /' \
's/GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1/' \
/etc/default/grub
sudo update-grub
fi
+1 -1
View File
@@ -323,7 +323,7 @@ zerombr yes
clearpart --all --initlabel
#Automatic partitioning
autopart
#System authorization information
#System authorization infomation
auth --useshadow --enablemd5
#Firewall configuration
firewall --disabled