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) + ']')
opts.add_option('--xterms', '-x', action = 'store_true',
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',
choices = LEVELS.keys(), default = 'info',
help = '[' + ' '.join(LEVELS.keys()) + ']')
@@ -131,8 +135,11 @@ class MininetRunner(object):
controller_params = ControllerParams(0x0a000000, 8) # 10.0.0.0/8
xterms = self.options.xterms
mac = self.options.mac
arp = self.options.arp
mn = Mininet(topo, switch, host, controller, controller_params,
xterms = xterms)
xterms = xterms, auto_set_macs = mac,
auto_static_arp = arp)
test = self.options.test
if test != 'build':
+34 -8
View File
@@ -79,7 +79,8 @@ class Mininet(object):
def __init__(self, topo, switch, host, controller, cparams,
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.
@param topo Topo object
@@ -91,6 +92,9 @@ class Mininet(object):
@param xterms if build now, spawn xterms?
@param cleanup if build now, cleanup before creating?
@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.switch = switch
@@ -102,13 +106,17 @@ class Mininet(object):
self.dps = 0 # number of created kernel datapaths
self.in_namespace = in_namespace
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.kernel = True #temporary!
if build:
self.build(xterms, cleanup)
self.build()
def _add_host(self, dpid):
'''Add host.
@@ -249,15 +257,12 @@ class Mininet(object):
lg.info('%s ', host.name)
lg.info('\n')
def build(self, xterms, cleanup):
def build(self):
'''Build mininet.
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
# validate topo?
kernel = self.kernel
@@ -289,8 +294,12 @@ class Mininet(object):
lg.info('*** Configuring hosts\n')
self._config_hosts()
if xterms:
if self.xterms:
self.start_xterms()
if self.auto_set_macs:
self.set_macs()
if self.auto_static_arp:
self.static_arp()
def switch_nodes(self):
'''Return switch nodes.'''
@@ -315,6 +324,23 @@ class Mininet(object):
os.kill(term.pid, signal.SIGKILL)
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):
'''Start controller and switches\n'''
lg.info('*** Starting controller\n')
+23 -1
View File
@@ -6,7 +6,7 @@ import os, signal, sys, select
flush = sys.stdout.flush
from mininet.logging_mod import lg
from mininet.util import quietRun
from mininet.util import quietRun, macColonHex, ipStr
class Node(object):
'''A virtual network node is simply a shell in a network namespace.
@@ -160,6 +160,28 @@ class Node(object):
self.intfs += [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):
'''Set the IP address for an interface.
+23 -1
View File
@@ -175,4 +175,26 @@ def createLink(node1, node2):
def fixLimits():
'''Fix ridiculously small resource limits.'''
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)