Skip to content
Snippets Groups Projects
Commit 1bb4412f authored by Brandon Heller's avatar Brandon Heller
Browse files

Separate kernel and user switches into separate objects

parent 16c57ddb
No related branches found
No related tags found
No related merge requests found
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
from mininet.logging_mod import lg, set_loglevel, LEVELS from mininet.logging_mod import lg, set_loglevel, LEVELS
from mininet.net import Mininet, init from mininet.net import Mininet, init
from mininet.node import Switch, Host, Controller, ControllerParams, NOX from mininet.node import KernelSwitch, Host, Controller, ControllerParams, NOX
from mininet.topo import TreeTopo from mininet.topo import TreeTopo
# built in topologies, created only when run # built in topologies, created only when run
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
'fattree6' : (lambda: FatTreeTopo(k = 6))} 'fattree6' : (lambda: FatTreeTopo(k = 6))}
SWITCH_DEF = 'kernel' SWITCH_DEF = 'kernel'
SWITCHES = {'kernel' : Switch} SWITCHES = {'kernel' : KernelSwitch}
HOST_DEF = 'process' HOST_DEF = 'process'
HOSTS = {'process' : Host} HOSTS = {'process' : Host}
......
...@@ -377,14 +377,20 @@ def ping(self, hosts = None): ...@@ -377,14 +377,20 @@ def ping(self, hosts = None):
return ploss return ploss
def ping_all(self): def ping_all(self):
'''Ping between all hosts.''' '''Ping between all hosts.
self.ping()
@return ploss packet loss percentage
'''
return self.ping()
def ping_pair(self): def ping_pair(self):
'''Ping between first two hosts, useful for testing.''' '''Ping between first two hosts, useful for testing.
@return ploss packet loss percentage
'''
hosts_sorted = sorted(self.topo.hosts()) hosts_sorted = sorted(self.topo.hosts())
hosts = [hosts_sorted[0], hosts_sorted[1]] hosts = [hosts_sorted[0], hosts_sorted[1]]
self.ping(hosts = hosts) return self.ping(hosts = hosts)
@staticmethod @staticmethod
def _parseIperf(iperfOutput): def _parseIperf(iperfOutput):
......
...@@ -211,49 +211,38 @@ class Host(Node): ...@@ -211,49 +211,38 @@ class Host(Node):
pass pass
class Controller(Node): class Switch(Node):
'''A Controller is a Node that is running (or has execed) an '''A Switch is a Node that is running (or has execed)
OpenFlow controller.''' an OpenFlow switch.'''
def __init__(self, name, inNamespace = False, controller = 'controller',
cargs = '-v ptcp:', cdir = None):
self.controller = controller
self.cargs = cargs
self.cdir = cdir
Node.__init__(self, name, inNamespace = inNamespace)
def start(self): def sendCmd(self, cmd):
'''Start <controller> <args> on controller. '''Send command to Node.
Log to /tmp/cN.log @param cmd string
''' '''
cout = '/tmp/' + self.name + '.log' if not self.execed:
if self.cdir is not None: return Node.sendCmd(self, cmd)
self.cmdPrint('cd ' + self.cdir) else:
self.cmdPrint(self.controller + ' ' + self.cargs + lg.error('*** Error: %s has execed and cannot accept commands' %
' 1> ' + cout + ' 2> ' + cout + ' &') self.name)
self.execed = False # XXX Until I fix it
def stop(self):
'''Stop controller.'''
self.cmd('kill %' + self.controller)
self.terminate()
def monitor(self):
'''Monitor node.'''
if not self.execed:
return Node.monitor(self)
else:
return True, ''
class Switch(Node): class UserSwitch(Switch):
'''A Switch is a Node that is running (or has execed)
an OpenFlow switch.'''
def __init__(self, name, datapath = None): def __init__(self, name):
'''Init. '''Init.
@param name @param name
@param datapath string, datapath name
''' '''
self.dp = datapath Node.__init__(self, name, inNamespace = True)
Node.__init__(self, name, inNamespace = (datapath == None))
def _startUserDatapath(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.
...@@ -273,12 +262,24 @@ def _startUserDatapath(self, controllers): ...@@ -273,12 +262,24 @@ def _startUserDatapath(self, controllers):
' tcp:localhost --fail=closed 1> ' + ofplog + ' 2>' + ' tcp:localhost --fail=closed 1> ' + ofplog + ' 2>' +
ofplog + ' &') ofplog + ' &')
def _stopUserDatapath(self): def stop(self):
'''Stop OpenFlow reference user datapath.''' '''Stop OpenFlow reference user datapath.'''
self.cmd('kill %ofdatapath') self.cmd('kill %ofdatapath')
self.cmd('kill %ofprotocol') self.cmd('kill %ofprotocol')
def _startKernelDatapath(self):
class KernelSwitch(Switch):
def __init__(self, name, datapath = None):
'''Init.
@param name
@param datapath string, datapath name
'''
self.dp = datapath
Node.__init__(self, name, inNamespace = (datapath == None))
def start(self, ignore):
'''Start up reference kernel datapath.''' '''Start up reference kernel datapath.'''
ofplog = '/tmp/' + self.name + '-ofp.log' ofplog = '/tmp/' + self.name + '-ofp.log'
quietRun('ifconfig lo up') quietRun('ifconfig lo up')
...@@ -293,7 +294,7 @@ def _startKernelDatapath(self): ...@@ -293,7 +294,7 @@ def _startKernelDatapath(self):
' --fail=closed 1> ' + ofplog + ' 2>' + ofplog + ' &') ' --fail=closed 1> ' + ofplog + ' 2>' + ofplog + ' &')
self.execed = False # XXX until I fix it self.execed = False # XXX until I fix it
def _stopKernelDatapath(self): def stop(self):
'''Terminate reference kernel datapath.''' '''Terminate reference kernel datapath.'''
quietRun('dpctl deldp ' + self.dp) quietRun('dpctl deldp ' + self.dp)
# In theory the interfaces should go away after we shut down. # In theory the interfaces should go away after we shut down.
...@@ -305,40 +306,46 @@ def _stopKernelDatapath(self): ...@@ -305,40 +306,46 @@ def _stopKernelDatapath(self):
quietRun('ip link del ' + intf) quietRun('ip link del ' + intf)
lg.info('.') lg.info('.')
def start(self, controllers):
'''Start datapath.
@param controllers dict of controller names to objects class Controller(Node):
'''A Controller is a Node that is running (or has execed) an
OpenFlow controller.'''
def __init__(self, name, inNamespace = False, controller = 'controller',
cargs = '-v ptcp:', cdir = None):
self.controller = controller
self.cargs = cargs
self.cdir = cdir
Node.__init__(self, name, inNamespace = inNamespace)
def start(self):
'''Start <controller> <args> on controller.
Log to /tmp/cN.log
''' '''
if self.dp is None: cout = '/tmp/' + self.name + '.log'
self._startUserDatapath(controllers) if self.cdir is not None:
else: self.cmdPrint('cd ' + self.cdir)
self._startKernelDatapath() self.cmdPrint(self.controller + ' ' + self.cargs +
' 1> ' + cout + ' 2> ' + cout + ' &')
self.execed = False # XXX Until I fix it
def stop(self): def stop(self):
'''Stop datapath.''' '''Stop controller.'''
if self.dp is None: self.cmd('kill %' + self.controller)
self._stopUserDatapath() self.terminate()
else:
self._stopKernelDatapath()
def sendCmd(self, cmd):
'''Send command to Node.
@param cmd string class ControllerParams(object):
''' '''Container for controller IP parameters.'''
if not self.execed: def __init__(self, ip, subnet_size):
return Node.sendCmd(self, cmd) '''Init.
else:
lg.error('*** Error: %s has execed and cannot accept commands' %
self.name)
def monitor(self): @param ip integer, controller IP
'''Monitor node.''' @param subnet_size integer, ex 8 for slash-8, covering 17M
if not self.execed: '''
return Node.monitor(self) self.ip = ip
else: self.subnet_size = subnet_size
return True, ''
class NOX(Controller): class NOX(Controller):
...@@ -360,16 +367,4 @@ def __init__(self, name, inNamespace = False, nox_args = None, **kwargs): ...@@ -360,16 +367,4 @@ def __init__(self, name, inNamespace = False, nox_args = None, **kwargs):
controller = nox_core_dir + '/nox_core', controller = nox_core_dir + '/nox_core',
cargs = '--libdir=/usr/local/lib -v -i ptcp: ' + \ cargs = '--libdir=/usr/local/lib -v -i ptcp: ' + \
' '.join(nox_args), ' '.join(nox_args),
cdir = nox_core_dir, **kwargs) cdir = nox_core_dir, **kwargs)
\ No newline at end of file
class ControllerParams(object):
'''Container for controller IP parameters.'''
def __init__(self, ip, subnet_size):
'''Init.
@param ip integer, controller IP
@param subnet_size integer, ex 8 for slash-8, covering 17M
'''
self.ip = ip
self.subnet_size = subnet_size
\ No newline at end of file
...@@ -8,12 +8,12 @@ ...@@ -8,12 +8,12 @@
import unittest import unittest
from mininet.net import init, Mininet #, DATAPATHS from mininet.net import init, Mininet #, DATAPATHS
from mininet.node import Switch, Host, NOXController, ControllerParams from mininet.node import KernelSwitch, Host, ControllerParams
from mininet.node import Controller from mininet.node import Controller
from mininet.topo import TreeTopo from mininet.topo import TreeTopo
# temporary, until user-space side is tested # temporary, until user-space side is tested
DATAPATHS = ['kernel'] SWITCHES = {'kernel' : KernelSwitch}
class testMinimal(unittest.TestCase): class testMinimal(unittest.TestCase):
'''For each datapath type, test ping with a minimal topology. '''For each datapath type, test ping with a minimal topology.
...@@ -24,15 +24,12 @@ class testMinimal(unittest.TestCase): ...@@ -24,15 +24,12 @@ class testMinimal(unittest.TestCase):
def testMinimal(self): def testMinimal(self):
'''Ping test with both datapaths on minimal topology''' '''Ping test with both datapaths on minimal topology'''
init() init()
for datapath in DATAPATHS: for switch in SWITCHES.values():
k = datapath == 'kernel'
controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8 controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
mn = Mininet(TreeTopo(), Switch, Host, Controller, mn = Mininet(TreeTopo(), switch, Host, Controller,
controller_params) controller_params)
mn.start() dropped = mn.run('ping')
dropped = mn.ping_test()
self.assertEqual(dropped, 0) self.assertEqual(dropped, 0)
mn.stop()
class testTree(unittest.TestCase): class testTree(unittest.TestCase):
...@@ -41,16 +38,13 @@ class testTree(unittest.TestCase): ...@@ -41,16 +38,13 @@ class testTree(unittest.TestCase):
def testTree16(self): def testTree16(self):
'''Ping test with both datapaths on 16-host topology''' '''Ping test with both datapaths on 16-host topology'''
init() init()
for datapath in DATAPATHS: for switch in SWITCHES.values():
k = datapath == 'kernel'
controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8 controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
tree_topo = TreeTopo(depth = 3, fanout = 4) tree_topo = TreeTopo(depth = 3, fanout = 4)
mn = Mininet(tree_topo, Switch, Host, Controller, mn = Mininet(tree_topo, switch, Host, Controller,
controller_params) controller_params)
mn.start() dropped = mn.run('ping')
dropped = mn.ping_test()
self.assertEqual(dropped, 0) self.assertEqual(dropped, 0)
mn.stop()
#class testLinear(unittest.TestCase): #class testLinear(unittest.TestCase):
# '''For each datapath type, test all-pairs ping with LinearNet.''' # '''For each datapath type, test all-pairs ping with LinearNet.'''
......
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