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:
parent
6547b898c3
commit
5390f280e3
2 changed files with 61 additions and 11 deletions
|
@ -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):
|
||||||
|
|
|
@ -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):
|
||||||
|
|
Loading…
Reference in a new issue