Working on examples.
Added new example to create xterms. Other minor changes.
This commit is contained in:
@@ -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:
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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 )
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Executable
+14
@@ -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()
|
||||||
|
|
||||||
Executable
+39
@@ -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
@@ -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 ):
|
||||||
|
|||||||
Reference in New Issue
Block a user