diff --git a/mininet/node.py b/mininet/node.py
new file mode 100644
index 0000000..4c54d75
--- /dev/null
+++ b/mininet/node.py
@@ -0,0 +1,1235 @@
+"""
+Node objects for Mininet.
+
+Nodes provide a simple abstraction for interacting with hosts, switches
+and controllers. Local nodes are simply one or more processes on the local
+machine.
+
+Node: superclass for all (primarily local) network nodes.
+
+Host: a virtual host. By default, a host is simply a shell; commands
+    may be sent using Cmd (which waits for output), or using sendCmd(),
+    which returns immediately, allowing subsequent monitoring using
+    monitor(). Examples of how to run experiments using this
+    functionality are provided in the examples/ directory.
+
+CPULimitedHost: a virtual host whose CPU bandwidth is limited by
+    RT or CFS bandwidth limiting.
+
+Switch: superclass for switch nodes.
+
+UserSwitch: a switch using the user-space switch from the OpenFlow
+    reference implementation.
+
+KernelSwitch: a switch using the kernel switch from the OpenFlow reference
+    implementation.
+
+OVSSwitch: a switch using the OpenVSwitch OpenFlow-compatible switch
+    implementation (openvswitch.org).
+
+Controller: superclass for OpenFlow controllers. The default controller
+    is controller(8) from the reference implementation.
+
+NOXController: a controller node using NOX (noxrepo.org).
+
+RemoteController: a remote controller node, which may use any
+    arbitrary OpenFlow-compatible controller, and which is not
+    created or managed by mininet.
+
+Future enhancements:
+
+- Possibly make Node, Switch and Controller more abstract so that
+  they can be used for both local and remote nodes
+
+- Create proxy objects for remote nodes (Mininet: Cluster Edition)
+"""
+
+import os
+import re
+import signal
+import select
+from subprocess import Popen, PIPE, STDOUT
+
+from mininet.log import info, error, warn, debug
+from mininet.util import ( quietRun, errRun, errFail, moveIntf, isShellBuiltin,
+                           numCores, retry, mountCgroups )
+from mininet.moduledeps import moduleDeps, pathCheck, OVS_KMOD, OF_KMOD, TUN
+from mininet.link import Link, Intf, TCIntf
+
+class Node( object ):
+    """A virtual network node is simply a shell in a network namespace.
+       We communicate with it using pipes."""
+
+    portBase = 0  # Nodes always start with eth0/port0, even in OF 1.0
+
+    def __init__( self, name, inNamespace=True, **params ):
+        """name: name of node
+           inNamespace: in network namespace?
+           params: Node parameters (see config() for details)"""
+
+        # Make sure class actually works
+        self.checkSetup()
+
+        self.name = name
+        self.inNamespace = inNamespace
+
+        # Stash configuration parameters for future reference
+        self.params = params
+
+        self.intfs = {}  # dict of port numbers to interfaces
+        self.ports = {}  # dict of interfaces to port numbers
+                         # replace with Port objects, eventually ?
+        self.nameToIntf = {}  # dict of interface names to Intfs
+
+        # Make pylint happy
+        ( self.shell, self.execed, self.pid, self.stdin, self.stdout,
+            self.lastPid, self.lastCmd, self.pollOut ) = (
+                None, None, None, None, None, None, None, None )
+        self.waiting = False
+        self.readbuf = ''
+
+        # Start command interpreter shell
+        self.startShell()
+
+    # File descriptor to node mapping support
+    # Class variables and methods
+
+    inToNode = {}  # mapping of input fds to nodes
+    outToNode = {}  # mapping of output fds to nodes
+
+    @classmethod
+    def fdToNode( cls, fd ):
+        """Return node corresponding to given file descriptor.
+           fd: file descriptor
+           returns: node"""
+        node = cls.outToNode.get( fd )
+        return node or cls.inToNode.get( fd )
+
+    # Command support via shell process in namespace
+
+    def startShell( self ):
+        "Start a shell process for running commands"
+        if self.shell:
+            error( "%s: shell is already running" )
+            return
+        # mnexec: (c)lose descriptors, (d)etach from tty,
+        # (p)rint pid, and run in (n)amespace
+        opts = '-cdp'
+        if self.inNamespace:
+            opts += 'n'
+        # bash -m: enable job control
+        cmd = [ 'mnexec', opts, 'bash', '-m' ]
+        self.shell = Popen( cmd, stdin=PIPE, stdout=PIPE, stderr=STDOUT,
+                            close_fds=True )
+        self.stdin = self.shell.stdin
+        self.stdout = self.shell.stdout
+        self.pid = self.shell.pid
+        self.pollOut = select.poll()
+        self.pollOut.register( self.stdout )
+        # Maintain mapping between file descriptors and nodes
+        # This is useful for monitoring multiple nodes
+        # using select.poll()
+        self.outToNode[ self.stdout.fileno() ] = self
+        self.inToNode[ self.stdin.fileno() ] = self
+        self.execed = False
+        self.lastCmd = None
+        self.lastPid = None
+        self.readbuf = ''
+        self.waiting = False
+
+    def cleanup( self ):
+        "Help python collect its garbage."
+        if not self.inNamespace:
+            for intfName in self.intfNames():
+                if self.name in intfName:
+                    quietRun( 'ip link del ' + intfName )
+        self.shell = None
+
+    # Subshell I/O, commands and control
+
+    def read( self, maxbytes=1024 ):
+        """Buffered read from node, non-blocking.
+           maxbytes: maximum number of bytes to return"""
+        count = len( self.readbuf )
+        if count < maxbytes:
+            data = os.read( self.stdout.fileno(), maxbytes - count )
+            self.readbuf += data
+        if maxbytes >= len( self.readbuf ):
+            result = self.readbuf
+            self.readbuf = ''
+        else:
+            result = self.readbuf[ :maxbytes ]
+            self.readbuf = self.readbuf[ maxbytes: ]
+        return result
+
+    def readline( self ):
+        """Buffered readline from node, non-blocking.
+           returns: line (minus newline) or None"""
+        self.readbuf += self.read( 1024 )
+        if '\n' not in self.readbuf:
+            return None
+        pos = self.readbuf.find( '\n' )
+        line = self.readbuf[ 0: pos ]
+        self.readbuf = self.readbuf[ pos + 1: ]
+        return line
+
+    def write( self, data ):
+        """Write data to node.
+           data: string"""
+        os.write( self.stdin.fileno(), data )
+
+    def terminate( self ):
+        "Send kill signal to Node and clean up after it."
+        os.kill( self.pid, signal.SIGKILL )
+        self.cleanup()
+
+    def stop( self ):
+        "Stop node."
+        self.terminate()
+
+    def waitReadable( self, timeoutms=None ):
+        """Wait until node's output is readable.
+           timeoutms: timeout in ms or None to wait indefinitely."""
+        if len( self.readbuf ) == 0:
+            self.pollOut.poll( timeoutms )
+
+    def sendCmd( self, *args, **kwargs ):
+        """Send a command, followed by a command to echo a sentinel,
+           and return without waiting for the command to complete.
+           args: command and arguments, or string
+           printPid: print command's PID?"""
+        assert not self.waiting
+        printPid = kwargs.get( 'printPid', True )
+        # Allow sendCmd( [ list ] )
+        if len( args ) == 1 and type( args[ 0 ] ) is list:
+            cmd = args[ 0 ]
+        # Allow sendCmd( cmd, arg1, arg2... )
+        elif len( args ) > 0:
+            cmd = args
+        # Convert to string
+        if not isinstance( cmd, str ):
+            cmd = ' '.join( [ str( c ) for c in cmd ] )
+        if not re.search( r'\w', cmd ):
+            # Replace empty commands with something harmless
+            cmd = 'echo -n'
+        self.lastCmd = cmd
+        printPid = printPid and not isShellBuiltin( cmd )
+        if len( cmd ) > 0 and cmd[ -1 ] == '&':
+            # print ^A{pid}\n{sentinel}
+            cmd += ' printf "\\001%d\n\\177" $! \n'
+        else:
+            # print sentinel
+            cmd += '; printf "\\177"'
+            if printPid and not isShellBuiltin( cmd ):
+                cmd = 'mnexec -p ' + cmd
+        self.write( cmd + '\n' )
+        self.lastPid = None
+        self.waiting = True
+
+    def sendInt( self, sig=signal.SIGINT ):
+        "Interrupt running command."
+        if self.lastPid:
+            try:
+                os.kill( self.lastPid, sig )
+            except OSError:
+                pass
+
+    def monitor( self, timeoutms=None ):
+        """Monitor and return the output of a command.
+           Set self.waiting to False if command has completed.
+           timeoutms: timeout in ms or None to wait indefinitely."""
+        self.waitReadable( timeoutms )
+        data = self.read( 1024 )
+        # Look for PID
+        marker = chr( 1 ) + r'\d+\n'
+        if chr( 1 ) in data:
+            markers = re.findall( marker, data )
+            if markers:
+                self.lastPid = int( markers[ 0 ][ 1: ] )
+                data = re.sub( marker, '', data )
+        # Look for sentinel/EOF
+        if len( data ) > 0 and data[ -1 ] == chr( 127 ):
+            self.waiting = False
+            data = data[ :-1 ]
+        elif chr( 127 ) in data:
+            self.waiting = False
+            data = data.replace( chr( 127 ), '' )
+        return data
+
+    def waitOutput( self, verbose=False ):
+        """Wait for a command to complete.
+           Completion is signaled by a sentinel character, ASCII(127)
+           appearing in the output stream.  Wait for the sentinel and return
+           the output, including trailing newline.
+           verbose: print output interactively"""
+        log = info if verbose else debug
+        output = ''
+        while self.waiting:
+            data = self.monitor()
+            output += data
+            log( data )
+        return output
+
+    def cmd( self, *args, **kwargs ):
+        """Send a command, wait for output, and return it.
+           cmd: string"""
+        verbose = kwargs.get( 'verbose', False )
+        log = info if verbose else debug
+        log( '*** %s : %s\n' % ( self.name, args ) )
+        self.sendCmd( *args, **kwargs )
+        return self.waitOutput( verbose )
+
+    def cmdPrint( self, *args):
+        """Call cmd and printing its output
+           cmd: string"""
+        return self.cmd( *args, **{ 'verbose': True } )
+
+    def popen( self, *args, **kwargs ):
+        """Return a Popen() object in our namespace
+           args: Popen() args, single list, or string
+           kwargs: Popen() keyword args"""
+        defaults = { 'stdout': PIPE, 'stderr': PIPE,
+                     'mncmd':
+                     [ 'mnexec', '-a', str( self.pid ) ] }
+        defaults.update( kwargs )
+        if len( args ) == 1:
+            if type( args[ 0 ] ) is list:
+                # popen([cmd, arg1, arg2...])
+                cmd = args[ 0 ]
+            elif type( args[ 0 ] ) is str:
+                # popen("cmd arg1 arg2...")
+                cmd = args[ 0 ].split()
+            else:
+                raise Exception( 'popen() requires a string or list' )
+        elif len( args ) > 0:
+            # popen( cmd, arg1, arg2... )
+            cmd = list( args )
+        # Attach to our namespace  using mnexec -a
+        mncmd = defaults[ 'mncmd' ]
+        del defaults[ 'mncmd' ]
+        cmd = mncmd + cmd
+        # Shell requires a string, not a list!
+        if defaults.get( 'shell', False ):
+            cmd = ' '.join( cmd )
+        return Popen( cmd, **defaults )
+
+    def pexec( self, *args, **kwargs ):
+        """Execute a command using popen
+           returns: out, err, exitcode"""
+        popen = self.popen( *args, **kwargs)
+        out, err = popen.communicate()
+        exitcode = popen.wait()
+        return out, err, exitcode
+
+    # Interface management, configuration, and routing
+
+    # BL notes: This might be a bit redundant or over-complicated.
+    # However, it does allow a bit of specialization, including
+    # changing the canonical interface names. It's also tricky since
+    # the real interfaces are created as veth pairs, so we can't
+    # make a single interface at a time.
+
+    def newPort( self ):
+        "Return the next port number to allocate."
+        if len( self.ports ) > 0:
+            return max( self.ports.values() ) + 1
+        return self.portBase
+
+    def addIntf( self, intf, port=None ):
+        """Add an interface.
+           intf: interface
+           port: port number (optional, typically OpenFlow port number)"""
+        if port is None:
+            port = self.newPort()
+        self.intfs[ port ] = intf
+        self.ports[ intf ] = port
+        self.nameToIntf[ intf.name ] = intf
+        debug( '\n' )
+        debug( 'added intf %s:%d to node %s\n' % ( intf, port, self.name ) )
+        if self.inNamespace:
+            debug( 'moving', intf, 'into namespace for', self.name, '\n' )
+            moveIntf( intf.name, self )
+
+    def defaultIntf( self ):
+        "Return interface for lowest port"
+        ports = self.intfs.keys()
+        if ports:
+            return self.intfs[ min( ports ) ]
+        else:
+            warn( '*** defaultIntf: warning:', self.name,
+                  'has no interfaces\n' )
+
+    def intf( self, intf='' ):
+        """Return our interface object with given string name,
+           default intf if name is falsy (None, empty string, etc).
+           or the input intf arg.
+
+        Having this fcn return its arg for Intf objects makes it
+        easier to construct functions with flexible input args for
+        interfaces (those that accept both string names and Intf objects).
+        """
+        if not intf:
+            return self.defaultIntf()
+        elif type( intf) is str:
+            return self.nameToIntf[ intf ]
+        else:
+            return intf
+
+    def connectionsTo( self, node):
+        "Return [ intf1, intf2... ] for all intfs that connect self to node."
+        # We could optimize this if it is important
+        connections = []
+        for intf in self.intfList():
+            link = intf.link
+            if link:
+                node1, node2 = link.intf1.node, link.intf2.node
+                if node1 == self and node2 == node:
+                    connections += [ ( intf, link.intf2 ) ]
+                elif node1 == node and node2 == self:
+                    connections += [ ( intf, link.intf1 ) ]
+        return connections
+
+    def deleteIntfs( self ):
+        "Delete all of our interfaces."
+        # In theory the interfaces should go away after we shut down.
+        # However, this takes time, so we're better off removing them
+        # explicitly so that we won't get errors if we run before they
+        # have been removed by the kernel. Unfortunately this is very slow,
+        # at least with Linux kernels before 2.6.33
+        for intf in self.intfs.values():
+            intf.delete()
+            info( '.' )
+
+    # Routing support
+
+    def setARP( self, ip, mac ):
+        """Add an ARP entry.
+           ip: IP address as string
+           mac: MAC address as string"""
+        result = self.cmd( 'arp', '-s', ip, mac )
+        return result
+
+    def setHostRoute( self, ip, intf ):
+        """Add route to host.
+           ip: IP address as dotted decimal
+           intf: string, interface name"""
+        return self.cmd( 'route add -host', ip, 'dev', intf )
+
+    def setDefaultRoute( self, intf=None ):
+        """Set the default route to go through intf.
+           intf: string, interface name"""
+        if not intf:
+            intf = self.defaultIntf()
+        self.cmd( 'ip route flush root 0/0' )
+        return self.cmd( 'route add default %s' % intf )
+
+    # Convenience and configuration methods
+
+    def setMAC( self, mac, intf=None ):
+        """Set the MAC address for an interface.
+           intf: intf or intf name
+           mac: MAC address as string"""
+        return self.intf( intf ).setMAC( mac )
+
+    def setIP( self, ip, prefixLen=8, intf=None ):
+        """Set the IP address for an interface.
+           intf: intf or intf name
+           ip: IP address as a string
+           prefixLen: prefix length, e.g. 8 for /8 or 16M addrs"""
+        # 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()
+
+    def MAC( self, intf=None ):
+        "Return MAC address of a node or specific interface."
+        return self.intf( intf ).MAC()
+
+    def intfIsUp( self, intf=None ):
+        "Check if an interface is up."
+        return self.intf( intf ).isUp()
+
+    # The reason why we configure things in this way is so
+    # That the parameters can be listed and documented in
+    # the config method.
+    # Dealing with subclasses and superclasses is slightly
+    # annoying, but at least the information is there!
+
+    def setParam( self, results, method, **param ):
+        """Internal method: configure a *single* parameter
+           results: dict of results to update
+           method: config method name
+           param: arg=value (ignore if value=None)
+           value may also be list or dict"""
+        name, value = param.items()[ 0 ]
+        f = getattr( self, method, None )
+        if not f or value is None:
+            return
+        if type( value ) is list:
+            result = f( *value )
+        elif type( value ) is dict:
+            result = f( **value )
+        else:
+            result = f( value )
+        results[ name ] = result
+        return result
+
+    def config( self, mac=None, ip=None,
+                defaultRoute=None, lo='up', **_params ):
+        """Configure Node according to (optional) parameters:
+           mac: MAC address for default interface
+           ip: IP address for default interface
+           ifconfig: arbitrary interface configuration
+           Subclasses should override this method and call
+           the parent class's config(**params)"""
+        # If we were overriding this method, we would call
+        # the superclass config method here as follows:
+        # r = Parent.config( **_params )
+        r = {}
+        self.setParam( r, 'setMAC', mac=mac )
+        self.setParam( r, 'setIP', ip=ip )
+        self.setParam( r, 'defaultRoute', defaultRoute=defaultRoute )
+        # This should be examined
+        self.cmd( 'ifconfig lo ' + lo )
+        return r
+
+    def configDefault( self, **moreParams ):
+        "Configure with default parameters"
+        self.params.update( moreParams )
+        self.config( **self.params )
+
+    # This is here for backward compatibility
+    def linkTo( self, node, link=Link ):
+        """(Deprecated) Link to another node
+           replace with Link( node1, node2)"""
+        return link( self, node )
+
+    # Other methods
+
+    def intfList( self ):
+        "List of our interfaces sorted by port number"
+        return [ self.intfs[ p ] for p in sorted( self.intfs.iterkeys() ) ]
+
+    def intfNames( self ):
+        "The names of our interfaces sorted by port number"
+        return [ str( i ) for i in self.intfList() ]
+
+    def __repr__( self ):
+        "More informative string representation"
+        intfs = ( ','.join( [ '%s:%s' % ( i.name, i.IP() )
+                              for i in self.intfList() ] ) )
+        return '<%s %s: %s pid=%s> ' % (
+            self.__class__.__name__, self.name, intfs, self.pid )
+
+    def __str__( self ):
+        "Abbreviated string representation"
+        return self.name
+
+    # Automatic class setup support
+
+    isSetup = False
+
+    @classmethod
+    def checkSetup( cls ):
+        "Make sure our class and superclasses are set up"
+        while cls and not getattr( cls, 'isSetup', True ):
+            cls.setup()
+            cls.isSetup = True
+            # Make pylint happy
+            cls = getattr( type( cls ), '__base__', None )
+
+    @classmethod
+    def setup( cls ):
+        "Make sure our class dependencies are available"
+        pathCheck( 'mnexec', 'ifconfig', moduleName='Mininet')
+
+
+class Host( Node ):
+    "A host is simply a Node"
+    pass
+
+
+        
+class CPULimitedHost( Host ):
+
+    "CPU limited host"
+
+    def __init__( self, name, sched='cfs', **kwargs ):
+        Host.__init__( self, name, **kwargs )
+        # Initialize class if necessary
+        if not CPULimitedHost.inited:
+            CPULimitedHost.init()
+        # Create a cgroup and move shell into it
+        self.cgroup = 'cpu,cpuacct,cpuset:/' + self.name
+        errFail( 'cgcreate -g ' + self.cgroup )
+        # We don't add ourselves to a cpuset because you must
+        # specify the cpu and memory placement first
+        errFail( 'cgclassify -g cpu,cpuacct:/%s %s' % ( self.name, self.pid ) )
+        # BL: Setting the correct period/quota is tricky, particularly
+        # for RT. RT allows very small quotas, but the overhead
+        # seems to be high. CFS has a mininimum quota of 1 ms, but
+        # still does better with larger period values.
+        self.period_us = kwargs.get( 'period_us', 100000 )
+        self.sched = sched
+        self.rtprio = 20
+
+    def cgroupSet( self, param, value, resource='cpu' ):
+        "Set a cgroup parameter and return its value"
+        cmd = 'cgset -r %s.%s=%s /%s' % (
+            resource, param, value, self.name )
+        quietRun( cmd )
+        nvalue = int( self.cgroupGet( param, resource ) )
+        if nvalue != value:
+            error( '*** error: cgroupSet: %s set to %s instead of %s\n'
+                   % ( param, nvalue, value ) )
+        return nvalue
+
+    def cgroupGet( self, param, resource='cpu' ):
+        "Return value of cgroup parameter"
+        cmd = 'cgget -r %s.%s /%s' % (
+            resource, param, self.name )
+        return int( quietRun( cmd ).split()[ -1 ] )
+
+    def cgroupDel( self ):
+        "Clean up our cgroup"
+        # info( '*** deleting cgroup', self.cgroup, '\n' )
+        _out, _err, exitcode = errRun( 'cgdelete -r ' + self.cgroup )
+        return exitcode != 0
+
+    def popen( self, *args, **kwargs ):
+        """Return a Popen() object in node's namespace
+           args: Popen() args, single list, or string
+           kwargs: Popen() keyword args"""
+        # Tell mnexec to execute command in our cgroup
+        mncmd = [ 'mnexec', '-a', str( self.pid ),
+                  '-g', self.name ]
+        if self.sched == 'rt':
+            mncmd += [ '-r', str( self.rtprio ) ]
+        return Host.popen( self, *args, mncmd=mncmd, **kwargs )
+
+    def cleanup( self ):
+        "Clean up our cgroup"
+        retry( retries=3, delaySecs=1, fn=self.cgroupDel )
+
+    def chrt( self ):
+        "Set RT scheduling priority"
+        quietRun( 'chrt -p %s %s' % ( self.rtprio, self.pid ) )
+        result = quietRun( 'chrt -p %s' % self.pid )
+        firstline = result.split( '\n' )[ 0 ]
+        lastword = firstline.split( ' ' )[ -1 ]
+        if lastword != 'SCHED_RR':
+            error( '*** error: could not assign SCHED_RR to %s\n' % self.name )
+        return lastword
+
+    def rtInfo( self, f ):
+        "Internal method: return parameters for RT bandwidth"
+        pstr, qstr = 'rt_period_us', 'rt_runtime_us'
+        # RT uses wall clock time for period and quota
+        quota = int( self.period_us * f * numCores() )
+        return pstr, qstr, self.period_us, quota
+
+    def cfsInfo( self, f):
+        "Internal method: return parameters for CFS bandwidth"
+        pstr, qstr = 'cfs_period_us', 'cfs_quota_us'
+        # CFS uses wall clock time for period and CPU time for quota.
+        quota = int( self.period_us * f * numCores() )
+        period = self.period_us
+        if f > 0 and quota < 1000:
+            debug( '(cfsInfo: increasing default period) ' )
+            quota = 1000
+            period = int( quota / f / numCores() )
+        return pstr, qstr, period, quota
+
+    # BL comment:
+    # This may not be the right API,
+    # since it doesn't specify CPU bandwidth in "absolute"
+    # units the way link bandwidth is specified.
+    # We should use MIPS or SPECINT or something instead.
+    # Alternatively, we should change from system fraction
+    # to CPU seconds per second, essentially assuming that
+    # all CPUs are the same.
+
+    def setCPUFrac( self, f=-1, sched=None):
+        """Set overall CPU fraction for this host
+           f: CPU bandwidth limit (fraction)
+           sched: 'rt' or 'cfs'
+           Note 'cfs' requires CONFIG_CFS_BANDWIDTH"""
+        if not f:
+            return
+        if not sched:
+            sched = self.sched
+        if sched == 'rt':
+            pstr, qstr, period, quota = self.rtInfo( f )
+        elif sched == 'cfs':
+            pstr, qstr, period, quota = self.cfsInfo( f )
+        else:
+            return
+        if quota < 0:
+            # Reset to unlimited
+            quota = -1
+        # Set cgroup's period and quota
+        self.cgroupSet( pstr, period )
+        self.cgroupSet( qstr, quota )
+        if sched == 'rt':
+            # Set RT priority if necessary
+            self.chrt()
+        info( '(%s %d/%dus) ' % ( sched, quota, period ) )
+
+    def setCPUs( self, cores, mems=0 ):
+        "Specify (real) cores that our cgroup can run on"
+        if type( cores ) is list:
+            cores = ','.join( [ str( c ) for c in cores ] )
+        self.cgroupSet( resource='cpuset', param='cpus',
+                        value=cores )
+        # Memory placement is probably not relevant, but we
+        # must specify it anyway
+        self.cgroupSet( resource='cpuset', param='mems',
+                        value=mems)
+        # We have to do this here after we've specified
+        # cpus and mems
+        errFail( 'cgclassify -g cpuset:/%s %s' % (
+                 self.name, self.pid ) )
+
+    def config( self, cpu=None, cores=None, **params ):
+        """cpu: desired overall system CPU fraction
+           cores: (real) core(s) this host can run on
+           params: parameters for Node.config()"""
+        r = Node.config( self, **params )
+        # Was considering cpu={'cpu': cpu , 'sched': sched}, but
+        # that seems redundant
+
+        self.setParam( r, 'setCPUFrac', cpu=cpu )
+        self.setParam( r, 'setCPUs', cores=cores )
+
+        return r
+
+    inited = False
+
+    @classmethod
+    def init( cls ):
+        "Initialization for CPULimitedHost class"
+        mountCgroups()
+        cls.inited = True
+
+class CCNHost( Host ):
+    "CCNHost is a Host that always runs the ccnd daemon"
+
+    def __init__( self, name, **kwargs ):
+
+        
+        Host.__init__( self, name, **kwargs )
+        if not CCNHost.inited:
+            CCNHost.init()
+            
+        self.cmd("export CCN_LOCAL_SOCKNAME=/tmp/.sock.ccnx.{0}".format(self.name))
+        self.cmd("ccndstart")
+        self.peerList = {}
+
+    def config( self, fib=None, app=None, **params ):
+             
+        r = Node.config( self, **params )
+        
+        self.setParam( r, 'app', fib=fib )
+        self.setParam( r, 'fib', app=app)
+        
+        return r
+    
+    def configCCN(self):
+        
+        self.buildPeerIP()
+        self.setFIB()
+    
+    def buildPeerIP(self):
+        for iface in self.intfList():
+            link = iface.link
+            if link:
+                node1, node2 = link.intf1.node, link.intf2.node
+                if node1 == self:
+                    self.peerList[node2.name] = link.intf2.node.IP(link.intf2)
+                else:
+                    self.peerList[node1.name] = link.intf1.node.IP(link.intf1)
+        
+        
+    def setFIB(self):
+
+        for name in self.params['fib']:
+            if not name:
+                pass
+            else:
+                self.insert_fib(name[0],self.peerList[name[1]])
+            
+        
+    def insert_fib(self, uri, host):
+        self.cmd('ccndc add {0} tcp {1}'.format(uri,host))
+        
+    def terminate( self ):
+        "Stop node."
+        self.cmd('ccndstop')
+        Host.terminate(self)
+        
+    inited = False
+
+    
+    @classmethod
+    def init( cls ):
+        "Initialization for CCNHost class"
+        cls.inited = True
+        
+class CPULimitedCCNHost( CPULimitedHost ):
+    '''CPULimitedCCNHost is a Host that always runs the ccnd daemon and extends CPULimitedHost.
+       It should be used when one wants to limit the resources of CCN routers and hosts '''
+    
+
+    def __init__( self, name, sched='cfs', **kwargs ):
+        
+        CPULimitedHost.__init__( self, name, sched, **kwargs )
+        if not CCNHost.inited:
+            CCNHost.init()
+            
+        self.cmd("export CCN_LOCAL_SOCKNAME=/tmp/.sock.ccnx.{0}".format(self.name))
+        self.cmd("ccndstart")
+        self.peerList = {}
+
+    def config( self, fib=None, app=None, cpu=None, cores=None, **params):   
+
+        r = CPULimitedHost.config(self,cpu,cores, **params)
+        
+        print 'nozess'
+        self.setParam( r, 'app', fib=fib )
+        self.setParam( r, 'fib', app=app)
+        
+        return r
+    
+    def configCCN(self):
+        
+        self.buildPeerIP()
+        self.setFIB()
+    
+    def buildPeerIP(self):
+        for iface in self.intfList():
+            link = iface.link
+            if link:
+                node1, node2 = link.intf1.node, link.intf2.node
+                if node1 == self:
+                    self.peerList[node2.name] = link.intf2.node.IP(link.intf2)
+                else:
+                    self.peerList[node1.name] = link.intf1.node.IP(link.intf1)
+        
+        
+    def setFIB(self):
+
+        for name in self.params['fib']:
+            if not name:
+                pass
+            else:
+                self.insert_fib(name[0],self.peerList[name[1]])
+            
+        
+    def insert_fib(self, uri, host):
+        self.cmd('ccndc add {0} tcp {1}'.format(uri,host))
+        
+    def terminate( self ):
+        "Stop node."
+        self.cmd('ccndstop')
+        Host.terminate(self)
+        
+    inited = False
+
+    
+    @classmethod
+    def init( cls ):
+        "Initialization for CCNHost class"
+        cls.inited = True
+
+# Some important things to note:
+#
+# The "IP" address which setIP() assigns to the switch is not
+# an "IP address for the switch" in the sense of IP routing.
+# Rather, it is the IP address for the control interface,
+# on the control network, and it is only relevant to the
+# controller. If you are running in the root namespace
+# (which is the only way to run OVS at the moment), the
+# control interface is the loopback interface, and you
+# normally never want to change its IP address!
+#
+# In general, you NEVER want to attempt to use Linux's
+# network stack (i.e. ifconfig) to "assign" an IP address or
+# MAC address to a switch data port. Instead, you "assign"
+# the IP and MAC addresses in the controller by specifying
+# packets that you want to receive or send. The "MAC" address
+# reported by ifconfig for a switch data port is essentially
+# meaningless. It is important to understand this if you
+# want to create a functional router using OpenFlow.
+
+class Switch( Node ):
+    """A Switch is a Node that is running (or has execed?)
+       an OpenFlow switch."""
+
+    portBase = 1  # Switches start with port 1 in OpenFlow
+    dpidLen = 16  # digits in dpid passed to switch
+
+    def __init__( self, name, dpid=None, opts='', listenPort=None, **params):
+        """dpid: dpid for switch (or None to derive from name, e.g. s1 -> 1)
+           opts: additional switch options
+           listenPort: port to listen on for dpctl connections"""
+        Node.__init__( self, name, **params )
+        self.dpid = dpid if dpid else self.defaultDpid()
+        self.opts = opts
+        self.listenPort = listenPort
+        if not self.inNamespace:
+            self.controlIntf = Intf( 'lo', self, port=0 )
+
+    def defaultDpid( self ):
+        "Derive dpid from switch name, s1 -> 1"
+        try:
+            dpid = int( re.findall( '\d+', self.name )[ 0 ] )
+            dpid = hex( dpid )[ 2: ]
+            dpid = '0' * ( self.dpidLen - len( dpid ) ) + dpid
+            return dpid
+        except IndexError:
+            raise Exception( 'Unable to derive default datapath ID - '
+                             'please either specify a dpid or use a '
+                             'canonical switch name such as s23.' )
+
+    def defaultIntf( self ):
+        "Return control interface"
+        if self.controlIntf:
+            return self.controlIntf
+        else:
+            return Node.defaultIntf( self )
+
+    def sendCmd( self, *cmd, **kwargs ):
+        """Send command to Node.
+           cmd: string"""
+        kwargs.setdefault( 'printPid', False )
+        if not self.execed:
+            return Node.sendCmd( self, *cmd, **kwargs )
+        else:
+            error( '*** Error: %s has execed and cannot accept commands' %
+                   self.name )
+
+    def __repr__( self ):
+        "More informative string representation"
+        intfs = ( ','.join( [ '%s:%s' % ( i.name, i.IP() )
+                              for i in self.intfList() ] ) )
+        return '<%s %s: %s pid=%s> ' % (
+            self.__class__.__name__, self.name, intfs, self.pid )
+
+class UserSwitch( Switch ):
+    "User-space switch."
+
+    dpidLen = 12
+
+    def __init__( self, name, **kwargs ):
+        """Init.
+           name: name for the switch"""
+        Switch.__init__( self, name, **kwargs )
+        pathCheck( 'ofdatapath', 'ofprotocol',
+                   moduleName='the OpenFlow reference user switch' +
+                              '(openflow.org)' )
+        if self.listenPort:
+            self.opts += ' --listen=ptcp:%i ' % self.listenPort
+
+    @classmethod
+    def setup( cls ):
+        "Ensure any dependencies are loaded; if not, try to load them."
+        if not os.path.exists( '/dev/net/tun' ):
+            moduleDeps( add=TUN )
+
+    def dpctl( self, *args ):
+        "Run dpctl command"
+        if not self.listenPort:
+            return "can't run dpctl without passive listening port"
+        return self.cmd( 'dpctl ' + ' '.join( args ) +
+                         ' tcp:127.0.0.1:%i' % self.listenPort )
+
+    def start( self, controllers ):
+        """Start OpenFlow reference user datapath.
+           Log to /tmp/sN-{ofd,ofp}.log.
+           controllers: list of controller objects"""
+        # Add controllers
+        clist = ','.join( [ 'tcp:%s:%d' % ( c.IP(), c.port )
+                            for c in controllers ] )
+        ofdlog = '/tmp/' + self.name + '-ofd.log'
+        ofplog = '/tmp/' + self.name + '-ofp.log'
+        self.cmd( 'ifconfig lo up' )
+        intfs = [ str( i ) for i in self.intfList() if not i.IP() ]
+        self.cmd( 'ofdatapath -i ' + ','.join( intfs ) +
+                  ' punix:/tmp/' + self.name + ' -d ' + self.dpid +
+                  ' 1> ' + ofdlog + ' 2> ' + ofdlog + ' &' )
+        self.cmd( 'ofprotocol unix:/tmp/' + self.name +
+                  ' ' + clist +
+                  ' --fail=closed ' + self.opts +
+                  ' 1> ' + ofplog + ' 2>' + ofplog + ' &' )
+
+    def stop( self ):
+        "Stop OpenFlow reference user datapath."
+        self.cmd( 'kill %ofdatapath' )
+        self.cmd( 'kill %ofprotocol' )
+        self.deleteIntfs()
+
+
+class OVSLegacyKernelSwitch( Switch ):
+    """Open VSwitch legacy kernel-space switch using ovs-openflowd.
+       Currently only works in the root namespace."""
+
+    def __init__( self, name, dp=None, **kwargs ):
+        """Init.
+           name: name for switch
+           dp: netlink id (0, 1, 2, ...)
+           defaultMAC: default MAC as unsigned int; random value if None"""
+        Switch.__init__( self, name, **kwargs )
+        self.dp = dp if dp else self.name
+        self.intf = self.dp
+        if self.inNamespace:
+            error( "OVSKernelSwitch currently only works"
+                   " in the root namespace.\n" )
+            exit( 1 )
+
+    @classmethod
+    def setup( cls ):
+        "Ensure any dependencies are loaded; if not, try to load them."
+        pathCheck( 'ovs-dpctl', 'ovs-openflowd',
+                   moduleName='Open vSwitch (openvswitch.org)')
+        moduleDeps( subtract=OF_KMOD, add=OVS_KMOD )
+
+    def start( self, controllers ):
+        "Start up kernel datapath."
+        ofplog = '/tmp/' + self.name + '-ofp.log'
+        quietRun( 'ifconfig lo up' )
+        # Delete local datapath if it exists;
+        # then create a new one monitoring the given interfaces
+        self.cmd( 'ovs-dpctl del-dp ' + self.dp )
+        self.cmd( 'ovs-dpctl add-dp ' + self.dp )
+        intfs = [ str( i ) for i in self.intfList() if not i.IP() ]
+        self.cmd( 'ovs-dpctl', 'add-if', self.dp, ' '.join( intfs ) )
+        # Run protocol daemon
+        clist = ','.join( [ 'tcp:%s:%d' % ( c.IP(), c.port )
+                            for c in controllers ] )
+        self.cmd( 'ovs-openflowd ' + self.dp +
+                  ' ' + clist +
+                  ' --fail=secure ' + self.opts +
+                  ' --datapath-id=' + self.dpid +
+                  ' 1>' + ofplog + ' 2>' + ofplog + '&' )
+        self.execed = False
+
+    def stop( self ):
+        "Terminate kernel datapath."
+        quietRun( 'ovs-dpctl del-dp ' + self.dp )
+        self.cmd( 'kill %ovs-openflowd' )
+        self.deleteIntfs()
+
+
+class OVSSwitch( Switch ):
+    "Open vSwitch switch. Depends on ovs-vsctl."
+
+    def __init__( self, name, failMode='secure', **params ):
+        """Init.
+           name: name for switch
+           failMode: controller loss behavior (secure|open)"""
+        Switch.__init__( self, name, **params )
+        self.failMode = failMode
+
+    @classmethod
+    def setup( cls ):
+        "Make sure Open vSwitch is installed and working"
+        pathCheck( 'ovs-vsctl',
+                   moduleName='Open vSwitch (openvswitch.org)')
+        # This should no longer be needed, and it breaks
+        # with OVS 1.7 which has renamed the kernel module:
+        #  moduleDeps( subtract=OF_KMOD, add=OVS_KMOD )
+        out, err, exitcode = errRun( 'ovs-vsctl -t 1 show' )
+        if exitcode:
+            error( out + err +
+                   'ovs-vsctl exited with code %d\n' % exitcode +
+                   '*** Error connecting to ovs-db with ovs-vsctl\n'
+                   'Make sure that Open vSwitch is installed, '
+                   'that ovsdb-server is running, and that\n'
+                   '"ovs-vsctl show" works correctly.\n'
+                   'You may wish to try '
+                   '"service openvswitch-switch start".\n' )
+            exit( 1 )
+
+    def dpctl( self, *args ):
+        "Run ovs-dpctl command"
+        return self.cmd( 'ovs-dpctl', args[ 0 ], self, *args[ 1: ] )
+
+    @staticmethod
+    def TCReapply( intf ):
+        """Unfortunately OVS and Mininet are fighting
+           over tc queuing disciplines. As a quick hack/
+           workaround, we clear OVS's and reapply our own."""
+        if type( intf ) is TCIntf:
+            intf.config( **intf.params )
+
+    def attach( self, intf ):
+        "Connect a data port"
+        self.cmd( 'ovs-vsctl add-port', self, intf )
+        self.cmd( 'ifconfig', intf, 'up' )
+        self.TCReapply( intf )
+
+    def detach( self, intf ):
+        "Disconnect a data port"
+        self.cmd( 'ovs-vsctl del-port', self, intf )
+
+    def start( self, controllers ):
+        "Start up a new OVS OpenFlow switch using ovs-vsctl"
+        if self.inNamespace:
+            raise Exception(
+                'OVS kernel switch does not work in a namespace' )
+        # We should probably call config instead, but this
+        # requires some rethinking...
+        self.cmd( 'ifconfig lo up' )
+        # Annoyingly, --if-exists option seems not to work
+        self.cmd( 'ovs-vsctl del-br', self )
+        self.cmd( 'ovs-vsctl add-br', self )
+        self.cmd( 'ovs-vsctl -- set Bridge', self,
+                  'other_config:datapath-id=' + self.dpid )
+        self.cmd( 'ovs-vsctl set-fail-mode', self, self.failMode )
+        for intf in self.intfList():
+            if not intf.IP():
+                self.attach( intf )
+        # Add controllers
+        clist = ' '.join( [ 'tcp:%s:%d' % ( c.IP(), c.port )
+                            for c in controllers ] )
+        if self.listenPort:
+            clist += ' ptcp:%s' % self.listenPort
+        self.cmd( 'ovs-vsctl set-controller', self, clist )
+
+    def stop( self ):
+        "Terminate OVS switch."
+        self.cmd( 'ovs-vsctl del-br', self )
+        self.deleteIntfs()
+
+OVSKernelSwitch = OVSSwitch
+
+
+class Controller( Node ):
+    """A Controller is a Node that is running (or has execed?) an
+       OpenFlow controller."""
+
+    def __init__( self, name, inNamespace=False, command='controller',
+                  cargs='-v ptcp:%d', cdir=None, ip="127.0.0.1",
+                  port=6633, **params ):
+        self.command = command
+        self.cargs = cargs
+        self.cdir = cdir
+        self.ip = ip
+        self.port = port
+        Node.__init__( self, name, inNamespace=inNamespace,
+                       ip=ip, **params  )
+        self.cmd( 'ifconfig lo up' )  # Shouldn't be necessary
+        self.checkListening()
+
+    def checkListening( self ):
+        "Make sure no controllers are running on our port"
+        # Verify that Telnet is installed first:
+        out, _err, returnCode = errRun( "which telnet" )
+        if 'telnet' not in out or returnCode != 0:
+            raise Exception( "Error running telnet to check for listening "
+                             "controllers; please check that it is "
+                             "installed." )
+        listening = self.cmd( "echo A | telnet -e A %s %d" %
+                              ( self.ip, self.port ) )
+        if 'Unable' not in listening:
+            servers = self.cmd( 'netstat -atp' ).split( '\n' )
+            pstr = ':%d ' % self.port
+            clist = servers[ 0:1 ] + [ s for s in servers if pstr in s ]
+            raise Exception( "Please shut down the controller which is"
+                             " running on port %d:\n" % self.port +
+                             '\n'.join( clist ) )
+
+    def start( self ):
+        """Start <controller> <args> on controller.
+           Log to /tmp/cN.log"""
+        pathCheck( self.command )
+        cout = '/tmp/' + self.name + '.log'
+        if self.cdir is not None:
+            self.cmd( 'cd ' + self.cdir )
+        self.cmd( self.command + ' ' + self.cargs % self.port +
+                  ' 1>' + cout + ' 2>' + cout + '&' )
+        self.execed = False
+
+    def stop( self ):
+        "Stop controller."
+        self.cmd( 'kill %' + self.command )
+        self.terminate()
+
+    def IP( self, intf=None ):
+        "Return IP address of the Controller"
+        if self.intfs:
+            ip = Node.IP( self, intf )
+        else:
+            ip = self.ip
+        return ip
+
+    def __repr__( self ):
+        "More informative string representation"
+        return '<%s %s: %s:%s pid=%s> ' % (
+            self.__class__.__name__, self.name,
+            self.IP(), self.port, self.pid )
+
+
+class OVSController( Controller ):
+    "Open vSwitch controller"
+    def __init__( self, name, command='ovs-controller', **kwargs ):
+        Controller.__init__( self, name, command=command, **kwargs )
+
+
+class NOX( Controller ):
+    "Controller to run a NOX application."
+
+    def __init__( self, name, *noxArgs, **kwargs ):
+        """Init.
+           name: name to give controller
+           noxArgs: arguments (strings) to pass to NOX"""
+        if not noxArgs:
+            warn( 'warning: no NOX modules specified; '
+                  'running packetdump only\n' )
+            noxArgs = [ 'packetdump' ]
+        elif type( noxArgs ) not in ( list, tuple ):
+            noxArgs = [ noxArgs ]
+
+        if 'NOX_CORE_DIR' not in os.environ:
+            exit( 'exiting; please set missing NOX_CORE_DIR env var' )
+        noxCoreDir = os.environ[ 'NOX_CORE_DIR' ]
+
+        Controller.__init__( self, name,
+                             command=noxCoreDir + '/nox_core',
+                             cargs='--libdir=/usr/local/lib -v -i ptcp:%s ' +
+                             ' '.join( noxArgs ),
+                             cdir=noxCoreDir,
+                             **kwargs )
+
+
+class RemoteController( Controller ):
+    "Controller running outside of Mininet's control."
+
+    def __init__( self, name, ip='127.0.0.1',
+                  port=6633, **kwargs):
+        """Init.
+           name: name to give controller
+           ip: the IP address where the remote controller is
+           listening
+           port: the port where the remote controller is listening"""
+        Controller.__init__( self, name, ip=ip, port=port, **kwargs )
+
+    def start( self ):
+        "Overridden to do nothing."
+        return
+
+    def stop( self ):
+        "Overridden to do nothing."
+        return
+
+    def checkListening( self ):
+        "Warn if remote controller is not accessible"
+        listening = self.cmd( "echo A | telnet -e A %s %d" %
+                              ( self.ip, self.port ) )
+        if 'Unable' in listening:
+            warn( "Unable to contact the remote controller"
+                  " at %s:%d\n" % ( self.ip, self.port ) )
