Skip to content
Snippets Groups Projects
Commit 6d72a3cb authored by Bob Lantz's avatar Bob Lantz
Browse files

Minor cleanup; clarified fdToNode (still need to test however.)

parent d5886525
No related branches found
No related tags found
No related merge requests found
""" """
Node objects for Mininet. Node objects for Mininet.
Nodes provide a simple abstraction for interacting with Nodes provide a simple abstraction for interacting with hosts, switches
hosts, switches and controllers. Local nodes are simply and controllers. Local nodes are simply one or more processes on the local
one or more processes on the local machine. machine.
Node: superclass for all (currently only local) network nodes. Node: superclass for all (primarily local) network nodes.
Host: a virtual host. Host: a virtual host.
...@@ -33,20 +33,18 @@ ...@@ -33,20 +33,18 @@
from subprocess import Popen, PIPE, STDOUT from subprocess import Popen, PIPE, STDOUT
import os import os
import signal import signal
import sys
import select import select
flush = sys.stdout.flush from mininet.log import info, error
from mininet.log import lg
from mininet.util import quietRun, macColonHex, ipStr from mininet.util import quietRun, macColonHex, ipStr
class Node( object ): class Node( object ):
"""A virtual network node is simply a shell in a network namespace. """A virtual network node is simply a shell in a network namespace.
We communicate with it using pipes.""" We communicate with it using pipes."""
inToNode = {}
outToNode = {} inToNode = {} # mapping of input fds to nodes
outToNode = {} # mapping of output fds to nodes
def __init__( self, name, inNamespace=True ): def __init__( self, name, inNamespace=True ):
self.name = name self.name = name
...@@ -71,28 +69,29 @@ def __init__( self, name, inNamespace=True ): ...@@ -71,28 +69,29 @@ def __init__( self, name, inNamespace=True ):
self.intfCount = 0 self.intfCount = 0
self.intfs = [] # list of interface names, as strings self.intfs = [] # list of interface names, as strings
self.ips = {} # dict of interfaces to ip addresses as strings self.ips = {} # dict of interfaces to ip addresses as strings
self.connection = {} self.connection = {} # remote node connected to each interface
self.waiting = False self.waiting = False
self.execed = False self.execed = False
self.ports = {} # dict of ints to interface strings self.ports = {} # dict of ints to interface strings
# replace with Port object, eventually # replace with Port object, eventually
def fdToNode( self, f ): @classmethod
"""Insert docstring. def fdToNode( cls, fd ):
f: unknown """Return node corresponding to given file descriptor.
returns: bool unknown""" fd: file descriptor
node = self.outToNode.get( f ) returns: node"""
return node or self.inToNode.get( f ) node = Node.outToNode.get( fd )
return node or Node.inToNode.get( fd )
def cleanup( self ): def cleanup( self ):
"Help python collect its garbage." "Help python collect its garbage."
self.shell = None self.shell = None
# Subshell I/O, commands and control # Subshell I/O, commands and control
def read( self, filenoMax ): def read( self, bytes ):
"""Insert docstring. """Read from a node.
filenoMax: unknown""" bytes: maximum number of bytes to read"""
return os.read( self.stdout.fileno(), filenoMax ) return os.read( self.stdout.fileno(), bytes )
def write( self, data ): def write( self, data ):
"""Write data to node. """Write data to node.
...@@ -100,7 +99,7 @@ def write( self, data ): ...@@ -100,7 +99,7 @@ def write( self, data ):
os.write( self.stdin.fileno(), data ) os.write( self.stdin.fileno(), data )
def terminate( self ): def terminate( self ):
"Send kill signal to Node and cleanup after it." "Send kill signal to Node and clean up after it."
os.kill( self.pid, signal.SIGKILL ) os.kill( self.pid, signal.SIGKILL )
self.cleanup() self.cleanup()
...@@ -109,7 +108,7 @@ def stop( self ): ...@@ -109,7 +108,7 @@ def stop( self ):
self.terminate() self.terminate()
def waitReadable( self ): def waitReadable( self ):
"Poll on node." "Wait until node's output is readable."
self.pollOut.poll() self.pollOut.poll()
def sendCmd( self, cmd ): def sendCmd( self, cmd ):
...@@ -127,7 +126,7 @@ def sendCmd( self, cmd ): ...@@ -127,7 +126,7 @@ def sendCmd( self, cmd ):
self.waiting = True self.waiting = True
def monitor( self ): def monitor( self ):
"Monitor the output of a command, returning (done, data)." "Monitor the output of a command, returning (done?, data)."
assert self.waiting assert self.waiting
self.waitReadable() self.waitReadable()
data = self.read( 1024 ) data = self.read( 1024 )
...@@ -138,7 +137,7 @@ def monitor( self ): ...@@ -138,7 +137,7 @@ def monitor( self ):
return False, data return False, data
def sendInt( self ): def sendInt( self ):
"Send ^C, hopefully interrupting a running subprocess." "Send ^C, hopefully interrupting an interactive subprocess."
self.write( chr( 3 ) ) self.write( chr( 3 ) )
def waitOutput( self ): def waitOutput( self ):
...@@ -168,9 +167,9 @@ def cmd( self, cmd ): ...@@ -168,9 +167,9 @@ def cmd( self, cmd ):
def cmdPrint( self, cmd ): def cmdPrint( self, cmd ):
"""Call cmd and printing its output """Call cmd and printing its output
cmd: string""" cmd: string"""
#lg.info( '*** %s : %s', self.name, cmd ) #info( '*** %s : %s', self.name, cmd )
result = self.cmd( cmd ) result = self.cmd( cmd )
#lg.info( '%s\n', result ) #info( '%s\n', result )
return result return result
# Interface management, configuration, and routing # Interface management, configuration, and routing
...@@ -249,7 +248,7 @@ class Host( Node ): ...@@ -249,7 +248,7 @@ class Host( Node ):
class Switch( Node ): class Switch( Node ):
"""A Switch is a Node that is running ( or has execed ) """A Switch is a Node that is running (or has execed?)
an OpenFlow switch.""" an OpenFlow switch."""
def sendCmd( self, cmd ): def sendCmd( self, cmd ):
...@@ -258,7 +257,7 @@ def sendCmd( self, cmd ): ...@@ -258,7 +257,7 @@ def sendCmd( self, cmd ):
if not self.execed: if not self.execed:
return Node.sendCmd( self, cmd ) return Node.sendCmd( self, cmd )
else: else:
lg.error( '*** Error: %s has execed and cannot accept commands' % error( '*** Error: %s has execed and cannot accept commands' %
self.name ) self.name )
def monitor( self ): def monitor( self ):
...@@ -280,7 +279,7 @@ def __init__( self, name ): ...@@ -280,7 +279,7 @@ def __init__( self, name ):
def start( self, controllers ): def start( self, controllers ):
"""Start OpenFlow reference user datapath. """Start OpenFlow reference user datapath.
Log to /tmp/sN-{ ofd,ofp }.log. Log to /tmp/sN-{ofd,ofp}.log.
controllers: dict of controller names to objects""" controllers: dict of controller names to objects"""
if 'c0' not in controllers: if 'c0' not in controllers:
raise Exception( 'User datapath start() requires controller c0' ) raise Exception( 'User datapath start() requires controller c0' )
...@@ -289,11 +288,13 @@ def start( self, controllers ): ...@@ -289,11 +288,13 @@ def start( self, controllers ):
ofplog = '/tmp/' + self.name + '-ofp.log' ofplog = '/tmp/' + self.name + '-ofp.log'
self.cmd( 'ifconfig lo up' ) self.cmd( 'ifconfig lo up' )
intfs = self.intfs intfs = self.intfs
self.cmdPrint( 'ofdatapath -i ' + ','.join( intfs ) + ' punix:/tmp/' +
self.name + ' 1> ' + ofdlog + ' 2> ' + ofdlog + ' &' ) self.cmdPrint( 'ofdatapath -i ' + ','.join( intfs ) +
self.cmdPrint( 'ofprotocol unix:/tmp/' + self.name + ' tcp:' + ' punix:/tmp/' + self.name +
controller.IP() + ' --fail=closed 1> ' + ofplog + ' 2>' + ' 1> ' + ofdlog + ' 2> ' + ofdlog + ' &' )
ofplog + ' &' ) self.cmdPrint( 'ofprotocol unix:/tmp/' + self.name +
' tcp:' + controller.IP() + ' --fail=closed' +
' 1> ' + ofplog + ' 2>' + ofplog + ' &' )
def stop( self ): def stop( self ):
"Stop OpenFlow reference user datapath." "Stop OpenFlow reference user datapath."
...@@ -308,7 +309,7 @@ class KernelSwitch( Switch ): ...@@ -308,7 +309,7 @@ class KernelSwitch( Switch ):
def __init__( self, name, dp=None, dpid=None ): def __init__( self, name, dp=None, dpid=None ):
"""Init. """Init.
name: name:
dp: netlink id ( 0, 1, 2, ... ) dp: netlink id (0, 1, 2, ...)
dpid: datapath ID as unsigned int; random value if None""" dpid: datapath ID as unsigned int; random value if None"""
Switch.__init__( self, name, inNamespace=False ) Switch.__init__( self, name, inNamespace=False )
self.dp = dp self.dp = dp
...@@ -350,7 +351,7 @@ def stop( self ): ...@@ -350,7 +351,7 @@ def stop( self ):
self.cmd( 'kill %ofprotocol' ) self.cmd( 'kill %ofprotocol' )
for intf in self.intfs: for intf in self.intfs:
quietRun( 'ip link del ' + intf ) quietRun( 'ip link del ' + intf )
lg.info( '.' ) info( '.' )
class OVSKernelSwitch( Switch ): class OVSKernelSwitch( Switch ):
...@@ -360,7 +361,7 @@ class OVSKernelSwitch( Switch ): ...@@ -360,7 +361,7 @@ class OVSKernelSwitch( Switch ):
def __init__( self, name, dp=None, dpid=None ): def __init__( self, name, dp=None, dpid=None ):
"""Init. """Init.
name: name:
dp: netlink id ( 0, 1, 2, ... ) dp: netlink id (0, 1, 2, ...)
dpid: datapath ID as unsigned int; random value if None""" dpid: datapath ID as unsigned int; random value if None"""
Switch.__init__( self, name, inNamespace=False ) Switch.__init__( self, name, inNamespace=False )
self.dp = dp self.dp = dp
...@@ -401,7 +402,7 @@ def stop( self ): ...@@ -401,7 +402,7 @@ def stop( self ):
self.cmd( 'kill %ovs-openflowd' ) self.cmd( 'kill %ovs-openflowd' )
for intf in self.intfs: for intf in self.intfs:
quietRun( 'ip link del ' + intf ) quietRun( 'ip link del ' + intf )
lg.info( '.' ) info( '.' )
class Controller( Node ): class Controller( Node ):
...@@ -465,7 +466,7 @@ def __init__( self, name, inNamespace=False, noxArgs=None, **kwargs ): ...@@ -465,7 +466,7 @@ def __init__( self, name, inNamespace=False, noxArgs=None, **kwargs ):
raise Exception( 'please set NOX_CORE_DIR env var\n' ) raise Exception( 'please set NOX_CORE_DIR env var\n' )
Controller.__init__( self, name, Controller.__init__( self, name,
controller=noxCoreDir + '/nox_core', controller=noxCoreDir + '/nox_core',
cargs='--libdir=/usr/local/lib -v -i ptcp: ' + \ cargs='--libdir=/usr/local/lib -v -i ptcp: ' +
' '.join( noxArgs ), ' '.join( noxArgs ),
cdir = noxCoreDir, **kwargs ) cdir = noxCoreDir, **kwargs )
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment