removed node map file and utilities, added formal class methods to session objects and added checks for specific classes where needed
This commit is contained in:
parent
8c348b5ab1
commit
b14012e5e9
24 changed files with 161 additions and 264 deletions
|
@ -4,8 +4,9 @@ url = "https://pypi.org/simple"
|
|||
verify_ssl = true
|
||||
|
||||
[scripts]
|
||||
coredev = "python scripts/core-daemon -f data/core.conf -l data/logging.conf"
|
||||
coretest = "python -m pytest -v tests"
|
||||
core = "python scripts/core-daemon -f data/core.conf -l data/logging.conf"
|
||||
test = "pytest -v tests"
|
||||
test_emane = "pytest -v tests/emane"
|
||||
|
||||
[dev-packages]
|
||||
grpcio-tools = "*"
|
||||
|
|
|
@ -12,6 +12,7 @@ import grpc
|
|||
|
||||
from core import CoreError
|
||||
from core.api.grpc import core_pb2, core_pb2_grpc
|
||||
from core.emane.nodes import EmaneNode
|
||||
from core.emulator.data import (
|
||||
ConfigData,
|
||||
EventData,
|
||||
|
@ -23,7 +24,6 @@ from core.emulator.data import (
|
|||
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
|
||||
from core.emulator.enumerations import EventTypes, LinkTypes, NodeTypes
|
||||
from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility
|
||||
from core.nodes import nodeutils
|
||||
from core.nodes.base import CoreNetworkBase
|
||||
from core.nodes.docker import DockerNode
|
||||
from core.nodes.ipaddress import MacAddress
|
||||
|
@ -444,7 +444,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
if not isinstance(node.id, int):
|
||||
continue
|
||||
|
||||
node_type = nodeutils.get_node_type(node.__class__).value
|
||||
node_type = session.get_node_type(node.__class__)
|
||||
model = getattr(node, "type", None)
|
||||
position = core_pb2.Position(
|
||||
x=node.position.x, y=node.position.y, z=node.position.z
|
||||
|
@ -456,7 +456,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
services = [x.name for x in services]
|
||||
|
||||
emane_model = None
|
||||
if nodeutils.is_node(node, NodeTypes.EMANE):
|
||||
if isinstance(node, EmaneNode):
|
||||
emane_model = node.model.name
|
||||
|
||||
node_proto = core_pb2.Node(
|
||||
|
@ -464,7 +464,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
name=node.name,
|
||||
emane=emane_model,
|
||||
model=model,
|
||||
type=node_type,
|
||||
type=node_type.value,
|
||||
position=position,
|
||||
services=services,
|
||||
)
|
||||
|
@ -809,18 +809,18 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer):
|
|||
interfaces.append(interface_proto)
|
||||
|
||||
emane_model = None
|
||||
if nodeutils.is_node(node, NodeTypes.EMANE):
|
||||
if isinstance(node, EmaneNode):
|
||||
emane_model = node.model.name
|
||||
|
||||
services = [x.name for x in getattr(node, "services", [])]
|
||||
position = core_pb2.Position(
|
||||
x=node.position.x, y=node.position.y, z=node.position.z
|
||||
)
|
||||
node_type = nodeutils.get_node_type(node.__class__).value
|
||||
node_type = session.get_node_type(node.__class__)
|
||||
node_proto = core_pb2.Node(
|
||||
id=node.id,
|
||||
name=node.name,
|
||||
type=node_type,
|
||||
type=node_type.value,
|
||||
emane=emane_model,
|
||||
model=node.type,
|
||||
position=position,
|
||||
|
|
|
@ -12,6 +12,7 @@ import threading
|
|||
|
||||
from core import utils
|
||||
from core.api.tlv import coreapi
|
||||
from core.emane.nodes import EmaneNet
|
||||
from core.emulator.enumerations import (
|
||||
ConfigDataTypes,
|
||||
ConfigFlags,
|
||||
|
@ -27,11 +28,10 @@ from core.emulator.enumerations import (
|
|||
NodeTypes,
|
||||
RegisterTlvs,
|
||||
)
|
||||
from core.nodes import nodeutils
|
||||
from core.nodes.base import CoreNetworkBase, CoreNodeBase
|
||||
from core.nodes.interface import GreTap
|
||||
from core.nodes.ipaddress import IpAddress
|
||||
from core.nodes.network import GreTapBridge
|
||||
from core.nodes.network import CtrlNet, GreTapBridge
|
||||
from core.nodes.physical import PhysicalNode
|
||||
|
||||
|
||||
|
@ -495,15 +495,12 @@ class CoreBroker(object):
|
|||
logging.info("adding net tunnel for: id(%s) %s", node_id, net)
|
||||
|
||||
# add other nets here that do not require tunnels
|
||||
if nodeutils.is_node(net, NodeTypes.EMANE_NET):
|
||||
if isinstance(net, EmaneNet):
|
||||
logging.warning("emane network does not require a tunnel")
|
||||
return None
|
||||
|
||||
server_interface = getattr(net, "serverintf", None)
|
||||
if (
|
||||
nodeutils.is_node(net, NodeTypes.CONTROL_NET)
|
||||
and server_interface is not None
|
||||
):
|
||||
if isinstance(net, CtrlNet) and server_interface is not None:
|
||||
logging.warning(
|
||||
"control networks with server interfaces do not need a tunnel"
|
||||
)
|
||||
|
@ -824,7 +821,8 @@ class CoreBroker(object):
|
|||
nodetype = message.get_tlv(NodeTlvs.TYPE.value)
|
||||
if nodetype is not None:
|
||||
try:
|
||||
nodecls = nodeutils.get_node_class(NodeTypes(nodetype))
|
||||
nodetype = NodeTypes(nodetype)
|
||||
nodecls = self.session.get_node_class(nodetype)
|
||||
except KeyError:
|
||||
logging.warning("broker invalid node type %s", nodetype)
|
||||
return handle_locally, servers
|
||||
|
|
|
@ -38,7 +38,7 @@ from core.emulator.enumerations import (
|
|||
SessionTlvs,
|
||||
)
|
||||
from core.location.mobility import BasicRangeModel
|
||||
from core.nodes import nodeutils
|
||||
from core.nodes.network import WlanNode
|
||||
from core.services.coreservices import ServiceManager, ServiceShim
|
||||
|
||||
|
||||
|
@ -1603,8 +1603,8 @@ class CoreHandler(socketserver.BaseRequestHandler):
|
|||
node = self.session.get_node(node_id)
|
||||
|
||||
# configure mobility models for WLAN added during runtime
|
||||
if event_type == EventTypes.INSTANTIATION_STATE and nodeutils.is_node(
|
||||
node, NodeTypes.WIRELESS_LAN
|
||||
if event_type == EventTypes.INSTANTIATION_STATE and isinstance(
|
||||
node, WlanNode
|
||||
):
|
||||
self.session.start_mobility(node_ids=(node.id,))
|
||||
return ()
|
||||
|
|
|
@ -15,6 +15,7 @@ from core.emane.bypass import EmaneBypassModel
|
|||
from core.emane.commeffect import EmaneCommEffectModel
|
||||
from core.emane.emanemodel import EmaneModel
|
||||
from core.emane.ieee80211abg import EmaneIeee80211abgModel
|
||||
from core.emane.nodes import EmaneNode
|
||||
from core.emane.rfpipe import EmaneRfPipeModel
|
||||
from core.emane.tdma import EmaneTdmaModel
|
||||
from core.emulator.enumerations import (
|
||||
|
@ -23,10 +24,8 @@ from core.emulator.enumerations import (
|
|||
ConfigTlvs,
|
||||
MessageFlags,
|
||||
MessageTypes,
|
||||
NodeTypes,
|
||||
RegisterTlvs,
|
||||
)
|
||||
from core.nodes import nodeutils
|
||||
from core.xml import emanexml
|
||||
|
||||
try:
|
||||
|
@ -266,7 +265,7 @@ class EmaneManager(ModelManager):
|
|||
with self.session._nodes_lock:
|
||||
for node_id in self.session.nodes:
|
||||
node = self.session.nodes[node_id]
|
||||
if nodeutils.is_node(node, NodeTypes.EMANE):
|
||||
if isinstance(node, EmaneNode):
|
||||
logging.debug(
|
||||
"adding emane node: id(%s) name(%s)", node.id, node.name
|
||||
)
|
||||
|
|
|
@ -25,7 +25,6 @@ class EmaneNet(CoreNetworkBase):
|
|||
|
||||
apitype = NodeTypes.EMANE.value
|
||||
linktype = LinkTypes.WIRELESS.value
|
||||
# icon used
|
||||
type = "wlan"
|
||||
|
||||
|
||||
|
@ -36,6 +35,8 @@ class EmaneNode(EmaneNet):
|
|||
Emane controller object that exists in a session.
|
||||
"""
|
||||
|
||||
is_emane = True
|
||||
|
||||
def __init__(self, session, _id=None, name=None, start=True):
|
||||
super(EmaneNode, self).__init__(session, _id, name, start)
|
||||
self.conf = ""
|
||||
|
|
|
@ -7,7 +7,6 @@ import sys
|
|||
import core.services
|
||||
from core.emulator.emudata import IdGen
|
||||
from core.emulator.session import Session
|
||||
from core.nodes import nodemaps, nodeutils
|
||||
from core.services.coreservices import ServiceManager
|
||||
|
||||
|
||||
|
@ -53,10 +52,6 @@ class CoreEmu(object):
|
|||
self.session_id_gen = IdGen(_id=0)
|
||||
self.sessions = {}
|
||||
|
||||
# set default nodes
|
||||
node_map = nodemaps.NODES
|
||||
nodeutils.set_node_map(node_map)
|
||||
|
||||
# load services
|
||||
self.service_errors = []
|
||||
self.load_services()
|
||||
|
@ -77,15 +72,6 @@ class CoreEmu(object):
|
|||
custom_service_errors = ServiceManager.add_services(service_path)
|
||||
self.service_errors.extend(custom_service_errors)
|
||||
|
||||
def update_nodes(self, node_map):
|
||||
"""
|
||||
Updates node map used by core.
|
||||
|
||||
:param dict node_map: node map to update existing node map with
|
||||
:return: nothing
|
||||
"""
|
||||
nodeutils.update_node_map(node_map)
|
||||
|
||||
def shutdown(self):
|
||||
"""
|
||||
Shutdown all CORE session.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
from core.emulator.enumerations import LinkTypes, NodeTypes
|
||||
from core.nodes import nodeutils
|
||||
from core.emane.nodes import EmaneNode
|
||||
from core.emulator.enumerations import LinkTypes
|
||||
from core.nodes.base import CoreNetworkBase
|
||||
from core.nodes.ipaddress import Ipv4Prefix, Ipv6Prefix, MacAddress
|
||||
from core.nodes.physical import PhysicalNode
|
||||
|
||||
|
||||
class IdGen(object):
|
||||
|
@ -65,7 +66,7 @@ def link_config(network, interface, link_options, devname=None, interface_two=No
|
|||
}
|
||||
|
||||
# hacky check here, because physical and emane nodes do not conform to the same linkconfig interface
|
||||
if not nodeutils.is_node(network, [NodeTypes.EMANE, NodeTypes.PHYSICAL]):
|
||||
if not isinstance(network, (EmaneNode, PhysicalNode)):
|
||||
config["devname"] = devname
|
||||
|
||||
network.linkconfig(**config)
|
||||
|
|
|
@ -14,11 +14,11 @@ import threading
|
|||
import time
|
||||
from multiprocessing.pool import ThreadPool
|
||||
|
||||
import core.nodes.base
|
||||
from core import CoreError, constants, utils
|
||||
from core.api.tlv import coreapi
|
||||
from core.api.tlv.broker import CoreBroker
|
||||
from core.emane.emanemanager import EmaneManager
|
||||
from core.emane.nodes import EmaneNet, EmaneNode
|
||||
from core.emulator.data import EventData, ExceptionData, NodeData
|
||||
from core.emulator.emudata import (
|
||||
IdGen,
|
||||
|
@ -33,14 +33,46 @@ from core.emulator.sessionconfig import SessionConfig, SessionMetaData
|
|||
from core.location.corelocation import CoreLocation
|
||||
from core.location.event import EventLoop
|
||||
from core.location.mobility import MobilityManager
|
||||
from core.nodes import nodeutils
|
||||
from core.nodes.base import CoreNodeBase
|
||||
from core.nodes.base import CoreNode, CoreNodeBase
|
||||
from core.nodes.docker import DockerNode
|
||||
from core.nodes.ipaddress import MacAddress
|
||||
from core.nodes.lxd import LxcNode
|
||||
from core.nodes.network import (
|
||||
CtrlNet,
|
||||
GreTapBridge,
|
||||
HubNode,
|
||||
PtpNet,
|
||||
SwitchNode,
|
||||
TunnelNode,
|
||||
WlanNode,
|
||||
)
|
||||
from core.nodes.physical import PhysicalNode, Rj45Node
|
||||
from core.plugins.sdt import Sdt
|
||||
from core.services.coreservices import CoreServices
|
||||
from core.xml import corexml, corexmldeployment
|
||||
from core.xml.corexml import CoreXmlReader, CoreXmlWriter
|
||||
|
||||
# maps for converting from API call node type values to classes and vice versa
|
||||
NODES = {
|
||||
NodeTypes.DEFAULT: CoreNode,
|
||||
NodeTypes.PHYSICAL: PhysicalNode,
|
||||
NodeTypes.TBD: None,
|
||||
NodeTypes.SWITCH: SwitchNode,
|
||||
NodeTypes.HUB: HubNode,
|
||||
NodeTypes.WIRELESS_LAN: WlanNode,
|
||||
NodeTypes.RJ45: Rj45Node,
|
||||
NodeTypes.TUNNEL: TunnelNode,
|
||||
NodeTypes.KTUNNEL: None,
|
||||
NodeTypes.EMANE: EmaneNode,
|
||||
NodeTypes.EMANE_NET: EmaneNet,
|
||||
NodeTypes.TAP_BRIDGE: GreTapBridge,
|
||||
NodeTypes.PEER_TO_PEER: PtpNet,
|
||||
NodeTypes.CONTROL_NET: CtrlNet,
|
||||
NodeTypes.DOCKER: DockerNode,
|
||||
NodeTypes.LXC: LxcNode,
|
||||
}
|
||||
NODES_TYPE = {NODES[x]: x for x in NODES}
|
||||
|
||||
|
||||
class Session(object):
|
||||
"""
|
||||
|
@ -121,6 +153,33 @@ class Session(object):
|
|||
"host": ("DefaultRoute", "SSH"),
|
||||
}
|
||||
|
||||
@classmethod
|
||||
def get_node_class(cls, _type):
|
||||
"""
|
||||
Retrieve the class for a given node type.
|
||||
|
||||
:param core.emulator.enumerations.NodeTypes _type: node type to get class for
|
||||
:return: node class
|
||||
"""
|
||||
node_class = NODES.get(_type)
|
||||
if node_class is None:
|
||||
raise CoreError("invalid node type: %s" % _type)
|
||||
return node_class
|
||||
|
||||
@classmethod
|
||||
def get_node_type(cls, _class):
|
||||
"""
|
||||
Retrieve node type for a given node class.
|
||||
|
||||
:param _class: node class to get a node type for
|
||||
:return: node type
|
||||
:rtype: core.emulator.enumerations.NodeTypes
|
||||
"""
|
||||
node_type = NODES_TYPE.get(_class)
|
||||
if node_type is None:
|
||||
raise CoreError("invalid node class: %s" % _class)
|
||||
return node_type
|
||||
|
||||
def _link_nodes(self, node_one_id, node_two_id):
|
||||
"""
|
||||
Convenience method for retrieving nodes within link data.
|
||||
|
@ -145,7 +204,7 @@ class Session(object):
|
|||
# both node ids are provided
|
||||
tunnel = self.broker.gettunnel(node_one_id, node_two_id)
|
||||
logging.debug("tunnel between nodes: %s", tunnel)
|
||||
if nodeutils.is_node(tunnel, NodeTypes.TAP_BRIDGE):
|
||||
if isinstance(tunnel, GreTapBridge):
|
||||
net_one = tunnel
|
||||
if tunnel.remotenum == node_one_id:
|
||||
node_one = None
|
||||
|
@ -203,9 +262,7 @@ class Session(object):
|
|||
raise CoreError("no common network found for wireless link/unlink")
|
||||
|
||||
for common_network, interface_one, interface_two in common_networks:
|
||||
if not nodeutils.is_node(
|
||||
common_network, [NodeTypes.WIRELESS_LAN, NodeTypes.EMANE]
|
||||
):
|
||||
if not isinstance(common_network, (WlanNode, EmaneNode)):
|
||||
logging.info(
|
||||
"skipping common network that is not wireless/emane: %s",
|
||||
common_network,
|
||||
|
@ -268,9 +325,8 @@ class Session(object):
|
|||
node_one.name,
|
||||
node_two.name,
|
||||
)
|
||||
ptp_class = nodeutils.get_node_class(NodeTypes.PEER_TO_PEER)
|
||||
start = self.state > EventTypes.DEFINITION_STATE.value
|
||||
net_one = self.create_node(cls=ptp_class, start=start)
|
||||
net_one = self.create_node(cls=PtpNet, start=start)
|
||||
|
||||
# node to network
|
||||
if node_one and net_one:
|
||||
|
@ -300,7 +356,7 @@ class Session(object):
|
|||
net_one.name,
|
||||
net_two.name,
|
||||
)
|
||||
if nodeutils.is_node(net_two, NodeTypes.RJ45):
|
||||
if isinstance(net_two, Rj45Node):
|
||||
interface = net_two.linknet(net_one)
|
||||
else:
|
||||
interface = net_one.linknet(net_two)
|
||||
|
@ -324,12 +380,12 @@ class Session(object):
|
|||
|
||||
# tunnel node logic
|
||||
key = link_options.key
|
||||
if key and nodeutils.is_node(net_one, NodeTypes.TUNNEL):
|
||||
if key and isinstance(net_one, TunnelNode):
|
||||
logging.info("setting tunnel key for: %s", net_one.name)
|
||||
net_one.setkey(key)
|
||||
if addresses:
|
||||
net_one.addrconfig(addresses)
|
||||
if key and nodeutils.is_node(net_two, NodeTypes.TUNNEL):
|
||||
if key and isinstance(net_two, TunnelNode):
|
||||
logging.info("setting tunnel key for: %s", net_two.name)
|
||||
net_two.setkey(key)
|
||||
if addresses:
|
||||
|
@ -337,14 +393,14 @@ class Session(object):
|
|||
|
||||
# physical node connected with tunnel
|
||||
if not net_one and not net_two and (node_one or node_two):
|
||||
if node_one and nodeutils.is_node(node_one, NodeTypes.PHYSICAL):
|
||||
if node_one and isinstance(node_one, PhysicalNode):
|
||||
logging.info("adding link for physical node: %s", node_one.name)
|
||||
addresses = interface_one.get_addresses()
|
||||
node_one.adoptnetif(
|
||||
tunnel, interface_one.id, interface_one.mac, addresses
|
||||
)
|
||||
link_config(node_one, tunnel, link_options)
|
||||
elif node_two and nodeutils.is_node(node_two, NodeTypes.PHYSICAL):
|
||||
elif node_two and isinstance(node_two, PhysicalNode):
|
||||
logging.info("adding link for physical node: %s", node_two.name)
|
||||
addresses = interface_two.get_addresses()
|
||||
node_two.adoptnetif(
|
||||
|
@ -584,14 +640,11 @@ class Session(object):
|
|||
:param int _id: id for node, defaults to None for generated id
|
||||
:param core.emulator.emudata.NodeOptions node_options: data to create node with
|
||||
:return: created node
|
||||
:raises core.CoreError: when an invalid node type is given
|
||||
"""
|
||||
|
||||
# retrieve node class for given node type
|
||||
try:
|
||||
node_class = nodeutils.get_node_class(_type)
|
||||
except KeyError:
|
||||
logging.error("invalid node type to create: %s", _type)
|
||||
return None
|
||||
# validate node type, get class, or throw error
|
||||
node_class = self.get_node_class(_type)
|
||||
|
||||
# set node start based on current session state, override and check when rj45
|
||||
start = self.state > EventTypes.DEFINITION_STATE.value
|
||||
|
@ -651,10 +704,8 @@ class Session(object):
|
|||
logging.debug("set node type: %s", node.type)
|
||||
self.services.add_services(node, node.type, node_options.services)
|
||||
|
||||
# boot nodes if created after runtime, LcxNodes, Physical, and RJ45 are all PyCoreNodes
|
||||
is_boot_node = isinstance(node, CoreNodeBase) and not nodeutils.is_node(
|
||||
node, NodeTypes.RJ45
|
||||
)
|
||||
# boot nodes if created after runtime, CoreNodes, Physical, and RJ45 are all nodes
|
||||
is_boot_node = isinstance(node, CoreNodeBase) and not isinstance(node, Rj45Node)
|
||||
if self.state == EventTypes.RUNTIME_STATE.value and is_boot_node:
|
||||
self.write_nodes()
|
||||
self.add_remove_control_interface(node=node, remove=False)
|
||||
|
@ -1441,12 +1492,10 @@ class Session(object):
|
|||
count = 0
|
||||
for node_id in self.nodes:
|
||||
node = self.nodes[node_id]
|
||||
is_p2p_ctrlnet = nodeutils.is_node(
|
||||
node, (NodeTypes.PEER_TO_PEER, NodeTypes.CONTROL_NET)
|
||||
is_p2p_ctrlnet = isinstance(node, (PtpNet, CtrlNet))
|
||||
is_tap = isinstance(node, GreTapBridge) and not isinstance(
|
||||
node, TunnelNode
|
||||
)
|
||||
is_tap = nodeutils.is_node(
|
||||
node, NodeTypes.TAP_BRIDGE
|
||||
) and not nodeutils.is_node(node, NodeTypes.TUNNEL)
|
||||
if is_p2p_ctrlnet or is_tap:
|
||||
continue
|
||||
|
||||
|
@ -1493,7 +1542,7 @@ class Session(object):
|
|||
for node_id in self.nodes:
|
||||
node = self.nodes[node_id]
|
||||
# TODO: determine if checking for CoreNode alone is ok
|
||||
if isinstance(node, core.nodes.base.CoreNodeBase):
|
||||
if isinstance(node, CoreNodeBase):
|
||||
self.services.stop_services(node)
|
||||
|
||||
# shutdown emane
|
||||
|
@ -1546,10 +1595,7 @@ class Session(object):
|
|||
start = time.time()
|
||||
for _id in self.nodes:
|
||||
node = self.nodes[_id]
|
||||
# TODO: PyCoreNode is not the type to check
|
||||
if isinstance(node, CoreNodeBase) and not nodeutils.is_node(
|
||||
node, NodeTypes.RJ45
|
||||
):
|
||||
if isinstance(node, CoreNodeBase) and not isinstance(node, Rj45Node):
|
||||
# add a control interface if configured
|
||||
logging.info(
|
||||
"booting node(%s): %s",
|
||||
|
@ -1648,8 +1694,7 @@ class Session(object):
|
|||
# no controlnet needed
|
||||
return None
|
||||
else:
|
||||
control_net_class = nodeutils.get_node_class(NodeTypes.CONTROL_NET)
|
||||
prefix_spec = control_net_class.DEFAULT_PREFIX_LIST[net_index]
|
||||
prefix_spec = CtrlNet.DEFAULT_PREFIX_LIST[net_index]
|
||||
logging.debug("prefix spec: %s", prefix_spec)
|
||||
|
||||
server_interface = self.get_control_net_server_interfaces()[net_index]
|
||||
|
@ -1725,9 +1770,8 @@ class Session(object):
|
|||
prefix = prefixes[0]
|
||||
|
||||
logging.info("controlnet prefix: %s - %s", type(prefix), prefix)
|
||||
control_net_class = nodeutils.get_node_class(NodeTypes.CONTROL_NET)
|
||||
control_net = self.create_node(
|
||||
cls=control_net_class,
|
||||
cls=CtrlNet,
|
||||
_id=_id,
|
||||
prefix=prefix,
|
||||
assign_address=assign_address,
|
||||
|
|
|
@ -17,7 +17,7 @@ from socket import AF_INET, AF_INET6
|
|||
from core import CoreCommandError, constants, utils
|
||||
from core.emulator.data import LinkData, NodeData
|
||||
from core.emulator.enumerations import LinkTypes, NodeTypes
|
||||
from core.nodes import client, ipaddress, nodeutils
|
||||
from core.nodes import client, ipaddress
|
||||
from core.nodes.interface import CoreInterface, TunTap, Veth
|
||||
|
||||
_DEFAULT_MTU = 1500
|
||||
|
@ -886,8 +886,8 @@ class CoreNode(CoreNodeBase):
|
|||
addrlist = []
|
||||
|
||||
with self.lock:
|
||||
# TODO: see if you can move this to emane specific code
|
||||
if nodeutils.is_node(net, NodeTypes.EMANE):
|
||||
# TODO: emane specific code
|
||||
if net.is_emane is True:
|
||||
ifindex = self.newtuntap(ifindex=ifindex, ifname=ifname, net=net)
|
||||
# TUN/TAP is not ready for addressing yet; the device may
|
||||
# take some time to appear, and installing it into a
|
||||
|
@ -1050,6 +1050,7 @@ class CoreNetworkBase(NodeBase):
|
|||
"""
|
||||
|
||||
linktype = LinkTypes.WIRED.value
|
||||
is_emane = False
|
||||
|
||||
def __init__(self, session, _id, name, start=True):
|
||||
"""
|
||||
|
|
|
@ -7,8 +7,6 @@ import time
|
|||
from builtins import int, range
|
||||
|
||||
from core import CoreCommandError, constants, utils
|
||||
from core.emulator.enumerations import NodeTypes
|
||||
from core.nodes import nodeutils
|
||||
|
||||
utils.check_executables([constants.IP_BIN])
|
||||
|
||||
|
@ -387,13 +385,12 @@ class TunTap(CoreInterface):
|
|||
if result:
|
||||
break
|
||||
|
||||
# TODO: emane specific code
|
||||
# check if this is an EMANE interface; if so, continue
|
||||
# waiting if EMANE is still running
|
||||
# TODO: remove emane code
|
||||
should_retry = count < 5
|
||||
is_emane_node = nodeutils.is_node(self.net, NodeTypes.EMANE)
|
||||
is_emane_running = self.node.session.emane.emanerunning(self.node)
|
||||
if all([should_retry, is_emane_node, is_emane_running]):
|
||||
if all([should_retry, self.net.is_emane, is_emane_running]):
|
||||
count += 1
|
||||
else:
|
||||
raise RuntimeError("node device failed to exist")
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
"""
|
||||
Provides default node maps that can be used to run core with.
|
||||
"""
|
||||
import core.nodes.base
|
||||
import core.nodes.docker
|
||||
import core.nodes.lxd
|
||||
import core.nodes.network
|
||||
import core.nodes.physical
|
||||
from core.emane.nodes import EmaneNet, EmaneNode
|
||||
from core.emulator.enumerations import NodeTypes
|
||||
from core.nodes import physical
|
||||
from core.nodes.network import GreTapBridge
|
||||
|
||||
# legacy core nodes, that leverage linux bridges
|
||||
NODES = {
|
||||
NodeTypes.DEFAULT: core.nodes.base.CoreNode,
|
||||
NodeTypes.PHYSICAL: physical.PhysicalNode,
|
||||
NodeTypes.TBD: None,
|
||||
NodeTypes.SWITCH: core.nodes.network.SwitchNode,
|
||||
NodeTypes.HUB: core.nodes.network.HubNode,
|
||||
NodeTypes.WIRELESS_LAN: core.nodes.network.WlanNode,
|
||||
NodeTypes.RJ45: core.nodes.physical.Rj45Node,
|
||||
NodeTypes.TUNNEL: core.nodes.network.TunnelNode,
|
||||
NodeTypes.KTUNNEL: None,
|
||||
NodeTypes.EMANE: EmaneNode,
|
||||
NodeTypes.EMANE_NET: EmaneNet,
|
||||
NodeTypes.TAP_BRIDGE: GreTapBridge,
|
||||
NodeTypes.PEER_TO_PEER: core.nodes.network.PtpNet,
|
||||
NodeTypes.CONTROL_NET: core.nodes.network.CtrlNet,
|
||||
NodeTypes.DOCKER: core.nodes.docker.DockerNode,
|
||||
NodeTypes.LXC: core.nodes.lxd.LxcNode,
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
"""
|
||||
Serves as a global point for storing and retrieving node types needed during simulation.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
_NODE_MAP = None
|
||||
|
||||
|
||||
def _log_map():
|
||||
global _NODE_MAP
|
||||
for key in _NODE_MAP:
|
||||
value = _NODE_MAP[key]
|
||||
name = None
|
||||
if value:
|
||||
name = value.__name__
|
||||
logging.debug("node type (%s) - class (%s)", key.name, name)
|
||||
|
||||
|
||||
def _convert_map(x, y):
|
||||
"""
|
||||
Convenience method to create a human readable version of the node map to log.
|
||||
|
||||
:param dict x: dictionary to reduce node items into
|
||||
:param tuple y: current node item
|
||||
:return: human readable name mapping of the node map
|
||||
"""
|
||||
x[y[0].name] = y[1]
|
||||
return x
|
||||
|
||||
|
||||
def update_node_map(node_map):
|
||||
"""
|
||||
Update the current node map with the provided node map values.
|
||||
|
||||
:param dict node_map: node map to update with
|
||||
"""
|
||||
global _NODE_MAP
|
||||
_NODE_MAP.update(node_map)
|
||||
_log_map()
|
||||
|
||||
|
||||
def set_node_map(node_map):
|
||||
"""
|
||||
Set the global node map that proides a consistent way to retrieve differently configured nodes.
|
||||
|
||||
:param dict node_map: node map to set to
|
||||
:return: nothing
|
||||
"""
|
||||
global _NODE_MAP
|
||||
_NODE_MAP = node_map
|
||||
_log_map()
|
||||
|
||||
|
||||
def get_node_class(node_type):
|
||||
"""
|
||||
Retrieve the node class for a given node type.
|
||||
|
||||
:param int node_type: node type to retrieve class for
|
||||
:return: node class
|
||||
"""
|
||||
global _NODE_MAP
|
||||
return _NODE_MAP[node_type]
|
||||
|
||||
|
||||
def get_node_type(node_class):
|
||||
"""
|
||||
Retrieve the node type given a node class.
|
||||
|
||||
:param class node_class: node class to get type for
|
||||
:return: node type
|
||||
:rtype: core.emulator.enumerations.NodeTypes
|
||||
"""
|
||||
global _NODE_MAP
|
||||
node_type_map = {_NODE_MAP[x]: x for x in _NODE_MAP}
|
||||
return node_type_map.get(node_class)
|
||||
|
||||
|
||||
def is_node(obj, node_types):
|
||||
"""
|
||||
Validates if an object is one of the provided node types.
|
||||
|
||||
:param obj: object to check type for
|
||||
:param int|tuple|list node_types: node type(s) to check against
|
||||
:return: True if the object is one of the node types, False otherwise
|
||||
:rtype: bool
|
||||
"""
|
||||
type_classes = []
|
||||
if isinstance(node_types, (tuple, list)):
|
||||
for node_type in node_types:
|
||||
type_class = get_node_class(node_type)
|
||||
type_classes.append(type_class)
|
||||
else:
|
||||
type_class = get_node_class(node_types)
|
||||
type_classes.append(type_class)
|
||||
|
||||
return isinstance(obj, tuple(type_classes))
|
|
@ -8,6 +8,7 @@ import socket
|
|||
from future.moves.urllib.parse import urlparse
|
||||
|
||||
from core import CoreError, constants
|
||||
from core.emane.nodes import EmaneNode
|
||||
from core.emulator.enumerations import (
|
||||
EventTypes,
|
||||
LinkTlvs,
|
||||
|
@ -17,8 +18,8 @@ from core.emulator.enumerations import (
|
|||
NodeTlvs,
|
||||
NodeTypes,
|
||||
)
|
||||
from core.nodes import nodeutils
|
||||
from core.nodes.base import CoreNetworkBase, NodeBase
|
||||
from core.nodes.network import WlanNode
|
||||
|
||||
|
||||
# TODO: A named tuple may be more appropriate, than abusing a class dict like this
|
||||
|
@ -27,14 +28,13 @@ class Bunch(object):
|
|||
Helper class for recording a collection of attributes.
|
||||
"""
|
||||
|
||||
def __init__(self, **kwds):
|
||||
def __init__(self, **kwargs):
|
||||
"""
|
||||
Create a Bunch instance.
|
||||
|
||||
:param dict kwds: keyword arguments
|
||||
:return:
|
||||
:param dict kwargs: keyword arguments
|
||||
"""
|
||||
self.__dict__.update(kwds)
|
||||
self.__dict__.update(kwargs)
|
||||
|
||||
|
||||
class Sdt(object):
|
||||
|
@ -365,9 +365,7 @@ class Sdt(object):
|
|||
for net in nets:
|
||||
all_links = net.all_link_data(flags=MessageFlags.ADD.value)
|
||||
for link_data in all_links:
|
||||
is_wireless = nodeutils.is_node(
|
||||
net, (NodeTypes.WIRELESS_LAN, NodeTypes.EMANE)
|
||||
)
|
||||
is_wireless = isinstance(net, (WlanNode, EmaneNode))
|
||||
wireless_link = link_data.message_type == LinkTypes.WIRELESS.value
|
||||
if is_wireless and link_data.node1_id == net.id:
|
||||
continue
|
||||
|
@ -401,7 +399,7 @@ class Sdt(object):
|
|||
def handlenodemsg(self, msg):
|
||||
"""
|
||||
Process a Node Message to add/delete or move a node on
|
||||
the SDT display. Node properties are found in session._objs or
|
||||
the SDT display. Node properties are found in a session or
|
||||
self.remotes for remote nodes (or those not yet instantiated).
|
||||
|
||||
:param msg: node message to handle
|
||||
|
@ -430,7 +428,8 @@ class Sdt(object):
|
|||
model = "router"
|
||||
nodetype = model
|
||||
elif nodetype is not None:
|
||||
nodetype = nodeutils.get_node_class(NodeTypes(nodetype)).type
|
||||
nodetype = NodeTypes(nodetype)
|
||||
nodetype = self.session.get_node_class(nodetype).type
|
||||
net = True
|
||||
else:
|
||||
nodetype = None
|
||||
|
@ -509,6 +508,6 @@ class Sdt(object):
|
|||
n = self.session.get_node(nodenum)
|
||||
except CoreError:
|
||||
return False
|
||||
if nodeutils.is_node(n, (NodeTypes.WIRELESS_LAN, NodeTypes.EMANE)):
|
||||
if isinstance(n, (WlanNode, EmaneNode)):
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
from core.emulator.enumerations import NodeTypes
|
||||
from core.nodes import nodeutils
|
||||
from core.emane.nodes import EmaneNode
|
||||
from core.services.coreservices import CoreService
|
||||
from core.xml import emanexml
|
||||
|
||||
|
@ -22,7 +21,7 @@ class EmaneTransportService(CoreService):
|
|||
transport_commands = []
|
||||
for interface in node.netifs(sort=True):
|
||||
network_node = node.session.get_node(interface.net.id)
|
||||
if nodeutils.is_node(network_node, NodeTypes.EMANE):
|
||||
if isinstance(network_node, EmaneNode):
|
||||
config = node.session.emane.get_configs(
|
||||
network_node.id, network_node.model.name
|
||||
)
|
||||
|
|
|
@ -4,8 +4,10 @@ Assumes installation of FRR via https://deb.frrouting.org/
|
|||
"""
|
||||
|
||||
from core import constants
|
||||
from core.emulator.enumerations import LinkTypes, NodeTypes
|
||||
from core.nodes import ipaddress, nodeutils
|
||||
from core.emulator.enumerations import LinkTypes
|
||||
from core.nodes import ipaddress
|
||||
from core.nodes.network import PtpNet
|
||||
from core.nodes.physical import Rj45Node
|
||||
from core.services.coreservices import CoreService
|
||||
|
||||
|
||||
|
@ -341,7 +343,7 @@ class FrrService(CoreService):
|
|||
for peerifc in ifc.net.netifs():
|
||||
if peerifc == ifc:
|
||||
continue
|
||||
if nodeutils.is_node(peerifc, NodeTypes.RJ45):
|
||||
if isinstance(peerifc, Rj45Node):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -395,7 +397,7 @@ class FRROspfv2(FrrService):
|
|||
Helper to detect whether interface is connected to a notional
|
||||
point-to-point link.
|
||||
"""
|
||||
if nodeutils.is_node(ifc.net, NodeTypes.PEER_TO_PEER):
|
||||
if isinstance(ifc.net, PtpNet):
|
||||
return " ip ospf network point-to-point\n"
|
||||
return ""
|
||||
|
||||
|
@ -481,7 +483,7 @@ class FRROspfv3(FrrService):
|
|||
Helper to detect whether interface is connected to a notional
|
||||
point-to-point link.
|
||||
"""
|
||||
if nodeutils.is_node(ifc.net, NodeTypes.PEER_TO_PEER):
|
||||
if isinstance(ifc.net, PtpNet):
|
||||
return " ipv6 ospf6 network point-to-point\n"
|
||||
return ""
|
||||
|
||||
|
|
|
@ -3,8 +3,11 @@ quagga.py: defines routing services provided by Quagga.
|
|||
"""
|
||||
|
||||
from core import constants
|
||||
from core.emulator.enumerations import LinkTypes, NodeTypes
|
||||
from core.nodes import ipaddress, nodeutils
|
||||
from core.emane.nodes import EmaneNode
|
||||
from core.emulator.enumerations import LinkTypes
|
||||
from core.nodes import ipaddress
|
||||
from core.nodes.network import PtpNet, WlanNode
|
||||
from core.nodes.physical import Rj45Node
|
||||
from core.services.coreservices import CoreService
|
||||
|
||||
|
||||
|
@ -267,7 +270,7 @@ class QuaggaService(CoreService):
|
|||
for peerifc in ifc.net.netifs():
|
||||
if peerifc == ifc:
|
||||
continue
|
||||
if nodeutils.is_node(peerifc, NodeTypes.RJ45):
|
||||
if isinstance(peerifc, Rj45Node):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -321,7 +324,7 @@ class Ospfv2(QuaggaService):
|
|||
Helper to detect whether interface is connected to a notional
|
||||
point-to-point link.
|
||||
"""
|
||||
if nodeutils.is_node(ifc.net, NodeTypes.PEER_TO_PEER):
|
||||
if isinstance(ifc.net, PtpNet):
|
||||
return " ip ospf network point-to-point\n"
|
||||
return ""
|
||||
|
||||
|
@ -407,7 +410,7 @@ class Ospfv3(QuaggaService):
|
|||
Helper to detect whether interface is connected to a notional
|
||||
point-to-point link.
|
||||
"""
|
||||
if nodeutils.is_node(ifc.net, NodeTypes.PEER_TO_PEER):
|
||||
if isinstance(ifc.net, PtpNet):
|
||||
return " ipv6 ospf6 network point-to-point\n"
|
||||
return ""
|
||||
|
||||
|
@ -457,9 +460,7 @@ class Ospfv3mdr(Ospfv3):
|
|||
cfg = cls.mtucheck(ifc)
|
||||
# Uncomment the following line to use Address Family Translation for IPv4
|
||||
cfg += " ipv6 ospf6 instance-id 65\n"
|
||||
if ifc.net is not None and nodeutils.is_node(
|
||||
ifc.net, (NodeTypes.WIRELESS_LAN, NodeTypes.EMANE)
|
||||
):
|
||||
if ifc.net is not None and isinstance(ifc.net, (WlanNode, EmaneNode)):
|
||||
return (
|
||||
cfg
|
||||
+ """\
|
||||
|
|
|
@ -4,11 +4,12 @@ from lxml import etree
|
|||
|
||||
import core.nodes.base
|
||||
import core.nodes.physical
|
||||
from core.emane.nodes import EmaneNode
|
||||
from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions
|
||||
from core.emulator.enumerations import NodeTypes
|
||||
from core.nodes import nodeutils
|
||||
from core.nodes.base import CoreNetworkBase
|
||||
from core.nodes.ipaddress import MacAddress
|
||||
from core.nodes.network import CtrlNet
|
||||
|
||||
|
||||
def write_xml_file(xml_element, file_path, doctype=None):
|
||||
|
@ -408,7 +409,7 @@ class CoreXmlWriter(object):
|
|||
is_network_or_rj45 = isinstance(
|
||||
node, (core.nodes.base.CoreNetworkBase, core.nodes.physical.Rj45Node)
|
||||
)
|
||||
is_controlnet = nodeutils.is_node(node, NodeTypes.CONTROL_NET)
|
||||
is_controlnet = isinstance(node, CtrlNet)
|
||||
if is_network_or_rj45 and not is_controlnet:
|
||||
self.write_network(node)
|
||||
# device node
|
||||
|
@ -457,7 +458,7 @@ class CoreXmlWriter(object):
|
|||
interface_name = node_interface.name
|
||||
|
||||
# check if emane interface
|
||||
if nodeutils.is_node(node_interface.net, NodeTypes.EMANE):
|
||||
if isinstance(node_interface.net, EmaneNode):
|
||||
nem = node_interface.net.getnemid(node_interface)
|
||||
add_attribute(interface, "nem", nem)
|
||||
|
||||
|
|
|
@ -4,8 +4,8 @@ import socket
|
|||
from lxml import etree
|
||||
|
||||
from core import constants, utils
|
||||
from core.emulator.enumerations import NodeTypes
|
||||
from core.nodes import ipaddress, nodeutils
|
||||
from core.emane.nodes import EmaneNode
|
||||
from core.nodes import ipaddress
|
||||
from core.nodes.base import CoreNodeBase
|
||||
|
||||
|
||||
|
@ -144,7 +144,7 @@ class CoreXmlDeployment(object):
|
|||
|
||||
for netif in node.netifs():
|
||||
emane_element = None
|
||||
if nodeutils.is_node(netif.net, NodeTypes.EMANE):
|
||||
if isinstance(netif.net, EmaneNode):
|
||||
emane_element = add_emane_interface(host_element, netif)
|
||||
|
||||
parent_element = host_element
|
||||
|
|
|
@ -60,9 +60,6 @@ def cored(cfg, use_ovs):
|
|||
try:
|
||||
address = (host, port)
|
||||
server = CoreServer(address, CoreHandler, cfg)
|
||||
if use_ovs:
|
||||
from core.nodes.openvswitch import OVS_NODES
|
||||
server.coreemu.update_nodes(OVS_NODES)
|
||||
except:
|
||||
logging.exception("error starting main server on: %s:%s", host, port)
|
||||
sys.exit(1)
|
||||
|
|
|
@ -10,17 +10,16 @@ import sys
|
|||
|
||||
import ns.core
|
||||
import ns.mobility
|
||||
|
||||
from core.nodes import nodeutils, nodemaps, ipaddress
|
||||
from corens3.obj import Ns3LteNet
|
||||
from corens3.obj import Ns3Session
|
||||
|
||||
from core.nodes import ipaddress
|
||||
|
||||
|
||||
def ltesession(opt):
|
||||
"""
|
||||
Run a test LTE session.
|
||||
"""
|
||||
nodeutils.set_node_map(nodemaps.NODES)
|
||||
session = Ns3Session(1, persistent=True, duration=opt.duration)
|
||||
lte = session.create_node(cls=Ns3LteNet, name="wlan1")
|
||||
lte.setsubchannels(range(25), range(50, 100))
|
||||
|
|
|
@ -27,11 +27,11 @@ import optparse
|
|||
import sys
|
||||
|
||||
import ns.core
|
||||
|
||||
from core.nodes import nodeutils, nodemaps, ipaddress
|
||||
from corens3.obj import Ns3Session
|
||||
from corens3.obj import Ns3WifiNet
|
||||
|
||||
from core.nodes import ipaddress
|
||||
|
||||
|
||||
def add_to_server(session):
|
||||
"""
|
||||
|
@ -50,7 +50,6 @@ def wifisession(opt):
|
|||
"""
|
||||
Run a test wifi session.
|
||||
"""
|
||||
nodeutils.set_node_map(nodemaps.NODES)
|
||||
session = Ns3Session(1, persistent=True, duration=opt.duration)
|
||||
session.name = "ns3wifi"
|
||||
session.filename = session.name + ".py"
|
||||
|
|
|
@ -14,13 +14,14 @@ How to run this:
|
|||
import logging
|
||||
import optparse
|
||||
import sys
|
||||
from builtins import range
|
||||
|
||||
import ns.core
|
||||
import ns.network
|
||||
from corens3.obj import Ns3Session
|
||||
from corens3.obj import Ns3WifiNet
|
||||
|
||||
from core.nodes import nodeutils, nodemaps, ipaddress
|
||||
from core.nodes import ipaddress
|
||||
|
||||
|
||||
def add_to_server(session):
|
||||
|
@ -40,7 +41,6 @@ def wifisession(opt):
|
|||
"""
|
||||
Run a random walk wifi session.
|
||||
"""
|
||||
nodeutils.set_node_map(nodemaps.NODES)
|
||||
session = Ns3Session(1, persistent=True, duration=opt.duration)
|
||||
session.name = "ns3wifirandomwalk"
|
||||
session.filename = session.name + ".py"
|
||||
|
@ -54,7 +54,7 @@ def wifisession(opt):
|
|||
prefix = ipaddress.Ipv4Prefix("10.0.0.0/16")
|
||||
services_str = "zebra|OSPFv3MDR|IPForward"
|
||||
nodes = []
|
||||
for i in xrange(1, opt.numnodes + 1):
|
||||
for i in range(1, opt.numnodes + 1):
|
||||
node = session.addnode(name="n%d" % i)
|
||||
node.newnetif(wifi, ["%s/%s" % (prefix.addr(i), prefix.prefixlen)])
|
||||
nodes.append(node)
|
||||
|
|
|
@ -12,17 +12,18 @@ Current issues:
|
|||
import logging
|
||||
import optparse
|
||||
import sys
|
||||
from builtins import range
|
||||
|
||||
from core.nodes import nodeutils, nodemaps, ipaddress
|
||||
from corens3.obj import Ns3Session
|
||||
from corens3.obj import Ns3WimaxNet
|
||||
|
||||
from core.nodes import ipaddress
|
||||
|
||||
|
||||
def wimaxsession(opt):
|
||||
"""
|
||||
Run a test wimax session.
|
||||
"""
|
||||
nodeutils.set_node_map(nodemaps.NODES)
|
||||
session = Ns3Session(1, persistent=True, duration=opt.duration)
|
||||
wimax = session.create_node(cls=Ns3WimaxNet, name="wlan1")
|
||||
# wimax.wimax.EnableLogComponents()
|
||||
|
@ -33,7 +34,7 @@ def wimaxsession(opt):
|
|||
# classifier = (0, 65000, 0, 65000, 1, 1)
|
||||
classifier = (0, 65000, 0, 65000, 17, 1)
|
||||
nodes = []
|
||||
for i in xrange(1, opt.numnodes + 1):
|
||||
for i in range(1, opt.numnodes + 1):
|
||||
node = session.addnode(name="n%d" % i)
|
||||
if i == 1:
|
||||
wimax.setbasestation(node)
|
||||
|
|
Loading…
Reference in a new issue