Added sshd example, which starts up sshd on each host, allowing host access via ssh.
(It also adds a route from the root namespace to the data network via the first OpenFlow switch, so when you ssh in you go through OpenFlow!) Modified Network() to optionally decouple starting the network, running tests, and stopping the network. This allows multiple tests to be run (or additional modifications to be made to the network before actually starting the switches and controller.) Still tweaking xterms - it sort of works but the screen sessions are not cleaned up, which leads to nasty garbage.
This commit is contained in:
Executable
+55
@@ -0,0 +1,55 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
"Create a network and start sshd on the hosts."
|
||||||
|
|
||||||
|
from mininet import init, Node, createLink, TreeNet, Cli
|
||||||
|
|
||||||
|
def nets( hosts ):
|
||||||
|
"Return list of networks (/24) for hosts."
|
||||||
|
nets = {}
|
||||||
|
for host in hosts:
|
||||||
|
net = host.IP().split( '.' )[ : -1 ]
|
||||||
|
net = '.'.join ( net ) + '.0/24'
|
||||||
|
nets[ net ] = True
|
||||||
|
return nets.keys()
|
||||||
|
|
||||||
|
def addRoutes( node, nets, intf ):
|
||||||
|
"""Add routes from node to nets through intf, assuming
|
||||||
|
a 24-bit netmask."""
|
||||||
|
for net in nets:
|
||||||
|
node.cmdPrint( 'route add -net ' + net + ' dev ' + intf )
|
||||||
|
|
||||||
|
def removeRoutes( node, nets ):
|
||||||
|
"Remove routes to nets from node."
|
||||||
|
for net in nets:
|
||||||
|
node.cmdPrint( 'route del -net ' + net )
|
||||||
|
|
||||||
|
def sshd( network ):
|
||||||
|
"Start sshd up on each host, routing appropriately."
|
||||||
|
controllers, switches, hosts = (
|
||||||
|
network.controllers, network.switches, network.hosts )
|
||||||
|
# Create a node in root ns and link to switch 0
|
||||||
|
root = Node( 'root', inNamespace=False )
|
||||||
|
createLink( root, switches[ 0 ] )
|
||||||
|
ip = '10.0.123.1'
|
||||||
|
root.setIP( root.intfs[ 0 ], ip, '/24' )
|
||||||
|
network.start()
|
||||||
|
# Add routes
|
||||||
|
routes = nets( hosts )
|
||||||
|
addRoutes( root, routes, root.intfs[ 0 ] )
|
||||||
|
# Start up sshd on each host
|
||||||
|
for host in hosts: host.cmdPrint( '/usr/sbin/sshd' )
|
||||||
|
# Dump out IP addresses and run CLI
|
||||||
|
print
|
||||||
|
print "*** Hosts are running sshd at the following addresses:"
|
||||||
|
for host in hosts: print host.name, host.IP()
|
||||||
|
print
|
||||||
|
print "*** Starting Mininet CLI - type 'exit' or ^D to exit"
|
||||||
|
network.runTest( Cli )
|
||||||
|
network.stop()
|
||||||
|
removeRoutes( root, routes )
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
init()
|
||||||
|
network = TreeNet( depth=1, fanout=2, kernel=True )
|
||||||
|
sshd( network )
|
||||||
+7
-4
@@ -9,9 +9,12 @@ from mininet import init, TreeNet, Cli, quietRun
|
|||||||
def makeXterm( node, title ):
|
def makeXterm( node, title ):
|
||||||
"Run screen on a node, and hook up an xterm."
|
"Run screen on a node, and hook up an xterm."
|
||||||
node.cmdPrint( 'screen -dmS ' + node.name )
|
node.cmdPrint( 'screen -dmS ' + node.name )
|
||||||
cmd = 'xterm -title ' + title + ':' + node.name
|
title += ': ' + node.name
|
||||||
cmd += ' -e screen -D -RR -S ' + node.name
|
if not node.inNamespace:
|
||||||
return Popen( cmd.split( ' ' ) )
|
title += ' (root ns)'
|
||||||
|
cmd = [ 'xterm', '-title', title ]
|
||||||
|
cmd += [ '-e', 'screen', '-D', '-RR', '-S', node.name ]
|
||||||
|
return Popen( cmd )
|
||||||
|
|
||||||
def makeXterms( nodes, title ):
|
def makeXterms( nodes, title ):
|
||||||
terms = []
|
terms = []
|
||||||
@@ -31,7 +34,7 @@ def xterms( controllers, switches, hosts ):
|
|||||||
|
|
||||||
def treeXterms():
|
def treeXterms():
|
||||||
print "Running xterms on", os.environ[ 'DISPLAY' ]
|
print "Running xterms on", os.environ[ 'DISPLAY' ]
|
||||||
network = TreeNet( depth=2, fanout=4, kernel=True )
|
network = TreeNet( depth=2, fanout=2, kernel=True )
|
||||||
network.run( xterms )
|
network.run( xterms )
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|||||||
+31
-16
@@ -445,15 +445,12 @@ class Network( object ):
|
|||||||
print "*** Error: ofdatapath not loaded:",
|
print "*** Error: ofdatapath not loaded:",
|
||||||
print " kernel datapath not supported"
|
print " kernel datapath not supported"
|
||||||
exit( 1 )
|
exit( 1 )
|
||||||
# In progress: we probably want to decouple creating/starting/stopping
|
# Create network, but don't start things up yet!
|
||||||
# the network and running tests, since we might wish to run
|
self.prepareNet()
|
||||||
# multiple tests on the same network. It's not clear if the network
|
def prepareNet( self ):
|
||||||
# should always be started/stopped for each test or not. Probably
|
|
||||||
# not...
|
|
||||||
def run( self, test ):
|
|
||||||
"""Create a network by calling makeNet as follows:
|
"""Create a network by calling makeNet as follows:
|
||||||
(switches, hosts ) = makeNet()
|
(switches, hosts ) = makeNet()
|
||||||
and then run test( controller, switches, hosts ) on it."""
|
Create a controller here as well."""
|
||||||
kernel = self.kernel
|
kernel = self.kernel
|
||||||
if kernel: print "*** Using kernel datapath"
|
if kernel: print "*** Using kernel datapath"
|
||||||
else: print "*** Using user datapath"
|
else: print "*** Using user datapath"
|
||||||
@@ -467,21 +464,39 @@ class Network( object ):
|
|||||||
configRoutedControlNetwork( controller, switches )
|
configRoutedControlNetwork( controller, switches )
|
||||||
print "*** Configuring hosts"
|
print "*** Configuring hosts"
|
||||||
configHosts( hosts, self.startAddr )
|
configHosts( hosts, self.startAddr )
|
||||||
|
self.controllers = [ controller ]
|
||||||
|
self.switches = switches
|
||||||
|
self.hosts = hosts
|
||||||
|
def start( self ):
|
||||||
|
"Start controller and switches"
|
||||||
print "*** Starting reference controller"
|
print "*** Starting reference controller"
|
||||||
controller.start()
|
for controller in self.controllers:
|
||||||
print "*** Starting", len( switches ), "switches"
|
controller.start()
|
||||||
for switch in switches:
|
print "*** Starting", len( self.switches ), "switches"
|
||||||
switch.start( controller )
|
for switch in self.switches:
|
||||||
print "*** Running test"
|
switch.start( self.controllers[ 0 ] )
|
||||||
result = test( [ controller ], switches, hosts )
|
def stop( self ):
|
||||||
|
"Stop the controller(s), switches and hosts"
|
||||||
print "*** Stopping controller"
|
print "*** Stopping controller"
|
||||||
controller.stop(); controller.terminate()
|
for controller in self.controllers:
|
||||||
|
controller.stop(); controller.terminate()
|
||||||
print "*** Stopping switches"
|
print "*** Stopping switches"
|
||||||
for switch in switches:
|
for switch in self.switches:
|
||||||
switch.stop() ; switch.terminate()
|
switch.stop() ; switch.terminate()
|
||||||
print "*** Stopping hosts"
|
print "*** Stopping hosts"
|
||||||
for host in hosts: host.terminate()
|
for host in self.hosts:
|
||||||
|
host.terminate()
|
||||||
print "*** Test complete"
|
print "*** Test complete"
|
||||||
|
def runTest( self, test ):
|
||||||
|
"Run a given test, called as test( controllers, switches, hosts)"
|
||||||
|
return test( self.controllers, self.switches, self.hosts )
|
||||||
|
def run( self, test ):
|
||||||
|
"""Perform a complete start/test/stop cycle; test is of the form
|
||||||
|
test( controllers, switches, hosts )"""
|
||||||
|
self.start()
|
||||||
|
print "*** Running test"
|
||||||
|
result = self.runTest( test )
|
||||||
|
self.stop()
|
||||||
return result
|
return result
|
||||||
def interact( self ):
|
def interact( self ):
|
||||||
"Create a network and run our simple CLI."
|
"Create a network and run our simple CLI."
|
||||||
|
|||||||
Reference in New Issue
Block a user