update daemon to generate extra Link Messages for bidirectional link effects

support bidirectional links with session reconnect and XML save/load
(Boeing r1799)
This commit is contained in:
ahrenholz 2013-12-03 18:14:39 +00:00
parent 6547b898c3
commit 5390f280e3
2 changed files with 61 additions and 11 deletions

View file

@ -195,7 +195,8 @@ class PyCoreNode(PyCoreObj):
PyCoreObj.__init__(self, session, objid, name, verbose=verbose, PyCoreObj.__init__(self, session, objid, name, verbose=verbose,
start=start) start=start)
self.services = [] self.services = []
self.type = None if not hasattr(self, "type"):
self.type = None
self.nodedir = None self.nodedir = None
def nodeid(self): def nodeid(self):
@ -337,6 +338,7 @@ class PyCoreNet(PyCoreObj):
if not hasattr(netif, "node"): if not hasattr(netif, "node"):
continue continue
otherobj = netif.node otherobj = netif.node
uni = False
if otherobj is None: if otherobj is None:
# two layer-2 switches/hubs linked together via linknet() # two layer-2 switches/hubs linked together via linknet()
if not hasattr(netif, "othernet"): if not hasattr(netif, "othernet"):
@ -344,6 +346,11 @@ class PyCoreNet(PyCoreObj):
otherobj = netif.othernet otherobj = netif.othernet
if otherobj.objid == self.objid: if otherobj.objid == self.objid:
continue continue
netif.swapparams('_params_up')
upstream_params = netif.getparams()
netif.swapparams('_params_up')
if netif.getparams() != upstream_params:
uni = True
tlvdata = "" tlvdata = ""
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N1NUMBER, tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N1NUMBER,
@ -353,6 +360,9 @@ class PyCoreNet(PyCoreObj):
tlvdata += self.netifparamstolink(netif) tlvdata += self.netifparamstolink(netif)
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_TYPE, tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_TYPE,
self.linktype) self.linktype)
if uni:
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_UNI,
1)
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2NUM, tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2NUM,
otherobj.getifindex(netif)) otherobj.getifindex(netif))
for addr in netif.addrlist: for addr in netif.addrlist:
@ -373,6 +383,20 @@ class PyCoreNet(PyCoreObj):
msg = coreapi.CoreLinkMessage.pack(flags, tlvdata) msg = coreapi.CoreLinkMessage.pack(flags, tlvdata)
msgs.append(msg) 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 return msgs
class PyCoreNetIf(object): class PyCoreNetIf(object):

View file

@ -208,17 +208,30 @@ class CoreDocumentParser(object):
# links between two nets (e.g. switch-switch) # links between two nets (e.g. switch-switch)
for ifc in net.getElementsByTagName("interface"): for ifc in net.getElementsByTagName("interface"):
netid = str(ifc.getAttribute("net")) netid = str(ifc.getAttribute("net"))
linkednets.append((n, netid)) ifcname = str(ifc.getAttribute("name"))
linkednets.append((n, netid, ifcname))
self.parsemodels(net, n) self.parsemodels(net, n)
# link networks together now that they all have been parsed # link networks together now that they all have been parsed
for (n, netid) in linkednets: for (n, netid, ifcname) in linkednets:
try: try:
n2 = n.session.objbyname(netid) n2 = n.session.objbyname(netid)
except KeyError: except KeyError:
n.warn("skipping net %s interface: unknown net %s" % \ n.warn("skipping net %s interface: unknown net %s" % \
(n.name, netid)) (n.name, netid))
continue 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): def parsenodes(self):
for node in self.np.getElementsByTagName("Node"): for node in self.np.getElementsByTagName("Node"):
@ -534,15 +547,27 @@ class CoreDocumentWriter(Document):
parameters. TODO: Interface parameters should be moved to the model parameters. TODO: Interface parameters should be moved to the model
construct, then this separate method shouldn't be required. construct, then this separate method shouldn't be required.
''' '''
if not hasattr(netif, "node") or netif.node is None:
return
params = netif.getparams() params = netif.getparams()
if len(params) == 0: if len(params) == 0:
return return
model = self.createElement("model") model = self.createElement("model")
model.setAttribute("name", "netem") model.setAttribute("name", "netem")
model.setAttribute("netif", netif.name) 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 has_params = False
for k, v in params: for k, v in params:
# default netem parameters are 0 or None # default netem parameters are 0 or None
@ -632,12 +657,13 @@ class CoreDocumentWriter(Document):
for ifc in net.netifs(sort=True): for ifc in net.netifs(sort=True):
if not hasattr(ifc, "othernet") or not ifc.othernet: if not hasattr(ifc, "othernet") or not ifc.othernet:
continue continue
if net.objid == ifc.net.objid:
continue
i = self.createElement("interface") i = self.createElement("interface")
n.appendChild(i) n.appendChild(i)
i.setAttribute("name", ifc.name) if net.objid == ifc.net.objid:
if ifc.net: i.setAttribute("name", ifc.localname)
i.setAttribute("net", ifc.othernet.name)
else:
i.setAttribute("name", ifc.name)
i.setAttribute("net", ifc.net.name) i.setAttribute("net", ifc.net.name)
def addposition(self, node): def addposition(self, node):