diff --git a/daemon/core/coreobj.py b/daemon/core/coreobj.py index 962c4a2a..6993a09a 100644 --- a/daemon/core/coreobj.py +++ b/daemon/core/coreobj.py @@ -323,7 +323,7 @@ class PyCoreNode(PyCoreObj): if ifindex in self._netif: raise ValueError("ifindex %s already exists" % ifindex) self._netif[ifindex] = netif - # TODO: this hould have probably been set ahead, seems bad to me, check for failure and fix + # TODO: this should have probably been set ahead, seems bad to me, check for failure and fix netif.netindex = ifindex def delnetif(self, ifindex): diff --git a/daemon/core/misc/event.py b/daemon/core/misc/event.py index 76bc95f1..ec11ee1b 100644 --- a/daemon/core/misc/event.py +++ b/daemon/core/misc/event.py @@ -215,7 +215,7 @@ class EventLoop(object): """ Add an event to the event loop. - :param int delaysec: delay in seconds for event + :param float delaysec: delay in seconds for event :param func: event function :param args: event arguments :param kwds: event keyword arguments diff --git a/daemon/core/netns/vif.py b/daemon/core/netns/vif.py index 33d656ac..362c7d20 100644 --- a/daemon/core/netns/vif.py +++ b/daemon/core/netns/vif.py @@ -25,7 +25,7 @@ class VEth(PyCoreNetIf): """ Creates a VEth instance. - :param core.netns.nodes.CoreNode node: related core node + :param core.netns.vnode.SimpleLxcNode node: related core node :param str name: interface name :param str localname: interface local name :param mtu: interface mtu @@ -76,7 +76,7 @@ class TunTap(PyCoreNetIf): """ Create a TunTap instance. - :param core.netns.nodes.CoreNode node: related core node + :param core.netns.vnode.SimpleLxcNode node: related core node :param str name: interface name :param str localname: local interface name :param mtu: interface mtu @@ -136,7 +136,7 @@ class TunTap(PyCoreNetIf): msg += ", retrying..." logger.info(msg) time.sleep(delay) - delay = delay + delay + delay += delay if delay > maxretrydelay: delay = maxretrydelay else: @@ -168,7 +168,7 @@ class TunTap(PyCoreNetIf): """ def nodedevexists(): - cmd = (constants.IP_BIN, "link", "show", self.name) + cmd = [constants.IP_BIN, "link", "show", self.name] return self.node.client.cmd(cmd) count = 0 @@ -180,8 +180,8 @@ class TunTap(PyCoreNetIf): # check if this is an EMANE interface; if so, continue # waiting if EMANE is still running # TODO: remove emane code - if count < 5 and nodeutils.is_node(self.net, NodeTypes.EMANE) and \ - self.node.session.emane.emanerunning(self.node): + if count < 5 and nodeutils.is_node(self.net, NodeTypes.EMANE) and self.node.session.emane.emanerunning( + self.node): count += 1 else: raise e @@ -233,7 +233,7 @@ class GreTap(PyCoreNetIf): """ Creates a GreTap instance. - :param core.netns.nodes.CoreNode node: related core node + :param core.netns.vnode.SimpleLxcNode node: related core node :param str name: interface name :param core.session.Session session: core session instance :param mtu: interface mtu diff --git a/daemon/core/netns/vnode.py b/daemon/core/netns/vnode.py index 33afbdce..1252e952 100644 --- a/daemon/core/netns/vnode.py +++ b/daemon/core/netns/vnode.py @@ -21,6 +21,8 @@ from core.netns import vnodeclient from core.netns.vif import TunTap from core.netns.vif import VEth +_DEFAULT_MTU = 1500 + utils.check_executables([constants.IP_BIN]) @@ -36,7 +38,7 @@ class SimpleLxcNode(PyCoreNode): :type lock: threading.RLock :type _mounts: list[tuple[str, str]] """ - valid_deladdrtype = ("inet", "inet6", "inet6link") + valid_address_types = {"inet", "inet6", "inet6link"} def __init__(self, session, objid=None, name=None, nodedir=None, start=True): """ @@ -80,10 +82,16 @@ class SimpleLxcNode(PyCoreNode): :return: nothing """ if self.up: - raise Exception("already up") - vnoded = ["%s/vnoded" % constants.CORE_BIN_DIR, "-v", "-c", self.ctrlchnlname, - "-l", self.ctrlchnlname + ".log", - "-p", self.ctrlchnlname + ".pid"] + raise ValueError("starting a node that is already up") + + # create a new namespace for this node using vnoded + vnoded = [ + "%s/vnoded" % constants.CORE_BIN_DIR, + "-v", + "-c", self.ctrlchnlname, + "-l", self.ctrlchnlname + ".log", + "-p", self.ctrlchnlname + ".pid" + ] if self.nodedir: vnoded += ["-C", self.nodedir] env = self.session.get_environment(state=False) @@ -91,28 +99,26 @@ class SimpleLxcNode(PyCoreNode): env["NODE_NAME"] = str(self.name) try: - tmp = subprocess.Popen(vnoded, stdout=subprocess.PIPE, env=env) - except OSError: - msg = "error running vnoded command: %s" % vnoded - logger.exception("SimpleLxcNode.startup(): %s", msg) - raise Exception(msg) - - try: - self.pid = int(tmp.stdout.read()) - tmp.stdout.close() - except ValueError: - msg = "vnoded failed to create a namespace; " - msg += "check kernel support and user priveleges" - logger.exception("SimpleLxcNode.startup(): %s", msg) - - if tmp.wait(): - raise Exception("command failed: %s" % vnoded) + p = subprocess.Popen(vnoded, stdout=subprocess.PIPE, env=env) + stdout, _ = p.communicate() + if p.returncode: + raise IOError("vnoded command failed: %s" % vnoded) + self.pid = int(stdout) + except (OSError, ValueError): + logger.exception("vnoded failed to create a namespace; check kernel support and user priveleges") + # create vnode client self.client = vnodeclient.VnodeClient(self.name, self.ctrlchnlname) + + # bring up the loopback interface logger.info("bringing up loopback interface") self.client.cmd([constants.IP_BIN, "link", "set", "lo", "up"]) + + # set hostname for node logger.info("setting hostname: %s" % self.name) self.client.cmd(["hostname", self.name]) + + # mark node as up self.up = True def shutdown(self): @@ -146,7 +152,7 @@ class SimpleLxcNode(PyCoreNode): if os.path.exists(self.ctrlchnlname): os.unlink(self.ctrlchnlname) except OSError: - logger.exception("error removing file") + logger.exception("error removing node directory") # clear interface data, close client, and mark self and not up self._netif.clear() @@ -190,9 +196,11 @@ class SimpleLxcNode(PyCoreNode): """ logger.info("unmounting: %s", target) try: - self.client.cmd([constants.UMOUNT_BIN, "-n", "-l", target]) + status, output = self.client.cmdresult([constants.UMOUNT_BIN, "-n", "-l", target]) + if status: + raise IOError("error unmounting %s: %s", target, output) except IOError: - logger.exception("unmounting failed for %s" % target) + logger.exception("error during unmount") def newifindex(self): """ @@ -213,8 +221,7 @@ class SimpleLxcNode(PyCoreNode): :param net: network to associate interface with :return: nothing """ - self.lock.acquire() - try: + with self.lock: if ifindex is None: ifindex = self.newifindex() @@ -234,7 +241,7 @@ class SimpleLxcNode(PyCoreNode): name = localname + "p" if len(name) >= 16: raise ValueError("interface name (%s) too long" % name) - veth = VEth(node=self, name=name, localname=localname, mtu=1500, net=net, start=self.up) + veth = VEth(node=self, name=name, localname=localname, net=net, start=self.up) if self.up: subprocess.check_call([constants.IP_BIN, "link", "set", veth.name, "netns", str(self.pid)]) @@ -255,14 +262,12 @@ class SimpleLxcNode(PyCoreNode): try: self.addnetif(veth, ifindex) - except: + except ValueError as e: veth.shutdown() del veth - raise + raise e return ifindex - finally: - self.lock.release() def newtuntap(self, ifindex=None, ifname=None, net=None): """ @@ -274,8 +279,7 @@ class SimpleLxcNode(PyCoreNode): :return: interface index :rtype: int """ - self.lock.acquire() - try: + with self.lock: if ifindex is None: ifindex = self.newifindex() if ifname is None: @@ -283,18 +287,14 @@ class SimpleLxcNode(PyCoreNode): sessionid = self.session.short_session_id() localname = "tap%s.%s.%s" % (self.objid, ifindex, sessionid) name = ifname - ifclass = TunTap - tuntap = ifclass(node=self, name=name, localname=localname, - mtu=1500, net=net, start=self.up) + tuntap = TunTap(node=self, name=name, localname=localname, net=net, start=self.up) try: self.addnetif(tuntap, ifindex) - except Exception as e: + except ValueError as e: tuntap.shutdown() del tuntap raise e return ifindex - finally: - self.lock.release() def sethwaddr(self, ifindex, addr): """ @@ -306,10 +306,10 @@ class SimpleLxcNode(PyCoreNode): """ self._netif[ifindex].sethwaddr(addr) if self.up: - (status, result) = self.client.cmdresult([constants.IP_BIN, "link", "set", "dev", - self.ifname(ifindex), "address", str(addr)]) + cmd = [constants.IP_BIN, "link", "set", "dev", self.ifname(ifindex), "address", str(addr)] + status, output = self.client.cmdresult(cmd) if status: - logger.error("error setting MAC address %s", str(addr)) + logger.error("error setting MAC address %s: %s", addr, output) def addaddr(self, ifindex, addr): """ @@ -320,12 +320,13 @@ class SimpleLxcNode(PyCoreNode): :return: nothing """ if self.up: - if ":" in str(addr): # check if addr is ipv6 - self.client.cmd([constants.IP_BIN, "addr", "add", str(addr), - "dev", self.ifname(ifindex)]) + # check if addr is ipv6 + if ":" in str(addr): + cmd = [constants.IP_BIN, "addr", "add", str(addr), "dev", self.ifname(ifindex)] + self.client.cmd(cmd) else: - self.client.cmd([constants.IP_BIN, "addr", "add", str(addr), "broadcast", "+", - "dev", self.ifname(ifindex)]) + cmd = [constants.IP_BIN, "addr", "add", str(addr), "broadcast", "+", "dev", self.ifname(ifindex)] + self.client.cmd(cmd) self._netif[ifindex].addaddr(addr) def deladdr(self, ifindex, addr): @@ -344,22 +345,23 @@ class SimpleLxcNode(PyCoreNode): if self.up: self.client.cmd([constants.IP_BIN, "addr", "del", str(addr), "dev", self.ifname(ifindex)]) - def delalladdr(self, ifindex, addrtypes=valid_deladdrtype): + def delalladdr(self, ifindex, address_types=valid_address_types): """ Delete all addresses from an interface. - :param int ifindex: index of interface to delete all addresses from - :param tuple addrtypes: address types to delete + :param int ifindex: index of interface to delete address types from + :param tuple[str] address_types: address types to delete :return: nothing """ - addr = self.getaddr(self.ifname(ifindex), rescan=True) - for t in addrtypes: - if t not in self.valid_deladdrtype: - raise ValueError("addr type must be in: " + " ".join(self.valid_deladdrtype)) - for a in addr[t]: - self.deladdr(ifindex, a) + interface_name = self.ifname(ifindex) + addresses = self.client.getaddr(interface_name, rescan=True) + for address_type in address_types: + if address_type not in self.valid_address_types: + raise ValueError("addr type must be in: %s" % " ".join(self.valid_address_types)) + for address in addresses[address_type]: + self.deladdr(ifindex, address) # update cached information - self.getaddr(self.ifname(ifindex), rescan=True) + self.client.getaddr(interface_name, rescan=True) def ifup(self, ifindex): """ @@ -371,20 +373,22 @@ class SimpleLxcNode(PyCoreNode): if self.up: self.client.cmd([constants.IP_BIN, "link", "set", self.ifname(ifindex), "up"]) - def newnetif(self, net=None, addrlist=None, hwaddr=None, ifindex=None, ifname=None): + def newnetif(self, net=None, address_list=None, hwaddr=None, ifindex=None, ifname=None): """ Create a new network interface. :param net: network to associate with - :param list addrlist: addresses to add on the interface + :param list address_list: addresses to add on the interface :param core.misc.ipaddress.MacAddress hwaddr: hardware address to set for interface :param int ifindex: index of interface to create :param str ifname: name for interface :return: interface index :rtype: int """ - self.lock.acquire() - try: + if not address_list: + address_list = [] + + with self.lock: # TODO: see if you can move this to emane specific code if nodeutils.is_node(net, NodeTypes.EMANE): ifindex = self.newtuntap(ifindex=ifindex, ifname=ifname, net=net) @@ -395,8 +399,8 @@ class SimpleLxcNode(PyCoreNode): self.attachnet(ifindex, net) netif = self.netif(ifindex) netif.sethwaddr(hwaddr) - for addr in utils.maketuple(addrlist): - netif.addaddr(addr) + for address in utils.maketuple(address_list): + netif.addaddr(address) return ifindex else: ifindex = self.newveth(ifindex=ifindex, ifname=ifname, net=net) @@ -407,14 +411,11 @@ class SimpleLxcNode(PyCoreNode): if hwaddr: self.sethwaddr(ifindex, hwaddr) - if addrlist: - for addr in utils.maketuple(addrlist): - self.addaddr(ifindex, addr) + for address in utils.maketuple(address_list): + self.addaddr(ifindex, address) self.ifup(ifindex) return ifindex - finally: - self.lock.release() def connectnode(self, ifname, othernode, otherifname): """ @@ -426,20 +427,19 @@ class SimpleLxcNode(PyCoreNode): :return: nothing """ tmplen = 8 - tmp1 = "tmp." + "".join([random.choice(string.ascii_lowercase) - for x in xrange(tmplen)]) - tmp2 = "tmp." + "".join([random.choice(string.ascii_lowercase) - for x in xrange(tmplen)]) - subprocess.check_call([constants.IP_BIN, "link", "add", "name", tmp1, - "type", "veth", "peer", "name", tmp2]) + tmp1 = "tmp." + "".join([random.choice(string.ascii_lowercase) for _ in xrange(tmplen)]) + tmp2 = "tmp." + "".join([random.choice(string.ascii_lowercase) for _ in xrange(tmplen)]) + subprocess.check_call([constants.IP_BIN, "link", "add", "name", tmp1, "type", "veth", "peer", "name", tmp2]) subprocess.call([constants.IP_BIN, "link", "set", tmp1, "netns", str(self.pid)]) self.client.cmd([constants.IP_BIN, "link", "set", tmp1, "name", ifname]) - self.addnetif(PyCoreNetIf(self, ifname), self.newifindex()) + interface = PyCoreNetIf(node=self, name=ifname, mtu=_DEFAULT_MTU) + self.addnetif(interface, self.newifindex()) subprocess.check_call([constants.IP_BIN, "link", "set", tmp2, "netns", str(othernode.pid)]) othernode.client.cmd([constants.IP_BIN, "link", "set", tmp2, "name", otherifname]) - othernode.addnetif(PyCoreNetIf(othernode, otherifname), othernode.newifindex()) + other_interface = PyCoreNetIf(node=othernode, name=otherifname, mtu=_DEFAULT_MTU) + othernode.addnetif(other_interface, othernode.newifindex()) def addfile(self, srcname, filename): """ @@ -456,29 +456,10 @@ class SimpleLxcNode(PyCoreNode): cmd = 'mkdir -p "%s" && mv "%s" "%s" && sync' % (directory, srcname, filename) status, output = self.client.shcmd_result(cmd) if status: - logger.error("error adding file: %s", output) + raise IOError("error adding file: %s" % output) except IOError: logger.exception("error during addfile") - def getaddr(self, ifname, rescan=False): - """ - Wrapper around vnodeclient getaddr. - - :param str ifname: interface name to get address for - :param bool rescan: rescan flag - :return: - """ - return self.client.getaddr(ifname=ifname, rescan=rescan) - - def netifstats(self, ifname=None): - """ - Wrapper around vnodeclient netifstate. - - :param str ifname: interface name to get state for - :return: - """ - return self.client.netifstats(ifname=ifname) - class LxcNode(SimpleLxcNode): """ @@ -523,16 +504,14 @@ class LxcNode(SimpleLxcNode): :return: nothing """ - self.lock.acquire() - try: - self.makenodedir() - super(LxcNode, self).startup() - self.privatedir("/var/run") - self.privatedir("/var/log") - except OSError: - logger.exception("error during LxcNode.startup()") - finally: - self.lock.release() + with self.lock: + try: + self.makenodedir() + super(LxcNode, self).startup() + self.privatedir("/var/run") + self.privatedir("/var/log") + except OSError: + logger.exception("error during startup") def shutdown(self): """ @@ -542,16 +521,16 @@ class LxcNode(SimpleLxcNode): """ if not self.up: return - self.lock.acquire() - # services are instead stopped when session enters datacollect state - # self.session.services.stopnodeservices(self) - try: - super(LxcNode, self).shutdown() - except: - logger.exception("error during shutdown") - finally: - self.rmnodedir() - self.lock.release() + + with self.lock: + # services are instead stopped when session enters datacollect state + # self.session.services.stopnodeservices(self) + try: + super(LxcNode, self).shutdown() + except OSError: + logger.exception("error during shutdown") + finally: + self.rmnodedir() # TODO: should change how this exception is just swallowed up def privatedir(self, path): @@ -612,11 +591,10 @@ class LxcNode(SimpleLxcNode): :param int mode: mode for file :return: nothing """ - f = self.opennodefile(filename, "w") - f.write(contents) - os.chmod(f.name, mode) - f.close() - logger.info("created nodefile: %s; mode: 0%o", f.name, mode) + with self.opennodefile(filename, "w") as open_file: + open_file.write(contents) + os.chmod(open_file.name, mode) + logger.info("created nodefile: %s; mode: 0%o", open_file.name, mode) def nodefilecopy(self, filename, srcfilename, mode=None): """ diff --git a/daemon/core/service.py b/daemon/core/service.py index b212d3e9..a6169ef7 100644 --- a/daemon/core/service.py +++ b/daemon/core/service.py @@ -7,11 +7,7 @@ a list of available services to the GUI and for configuring individual services. """ -import importlib -import inspect -import os import shlex -import sys import time from itertools import repeat @@ -263,8 +259,8 @@ class CoreServices(ConfigurableManager): """ Start all services on a node. - :param core.netns.nodes.CoreNode node: node to start services on - :return: + :param core.netns.vnode.LxcNode node: node to start services on + :return: nothing """ services = sorted(node.services, key=lambda service: service._startindex) use_startup_service = any(map(self.is_startup_service, services)) @@ -285,7 +281,7 @@ class CoreServices(ConfigurableManager): Start a service on a node. Create private dirs, generate config files, and execute startup commands. - :param core.netns.nodes.CoreNode node: node to boot services on + :param core.netns.vnode.LxcNode node: node to boot services on :param CoreService service: service to start :param list services: service list :param bool use_startup_service: flag to use startup services or not @@ -295,7 +291,7 @@ class CoreServices(ConfigurableManager): self.bootnodecustomservice(node, service, services, use_startup_service) return - logger.info("starting service %s (%s)" % (service._name, service._startindex)) + logger.info("starting service %s (%s)", service._name, service._startindex) for directory in service._dirs: try: node.privatedir(directory) @@ -321,7 +317,7 @@ class CoreServices(ConfigurableManager): Start a custom service on a node. Create private dirs, use supplied config files, and execute supplied startup commands. - :param core.netns.nodes.CoreNode node: node to boot services on + :param core.netns.vnode.LxcNode node: node to boot services on :param CoreService service: service to start :param list services: service list :param bool use_startup_service: flag to use startup services or not @@ -368,7 +364,7 @@ class CoreServices(ConfigurableManager): config references an existing file that should be copied. Returns True for local files, False for generated. - :param core.netns.nodes.CoreNode node: node to copy service for + :param core.netns.vnode.LxcNode node: node to copy service for :param str filename: file name for a configured service :param str cfg: configuration string :return: True if successful, False otherwise @@ -387,7 +383,7 @@ class CoreServices(ConfigurableManager): """ Run validation commands for all services on a node. - :param core.netns.nodes.CoreNode node: node to validate services for + :param core.netns.vnode.LxcNode node: node to validate services for :return: nothing """ services = sorted(node.services, key=lambda service: service._startindex) @@ -398,7 +394,7 @@ class CoreServices(ConfigurableManager): """ Run the validation command(s) for a service. - :param core.netns.nodes.CoreNode node: node to validate service for + :param core.netns.vnode.LxcNode node: node to validate service for :param CoreService service: service to validate :param list services: services for node :return: service validation status @@ -441,7 +437,7 @@ class CoreServices(ConfigurableManager): """ Stop a service on a node. - :param core.netns.nodes.CoreNode node: node to stop a service on + :param core.netns.vnode.LxcNode node: node to stop a service on :param CoreService service: service to stop :return: status for stopping the services :rtype: str @@ -647,7 +643,7 @@ class CoreServices(ConfigurableManager): The file data is either auto-generated or comes from an existing config. :param list services: service list - :param core.netns.nodes.CoreNode node: node to get service file from + :param core.netns.vnode.LxcNode node: node to get service file from :param str filename: file name to retrieve :return: file message for node """ @@ -887,7 +883,7 @@ class CoreService(object): Return the configuration string to be written to a file or sent to the GUI for customization. - :param core.netns.nodes.CoreNode node: node to generate config for + :param core.netns.vnode.LxcNode node: node to generate config for :param str filename: file name to generate config for :param list services: services for node :return: nothing @@ -902,7 +898,7 @@ class CoreService(object): overridden to provide node-specific commands that may be based on other services. - :param core.netns.nodes.CoreNode node: node to get startup for + :param core.netns.vnode.LxcNode node: node to get startup for :param list services: services for node :return: startup commands :rtype: tuple @@ -917,7 +913,7 @@ class CoreService(object): overriden to provide node-specific commands that may be based on other services. - :param core.netns.nodes.CoreNode node: node to validate + :param core.netns.vnode.LxcNode node: node to validate :param list services: services for node :return: validation commands :rtype: tuple @@ -939,10 +935,8 @@ class CoreService(object): cls._shutdown, cls._validate, cls._meta, cls._starttime] if not cls._custom: # this is always reached due to classmethod - valmap[valmap.index(cls._configs)] = \ - cls.getconfigfilenames(node.objid, services) - valmap[valmap.index(cls._startup)] = \ - cls.getstartup(node, services) + valmap[valmap.index(cls._configs)] = cls.getconfigfilenames(node.objid, services) + valmap[valmap.index(cls._startup)] = cls.getstartup(node, services) vals = map(lambda a, b: "%s=%s" % (a, str(b)), cls.keys, valmap) return "|".join(vals) diff --git a/daemon/core/session.py b/daemon/core/session.py index f4d7e01d..5a75752a 100644 --- a/daemon/core/session.py +++ b/daemon/core/session.py @@ -49,7 +49,6 @@ from core.service import CoreServices from core.xen.xenconfig import XenConfigManager from core.xml.xmlsession import save_session_xml - # set default node map node_map = nodemaps.NODES nodeutils.set_node_map(node_map) @@ -523,7 +522,7 @@ class Session(object): if os.path.isfile(environment_config_file): utils.readfileintodict(environment_config_file, env) except IOError: - logger.exception("error reading environment configuration file: %s", environment_config_file) + logger.warn("environment configuration file does not exist: %s", environment_config_file) # attempt to read and add user environment file if self.user: @@ -610,7 +609,7 @@ class Session(object): :param int object_id: object id to retrieve :return: object for the given id - :rtype: core.netns.vnode.SimpleLxcNode + :rtype: core.netns.vnode.LxcNode """ if object_id not in self.objects: raise KeyError("unknown object id %s" % object_id) @@ -1167,7 +1166,7 @@ class Session(object): interface1 = node.newnetif(net=control_net, ifindex=control_net.CTRLIF_IDX_BASE + net_index, ifname="ctrl%d" % net_index, hwaddr=MacAddress.random(), - addrlist=addrlist) + address_list=addrlist) node.netif(interface1).control = True def update_control_interface_hosts(self, net_index=0, remove=False): diff --git a/daemon/core/xml/xmlparser0.py b/daemon/core/xml/xmlparser0.py index c0850d9c..7443070e 100644 --- a/daemon/core/xml/xmlparser0.py +++ b/daemon/core/xml/xmlparser0.py @@ -162,7 +162,7 @@ class CoreDocumentParser0(object): hwaddr = addrstr else: addrlist.append(addrstr) - i = n.newnetif(net, addrlist=addrlist, hwaddr=hwaddr, ifindex=None, ifname=name) + i = n.newnetif(net, address_list=addrlist, hwaddr=hwaddr, ifindex=None, ifname=name) for model in ifc.getElementsByTagName("model"): self.parsemodel(model, n, n.objid) key = (n.name, name) diff --git a/daemon/core/xml/xmlparser1.py b/daemon/core/xml/xmlparser1.py index b73bbb60..4b3b4be3 100644 --- a/daemon/core/xml/xmlparser1.py +++ b/daemon/core/xml/xmlparser1.py @@ -389,7 +389,7 @@ class CoreDocumentParser1(object): hwaddr = MacAddress.from_string(mac[0]) else: hwaddr = None - ifindex = node.newnetif(network, addrlist=ipv4 + ipv6, hwaddr=hwaddr, ifindex=None, ifname=if_name) + ifindex = node.newnetif(network, address_list=ipv4 + ipv6, hwaddr=hwaddr, ifindex=None, ifname=if_name) # TODO: 'hostname' addresses are unused msg = 'node \'%s\' interface \'%s\' connected ' \ 'to network \'%s\'' % (node.name, if_name, network.name) diff --git a/ns3/corens3/obj.py b/ns3/corens3/obj.py index 0d392a4b..6983f25b 100644 --- a/ns3/corens3/obj.py +++ b/ns3/corens3/obj.py @@ -51,21 +51,21 @@ class CoreNs3Node(CoreNode, ns.network.Node): kwds['objid'] = objid CoreNode.__init__(self, *args, **kwds) - def newnetif(self, net=None, addrlist=None, hwaddr=None, ifindex=None, ifname=None): + def newnetif(self, net=None, address_list=None, hwaddr=None, ifindex=None, ifname=None): """ Add a network interface. If we are attaching to a CoreNs3Net, this will be a TunTap. Otherwise dispatch to CoreNode.newnetif(). """ - if not addrlist: - addrlist = [] + if not address_list: + address_list = [] if not isinstance(net, CoreNs3Net): - return CoreNode.newnetif(self, net, addrlist, hwaddr, ifindex, ifname) + return CoreNode.newnetif(self, net, address_list, hwaddr, ifindex, ifname) ifindex = self.newtuntap(ifindex=ifindex, ifname=ifname, net=net) self.attachnet(ifindex, net) netif = self.netif(ifindex) netif.sethwaddr(hwaddr) - for addr in maketuple(addrlist): + for addr in maketuple(address_list): netif.addaddr(addr) addrstr = netif.addrlist[0]