From 540379957b3a28f75a0baa46cb72f04b92f97157 Mon Sep 17 00:00:00 2001 From: Brandon Heller <brandonh@stanford.edu> Date: Fri, 1 Jan 2010 03:16:57 -0800 Subject: [PATCH] Add MAC auto set for switches Also use indexing for DPIDs to avoid zeroed MAC --- bin/mn_run.py | 2 +- mininet/net.py | 16 ++++++++++------ mininet/node.py | 26 ++++++++++++++++---------- mininet/topo.py | 10 +++++----- mininet/util.py | 22 +++++++++++++++++----- 5 files changed, 49 insertions(+), 27 deletions(-) diff --git a/bin/mn_run.py b/bin/mn_run.py index e7103c19..38372d4d 100755 --- a/bin/mn_run.py +++ b/bin/mn_run.py @@ -100,7 +100,7 @@ def parse_args(self): 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') + default = False, help = 'set 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', diff --git a/mininet/net.py b/mininet/net.py index fe7f6316..a4a8b7bd 100755 --- a/mininet/net.py +++ b/mininet/net.py @@ -53,6 +53,7 @@ from time import sleep from mininet.logging_mod import lg +from mininet.node import KernelSwitch from mininet.util import quietRun, fixLimits from mininet.util import make_veth_pair, move_intf, retry, MOVEINTF_DELAY from mininet.xterm import cleanUpScreens, makeXterms @@ -79,7 +80,7 @@ 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, auto_set_macs = False, auto_static_arp = False): '''Create Mininet object. @@ -92,7 +93,6 @@ def __init__(self, topo, switch, host, controller, cparams, @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? ''' @@ -105,7 +105,6 @@ def __init__(self, topo, switch, host, controller, cparams, self.controllers = {} # controller name to Controller objects 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 @@ -130,12 +129,17 @@ def _add_host(self, dpid): #lg.info('%s ' % host.name) def _add_switch(self, dpid): - ''' + '''Add switch. + @param dpid DPID of switch to add ''' sw = None - if self.switch_is_kernel: - sw = self.switch('s_' + self.topo.name(dpid), 'nl:' + str(self.dps)) + sw_dpid = None + if self.auto_set_macs: + sw_dpid = dpid + if self.switch is KernelSwitch: + sw = self.switch('s_' + self.topo.name(dpid), dp = self.dps, + dpid = sw_dpid) self.dps += 1 else: sw = self.switch('s_' + self.topo.name(dpid)) diff --git a/mininet/node.py b/mininet/node.py index da449279..a161f4b6 100644 --- a/mininet/node.py +++ b/mininet/node.py @@ -292,14 +292,16 @@ def stop(self): class KernelSwitch(Switch): - def __init__(self, name, datapath = None): + def __init__(self, name, dp = None, dpid = None): '''Init. @param name - @param datapath string, datapath name + @param dp netlink id (0, 1, 2, ...) + @param dpid datapath ID as unsigned int; random value if None ''' - self.dp = datapath - Node.__init__(self, name, inNamespace = (datapath == None)) + Node.__init__(self, name, inNamespace = False) + self.dp = dp + self.dpid = dpid def start(self, ignore): '''Start up reference kernel datapath.''' @@ -307,18 +309,22 @@ def start(self, ignore): quietRun('ifconfig lo up') # Delete local datapath if it exists; # then create a new one monitoring the given interfaces - quietRun('dpctl deldp ' + self.dp) - self.cmdPrint('dpctl adddp ' + self.dp) - self.cmdPrint('dpctl addif ' + self.dp + ' ' + ' '.join(self.intfs)) + quietRun('dpctl deldp nl:%i' % self.dp) + self.cmdPrint('dpctl adddp nl:%i' % self.dp) + if self.dpid: + intf = 'of%i' % self.dp + mac_str = macColonHex(self.dpid) + self.cmd(['ifconfig', intf, 'hw', 'ether', mac_str]) + self.cmdPrint('dpctl addif nl:' + str(self.dp) + ' ' + + ' '.join(self.intfs)) # Run protocol daemon - self.cmdPrint('ofprotocol' + - ' ' + self.dp + ' tcp:127.0.0.1 ' + + self.cmdPrint('ofprotocol nl:' + str(self.dp) + ' tcp:127.0.0.1 ' + ' --fail=closed 1> ' + ofplog + ' 2>' + ofplog + ' &') self.execed = False # XXX until I fix it def stop(self): '''Terminate reference kernel datapath.''' - quietRun('dpctl deldp ' + self.dp) + quietRun('dpctl deldp nl:%i' % self.dp) # In theory the interfaces should go away after we shut down. # However, this takes time, so we're better off to remove them # explicitly so that we won't get errors if we run before they diff --git a/mininet/topo.py b/mininet/topo.py index 1f2a9635..943f71ef 100644 --- a/mininet/topo.py +++ b/mininet/topo.py @@ -324,11 +324,11 @@ def __init__(self, k = 2, enable_all = True): self.k = k - self._add_node(0, Node()) - hosts = range(1, k + 1) + self._add_node(1, Node()) + hosts = range(2, k + 2) for h in hosts: self._add_node(h, Node(is_switch = False)) - self._add_edge(h, 0, Edge()) + self._add_edge(h, 1, Edge()) if enable_all: self.enable_all() @@ -347,14 +347,14 @@ def __init__(self, k = 2, enable_all = True): self.k = k - switches = range(0, k) + switches = range(1, k + 1) for s in switches: h = s + k self._add_node(s, Node()) self._add_node(h, Node(is_switch = False)) self._add_edge(s, h, Edge()) for s in switches: - if s != k - 1: + if s != k: self._add_edge(s, s + 1, Edge()) if enable_all: diff --git a/mininet/util.py b/mininet/util.py index 2006114f..bbba5b7f 100644 --- a/mininet/util.py +++ b/mininet/util.py @@ -177,17 +177,29 @@ def fixLimits(): setrlimit( RLIMIT_NPROC, (4096, 8192)) setrlimit( RLIMIT_NOFILE, (16384, 32768)) + +def _colonHex(val, bytes): + '''Generate colon-hex string. + + @param val input as unsigned int + @param bytes number of bytes to convert + @return ch_str colon-hex string + ''' + pieces = [] + for i in range (bytes - 1, -1, -1): + pieces.append('%02x' % (((0xff << (i * 8)) & val) >> (i * 8))) + ch_str = ':'.join(pieces) + return ch_str + + 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 + return _colonHex(mac, 6) + def ipStr(ip): '''Generate IP address string -- GitLab