Add options for auto MAC and ARP setup.
Auto MAC setup sets each host MAC equal to its DPID, which simplifies debugging. Auto ARP setup removes the need for broadcast support for ARP, which enables a smaller NOX controller.
This commit is contained in:
+8
-1
@@ -99,6 +99,10 @@ class MininetRunner(object):
|
|||||||
help = '[' + ' '.join(TESTS) + ']')
|
help = '[' + ' '.join(TESTS) + ']')
|
||||||
opts.add_option('--xterms', '-x', action = 'store_true',
|
opts.add_option('--xterms', '-x', action = 'store_true',
|
||||||
default = False, help = 'spawn xterms for each node')
|
default = False, help = 'spawn xterms for each node')
|
||||||
|
opts.add_option('--mac', action = 'store_true',
|
||||||
|
default = False, help = 'set host MACs equal to DPIDs')
|
||||||
|
opts.add_option('--arp', action = 'store_true',
|
||||||
|
default = False, help = 'set all-pairs ARP entries')
|
||||||
opts.add_option('--verbosity', '-v', type = 'choice',
|
opts.add_option('--verbosity', '-v', type = 'choice',
|
||||||
choices = LEVELS.keys(), default = 'info',
|
choices = LEVELS.keys(), default = 'info',
|
||||||
help = '[' + ' '.join(LEVELS.keys()) + ']')
|
help = '[' + ' '.join(LEVELS.keys()) + ']')
|
||||||
@@ -131,8 +135,11 @@ class MininetRunner(object):
|
|||||||
|
|
||||||
controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
|
controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
|
||||||
xterms = self.options.xterms
|
xterms = self.options.xterms
|
||||||
|
mac = self.options.mac
|
||||||
|
arp = self.options.arp
|
||||||
mn = Mininet(topo, switch, host, controller, controller_params,
|
mn = Mininet(topo, switch, host, controller, controller_params,
|
||||||
xterms = xterms)
|
xterms = xterms, auto_set_macs = mac,
|
||||||
|
auto_static_arp = arp)
|
||||||
|
|
||||||
test = self.options.test
|
test = self.options.test
|
||||||
if test != 'build':
|
if test != 'build':
|
||||||
|
|||||||
+34
-8
@@ -79,7 +79,8 @@ class Mininet(object):
|
|||||||
|
|
||||||
def __init__(self, topo, switch, host, controller, cparams,
|
def __init__(self, topo, switch, host, controller, cparams,
|
||||||
build = True, xterms = False, cleanup = False,
|
build = True, xterms = False, cleanup = False,
|
||||||
in_namespace = False, switch_is_kernel = True):
|
in_namespace = False, switch_is_kernel = True,
|
||||||
|
auto_set_macs = False, auto_static_arp = False):
|
||||||
'''Create Mininet object.
|
'''Create Mininet object.
|
||||||
|
|
||||||
@param topo Topo object
|
@param topo Topo object
|
||||||
@@ -91,6 +92,9 @@ class Mininet(object):
|
|||||||
@param xterms if build now, spawn xterms?
|
@param xterms if build now, spawn xterms?
|
||||||
@param cleanup if build now, cleanup before creating?
|
@param cleanup if build now, cleanup before creating?
|
||||||
@param in_namespace spawn switches and hosts in their own namespace?
|
@param in_namespace spawn switches and hosts in their own namespace?
|
||||||
|
@param switch_is_kernel is the switch kernel-based?
|
||||||
|
@param auto_set_macs set MAC addrs to DPIDs?
|
||||||
|
@param auto_static_arp set all-pairs static MAC addrs?
|
||||||
'''
|
'''
|
||||||
self.topo = topo
|
self.topo = topo
|
||||||
self.switch = switch
|
self.switch = switch
|
||||||
@@ -102,13 +106,17 @@ class Mininet(object):
|
|||||||
self.dps = 0 # number of created kernel datapaths
|
self.dps = 0 # number of created kernel datapaths
|
||||||
self.in_namespace = in_namespace
|
self.in_namespace = in_namespace
|
||||||
self.switch_is_kernel = switch_is_kernel
|
self.switch_is_kernel = switch_is_kernel
|
||||||
|
self.xterms = xterms
|
||||||
|
self.cleanup = cleanup
|
||||||
|
self.auto_set_macs = auto_set_macs
|
||||||
|
self.auto_static_arp = auto_static_arp
|
||||||
|
|
||||||
self.terms = [] # list of spawned xterm processes
|
self.terms = [] # list of spawned xterm processes
|
||||||
|
|
||||||
self.kernel = True #temporary!
|
self.kernel = True #temporary!
|
||||||
|
|
||||||
if build:
|
if build:
|
||||||
self.build(xterms, cleanup)
|
self.build()
|
||||||
|
|
||||||
def _add_host(self, dpid):
|
def _add_host(self, dpid):
|
||||||
'''Add host.
|
'''Add host.
|
||||||
@@ -249,15 +257,12 @@ class Mininet(object):
|
|||||||
lg.info('%s ', host.name)
|
lg.info('%s ', host.name)
|
||||||
lg.info('\n')
|
lg.info('\n')
|
||||||
|
|
||||||
def build(self, xterms, cleanup):
|
def build(self):
|
||||||
'''Build mininet.
|
'''Build mininet.
|
||||||
|
|
||||||
At the end of this function, everything should be connected and up.
|
At the end of this function, everything should be connected and up.
|
||||||
|
|
||||||
@param xterms spawn xterms on build?
|
|
||||||
@param cleanup cleanup before creating?
|
|
||||||
'''
|
'''
|
||||||
if cleanup:
|
if self.cleanup:
|
||||||
pass # cleanup
|
pass # cleanup
|
||||||
# validate topo?
|
# validate topo?
|
||||||
kernel = self.kernel
|
kernel = self.kernel
|
||||||
@@ -289,8 +294,12 @@ class Mininet(object):
|
|||||||
lg.info('*** Configuring hosts\n')
|
lg.info('*** Configuring hosts\n')
|
||||||
self._config_hosts()
|
self._config_hosts()
|
||||||
|
|
||||||
if xterms:
|
if self.xterms:
|
||||||
self.start_xterms()
|
self.start_xterms()
|
||||||
|
if self.auto_set_macs:
|
||||||
|
self.set_macs()
|
||||||
|
if self.auto_static_arp:
|
||||||
|
self.static_arp()
|
||||||
|
|
||||||
def switch_nodes(self):
|
def switch_nodes(self):
|
||||||
'''Return switch nodes.'''
|
'''Return switch nodes.'''
|
||||||
@@ -315,6 +324,23 @@ class Mininet(object):
|
|||||||
os.kill(term.pid, signal.SIGKILL)
|
os.kill(term.pid, signal.SIGKILL)
|
||||||
cleanUpScreens()
|
cleanUpScreens()
|
||||||
|
|
||||||
|
def set_macs(self):
|
||||||
|
'''Set MAC addrs to correspond to datapath IDs on hosts.
|
||||||
|
|
||||||
|
Assume that the host only has one interface.
|
||||||
|
'''
|
||||||
|
for dpid in self.topo.hosts():
|
||||||
|
host_node = self.nodes[dpid]
|
||||||
|
host_node.setMAC(host_node.intfs[0], dpid)
|
||||||
|
|
||||||
|
def static_arp(self):
|
||||||
|
'''Add all-pairs ARP entries to remove the need to handle broadcast.'''
|
||||||
|
for src in self.topo.hosts():
|
||||||
|
src_node = self.nodes[src]
|
||||||
|
for dst in self.topo.hosts():
|
||||||
|
if src != dst:
|
||||||
|
src_node.setARP(dst, dst)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
'''Start controller and switches\n'''
|
'''Start controller and switches\n'''
|
||||||
lg.info('*** Starting controller\n')
|
lg.info('*** Starting controller\n')
|
||||||
|
|||||||
+23
-1
@@ -6,7 +6,7 @@ import os, signal, sys, select
|
|||||||
flush = sys.stdout.flush
|
flush = sys.stdout.flush
|
||||||
|
|
||||||
from mininet.logging_mod import lg
|
from mininet.logging_mod import lg
|
||||||
from mininet.util import quietRun
|
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.
|
||||||
@@ -160,6 +160,28 @@ class Node(object):
|
|||||||
self.intfs += [intfName]
|
self.intfs += [intfName]
|
||||||
return intfName
|
return intfName
|
||||||
|
|
||||||
|
def setMAC(self, intf, mac):
|
||||||
|
'''Set the MAC address for an interface.
|
||||||
|
|
||||||
|
@param mac MAC address as unsigned int
|
||||||
|
'''
|
||||||
|
mac_str = macColonHex(mac)
|
||||||
|
result = self.cmd(['ifconfig', intf, 'down'])
|
||||||
|
result += self.cmd(['ifconfig', intf, 'hw', 'ether', mac_str])
|
||||||
|
result += self.cmd(['ifconfig', intf, 'up'])
|
||||||
|
return result
|
||||||
|
|
||||||
|
def setARP(self, ip, mac):
|
||||||
|
'''Add an ARP entry.
|
||||||
|
|
||||||
|
@param ip IP address as unsigned int
|
||||||
|
@param mac MAC address as unsigned int
|
||||||
|
'''
|
||||||
|
ip_str = ipStr(ip)
|
||||||
|
mac_str = macColonHex(mac)
|
||||||
|
result = self.cmd(['arp', '-s', ip_str, mac_str])
|
||||||
|
return result
|
||||||
|
|
||||||
def setIP(self, intf, ip, bits):
|
def setIP(self, intf, ip, bits):
|
||||||
'''Set the IP address for an interface.
|
'''Set the IP address for an interface.
|
||||||
|
|
||||||
|
|||||||
@@ -176,3 +176,25 @@ def fixLimits():
|
|||||||
'''Fix ridiculously small resource limits.'''
|
'''Fix ridiculously small resource limits.'''
|
||||||
setrlimit( RLIMIT_NPROC, (4096, 8192))
|
setrlimit( RLIMIT_NPROC, (4096, 8192))
|
||||||
setrlimit( RLIMIT_NOFILE, (16384, 32768))
|
setrlimit( RLIMIT_NOFILE, (16384, 32768))
|
||||||
|
|
||||||
|
def macColonHex(mac):
|
||||||
|
'''Generate MAC colon-hex string from unsigned int.
|
||||||
|
|
||||||
|
@param mac MAC address as unsigned int
|
||||||
|
@return mac_str MAC colon-hex string
|
||||||
|
'''
|
||||||
|
mac_pieces = []
|
||||||
|
for i in range (5, -1, -1):
|
||||||
|
mac_pieces.append('%02x' % (((0xff << (i * 8)) & mac) >> (i * 8)))
|
||||||
|
mac_str = ':'.join(mac_pieces)
|
||||||
|
return mac_str
|
||||||
|
|
||||||
|
def ipStr(ip):
|
||||||
|
'''Generate IP address string
|
||||||
|
|
||||||
|
@return ip addr string
|
||||||
|
'''
|
||||||
|
hi = (ip & 0xff0000) >> 16
|
||||||
|
mid = (ip & 0xff00) >> 8
|
||||||
|
lo = ip & 0xff
|
||||||
|
return "10.%i.%i.%i" % (hi, mid, lo)
|
||||||
Reference in New Issue
Block a user