diff --git a/mininet/net.py b/mininet/net.py
new file mode 100644
index 0000000..1255e12
--- /dev/null
+++ b/mininet/net.py
@@ -0,0 +1,770 @@
+"""
+
+    Mininet: A simple networking testbed for OpenFlow/SDN!
+
+author: Bob Lantz (rlantz@cs.stanford.edu)
+author: Brandon Heller (brandonh@stanford.edu)
+
+Mininet creates scalable OpenFlow test networks by using
+process-based virtualization and network namespaces.
+
+Simulated hosts are created as processes in separate network
+namespaces. This allows a complete OpenFlow network to be simulated on
+top of a single Linux kernel.
+
+Each host has:
+
+A virtual console (pipes to a shell)
+A virtual interfaces (half of a veth pair)
+A parent shell (and possibly some child processes) in a namespace
+
+Hosts have a network interface which is configured via ifconfig/ip
+link/etc.
+
+This version supports both the kernel and user space datapaths
+from the OpenFlow reference implementation (openflowswitch.org)
+as well as OpenVSwitch (openvswitch.org.)
+
+In kernel datapath mode, the controller and switches are simply
+processes in the root namespace.
+
+Kernel OpenFlow datapaths are instantiated using dpctl(8), and are
+attached to the one side of a veth pair; the other side resides in the
+host namespace. In this mode, switch processes can simply connect to the
+controller via the loopback interface.
+
+In user datapath mode, the controller and switches can be full-service
+nodes that live in their own network namespaces and have management
+interfaces and IP addresses on a control network (e.g. 192.168.123.1,
+currently routed although it could be bridged.)
+
+In addition to a management interface, user mode switches also have
+several switch interfaces, halves of veth pairs whose other halves
+reside in the host nodes that the switches are connected to.
+
+Consistent, straightforward naming is important in order to easily
+identify hosts, switches and controllers, both from the CLI and
+from program code. Interfaces are named to make it easy to identify
+which interfaces belong to which node.
+
+The basic naming scheme is as follows:
+
+    Host nodes are named h1-hN
+    Switch nodes are named s1-sN
+    Controller nodes are named c0-cN
+    Interfaces are named {nodename}-eth0 .. {nodename}-ethN
+
+Note: If the network topology is created using mininet.topo, then
+node numbers are unique among hosts and switches (e.g. we have
+h1..hN and SN..SN+M) and also correspond to their default IP addresses
+of 10.x.y.z/8 where x.y.z is the base-256 representation of N for
+hN. This mapping allows easy determination of a node's IP
+address from its name, e.g. h1 -> 10.0.0.1, h257 -> 10.0.1.1.
+
+Note also that 10.0.0.1 can often be written as 10.1 for short, e.g.
+"ping 10.1" is equivalent to "ping 10.0.0.1".
+
+Currently we wrap the entire network in a 'mininet' object, which
+constructs a simulated network based on a network topology created
+using a topology object (e.g. LinearTopo) from mininet.topo or
+mininet.topolib, and a Controller which the switches will connect
+to. Several configuration options are provided for functions such as
+automatically setting MAC addresses, populating the ARP table, or
+even running a set of terminals to allow direct interaction with nodes.
+
+After the network is created, it can be started using start(), and a
+variety of useful tasks maybe performed, including basic connectivity
+and bandwidth tests and running the mininet CLI.
+
+Once the network is up and running, test code can easily get access
+to host and switch objects which can then be used for arbitrary
+experiments, typically involving running a series of commands on the
+hosts.
+
+After all desired tests or activities have been completed, the stop()
+method may be called to shut down the network.
+
+"""
+
+import os
+import re
+import select
+import signal
+from time import sleep
+
+from mininet.cli import CLI
+from mininet.log import info, error, debug, output
+from mininet.node import Host, OVSKernelSwitch, Controller
+from mininet.link import Link, Intf
+from mininet.util import quietRun, fixLimits, numCores, ensureRoot
+from mininet.util import macColonHex, ipStr, ipParse, netParse, ipAdd, nextCCNnet
+from mininet.term import cleanUpScreens, makeTerms
+
+# Mininet version: should be consistent with README and LICENSE
+VERSION = "2.0.0"
+
+class Mininet( object ):
+    "Network emulation with hosts spawned in network namespaces."
+
+    def __init__( self, topo=None, switch=OVSKernelSwitch, host=Host,
+                  controller=Controller, link=Link, intf=Intf,
+                  build=True, xterms=False, cleanup=False, ipBase='10.0.0.0/8',
+                  inNamespace=False,
+                  autoSetMacs=False, autoStaticArp=False, autoPinCpus=False,
+                  listenPort=None ):
+        """Create Mininet object.
+           topo: Topo (topology) object or None
+           switch: default Switch class
+           host: default Host class/constructor
+           controller: default Controller class/constructor
+           link: default Link class/constructor
+           intf: default Intf class/constructor
+           ipBase: base IP address for hosts,
+           build: build now from topo?
+           xterms: if build now, spawn xterms?
+           cleanup: if build now, cleanup before creating?
+           inNamespace: spawn switches and controller in net namespaces?
+           autoSetMacs: set MAC addrs automatically like IP addresses?
+           autoStaticArp: set all-pairs static MAC addrs?
+           autoPinCpus: pin hosts to (real) cores (requires CPULimitedHost)?
+           listenPort: base listening port to open; will be incremented for
+               each additional switch in the net if inNamespace=False"""
+        self.topo = topo
+        self.switch = switch
+        self.host = host
+        self.controller = controller
+        self.link = link
+        self.intf = intf
+        self.ipBase = ipBase
+        self.ipBaseNum, self.prefixLen = netParse( self.ipBase )
+        self.nextIP = 1  # start for address allocation
+        self.ccnNetBase = '1.0.0.0'
+        self.inNamespace = inNamespace
+        self.xterms = xterms
+        self.cleanup = cleanup
+        self.autoSetMacs = autoSetMacs
+        self.autoStaticArp = autoStaticArp
+        self.autoPinCpus = autoPinCpus
+        self.numCores = numCores()
+        self.nextCore = 0  # next core for pinning hosts to CPUs
+        self.listenPort = listenPort
+
+        self.hosts = []
+        self.switches = []
+        self.controllers = []
+
+        self.nameToNode = {}  # name to Node (Host/Switch) objects
+
+        self.terms = []  # list of spawned xterm processes
+
+        Mininet.init()  # Initialize Mininet if necessary
+
+        self.built = False
+        if topo and build:
+            self.build()
+
+    def isCCNhost(self, node):
+        if 'fib' in node.params:
+            return True
+        else:
+            return False
+        
+    def addHost( self, name, cls=None, **params ):
+        """Add host.
+           name: name of host to add
+           cls: custom host class/constructor (optional)
+           params: parameters for host
+           returns: added host"""
+        # Default IP and MAC addresses
+
+        defaults = { 'ip': ipAdd( self.nextIP,
+                                  ipBaseNum=self.ipBaseNum,
+                                  prefixLen=self.prefixLen ) +
+                                  '/%s' % self.prefixLen }
+        if self.autoSetMacs:
+            defaults[ 'mac'] = macColonHex( self.nextIP )
+        if self.autoPinCpus:
+            defaults[ 'cores' ] = self.nextCore
+            self.nextCore = ( self.nextCore + 1 ) % self.numCores        
+        self.nextIP += 1
+        defaults.update( params )
+        if not cls:
+            cls = self.host
+        h = cls( name, **defaults )
+        self.hosts.append( h )
+        self.nameToNode[ name ] = h
+        return h
+
+    def addSwitch( self, name, cls=None, **params ):
+        """Add switch.
+           name: name of switch to add
+           cls: custom switch class/constructor (optional)
+           returns: added switch
+           side effect: increments listenPort ivar ."""
+        defaults = { 'listenPort': self.listenPort,
+                     'inNamespace': self.inNamespace }
+        defaults.update( params )
+        if not cls:
+            cls = self.switch
+        sw = cls( name, **defaults )
+        if not self.inNamespace and self.listenPort:
+            self.listenPort += 1
+        self.switches.append( sw )
+        self.nameToNode[ name ] = sw
+        return sw
+
+    def addController( self, name='c0', controller=None, **params ):
+        """Add controller.
+           controller: Controller class"""
+        if not controller:
+            controller = self.controller
+        controller_new = controller( name, **params )
+        if controller_new:  # allow controller-less setups
+            self.controllers.append( controller_new )
+            self.nameToNode[ name ] = controller_new
+        return controller_new
+
+    # BL: is this better than just using nameToNode[] ?
+    # Should it have a better name?
+    def getNodeByName( self, *args ):
+        "Return node(s) with given name(s)"
+        if len( args ) == 1:
+            return self.nameToNode[ args[ 0 ] ]
+        return [ self.nameToNode[ n ] for n in args ]
+
+    def get( self, *args ):
+        "Convenience alias for getNodeByName"
+        return self.getNodeByName( *args )
+
+    def addLink( self, node1, node2, port1=None, port2=None,
+                 cls=None, **params ):
+        """"Add a link from node1 to node2
+            node1: source node
+            node2: dest node
+            port1: source port
+            port2: dest port
+            returns: link object"""
+        defaults = { 'port1': port1,
+                     'port2': port2,
+                     'intf': self.intf }
+        defaults.update( params )
+        if not cls:
+            cls = self.link
+        return cls( node1, node2, **defaults )
+
+    def configHosts( self ):
+        "Configure a set of hosts."
+        for host in self.hosts:
+            info( host.name + ' ' )
+            intf = host.defaultIntf()
+            if self.isCCNhost(host):
+                host.configCCN()    
+                host.configDefault(ip=None,mac=None)         
+            elif intf:
+                host.configDefault( defaultRoute=intf )
+            else:
+                # Don't configure nonexistent intf
+                host.configDefault( ip=None, mac=None )
+            # You're low priority, dude!
+            # BL: do we want to do this here or not?
+            # May not make sense if we have CPU lmiting...
+            # quietRun( 'renice +18 -p ' + repr( host.pid ) )
+            # This may not be the right place to do this, but
+            # it needs to be done somewhere.
+            host.cmd( 'ifconfig lo up' )
+        info( '\n' )
+
+    def buildFromTopo( self, topo=None ):
+        """Build mininet from a topology object
+           At the end of this function, everything should be connected
+           and up."""
+
+        # Possibly we should clean up here and/or validate
+        # the topo
+        if self.cleanup:
+            pass
+
+        info( '*** Creating network\n' )
+
+        if not self.controllers:
+            # Add a default controller
+            info( '*** Adding controller\n' )
+            classes = self.controller
+            if type( classes ) is not list:
+                classes = [ classes ]
+            for i, cls in enumerate( classes ):
+                self.addController( 'c%d' % i, cls )
+
+        info( '*** Adding hosts:\n' )
+        for hostName in topo.hosts():
+            self.addHost( hostName, **topo.nodeInfo( hostName ) )
+            info( hostName + ' ' )
+
+        info( '\n*** Adding switches:\n' )
+        for switchName in topo.switches():
+            self.addSwitch( switchName, **topo.nodeInfo( switchName) )
+            info( switchName + ' ' )
+
+        info( '\n*** Adding links:\n' )
+        for srcName, dstName in topo.links(sort=True):
+            src, dst = self.nameToNode[ srcName ], self.nameToNode[ dstName ]
+            params = topo.linkInfo( srcName, dstName )
+            srcPort, dstPort = topo.port( srcName, dstName )
+            self.addLink( src, dst, srcPort, dstPort, **params )
+            if self.isCCNhost(src):
+                src.setIP(ipStr(ipParse(self.ccnNetBase) + 1) + '/30', intf=src.name + '-eth' + str(srcPort))
+                dst.setIP(ipStr(ipParse(self.ccnNetBase) + 2) + '/30', intf=dst.name + '-eth' + str(dstPort))
+                self.ccnNetBase=nextCCNnet(self.ccnNetBase)
+                
+            info( '(%s, %s) ' % ( src.name, dst.name ) )
+
+        info( '\n' )
+        
+        
+    def configureControlNetwork( self ):
+        "Control net config hook: override in subclass"
+        raise Exception( 'configureControlNetwork: '
+                         'should be overriden in subclass', self )
+
+    def build( self ):
+        "Build mininet."
+        if self.topo:
+            self.buildFromTopo( self.topo )
+        if ( self.inNamespace ):
+            self.configureControlNetwork()
+        info( '*** Configuring hosts\n' )
+        self.configHosts()
+        if self.xterms:
+            self.startTerms()
+        if self.autoStaticArp:
+            self.staticArp()
+        self.built = True
+
+    def startTerms( self ):
+        "Start a terminal for each node."
+        info( "*** Running terms on %s\n" % os.environ[ 'DISPLAY' ] )
+        cleanUpScreens()
+        self.terms += makeTerms( self.controllers, 'controller' )
+        self.terms += makeTerms( self.switches, 'switch' )
+        self.terms += makeTerms( self.hosts, 'host' )
+
+    def stopXterms( self ):
+        "Kill each xterm."
+        for term in self.terms:
+            os.kill( term.pid, signal.SIGKILL )
+        cleanUpScreens()
+
+    def staticArp( self ):
+        "Add all-pairs ARP entries to remove the need to handle broadcast."
+        for src in self.hosts:
+            for dst in self.hosts:
+                if src != dst:
+                    src.setARP( ip=dst.IP(), mac=dst.MAC() )
+
+    def start( self ):
+        "Start controller and switches."
+        if not self.built:
+            self.build()
+        info( '*** Starting controller\n' )
+        for controller in self.controllers:
+            controller.start()
+        info( '*** Starting %s switches\n' % len( self.switches ) )
+        for switch in self.switches:
+            info( switch.name + ' ')
+            switch.start( self.controllers )
+        info( '\n' )
+
+    def stop( self ):
+        "Stop the controller(s), switches and hosts"
+        if self.terms:
+            info( '*** Stopping %i terms\n' % len( self.terms ) )
+            self.stopXterms()
+        info( '*** Stopping %i hosts\n' % len( self.hosts ) )
+        for host in self.hosts:
+            info( host.name + ' ' )
+            host.terminate()
+        info( '\n' )
+        info( '*** Stopping %i switches\n' % len( self.switches ) )
+        for switch in self.switches:
+            info( switch.name + ' ' )
+            switch.stop()
+        info( '\n' )
+        info( '*** Stopping %i controllers\n' % len( self.controllers ) )
+        for controller in self.controllers:
+            info( controller.name + ' ' )
+            controller.stop()
+        info( '\n*** Done\n' )
+
+    def run( self, test, *args, **kwargs ):
+        "Perform a complete start/test/stop cycle."
+        self.start()
+        info( '*** Running test\n' )
+        result = test( *args, **kwargs )
+        self.stop()
+        return result
+
+    def monitor( self, hosts=None, timeoutms=-1 ):
+        """Monitor a set of hosts (or all hosts by default),
+           and return their output, a line at a time.
+           hosts: (optional) set of hosts to monitor
+           timeoutms: (optional) timeout value in ms
+           returns: iterator which returns host, line"""
+        if hosts is None:
+            hosts = self.hosts
+        poller = select.poll()
+        Node = hosts[ 0 ]  # so we can call class method fdToNode
+        for host in hosts:
+            poller.register( host.stdout )
+        while True:
+            ready = poller.poll( timeoutms )
+            for fd, event in ready:
+                host = Node.fdToNode( fd )
+                if event & select.POLLIN:
+                    line = host.readline()
+                    if line is not None:
+                        yield host, line
+            # Return if non-blocking
+            if not ready and timeoutms >= 0:
+                yield None, None
+
+    # XXX These test methods should be moved out of this class.
+    # Probably we should create a tests.py for them
+
+    @staticmethod
+    def _parsePing( pingOutput ):
+        "Parse ping output and return packets sent, received."
+        # Check for downed link
+        if 'connect: Network is unreachable' in pingOutput:
+            return (1, 0)
+        r = r'(\d+) packets transmitted, (\d+) received'
+        m = re.search( r, pingOutput )
+        if m is None:
+            error( '*** Error: could not parse ping output: %s\n' %
+                   pingOutput )
+            return (1, 0)
+        sent, received = int( m.group( 1 ) ), int( m.group( 2 ) )
+        return sent, received
+
+    def ping( self, hosts=None, timeout=None ):
+        """Ping between all specified hosts.
+           hosts: list of hosts
+           timeout: time to wait for a response, as string
+           returns: ploss packet loss percentage"""
+        # should we check if running?
+        packets = 0
+        lost = 0
+        ploss = None
+        if not hosts:
+            hosts = self.hosts
+            output( '*** Ping: testing ping reachability\n' )
+        for node in hosts:
+            output( '%s -> ' % node.name )
+            for dest in hosts:
+                if node != dest:
+                    opts = ''
+                    if timeout:
+                        opts = '-W %s' % timeout
+                    result = node.cmd( 'ping -c1 %s %s' % (opts, dest.IP()) )
+                    sent, received = self._parsePing( result )
+                    packets += sent
+                    if received > sent:
+                        error( '*** Error: received too many packets' )
+                        error( '%s' % result )
+                        node.cmdPrint( 'route' )
+                        exit( 1 )
+                    lost += sent - received
+                    output( ( '%s ' % dest.name ) if received else 'X ' )
+            output( '\n' )
+            ploss = 100 * lost / packets
+        output( "*** Results: %i%% dropped (%d/%d lost)\n" %
+                ( ploss, lost, packets ) )
+        return ploss
+
+    @staticmethod
+    def _parsePingFull( pingOutput ):
+        "Parse ping output and return all data."
+        # Check for downed link
+        if 'connect: Network is unreachable' in pingOutput:
+            return (1, 0)
+        r = r'(\d+) packets transmitted, (\d+) received'
+        m = re.search( r, pingOutput )
+        if m is None:
+            error( '*** Error: could not parse ping output: %s\n' %
+                   pingOutput )
+            return (1, 0, 0, 0, 0, 0)
+        sent, received = int( m.group( 1 ) ), int( m.group( 2 ) )
+        r = r'rtt min/avg/max/mdev = '
+        r += r'(\d+\.\d+)/(\d+\.\d+)/(\d+\.\d+)/(\d+\.\d+) ms'
+        m = re.search( r, pingOutput )
+        rttmin = float( m.group( 1 ) )
+        rttavg = float( m.group( 2 ) )
+        rttmax = float( m.group( 3 ) )
+        rttdev = float( m.group( 4 ) )
+        return sent, received, rttmin, rttavg, rttmax, rttdev
+
+    def pingFull( self, hosts=None, timeout=None ):
+        """Ping between all specified hosts and return all data.
+           hosts: list of hosts
+           timeout: time to wait for a response, as string
+           returns: all ping data; see function body."""
+        # should we check if running?
+        # Each value is a tuple: (src, dsd, [all ping outputs])
+        all_outputs = []
+        if not hosts:
+            hosts = self.hosts
+            output( '*** Ping: testing ping reachability\n' )
+        for node in hosts:
+            output( '%s -> ' % node.name )
+            for dest in hosts:
+                if node != dest:
+                    opts = ''
+                    if timeout:
+                        opts = '-W %s' % timeout
+                    result = node.cmd( 'ping -c1 %s %s' % (opts, dest.IP()) )
+                    outputs = self._parsePingFull( result )
+                    sent, received, rttmin, rttavg, rttmax, rttdev = outputs
+                    all_outputs.append( (node, dest, outputs) )
+                    output( ( '%s ' % dest.name ) if received else 'X ' )
+            output( '\n' )
+        output( "*** Results: \n" )
+        for outputs in all_outputs:
+            src, dest, ping_outputs = outputs
+            sent, received, rttmin, rttavg, rttmax, rttdev = ping_outputs
+            output( " %s->%s: %s/%s, " % (src, dest, sent, received ) )
+            output( "rtt min/avg/max/mdev %0.3f/%0.3f/%0.3f/%0.3f ms\n" %
+                    (rttmin, rttavg, rttmax, rttdev) )
+        return all_outputs
+
+    def pingAll( self ):
+        """Ping between all hosts.
+           returns: ploss packet loss percentage"""
+        return self.ping()
+
+    def pingPair( self ):
+        """Ping between first two hosts, useful for testing.
+           returns: ploss packet loss percentage"""
+        hosts = [ self.hosts[ 0 ], self.hosts[ 1 ] ]
+        return self.ping( hosts=hosts )
+
+    def pingAllFull( self ):
+        """Ping between all hosts.
+           returns: ploss packet loss percentage"""
+        return self.pingFull()
+
+    def pingPairFull( self ):
+        """Ping between first two hosts, useful for testing.
+           returns: ploss packet loss percentage"""
+        hosts = [ self.hosts[ 0 ], self.hosts[ 1 ] ]
+        return self.pingFull( hosts=hosts )
+
+    @staticmethod
+    def _parseIperf( iperfOutput ):
+        """Parse iperf output and return bandwidth.
+           iperfOutput: string
+           returns: result string"""
+        r = r'([\d\.]+ \w+/sec)'
+        m = re.findall( r, iperfOutput )
+        if m:
+            return m[-1]
+        else:
+            # was: raise Exception(...)
+            error( 'could not parse iperf output: ' + iperfOutput )
+            return ''
+
+    # XXX This should be cleaned up
+
+    def iperf( self, hosts=None, l4Type='TCP', udpBw='10M' ):
+        """Run iperf between two hosts.
+           hosts: list of hosts; if None, uses opposite hosts
+           l4Type: string, one of [ TCP, UDP ]
+           returns: results two-element array of server and client speeds"""
+        if not quietRun( 'which telnet' ):
+            error( 'Cannot find telnet in $PATH - required for iperf test' )
+            return
+        if not hosts:
+            hosts = [ self.hosts[ 0 ], self.hosts[ -1 ] ]
+        else:
+            assert len( hosts ) == 2
+        client, server = hosts
+        output( '*** Iperf: testing ' + l4Type + ' bandwidth between ' )
+        output( "%s and %s\n" % ( client.name, server.name ) )
+        server.cmd( 'killall -9 iperf' )
+        iperfArgs = 'iperf '
+        bwArgs = ''
+        if l4Type == 'UDP':
+            iperfArgs += '-u '
+            bwArgs = '-b ' + udpBw + ' '
+        elif l4Type != 'TCP':
+            raise Exception( 'Unexpected l4 type: %s' % l4Type )
+        server.sendCmd( iperfArgs + '-s', printPid=True )
+        servout = ''
+        while server.lastPid is None:
+            servout += server.monitor()
+        if l4Type == 'TCP':
+            while 'Connected' not in client.cmd(
+                    'sh -c "echo A | telnet -e A %s 5001"' % server.IP()):
+                output('waiting for iperf to start up...')
+                sleep(.5)
+        cliout = client.cmd( iperfArgs + '-t 5 -c ' + server.IP() + ' ' +
+                             bwArgs )
+        debug( 'Client output: %s\n' % cliout )
+        server.sendInt()
+        servout += server.waitOutput()
+        debug( 'Server output: %s\n' % servout )
+        result = [ self._parseIperf( servout ), self._parseIperf( cliout ) ]
+        if l4Type == 'UDP':
+            result.insert( 0, udpBw )
+        output( '*** Results: %s\n' % result )
+        return result
+
+    def runCpuLimitTest( self, cpu, duration=5 ):
+        """run CPU limit test with 'while true' processes.
+        cpu: desired CPU fraction of each host
+        duration: test duration in seconds
+        returns a single list of measured CPU fractions as floats.
+        """
+        pct = cpu * 100
+        info('*** Testing CPU %.0f%% bandwidth limit\n' % pct)
+        hosts = self.hosts
+        for h in hosts:
+            h.cmd( 'while true; do a=1; done &' )
+        pids = [h.cmd( 'echo $!' ).strip() for h in hosts]
+        pids_str = ",".join(["%s" % pid for pid in pids])
+        cmd = 'ps -p %s -o pid,%%cpu,args' % pids_str
+        # It's a shame that this is what pylint prefers
+        outputs = []
+        for _ in range( duration ):
+            sleep( 1 )
+            outputs.append( quietRun( cmd ).strip() )
+        for h in hosts:
+            h.cmd( 'kill %1' )
+        cpu_fractions = []
+        for test_output in outputs:
+            # Split by line.  Ignore first line, which looks like this:
+            # PID %CPU COMMAND\n
+            for line in test_output.split('\n')[1:]:
+                r = r'\d+\s*(\d+\.\d+)'
+                m = re.search( r, line )
+                if m is None:
+                    error( '*** Error: could not extract CPU fraction: %s\n' %
+                           line )
+                    return None
+                cpu_fractions.append( float( m.group( 1 ) ) )
+        output( '*** Results: %s\n' % cpu_fractions )
+        return cpu_fractions
+
+    # BL: I think this can be rewritten now that we have
+    # a real link class.
+    def configLinkStatus( self, src, dst, status ):
+        """Change status of src <-> dst links.
+           src: node name
+           dst: node name
+           status: string {up, down}"""
+        if src not in self.nameToNode:
+            error( 'src not in network: %s\n' % src )
+        elif dst not in self.nameToNode:
+            error( 'dst not in network: %s\n' % dst )
+        else:
+            if type( src ) is str:
+                src = self.nameToNode[ src ]
+            if type( dst ) is str:
+                dst = self.nameToNode[ dst ]
+            connections = src.connectionsTo( dst )
+            if len( connections ) == 0:
+                error( 'src and dst not connected: %s %s\n' % ( src, dst) )
+            for srcIntf, dstIntf in connections:
+                result = srcIntf.ifconfig( status )
+                if result:
+                    error( 'link src status change failed: %s\n' % result )
+                result = dstIntf.ifconfig( status )
+                if result:
+                    error( 'link dst status change failed: %s\n' % result )
+
+    def interact( self ):
+        "Start network and run our simple CLI."
+        self.start()
+        result = CLI( self )
+        self.stop()
+        return result
+
+    inited = False
+
+    @classmethod
+    def init( cls ):
+        "Initialize Mininet"
+        if cls.inited:
+            return
+        ensureRoot()
+        fixLimits()
+        cls.inited = True
+
+
+class MininetWithControlNet( Mininet ):
+
+    """Control network support:
+
+       Create an explicit control network. Currently this is only
+       used/usable with the user datapath.
+
+       Notes:
+
+       1. If the controller and switches are in the same (e.g. root)
+          namespace, they can just use the loopback connection.
+
+       2. If we can get unix domain sockets to work, we can use them
+          instead of an explicit control network.
+
+       3. Instead of routing, we could bridge or use 'in-band' control.
+
+       4. Even if we dispense with this in general, it could still be
+          useful for people who wish to simulate a separate control
+          network (since real networks may need one!)
+
+       5. Basically nobody ever used this code, so it has been moved
+          into its own class.
+
+       6. Ultimately we may wish to extend this to allow us to create a
+          control network which every node's control interface is
+          attached to."""
+
+    def configureControlNetwork( self ):
+        "Configure control network."
+        self.configureRoutedControlNetwork()
+
+    # We still need to figure out the right way to pass
+    # in the control network location.
+
+    def configureRoutedControlNetwork( self, ip='192.168.123.1',
+                                       prefixLen=16 ):
+        """Configure a routed control network on controller and switches.
+           For use with the user datapath only right now."""
+        controller = self.controllers[ 0 ]
+        info( controller.name + ' <->' )
+        cip = ip
+        snum = ipParse( ip )
+        for switch in self.switches:
+            info( ' ' + switch.name )
+            link = self.link( switch, controller, port1=0 )
+            sintf, cintf = link.intf1, link.intf2
+            switch.controlIntf = sintf
+            snum += 1
+            while snum & 0xff in [ 0, 255 ]:
+                snum += 1
+            sip = ipStr( snum )
+            cintf.setIP( cip, prefixLen )
+            sintf.setIP( sip, prefixLen )
+            controller.setHostRoute( sip, cintf )
+            switch.setHostRoute( cip, sintf )
+        info( '\n' )
+        info( '*** Testing control network\n' )
+        while not cintf.isUp():
+            info( '*** Waiting for', cintf, 'to come up\n' )
+            sleep( 1 )
+        for switch in self.switches:
+            while not sintf.isUp():
+                info( '*** Waiting for', sintf, 'to come up\n' )
+                sleep( 1 )
+            if self.ping( hosts=[ switch, controller ] ) != 0:
+                error( '*** Error: control network test failed\n' )
+                exit( 1 )
+        info( '\n' )
