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