Working on examples.

Added new example to create xterms.
Other minor changes.
This commit is contained in:
Bob Lantz
2009-12-10 23:39:06 -08:00
parent 4ccc7ee941
commit 748e35d50f
6 changed files with 117 additions and 43 deletions
+23 -19
View File
@@ -1,6 +1,6 @@
Mininet: A Simple Virtual Testbed for OpenFlow Mininet: A Simple Virtual Testbed for OpenFlow
aka aka
How to Squeeze a 1024-node OpenFlow Network onto your Laptop How to Squeeze a 1024-node OpenFlow Network onto your Laptop
(Extremely Experimental Development Version 0.1, December 2009) (Extremely Experimental Development Version 0.1, December 2009)
@@ -10,40 +10,44 @@ How to Squeeze a 1024-node OpenFlow Network onto your Laptop
Mininet creates simple OpenFlow test networks by using process-based Mininet creates simple OpenFlow test networks by using process-based
virtualization and network namespaces. virtualization and network namespaces.
Simulated hosts (as well as switches and controllers with the user datapath) Simulated hosts (as well as switches and controllers with the user
are created as processes in separate network namespaces. This allows a datapath) are created as processes in separate network namespaces. This
complete OpenFlow network to be simulated on top of a single Linux kernel. allows a complete OpenFlow network to be simulated on top of a single
Linux kernel.
In order to run Mininet, you must have: In order to run Mininet, you must have:
* A Linux 2.6.26 or greater kernel compiled with network namespace support * A Linux 2.6.26 or greater kernel compiled with network namespace support
enabled. (Debian-testing should work.) enabled. (Debian 5.0 or greater should work.)
* The OpenFlow reference implementation (either the user or kernel datapath * The OpenFlow reference implementation (either the user or kernel
may be used, and the tun or ofdatapath kernel modules must be loaded, datapath may be used, and the tun or ofdatapath kernel modules must be
respectively) loaded, respectively)
* Python, Bash, etc. * Python, Bash, etc.
* Root privilieges (required for network device access) * Root privilieges (required for network device access)
* The netns program or equivalent (included as netns.c) * The netns program or equivalent (included as netns.c) installed
in an appropriate path location.
* mininet.py installed in an appropriate Python path location.
Currently mininet includes: Currently mininet includes:
A simple node infrastructure (Host, Switch, Controller classes) for - A simple node infrastructure (Host, Switch, Controller classes) for
creating virtual OpenFlow networks. creating virtual OpenFlow networks.
A simple network infrastructure (class Network and its descendants - A simple network infrastructure (class Network and its descendants
TreeNet, GridNet and LinearNet) for creating scalable topologies and TreeNet, GridNet and LinearNet) for creating scalable topologies and
running experiments (using someNetwork.run( test ) ) running experiments (using someNetwork.run( test ) )
Some simple tests which can be run by someNetwork.run( test ) - Some simple tests which can be run using someNetwork.run( test )
A simple command-line interface which may be invoked on a network - A simple command-line interface which may be invoked on a network using
using .run( Cli ) .run( Cli )
Examples (in examples/ directory) to help you get started. - Examples (in examples/ directory) to help you get started.
Notes and Advice: Notes and Advice:
+6 -7
View File
@@ -1,22 +1,21 @@
#!/usr/bin/python #!/usr/bin/python
"""Create a tree network of depth 4 and fanout 2, and
test connectivity using pingTest."""
from mininet import init, TreeNet, iperfTest from mininet import init, TreeNet, iperfTest
def bigTreePing64(): def bigTreePing64():
"""Create a tree network of depth 4 and fanout 2, and
test connectivity using pingTest."""
results = {} results = {}
print "*** Testing Mininet with kernel and user datapath" print "*** Testing Mininet with kernel and user datapath"
for datapath in [ 'kernel', 'user' ]: for datapath in [ 'kernel', 'user' ]:
k = datapath == 'kernel' k = datapath == 'kernel'
results[ datapath ] = [] results[ datapath ] = []
for switchCount in range( 1, 4 ): for switchCount in range( 1, 4 ):
print "*** Creating Linear Network of size", switchCount network = TreeNet( depth=4, fanout=4, kernel=k )
network = TreeNet( depth=4, fanout=2, kernel=k ) testResult = network.run( pingTest )
testResult = network.run( iperfTest )
results[ datapath ] += testResult results[ datapath ] += testResult
print "*** Test results:", results print "*** Test results:", results
+24 -13
View File
@@ -1,36 +1,47 @@
#!/usr/bin/python #!/usr/bin/python
"""
Test bandwidth on a linear network of varying size, using both
the kernel and user datapaths.
The network looks like:
h0 <-> s0 <-> s1 .. sN <-> h1
"""
from mininet import init, LinearNet, iperfTest from mininet import init, LinearNet, iperfTest
def linearBandwidthTest(): def linearBandwidthTest():
"""Test bandwidth on a linear network of varying size, using both
the kernel and user datapaths.""" datapaths = [ 'kernel', 'user' ]
switchCounts = [ 1, 20, 40, 60, 80, 100 ]
print "*** Testing Mininet with kernel and user datapath"
datapaths = [ 'kernel' ]
results = {} results = {}
for datapath in datapaths: for datapath in datapaths:
k = datapath == 'kernel' k = datapath == 'kernel'
results[ datapath ] = [] results[ datapath ] = []
for switchCount in range( 1, 17, 2 ): for switchCount in switchCounts:
print "*** Creating Linear Network of size", switchCount print "*** Creating linear network of size", switchCount
network = LinearNet( switchCount, k) network = LinearNet( switchCount, k)
bandwidth = network.run( iperfTest ) bandwidth = network.run( iperfTest )
results[ datapath ] += [ ( switchCount, bandwidth ) ] results[ datapath ] += [ ( switchCount, bandwidth ) ]
for datapath in datapaths: for datapath in datapaths:
print print
print "*** Linear network results for", datapath, "datapath" print "*** Linear network results for", datapath, "datapath:"
print print
result = results[ datapath ] result = results[ datapath ]
print "SwitchCount\tiPerf results"
for switchCount, bandwidth in result: for switchCount, bandwidth in result:
print "switchCount:", switchCount, "bandwidth:", bandwidth[ 0 ] print switchCount, '\t\t',
print bandwidth[ 0 ], 'server, ', bandwidth[ 1 ], 'client'
print
print
if __name__ == '__main__': if __name__ == '__main__':
init() init()
print "*** Running linearBandwidthTest"
linearBandwidthTest() linearBandwidthTest()
exit( 1 ) exit( 1 )
+14
View File
@@ -0,0 +1,14 @@
#!/usr/bin/python
"""Create a tree network and run the CLI on it."""
from mininet import init, TreeNet, Cli
def treeInteract():
network = TreeNet( depth=2, fanout=4, kernel=True )
network.run( Cli )
if __name__ == '__main__':
init()
treeInteract()
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/python
"Create a network and run an xterm (connected via screen) on each host."
import os
from subprocess import Popen
from mininet import init, TreeNet, Cli, quietRun
def makeXterm( node, title ):
"Run screen on a node, and hook up an xterm."
node.cmdPrint( 'screen -dmS ' + node.name )
cmd = 'xterm -title ' + title + ':' + node.name
cmd += ' -e screen -D -RR -S ' + node.name
return Popen( cmd.split( ' ' ) )
def makeXterms( nodes, title ):
terms = []
for node in nodes:
if not node.execed:
terms += [ makeXterm( node, title ) ]
return terms
def xterms( controllers, switches, hosts ):
terms = []
terms += makeXterms( controllers, 'controller' )
terms += makeXterms( switches, 'switch' )
terms += makeXterms( hosts, 'host' )
# Wait for completion
for term in terms:
os.waitpid( term.pid, 0 )
def treeXterms():
print "Running xterms on", os.environ[ 'DISPLAY' ]
network = TreeNet( depth=2, fanout=4, kernel=True )
network.run( xterms )
if __name__ == '__main__':
init()
treeXterms()
+11 -4
View File
@@ -126,10 +126,16 @@ class Node( object ):
self.ips = {} self.ips = {}
self.connection = {} self.connection = {}
self.waiting = False self.waiting = False
self.execed = False
def cleanup( self ):
# Help python collect its garbage
self.shell = None
# Subshell I/O, commands and control # Subshell I/O, commands and control
def read( self, max ): return os.read( self.stdout.fileno(), max ) def read( self, max ): return os.read( self.stdout.fileno(), max )
def write( self, data ): os.write( self.stdin.fileno(), data ) def write( self, data ): os.write( self.stdin.fileno(), data )
def terminate( self ): os.kill( self.pid, signal.SIGKILL ) def terminate( self ):
self.cleanup()
os.kill( self.pid, signal.SIGKILL )
def waitReadable( self ): self.pollOut.poll() def waitReadable( self ): self.pollOut.poll()
def sendCmd( self, cmd ): def sendCmd( self, cmd ):
"""Send a command, followed by a command to echo a sentinel, """Send a command, followed by a command to echo a sentinel,
@@ -251,7 +257,6 @@ class Switch( Node ):
an OpenFlow switch.""" an OpenFlow switch."""
def __init__( self, name, datapath=None ): def __init__( self, name, datapath=None ):
self.dp = datapath self.dp = datapath
self.execed = False
Node.__init__( self, name, inNamespace=( datapath == None ) ) Node.__init__( self, name, inNamespace=( datapath == None ) )
def startUserDatapath( self, controller ): def startUserDatapath( self, controller ):
"""Start OpenFlow reference user datapath, """Start OpenFlow reference user datapath,
@@ -470,10 +475,12 @@ class Network( object ):
print "*** Running test" print "*** Running test"
result = test( [ controller ], switches, hosts ) result = test( [ controller ], switches, hosts )
print "*** Stopping controller" print "*** Stopping controller"
controller.stop() controller.stop(); controller.terminate()
print "*** Stopping switches" print "*** Stopping switches"
for switch in switches: for switch in switches:
switch.stop() switch.stop() ; switch.terminate()
print "*** Stopping hosts"
for host in hosts: host.terminate()
print "*** Test complete" print "*** Test complete"
return result return result
def interact( self ): def interact( self ):