initial commit after bringing over cleaned up code and testing some examples
This commit is contained in:
parent
c4858e6e0d
commit
00f4ebf5a9
93 changed files with 15189 additions and 13083 deletions
|
@ -1,32 +1,37 @@
|
|||
#
|
||||
# CORE
|
||||
# Copyright (c)2010-2013 the Boeing Company.
|
||||
# See the LICENSE file included in this distribution.
|
||||
#
|
||||
# authors: Tom Goff <thomas.goff@boeing.com>
|
||||
# Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
|
||||
#
|
||||
'''
|
||||
coreobj.py: defines the basic objects for emulation: the PyCoreObj base class,
|
||||
"""
|
||||
coreobj.py: defines the basic objects for emulation: the PyCoreObj base class,
|
||||
along with PyCoreNode, PyCoreNet, and PyCoreNetIf
|
||||
'''
|
||||
import sys, threading, os, shutil
|
||||
"""
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import socket
|
||||
import threading
|
||||
from socket import AF_INET
|
||||
from socket import AF_INET6
|
||||
|
||||
from core.api import coreapi
|
||||
from core.misc.ipaddr import *
|
||||
from core.data import NodeData, LinkData
|
||||
from core.enumerations import LinkTlvs
|
||||
from core.enumerations import LinkTypes
|
||||
from core.misc import ipaddress
|
||||
|
||||
|
||||
class Position(object):
|
||||
''' Helper class for Cartesian coordinate position
|
||||
'''
|
||||
def __init__(self, x = None, y = None, z = None):
|
||||
"""
|
||||
Helper class for Cartesian coordinate position
|
||||
"""
|
||||
|
||||
def __init__(self, x=None, y=None, z=None):
|
||||
self.x = None
|
||||
self.y = None
|
||||
self.z = None
|
||||
self.set(x, y, z)
|
||||
|
||||
def set(self, x = None, y = None, z = None):
|
||||
''' Returns True if the position has actually changed.
|
||||
'''
|
||||
def set(self, x=None, y=None, z=None):
|
||||
"""
|
||||
Returns True if the position has actually changed.
|
||||
"""
|
||||
if self.x == x and self.y == y and self.z == z:
|
||||
return False
|
||||
self.x = x
|
||||
|
@ -35,20 +40,22 @@ class Position(object):
|
|||
return True
|
||||
|
||||
def get(self):
|
||||
''' Fetch the (x,y,z) position tuple.
|
||||
'''
|
||||
return (self.x, self.y, self.z)
|
||||
"""
|
||||
Fetch the (x,y,z) position tuple.
|
||||
"""
|
||||
return self.x, self.y, self.z
|
||||
|
||||
|
||||
class PyCoreObj(object):
|
||||
''' Base class for pycore objects (nodes and nets)
|
||||
'''
|
||||
"""
|
||||
Base class for pycore objects (nodes and nets)
|
||||
"""
|
||||
apitype = None
|
||||
|
||||
def __init__(self, session, objid = None, name = None, verbose = False,
|
||||
start = True):
|
||||
def __init__(self, session, objid=None, name=None, start=True):
|
||||
self.session = session
|
||||
if objid is None:
|
||||
objid = session.getobjid()
|
||||
objid = session.get_object_id()
|
||||
self.objid = objid
|
||||
if name is None:
|
||||
name = "o%s" % self.objid
|
||||
|
@ -59,45 +66,50 @@ class PyCoreObj(object):
|
|||
self.canvas = None
|
||||
self.icon = None
|
||||
self.opaque = None
|
||||
self.verbose = verbose
|
||||
self.position = Position()
|
||||
|
||||
def startup(self):
|
||||
''' Each object implements its own startup method.
|
||||
'''
|
||||
"""
|
||||
Each object implements its own startup method.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def shutdown(self):
|
||||
''' Each object implements its own shutdown method.
|
||||
'''
|
||||
"""
|
||||
Each object implements its own shutdown method.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def setposition(self, x = None, y = None, z = None):
|
||||
''' Set the (x,y,z) position of the object.
|
||||
'''
|
||||
return self.position.set(x = x, y = y, z = z)
|
||||
def setposition(self, x=None, y=None, z=None):
|
||||
"""
|
||||
Set the (x,y,z) position of the object.
|
||||
"""
|
||||
return self.position.set(x=x, y=y, z=z)
|
||||
|
||||
def getposition(self):
|
||||
''' Return an (x,y,z) tuple representing this object's position.
|
||||
'''
|
||||
"""
|
||||
Return an (x,y,z) tuple representing this object's position.
|
||||
"""
|
||||
return self.position.get()
|
||||
|
||||
def ifname(self, ifindex):
|
||||
return self.netif(ifindex).name
|
||||
|
||||
def netifs(self, sort=False):
|
||||
''' Iterate over attached network interfaces.
|
||||
'''
|
||||
"""
|
||||
Iterate over attached network interfaces.
|
||||
"""
|
||||
if sort:
|
||||
return map(lambda k: self._netif[k], sorted(self._netif.keys()))
|
||||
else:
|
||||
return self._netif.itervalues()
|
||||
|
||||
def numnetif(self):
|
||||
''' Return the attached interface count.
|
||||
'''
|
||||
"""
|
||||
Return the attached interface count.
|
||||
"""
|
||||
return len(self._netif)
|
||||
|
||||
|
||||
def getifindex(self, netif):
|
||||
for ifindex in self._netif:
|
||||
if self._netif[ifindex] is netif:
|
||||
|
@ -111,95 +123,71 @@ class PyCoreObj(object):
|
|||
self.ifindex += 1
|
||||
return ifindex
|
||||
|
||||
def tonodemsg(self, flags):
|
||||
''' Build a CORE API Node Message for this object. Both nodes and
|
||||
networks can be represented by a Node Message.
|
||||
'''
|
||||
def data(self, message_type):
|
||||
"""
|
||||
Build a data object for this node.
|
||||
|
||||
:param message_type: purpose for the data object we are creating
|
||||
:return: node data object
|
||||
:rtype: core.data.NodeData
|
||||
"""
|
||||
if self.apitype is None:
|
||||
return None
|
||||
tlvdata = ""
|
||||
(x, y, z) = self.getposition()
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_NUMBER,
|
||||
self.objid)
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_TYPE,
|
||||
self.apitype)
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_NAME,
|
||||
self.name)
|
||||
if hasattr(self, "type") and self.type is not None:
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_MODEL,
|
||||
self.type)
|
||||
if hasattr(self, "server") and self.server is not None:
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_EMUSRV,
|
||||
self.server)
|
||||
|
||||
x, y, z = self.getposition()
|
||||
|
||||
model = None
|
||||
if hasattr(self, "type"):
|
||||
model = self.type
|
||||
|
||||
emulation_server = None
|
||||
if hasattr(self, "server"):
|
||||
emulation_server = self.server
|
||||
|
||||
services = None
|
||||
if hasattr(self, "services") and len(self.services) != 0:
|
||||
nodeservices = []
|
||||
for s in self.services:
|
||||
nodeservices.append(s._name)
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_SERVICES,
|
||||
"|".join(nodeservices))
|
||||
nodeservices.append(s._name)
|
||||
services = "|".join(nodeservices)
|
||||
|
||||
node_data = NodeData(
|
||||
message_type=message_type,
|
||||
id=self.objid,
|
||||
node_type=self.apitype,
|
||||
name=self.name,
|
||||
emulation_id=self.objid,
|
||||
canvas=self.canvas,
|
||||
icon=self.icon,
|
||||
opaque=self.opaque,
|
||||
x_position=x,
|
||||
y_position=y,
|
||||
model=model,
|
||||
emulation_server=emulation_server,
|
||||
services=services
|
||||
)
|
||||
|
||||
if x is not None:
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_XPOS, x)
|
||||
if y is not None:
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_YPOS, y)
|
||||
if self.canvas is not None:
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_CANVAS,
|
||||
self.canvas)
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_EMUID,
|
||||
self.objid)
|
||||
if self.icon is not None:
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_ICON,
|
||||
self.icon)
|
||||
if self.opaque is not None:
|
||||
tlvdata += coreapi.CoreNodeTlv.pack(coreapi.CORE_TLV_NODE_OPAQUE,
|
||||
self.opaque)
|
||||
msg = coreapi.CoreNodeMessage.pack(flags, tlvdata)
|
||||
return msg
|
||||
return node_data
|
||||
|
||||
def tolinkmsgs(self, flags):
|
||||
''' Build CORE API Link Messages for this object. There is no default
|
||||
method for PyCoreObjs as PyCoreNodes do not implement this but
|
||||
PyCoreNets do.
|
||||
'''
|
||||
def all_link_data(self, flags):
|
||||
"""
|
||||
Build CORE API Link Messages for this object. There is no default
|
||||
method for PyCoreObjs as PyCoreNodes do not implement this but
|
||||
PyCoreNets do.
|
||||
"""
|
||||
return []
|
||||
|
||||
def info(self, msg):
|
||||
''' Utility method for printing informational messages when verbose
|
||||
is turned on.
|
||||
'''
|
||||
if self.verbose:
|
||||
print "%s: %s" % (self.name, msg)
|
||||
sys.stdout.flush()
|
||||
|
||||
def warn(self, msg):
|
||||
''' Utility method for printing warning/error messages
|
||||
'''
|
||||
print >> sys.stderr, "%s: %s" % (self.name, msg)
|
||||
sys.stderr.flush()
|
||||
|
||||
def exception(self, level, source, text):
|
||||
''' Generate an Exception Message for this session, providing this
|
||||
object number.
|
||||
'''
|
||||
if self.session:
|
||||
id = None
|
||||
if isinstance(self.objid, int):
|
||||
id = self.objid
|
||||
elif isinstance(self.objid, str) and self.objid.isdigit():
|
||||
id = int(self.objid)
|
||||
self.session.exception(level, source, id, text)
|
||||
|
||||
|
||||
class PyCoreNode(PyCoreObj):
|
||||
''' Base class for nodes
|
||||
'''
|
||||
def __init__(self, session, objid = None, name = None, verbose = False,
|
||||
start = True):
|
||||
''' Initialization for node objects.
|
||||
'''
|
||||
PyCoreObj.__init__(self, session, objid, name, verbose=verbose,
|
||||
start=start)
|
||||
"""
|
||||
Base class for nodes
|
||||
"""
|
||||
|
||||
def __init__(self, session, objid=None, name=None, start=True):
|
||||
"""
|
||||
Initialization for node objects.
|
||||
"""
|
||||
PyCoreObj.__init__(self, session, objid, name, start=start)
|
||||
self.services = []
|
||||
if not hasattr(self, "type"):
|
||||
self.type = None
|
||||
|
@ -207,26 +195,26 @@ class PyCoreNode(PyCoreObj):
|
|||
|
||||
def nodeid(self):
|
||||
return self.objid
|
||||
|
||||
def addservice(self, service):
|
||||
|
||||
def addservice(self, service):
|
||||
if service is not None:
|
||||
self.services.append(service)
|
||||
|
||||
def makenodedir(self):
|
||||
if self.nodedir is None:
|
||||
self.nodedir = \
|
||||
os.path.join(self.session.sessiondir, self.name + ".conf")
|
||||
os.path.join(self.session.session_dir, self.name + ".conf")
|
||||
os.makedirs(self.nodedir)
|
||||
self.tmpnodedir = True
|
||||
else:
|
||||
self.tmpnodedir = False
|
||||
|
||||
|
||||
def rmnodedir(self):
|
||||
if hasattr(self.session.options, 'preservedir'):
|
||||
if self.session.options.preservedir == '1':
|
||||
return
|
||||
if self.tmpnodedir:
|
||||
shutil.rmtree(self.nodedir, ignore_errors = True)
|
||||
shutil.rmtree(self.nodedir, ignore_errors=True)
|
||||
|
||||
def addnetif(self, netif, ifindex):
|
||||
if ifindex in self._netif:
|
||||
|
@ -241,12 +229,12 @@ class PyCoreNode(PyCoreObj):
|
|||
netif.shutdown()
|
||||
del netif
|
||||
|
||||
def netif(self, ifindex, net = None):
|
||||
def netif(self, ifindex, net=None):
|
||||
if ifindex in self._netif:
|
||||
return self._netif[ifindex]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def attachnet(self, ifindex, net):
|
||||
if ifindex not in self._netif:
|
||||
raise ValueError, "ifindex %s does not exist" % ifindex
|
||||
|
@ -257,8 +245,8 @@ class PyCoreNode(PyCoreObj):
|
|||
raise ValueError, "ifindex %s does not exist" % ifindex
|
||||
self._netif[ifindex].detachnet()
|
||||
|
||||
def setposition(self, x = None, y = None, z = None):
|
||||
changed = PyCoreObj.setposition(self, x = x, y = y, z = z)
|
||||
def setposition(self, x=None, y=None, z=None):
|
||||
changed = PyCoreObj.setposition(self, x=x, y=y, z=z)
|
||||
if not changed:
|
||||
# save extra interface range calculations
|
||||
return
|
||||
|
@ -266,31 +254,32 @@ class PyCoreNode(PyCoreObj):
|
|||
netif.setposition(x, y, z)
|
||||
|
||||
def commonnets(self, obj, want_ctrl=False):
|
||||
''' Given another node or net object, return common networks between
|
||||
this node and that object. A list of tuples is returned, with each tuple
|
||||
consisting of (network, interface1, interface2).
|
||||
'''
|
||||
"""
|
||||
Given another node or net object, return common networks between
|
||||
this node and that object. A list of tuples is returned, with each tuple
|
||||
consisting of (network, interface1, interface2).
|
||||
"""
|
||||
r = []
|
||||
for netif1 in self.netifs():
|
||||
if not want_ctrl and hasattr(netif1, 'control'):
|
||||
continue
|
||||
for netif2 in obj.netifs():
|
||||
if netif1.net == netif2.net:
|
||||
r += (netif1.net, netif1, netif2),
|
||||
r += (netif1.net, netif1, netif2),
|
||||
return r
|
||||
|
||||
|
||||
|
||||
class PyCoreNet(PyCoreObj):
|
||||
''' Base class for networks
|
||||
'''
|
||||
linktype = coreapi.CORE_LINK_WIRED
|
||||
"""
|
||||
Base class for networks
|
||||
"""
|
||||
linktype = LinkTypes.WIRED.value
|
||||
|
||||
def __init__(self, session, objid, name, verbose = False, start = True):
|
||||
''' Initialization for network objects.
|
||||
'''
|
||||
PyCoreObj.__init__(self, session, objid, name, verbose=verbose,
|
||||
start=start)
|
||||
def __init__(self, session, objid, name, start=True):
|
||||
"""
|
||||
Initialization for network objects.
|
||||
"""
|
||||
PyCoreObj.__init__(self, session, objid, name, start=start)
|
||||
self._linked = {}
|
||||
self._linked_lock = threading.Lock()
|
||||
|
||||
|
@ -300,7 +289,7 @@ class PyCoreNet(PyCoreObj):
|
|||
netif.netifi = i
|
||||
with self._linked_lock:
|
||||
self._linked[netif] = {}
|
||||
|
||||
|
||||
def detach(self, netif):
|
||||
del self._netif[netif.netifi]
|
||||
netif.netifi = None
|
||||
|
@ -308,37 +297,37 @@ class PyCoreNet(PyCoreObj):
|
|||
del self._linked[netif]
|
||||
|
||||
def netifparamstolink(self, netif):
|
||||
''' Helper for tolinkmsgs() to build TLVs having link parameters
|
||||
from interface parameters.
|
||||
'''
|
||||
tlvdata = ""
|
||||
"""
|
||||
Helper for tolinkmsgs() to build TLVs having link parameters
|
||||
from interface parameters.
|
||||
"""
|
||||
|
||||
delay = netif.getparam('delay')
|
||||
bw = netif.getparam('bw')
|
||||
loss = netif.getparam('loss')
|
||||
duplicate = netif.getparam('duplicate')
|
||||
jitter = netif.getparam('jitter')
|
||||
|
||||
tlvdata = ""
|
||||
if delay is not None:
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_DELAY,
|
||||
delay)
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.DELAY.value, delay)
|
||||
if bw is not None:
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_BW, bw)
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.BANDWIDTH.value, bw)
|
||||
if loss is not None:
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_PER,
|
||||
str(loss))
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.PER.value, str(loss))
|
||||
if duplicate is not None:
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_DUP,
|
||||
str(duplicate))
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.DUP.value, str(duplicate))
|
||||
if jitter is not None:
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_JITTER,
|
||||
jitter)
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(LinkTlvs.JITTER.value, jitter)
|
||||
return tlvdata
|
||||
|
||||
|
||||
def tolinkmsgs(self, flags):
|
||||
''' Build CORE API Link Messages for this network. Each link message
|
||||
describes a link between this network and a node.
|
||||
'''
|
||||
msgs = []
|
||||
def all_link_data(self, flags):
|
||||
"""
|
||||
Build CORE API Link Messages for this network. Each link message
|
||||
describes a link between this network and a node.
|
||||
"""
|
||||
all_links = []
|
||||
|
||||
# build a link message from this network node to each node having a
|
||||
# connected interface
|
||||
for netif in self.netifs(sort=True):
|
||||
|
@ -358,61 +347,77 @@ class PyCoreNet(PyCoreObj):
|
|||
netif.swapparams('_params_up')
|
||||
if netif.getparams() != upstream_params:
|
||||
uni = True
|
||||
|
||||
tlvdata = ""
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N1NUMBER,
|
||||
self.objid)
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_N2NUMBER,
|
||||
otherobj.objid)
|
||||
tlvdata += self.netifparamstolink(netif)
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_TYPE,
|
||||
self.linktype)
|
||||
|
||||
unidirectional = 0
|
||||
if uni:
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_UNI,
|
||||
1)
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2NUM,
|
||||
otherobj.getifindex(netif))
|
||||
if netif.hwaddr:
|
||||
tlvdata += \
|
||||
coreapi.CoreLinkTlv.pack(coreapi.CORE_TLV_LINK_IF2MAC,
|
||||
netif.hwaddr)
|
||||
for addr in netif.addrlist:
|
||||
(ip, sep, mask) = addr.partition('/')
|
||||
unidirectional = 1
|
||||
|
||||
interface2_ip4 = None
|
||||
interface2_ip4_mask = None
|
||||
interface2_ip6 = None
|
||||
interface2_ip6_mask = None
|
||||
for address in netif.addrlist:
|
||||
ip, sep, mask = address.partition('/')
|
||||
mask = int(mask)
|
||||
if isIPv4Address(ip):
|
||||
if ipaddress.is_ipv4_address(ip):
|
||||
family = AF_INET
|
||||
tlvtypeip = coreapi.CORE_TLV_LINK_IF2IP4
|
||||
tlvtypemask = coreapi.CORE_TLV_LINK_IF2IP4MASK
|
||||
ipl = socket.inet_pton(family, ip)
|
||||
interface2_ip4 = ipaddress.IpAddress(af=family, address=ipl)
|
||||
interface2_ip4_mask = mask
|
||||
else:
|
||||
family = AF_INET6
|
||||
tlvtypeip = coreapi.CORE_TLV_LINK_IF2IP6
|
||||
tlvtypemask = coreapi.CORE_TLV_LINK_IF2IP6MASK
|
||||
ipl = socket.inet_pton(family, ip)
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(tlvtypeip, \
|
||||
IPAddr(af=family, addr=ipl))
|
||||
tlvdata += coreapi.CoreLinkTlv.pack(tlvtypemask, mask)
|
||||
ipl = socket.inet_pton(family, ip)
|
||||
interface2_ip6 = ipaddress.IpAddress(af=family, address=ipl)
|
||||
interface2_ip6_mask = mask
|
||||
|
||||
# TODO: not currently used
|
||||
# loss = netif.getparam('loss')
|
||||
link_data = LinkData(
|
||||
message_type=flags,
|
||||
node1_id=self.objid,
|
||||
node2_id=otherobj.objid,
|
||||
link_type=self.linktype,
|
||||
unidirectional=unidirectional,
|
||||
interface2_id=otherobj.getifindex(netif),
|
||||
interface2_mac=netif.hwaddr,
|
||||
interface2_ip4=interface2_ip4,
|
||||
interface2_ip4_mask=interface2_ip4_mask,
|
||||
interface2_ip6=interface2_ip6,
|
||||
interface2_ip6_mask=interface2_ip6_mask,
|
||||
delay=netif.getparam("delay"),
|
||||
bandwidth=netif.getparam("bw"),
|
||||
dup=netif.getparam("duplicate"),
|
||||
jitter=netif.getparam("jitter")
|
||||
)
|
||||
|
||||
all_links.append(link_data)
|
||||
|
||||
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)
|
||||
link_data = LinkData(
|
||||
message_type=0,
|
||||
node1_id=otherobj.objid,
|
||||
node2_id=self.objid,
|
||||
unidirectional=1,
|
||||
delay=netif.getparam("delay"),
|
||||
bandwidth=netif.getparam("bw"),
|
||||
dup=netif.getparam("duplicate"),
|
||||
jitter=netif.getparam("jitter")
|
||||
)
|
||||
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
|
||||
|
||||
all_links.append(link_data)
|
||||
|
||||
return all_links
|
||||
|
||||
|
||||
class PyCoreNetIf(object):
|
||||
''' Base class for interfaces.
|
||||
'''
|
||||
"""
|
||||
Base class for interfaces.
|
||||
"""
|
||||
|
||||
def __init__(self, node, name, mtu):
|
||||
self.node = node
|
||||
self.name = name
|
||||
|
@ -428,13 +433,15 @@ class PyCoreNetIf(object):
|
|||
self.transport_type = None
|
||||
# interface index on the network
|
||||
self.netindex = None
|
||||
# index used to find flow data
|
||||
self.flow_id = None
|
||||
|
||||
def startup(self):
|
||||
pass
|
||||
|
||||
def shutdown(self):
|
||||
pass
|
||||
|
||||
|
||||
def attachnet(self, net):
|
||||
if self.net:
|
||||
self.detachnet()
|
||||
|
@ -456,25 +463,28 @@ class PyCoreNetIf(object):
|
|||
self.hwaddr = addr
|
||||
|
||||
def getparam(self, key):
|
||||
''' Retrieve a parameter from the _params dict,
|
||||
or None if the parameter does not exist.
|
||||
'''
|
||||
"""
|
||||
Retrieve a parameter from the _params dict,
|
||||
or None if the parameter does not exist.
|
||||
"""
|
||||
if key not in self._params:
|
||||
return None
|
||||
return self._params[key]
|
||||
|
||||
|
||||
def getparams(self):
|
||||
''' Return (key, value) pairs from the _params dict.
|
||||
'''
|
||||
"""
|
||||
Return (key, value) pairs from the _params dict.
|
||||
"""
|
||||
r = []
|
||||
for k in sorted(self._params.keys()):
|
||||
r.append((k, self._params[k]))
|
||||
return r
|
||||
|
||||
|
||||
def setparam(self, key, value):
|
||||
''' Set a parameter in the _params dict.
|
||||
Returns True if the parameter has changed.
|
||||
'''
|
||||
"""
|
||||
Set a parameter in the _params dict.
|
||||
Returns True if the parameter has changed.
|
||||
"""
|
||||
if key in self._params:
|
||||
if self._params[key] == value:
|
||||
return False
|
||||
|
@ -483,12 +493,13 @@ class PyCoreNetIf(object):
|
|||
return False
|
||||
self._params[key] = value
|
||||
return True
|
||||
|
||||
|
||||
def swapparams(self, name):
|
||||
''' Swap out the _params dict for name. If name does not exist,
|
||||
"""
|
||||
Swap out the _params dict for name. If name does not exist,
|
||||
intialize it. This is for supporting separate upstream/downstream
|
||||
parameters when two layer-2 nodes are linked together.
|
||||
'''
|
||||
"""
|
||||
tmp = self._params
|
||||
if not hasattr(self, name):
|
||||
setattr(self, name, {})
|
||||
|
@ -496,8 +507,8 @@ class PyCoreNetIf(object):
|
|||
setattr(self, name, tmp)
|
||||
|
||||
def setposition(self, x, y, z):
|
||||
''' Dispatch to any position hook (self.poshook) handler.
|
||||
'''
|
||||
"""
|
||||
Dispatch to any position hook (self.poshook) handler.
|
||||
"""
|
||||
if self.poshook is not None:
|
||||
self.poshook(self, x, y, z)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue