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:
Brandon Heller
2010-01-03 09:16:14 -08:00
parent 433a7cc88c
commit 376bcba442
4 changed files with 88 additions and 11 deletions
+8 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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.
+22
View File
@@ -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)