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
|
||||
aka
|
||||
Mininet: A Simple Virtual Testbed for OpenFlow
|
||||
aka
|
||||
How to Squeeze a 1024-node OpenFlow Network onto your Laptop
|
||||
|
||||
(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
|
||||
virtualization and network namespaces.
|
||||
|
||||
Simulated hosts (as well as switches and controllers with the user datapath)
|
||||
are created as processes in separate network namespaces. This allows a
|
||||
complete OpenFlow network to be simulated on top of a single Linux kernel.
|
||||
Simulated hosts (as well as switches and controllers with the user
|
||||
datapath) are created as processes in separate network namespaces. This
|
||||
allows a complete OpenFlow network to be simulated on top of a single
|
||||
Linux kernel.
|
||||
|
||||
In order to run Mininet, you must have:
|
||||
|
||||
* 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
|
||||
may be used, and the tun or ofdatapath kernel modules must be loaded,
|
||||
respectively)
|
||||
* The OpenFlow reference implementation (either the user or kernel
|
||||
datapath may be used, and the tun or ofdatapath kernel modules must be
|
||||
loaded, respectively)
|
||||
|
||||
* Python, Bash, etc.
|
||||
|
||||
* 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:
|
||||
|
||||
A simple node infrastructure (Host, Switch, Controller classes) for
|
||||
creating virtual OpenFlow networks.
|
||||
- A simple node infrastructure (Host, Switch, Controller classes) for
|
||||
creating virtual OpenFlow networks.
|
||||
|
||||
A simple network infrastructure (class Network and its descendants
|
||||
TreeNet, GridNet and LinearNet) for creating scalable topologies and
|
||||
running experiments (using someNetwork.run( test ) )
|
||||
- A simple network infrastructure (class Network and its descendants
|
||||
TreeNet, GridNet and LinearNet) for creating scalable topologies and
|
||||
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
|
||||
using .run( Cli )
|
||||
- A simple command-line interface which may be invoked on a network using
|
||||
.run( Cli )
|
||||
|
||||
Examples (in examples/ directory) to help you get started.
|
||||
- Examples (in examples/ directory) to help you get started.
|
||||
|
||||
Notes and Advice:
|
||||
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
"""Create a tree network of depth 4 and fanout 2, and
|
||||
test connectivity using pingTest."""
|
||||
|
||||
from mininet import init, TreeNet, iperfTest
|
||||
|
||||
def bigTreePing64():
|
||||
"""Create a tree network of depth 4 and fanout 2, and
|
||||
test connectivity using pingTest."""
|
||||
|
||||
results = {}
|
||||
|
||||
|
||||
print "*** Testing Mininet with kernel and user datapath"
|
||||
|
||||
for datapath in [ 'kernel', 'user' ]:
|
||||
k = datapath == 'kernel'
|
||||
results[ datapath ] = []
|
||||
for switchCount in range( 1, 4 ):
|
||||
print "*** Creating Linear Network of size", switchCount
|
||||
network = TreeNet( depth=4, fanout=2, kernel=k )
|
||||
testResult = network.run( iperfTest )
|
||||
network = TreeNet( depth=4, fanout=4, kernel=k )
|
||||
testResult = network.run( pingTest )
|
||||
results[ datapath ] += testResult
|
||||
|
||||
print "*** Test results:", results
|
||||
|
||||
+24
-13
@@ -1,36 +1,47 @@
|
||||
#!/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
|
||||
|
||||
def linearBandwidthTest():
|
||||
"""Test bandwidth on a linear network of varying size, using both
|
||||
the kernel and user datapaths."""
|
||||
|
||||
print "*** Testing Mininet with kernel and user datapath"
|
||||
|
||||
datapaths = [ 'kernel' ]
|
||||
|
||||
datapaths = [ 'kernel', 'user' ]
|
||||
switchCounts = [ 1, 20, 40, 60, 80, 100 ]
|
||||
results = {}
|
||||
|
||||
|
||||
for datapath in datapaths:
|
||||
k = datapath == 'kernel'
|
||||
results[ datapath ] = []
|
||||
for switchCount in range( 1, 17, 2 ):
|
||||
print "*** Creating Linear Network of size", switchCount
|
||||
for switchCount in switchCounts:
|
||||
print "*** Creating linear network of size", switchCount
|
||||
network = LinearNet( switchCount, k)
|
||||
bandwidth = network.run( iperfTest )
|
||||
results[ datapath ] += [ ( switchCount, bandwidth ) ]
|
||||
|
||||
for datapath in datapaths:
|
||||
print
|
||||
print "*** Linear network results for", datapath, "datapath"
|
||||
print "*** Linear network results for", datapath, "datapath:"
|
||||
print
|
||||
result = results[ datapath ]
|
||||
print "SwitchCount\tiPerf results"
|
||||
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__':
|
||||
init()
|
||||
print "*** Running linearBandwidthTest"
|
||||
linearBandwidthTest()
|
||||
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.connection = {}
|
||||
self.waiting = False
|
||||
self.execed = False
|
||||
def cleanup( self ):
|
||||
# Help python collect its garbage
|
||||
self.shell = None
|
||||
# Subshell I/O, commands and control
|
||||
def read( self, max ): return os.read( self.stdout.fileno(), max )
|
||||
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 sendCmd( self, cmd ):
|
||||
"""Send a command, followed by a command to echo a sentinel,
|
||||
@@ -251,7 +257,6 @@ class Switch( Node ):
|
||||
an OpenFlow switch."""
|
||||
def __init__( self, name, datapath=None ):
|
||||
self.dp = datapath
|
||||
self.execed = False
|
||||
Node.__init__( self, name, inNamespace=( datapath == None ) )
|
||||
def startUserDatapath( self, controller ):
|
||||
"""Start OpenFlow reference user datapath,
|
||||
@@ -470,10 +475,12 @@ class Network( object ):
|
||||
print "*** Running test"
|
||||
result = test( [ controller ], switches, hosts )
|
||||
print "*** Stopping controller"
|
||||
controller.stop()
|
||||
controller.stop(); controller.terminate()
|
||||
print "*** Stopping switches"
|
||||
for switch in switches:
|
||||
switch.stop()
|
||||
switch.stop() ; switch.terminate()
|
||||
print "*** Stopping hosts"
|
||||
for host in hosts: host.terminate()
|
||||
print "*** Test complete"
|
||||
return result
|
||||
def interact( self ):
|
||||
|
||||
Reference in New Issue
Block a user