From a49c85a61082d9bacf822cc369bcf62b98a1416c Mon Sep 17 00:00:00 2001 From: Bob Lantz Date: Fri, 9 Mar 2012 16:06:23 -0800 Subject: [PATCH] Fix examples to work with new API (and vice-versa.) --- examples/README | 17 +++++++++++------ examples/baresshd.py | 7 +++++-- examples/scratchnet.py | 37 ++++++++++++++++++++++++------------- examples/scratchnetuser.py | 23 ++++++++++++++--------- examples/sshd.py | 8 ++++---- mininet/clean.py | 6 ++++++ mininet/link.py | 5 ++++- mininet/net.py | 4 ++-- mininet/node.py | 13 ++++++++----- mininet/util.py | 9 --------- 10 files changed, 78 insertions(+), 51 deletions(-) diff --git a/examples/README b/examples/README index 4f233a0..984c9a3 100644 --- a/examples/README +++ b/examples/README @@ -6,12 +6,21 @@ Mininet's Python API. --- +baresshd.py: + +This example uses Mininet's medium-level API to create an sshd +process running in a namespace. Doesn't use OpenFlow. + consoles.py: This example creates a grid of console windows, one for each node, and allows interaction with and monitoring of each console, including graphical monitoring. +controllers.py: + +This example creates a network and adds multiple controllers to it. + emptynet.py: This example demonstrates creating an empty network (i.e. with no @@ -44,10 +53,10 @@ to an interface in the root namespace (generaly the control network already lives in the root namespace, so it does not need to be explicitly connected.) -treeping64: +treeping64.py: This example creates a 64-host tree network, and attempts to check full -connectivity using ping, for three different switch/datapath types. +connectivity using ping, for different switch/datapath types. tree1024.py: @@ -55,7 +64,3 @@ This example attempts to create a 1024-host network, and then runs the CLI on it. It may run into scalability limits, depending on available memory and sysctl configuration (see INSTALL.) -udpbwtest.py: - -This example shows how to run a test across an entire network, and monitor -the output of a set of hosts in real time. diff --git a/examples/baresshd.py b/examples/baresshd.py index 841454a..3b616d1 100755 --- a/examples/baresshd.py +++ b/examples/baresshd.py @@ -6,14 +6,17 @@ from mininet.node import Host print "*** Creating nodes" h1 = Host( 'h1' ) + root = Host( 'root', inNamespace=False ) print "*** Creating links" h1.linkTo( root ) +print h1 + print "*** Configuring nodes" -h1.setIP( h1.intfs[ 0 ], '10.0.0.1', 8 ) -root.setIP( root.intfs[ 0 ], '10.0.0.2', 8 ) +h1.setIP( '10.0.0.1', 8 ) +root.setIP( '10.0.0.2', 8 ) print "*** Creating banner file" f = open( '/tmp/%s.banner' % h1.name, 'w' ) diff --git a/examples/scratchnet.py b/examples/scratchnet.py index 2154620..966a183 100755 --- a/examples/scratchnet.py +++ b/examples/scratchnet.py @@ -10,10 +10,13 @@ For most tasks, the higher-level API will be preferable. from mininet.net import Mininet from mininet.node import Node -from mininet.util import createLink +from mininet.link import Link from mininet.log import setLogLevel, info +from mininet.util import quietRun -def scratchNet( cname='controller', cargs='ptcp:' ): +from time import sleep + +def scratchNet( cname='controller', cargs='-v ptcp:' ): "Create network from scratch using Open vSwitch." info( "*** Creating nodes\n" ) @@ -23,30 +26,38 @@ def scratchNet( cname='controller', cargs='ptcp:' ): h1 = Node( 'h1' ) info( "*** Creating links\n" ) - createLink( node1=h0, node2=switch, port1=0, port2=0 ) - createLink( node1=h1, node2=switch, port1=0, port2=1 ) + Link( h0, switch ) + Link( h1, switch ) info( "*** Configuring hosts\n" ) - h0.setIP( h0.intfs[ 0 ], '192.168.123.1', 24 ) - h1.setIP( h1.intfs[ 0 ], '192.168.123.2', 24 ) + h0.setIP( '192.168.123.1/24' ) + h1.setIP( '192.168.123.2/24' ) info( str( h0 ) + '\n' ) info( str( h1 ) + '\n' ) - info( "*** Starting network using Open vSwitch kernel datapath\n" ) + info( "*** Starting network using Open vSwitch\n" ) controller.cmd( cname + ' ' + cargs + '&' ) - switch.cmd( 'ovs-dpctl del-dp dp0' ) - switch.cmd( 'ovs-dpctl add-dp dp0' ) + switch.cmd( 'ovs-vsctl del-br dp0' ) + switch.cmd( 'ovs-vsctl add-br dp0' ) for intf in switch.intfs.values(): - print switch.cmd( 'ovs-dpctl add-if dp0 ' + intf ) - print switch.cmd( 'ovs-openflowd dp0 tcp:127.0.0.1 &' ) + print switch.cmd( 'ovs-vsctl add-port dp0 %s' % intf ) + + # Note: controller and switch are in root namespace, and we + # can connect via loopback interface + switch.cmd( 'ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633' ) + + info( '*** Waiting for switch to connect to controller' ) + while 'is_connected' not in quietRun( 'ovs-vsctl show' ): + sleep( 1 ) + info( '.' ) + info( '\n' ) info( "*** Running test\n" ) h0.cmdPrint( 'ping -c1 ' + h1.IP() ) info( "*** Stopping network\n" ) controller.cmd( 'kill %' + cname ) - switch.cmd( 'ovs-dpctl del-dp dp0' ) - switch.cmd( 'kill %ovs-openflowd' ) + switch.cmd( 'ovs-vsctl del-br dp0' ) switch.deleteIntfs() info( '\n' ) diff --git a/examples/scratchnetuser.py b/examples/scratchnetuser.py index e43bc3f..59bc601 100755 --- a/examples/scratchnetuser.py +++ b/examples/scratchnetuser.py @@ -12,9 +12,14 @@ This version uses the user datapath and an explicit control network. from mininet.net import Mininet from mininet.node import Node -from mininet.util import createLink +from mininet.link import Link from mininet.log import setLogLevel, info +def linkIntfs( node1, node2 ): + "Create link from node1 to node2 and return intfs" + link = Link( node1, node2 ) + return link.intf1, link.intf2 + def scratchNetUser( cname='controller', cargs='ptcp:' ): "Create network from scratch using user switch." @@ -28,17 +33,17 @@ def scratchNetUser( cname='controller', cargs='ptcp:' ): switch = Node( 's0') h0 = Node( 'h0' ) h1 = Node( 'h1' ) - cintf, sintf = createLink( controller, switch ) - h0intf, sintf1 = createLink( h0, switch ) - h1intf, sintf2 = createLink( h1, switch ) + cintf, sintf = linkIntfs( controller, switch ) + h0intf, sintf1 = linkIntfs( h0, switch ) + h1intf, sintf2 = linkIntfs( h1, switch ) info( '*** Configuring control network\n' ) - controller.setIP( cintf, '10.0.123.1', 24 ) - switch.setIP( sintf, '10.0.123.2', 24 ) + controller.setIP( '10.0.123.1/24', cintf ) + switch.setIP( '10.0.123.2/24', sintf) info( '*** Configuring hosts\n' ) - h0.setIP( h0intf, '192.168.123.1', 24 ) - h1.setIP( h1intf, '192.168.123.2', 24 ) + h0.setIP( '192.168.123.1/24', h0intf ) + h1.setIP( '192.168.123.2/24', h1intf ) info( '*** Network state:\n' ) for node in controller, switch, h0, h1: @@ -47,7 +52,7 @@ def scratchNetUser( cname='controller', cargs='ptcp:' ): info( '*** Starting controller and user datapath\n' ) controller.cmd( cname + ' ' + cargs + '&' ) switch.cmd( 'ifconfig lo 127.0.0.1' ) - intfs = [ sintf1, sintf2 ] + intfs = map( str, [ sintf1, sintf2 ] ) switch.cmd( 'ofdatapath -i ' + ','.join( intfs ) + ' ptcp: &' ) switch.cmd( 'ofprotocol tcp:' + controller.IP() + ' tcp:localhost &' ) diff --git a/examples/sshd.py b/examples/sshd.py index 9082d7d..2bedb9c 100755 --- a/examples/sshd.py +++ b/examples/sshd.py @@ -21,7 +21,7 @@ from mininet.cli import CLI from mininet.log import lg from mininet.node import Node, OVSKernelSwitch from mininet.topolib import TreeTopo -from mininet.util import createLink +from mininet.link import Link def TreeNet( depth=1, fanout=2, **kwargs ): "Convenience function for creating tree networks." @@ -37,13 +37,13 @@ def connectToRootNS( network, switch, ip, prefixLen, routes ): routes: host networks to route to""" # Create a node in root namespace and link to switch 0 root = Node( 'root', inNamespace=False ) - intf = createLink( root, switch )[ 0 ] - root.setIP( intf, ip, prefixLen ) + intf = Link( root, switch ).intf1 + root.setIP( ip, prefixLen, intf ) # Start network that now includes link to root namespace network.start() # Add routes from root ns to hosts for route in routes: - root.cmd( 'route add -net ' + route + ' dev ' + intf ) + root.cmd( 'route add -net ' + route + ' dev ' + str( intf ) ) def sshd( network, cmd='/usr/sbin/sshd', opts='-D' ): "Start a network, connect it to root ns, and run sshd on all hosts." diff --git a/mininet/clean.py b/mininet/clean.py index 3052e97..eac8fda 100755 --- a/mininet/clean.py +++ b/mininet/clean.py @@ -45,6 +45,12 @@ def cleanup(): if dp != '': sh( 'dpctl deldp ' + dp ) + info( "*** Removing OVS datapaths" ) + dps = sh("ovs-vsctl list-br").split( '\n' ) + for dp in dps: + if dp: + sh( 'ovs-vsctl del-br ' + dp ) + info( "*** Removing all links of the pattern foo-ethX\n" ) links = sh( "ip link show | egrep -o '(\w+-eth\w+)'" ).split( '\n' ) for link in links: diff --git a/mininet/link.py b/mininet/link.py index ed65e5b..7d606f9 100644 --- a/mininet/link.py +++ b/mininet/link.py @@ -95,6 +95,8 @@ class Intf( object ): def isUp( self, set=False ): "Return whether interface is up" + if set: + self.ifconfig( 'up' ) return "UP" in self.ifconfig() # The reason why we configure things in this way is so @@ -123,7 +125,7 @@ class Intf( object ): return result def config( self, mac=None, ip=None, ifconfig=None, - defaultRoute=None, **params): + defaultRoute=None, up=True, **params): """Configure Node according to (optional) parameters: mac: MAC address ip: IP address @@ -136,6 +138,7 @@ class Intf( object ): r = {} self.setParam( r, 'setMAC', mac=mac ) self.setParam( r, 'setIP', ip=ip ) + self.setParam( r, 'isUp', up=up ) self.setParam( r, 'ifconfig', ifconfig=ifconfig ) return r diff --git a/mininet/net.py b/mininet/net.py index 3be43c0..3fb2d3d 100755 --- a/mininet/net.py +++ b/mininet/net.py @@ -97,7 +97,7 @@ from mininet.log import info, error, debug, output from mininet.node import Host, OVSKernelSwitch, Controller from mininet.link import Link from mininet.util import quietRun, fixLimits -from mininet.util import createLink, macColonHex, ipStr, ipParse +from mininet.util import macColonHex, ipStr, ipParse from mininet.term import cleanUpScreens, makeTerms class Mininet( object ): @@ -584,7 +584,7 @@ class MininetWithControlNet( Mininet ): snum = ipParse( ip ) for switch in self.switches: info( ' ' + switch.name ) - sintf, cintf = createLink( switch, controller ) + sintf, cintf = self.link( switch, controller ) snum += 1 while snum & 0xff in [ 0, 255 ]: snum += 1 diff --git a/mininet/node.py b/mininet/node.py index 90a749c..cbe2917 100644 --- a/mininet/node.py +++ b/mininet/node.py @@ -386,17 +386,20 @@ class Node( object ): intf: interface name ip: IP address as a string prefixLen: prefix length, e.g. 8 for /8 or 16M addrs""" - # This should probably be rethought: - ipSub = '%s/%s' % ( ip, prefixLen ) - return self.intf( intf ).setIP( ipSub ) + # 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." - return self.intf( intf ).IP() + i = self.intf( intf ) + return self.intf( i ).IP() if i else None def MAC( self, intf=None ): "Return MAC address of a node or specific interface." - return self.intf( intf ).MAC() + i = self.intf( intf ) + return self.intf( i ).MAC() if i else None def intfIsUp( self, intf=None ): "Check if an interface is up." diff --git a/mininet/util.py b/mininet/util.py index 3bf9dd0..1a503e1 100644 --- a/mininet/util.py +++ b/mininet/util.py @@ -183,15 +183,6 @@ def moveIntf( intf, node, printError=False, retries=3, delaySecs=0.001 ): printError: if true, print error""" retry( retries, delaySecs, moveIntfNoRetry, intf, node, printError ) -def createLink( node1, node2, port1=None, port2=None ): - """Create a link between nodes, making an interface for each. - node1: Node object - node2: Node object - port1: node1 port number (optional) - port2: node2 port number (optional) - returns: intf1 name, intf2 name""" - return node1.linkTo( node2, port1, port2 ) - # IP and Mac address formatting and parsing