diff --git a/daemon/core/coreobj.py b/daemon/core/coreobj.py index 904a5309..ec7587db 100644 --- a/daemon/core/coreobj.py +++ b/daemon/core/coreobj.py @@ -195,7 +195,8 @@ class PyCoreNode(PyCoreObj): PyCoreObj.__init__(self, session, objid, name, verbose=verbose, start=start) self.services = [] - self.type = None + if not hasattr(self, "type"): + self.type = None self.nodedir = None def nodeid(self): @@ -337,6 +338,7 @@ class PyCoreNet(PyCoreObj): if not hasattr(netif, "node"): continue otherobj = netif.node + uni = False if otherobj is None: # two layer-2 switches/hubs linked together via linknet() if not hasattr(netif, "othernet"): @@ -344,6 +346,11 @@ class PyCoreNet(PyCoreObj): otherobj = netif.othernet if otherobj.objid == self.objid: continue + netif.swapparams('_params_up') + upstream_params = netif.getparams() + netif.swapparams('_params_up') + if netif.getparams() != upstream_params: + uni = True tlvdata = "" tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N1NUMBER, @@ -353,6 +360,9 @@ class PyCoreNet(PyCoreObj): tlvdata += self.netifparamstolink(netif) tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_TYPE, self.linktype) + if uni: + tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_UNI, + 1) tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2NUM, otherobj.getifindex(netif)) for addr in netif.addrlist: @@ -373,6 +383,20 @@ class PyCoreNet(PyCoreObj): msg = coreapi.CoreLinkMessage.pack(flags, tlvdata) msgs.append(msg) + if not uni: + continue + # build a 2nd link message for any upstream link parameters + tlvdata = "" + tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N1NUMBER, + otherobj.objid) + tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N2NUMBER, + self.objid) + netif.swapparams('_params_up') + tlvdata += self.netifparamstolink(netif) + netif.swapparams('_params_up') + tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_UNI, 1) + msg = coreapi.CoreLinkMessage.pack(0, tlvdata) + msgs.append(msg) return msgs class PyCoreNetIf(object): diff --git a/daemon/core/misc/xmlutils.py b/daemon/core/misc/xmlutils.py index 54543c14..c59f63e1 100644 --- a/daemon/core/misc/xmlutils.py +++ b/daemon/core/misc/xmlutils.py @@ -208,17 +208,30 @@ class CoreDocumentParser(object): # links between two nets (e.g. switch-switch) for ifc in net.getElementsByTagName("interface"): netid = str(ifc.getAttribute("net")) - linkednets.append((n, netid)) + ifcname = str(ifc.getAttribute("name")) + linkednets.append((n, netid, ifcname)) self.parsemodels(net, n) # link networks together now that they all have been parsed - for (n, netid) in linkednets: + for (n, netid, ifcname) in linkednets: try: n2 = n.session.objbyname(netid) except KeyError: n.warn("skipping net %s interface: unknown net %s" % \ (n.name, netid)) continue - n.linknet(n2) + upstream = False + netif = n.getlinknetif(n2) + if netif is None: + netif = n2.linknet(n) + else: + netif.swapparams('_params_up') + upstream = True + key = (n2.name, ifcname) + if key in self.linkparams: + for (k, v) in self.linkparams[key]: + netif.setparam(k, v) + if upstream: + netif.swapparams('_params_up') def parsenodes(self): for node in self.np.getElementsByTagName("Node"): @@ -534,15 +547,27 @@ class CoreDocumentWriter(Document): parameters. TODO: Interface parameters should be moved to the model construct, then this separate method shouldn't be required. ''' - if not hasattr(netif, "node") or netif.node is None: - return params = netif.getparams() if len(params) == 0: return model = self.createElement("model") model.setAttribute("name", "netem") model.setAttribute("netif", netif.name) - model.setAttribute("peer", netif.node.name) + if hasattr(netif, "node") and netif.node is not None: + model.setAttribute("peer", netif.node.name) + # link between switches uses one veth interface + elif hasattr(netif, "othernet") and netif.othernet is not None: + if netif.othernet.name == n.getAttribute("name"): + model.setAttribute("peer", netif.net.name) + else: + model.setAttribute("peer", netif.othernet.name) + model.setAttribute("netif", netif.localname) + # hack used for upstream parameters for link between switches + # (see LxBrNet.linknet()) + if netif.othernet.objid == int(n.getAttribute("id")): + netif.swapparams('_params_up') + params = netif.getparams() + netif.swapparams('_params_up') has_params = False for k, v in params: # default netem parameters are 0 or None @@ -632,12 +657,13 @@ class CoreDocumentWriter(Document): for ifc in net.netifs(sort=True): if not hasattr(ifc, "othernet") or not ifc.othernet: continue - if net.objid == ifc.net.objid: - continue i = self.createElement("interface") n.appendChild(i) - i.setAttribute("name", ifc.name) - if ifc.net: + if net.objid == ifc.net.objid: + i.setAttribute("name", ifc.localname) + i.setAttribute("net", ifc.othernet.name) + else: + i.setAttribute("name", ifc.name) i.setAttribute("net", ifc.net.name) def addposition(self, node):