daemon: initial changes to rework logic to start emane for a given interface
This commit is contained in:
parent
da9c0d0660
commit
bd48e14348
6 changed files with 262 additions and 496 deletions
|
@ -10,6 +10,7 @@ from core.config import Configuration
|
|||
from core.emane.nodes import EmaneNet
|
||||
from core.emulator.distributed import DistributedServer
|
||||
from core.emulator.enumerations import TransportType
|
||||
from core.errors import CoreError
|
||||
from core.nodes.interface import CoreInterface
|
||||
from core.nodes.network import CtrlNet
|
||||
from core.xml import corexml
|
||||
|
@ -40,15 +41,11 @@ def _value_to_params(value: str) -> Optional[Tuple[str]]:
|
|||
"""
|
||||
try:
|
||||
values = utils.make_tuple_fromstr(value, str)
|
||||
|
||||
if not hasattr(values, "__iter__"):
|
||||
return None
|
||||
|
||||
if len(values) < 2:
|
||||
return None
|
||||
|
||||
return values
|
||||
|
||||
except SyntaxError:
|
||||
logging.exception("error in value string to param list")
|
||||
return None
|
||||
|
@ -127,13 +124,13 @@ def add_configurations(
|
|||
add_param(xml_element, name, value)
|
||||
|
||||
|
||||
def build_node_platform_xml(
|
||||
def build_platform_xml(
|
||||
emane_manager: "EmaneManager",
|
||||
control_net: CtrlNet,
|
||||
node: EmaneNet,
|
||||
emane_net: EmaneNet,
|
||||
iface: CoreInterface,
|
||||
nem_id: int,
|
||||
platform_xmls: Dict[str, etree.Element],
|
||||
) -> int:
|
||||
) -> None:
|
||||
"""
|
||||
Create platform xml for a specific node.
|
||||
|
||||
|
@ -141,175 +138,121 @@ def build_node_platform_xml(
|
|||
configurations
|
||||
:param control_net: control net node for this emane
|
||||
network
|
||||
:param node: node to write platform xml for
|
||||
:param nem_id: nem id to use for interfaces for this node
|
||||
:param platform_xmls: stores platform xml elements to append nem entries to
|
||||
:param emane_net: emane network associated with interface
|
||||
:param iface: interface running emane
|
||||
:param nem_id: nem id to use for this interface
|
||||
:return: the next nem id that can be used for creating platform xml files
|
||||
"""
|
||||
logging.debug(
|
||||
"building emane platform xml for node(%s) nem_id(%s): %s",
|
||||
node,
|
||||
nem_id,
|
||||
node.name,
|
||||
# build nem xml
|
||||
nem_definition = nem_file_name(iface)
|
||||
nem_element = etree.Element(
|
||||
"nem", id=str(nem_id), name=iface.localname, definition=nem_definition
|
||||
)
|
||||
nem_entries = {}
|
||||
|
||||
if node.model is None:
|
||||
logging.warning("warning: EMANE network %s has no associated model", node.name)
|
||||
return nem_id
|
||||
|
||||
for iface in node.get_ifaces():
|
||||
logging.debug(
|
||||
"building platform xml for interface(%s) nem_id(%s)", iface.name, nem_id
|
||||
)
|
||||
# build nem xml
|
||||
nem_definition = nem_file_name(node.model, iface)
|
||||
nem_element = etree.Element(
|
||||
"nem", id=str(nem_id), name=iface.localname, definition=nem_definition
|
||||
# check if this is an external transport, get default config if an interface
|
||||
# specific one does not exist
|
||||
config = emane_manager.get_iface_config(emane_net, iface)
|
||||
if is_external(config):
|
||||
nem_element.set("transport", "external")
|
||||
platform_endpoint = "platformendpoint"
|
||||
add_param(nem_element, platform_endpoint, config[platform_endpoint])
|
||||
transport_endpoint = "transportendpoint"
|
||||
add_param(nem_element, transport_endpoint, config[transport_endpoint])
|
||||
else:
|
||||
# build transport xml
|
||||
transport_type = iface.transport_type
|
||||
if not transport_type:
|
||||
logging.info("warning: %s interface type unsupported!", iface.name)
|
||||
transport_type = TransportType.RAW
|
||||
transport_file = transport_file_name(iface, transport_type)
|
||||
transport_element = etree.SubElement(
|
||||
nem_element, "transport", definition=transport_file
|
||||
)
|
||||
add_param(transport_element, "device", iface.name)
|
||||
|
||||
# check if this is an external transport, get default config if an interface
|
||||
# specific one does not exist
|
||||
config = emane_manager.get_iface_config(node.model.id, iface, node.model.name)
|
||||
|
||||
if is_external(config):
|
||||
nem_element.set("transport", "external")
|
||||
platform_endpoint = "platformendpoint"
|
||||
add_param(nem_element, platform_endpoint, config[platform_endpoint])
|
||||
transport_endpoint = "transportendpoint"
|
||||
add_param(nem_element, transport_endpoint, config[transport_endpoint])
|
||||
else:
|
||||
# build transport xml
|
||||
transport_type = iface.transport_type
|
||||
if not transport_type:
|
||||
logging.info("warning: %s interface type unsupported!", iface.name)
|
||||
transport_type = TransportType.RAW
|
||||
transport_file = transport_file_name(node.id, transport_type)
|
||||
transport_element = etree.SubElement(
|
||||
nem_element, "transport", definition=transport_file
|
||||
)
|
||||
|
||||
# add transport parameter
|
||||
add_param(transport_element, "device", iface.name)
|
||||
|
||||
# add nem entry
|
||||
nem_entries[iface] = nem_element
|
||||
|
||||
# merging code
|
||||
key = iface.node.id
|
||||
if iface.transport_type == TransportType.RAW:
|
||||
key = "host"
|
||||
otadev = control_net.brname
|
||||
eventdev = control_net.brname
|
||||
else:
|
||||
otadev = None
|
||||
eventdev = None
|
||||
|
||||
platform_element = platform_xmls.get(key)
|
||||
if platform_element is None:
|
||||
platform_element = etree.Element("platform")
|
||||
|
||||
if otadev:
|
||||
emane_manager.set_config("otamanagerdevice", otadev)
|
||||
|
||||
if eventdev:
|
||||
emane_manager.set_config("eventservicedevice", eventdev)
|
||||
|
||||
# append all platform options (except starting id) to doc
|
||||
for configuration in emane_manager.emane_config.emulator_config:
|
||||
name = configuration.id
|
||||
if name == "platform_id_start":
|
||||
continue
|
||||
|
||||
value = emane_manager.get_config(name)
|
||||
add_param(platform_element, name, value)
|
||||
|
||||
# add platform xml
|
||||
platform_xmls[key] = platform_element
|
||||
|
||||
platform_element.append(nem_element)
|
||||
|
||||
node.setnemid(iface, nem_id)
|
||||
mac = _MAC_PREFIX + ":00:00:"
|
||||
mac += f"{(nem_id >> 8) & 0xFF:02X}:{nem_id & 0xFF:02X}"
|
||||
iface.set_mac(mac)
|
||||
|
||||
# increment nem id
|
||||
nem_id += 1
|
||||
# determine platform element to add xml to
|
||||
key = iface.node.id
|
||||
if iface.transport_type == TransportType.RAW:
|
||||
key = "host"
|
||||
otadev = control_net.brname
|
||||
eventdev = control_net.brname
|
||||
else:
|
||||
otadev = None
|
||||
eventdev = None
|
||||
platform_element = etree.Element("platform")
|
||||
if otadev:
|
||||
emane_manager.set_config("otamanagerdevice", otadev)
|
||||
if eventdev:
|
||||
emane_manager.set_config("eventservicedevice", eventdev)
|
||||
for configuration in emane_manager.emane_config.emulator_config:
|
||||
name = configuration.id
|
||||
value = emane_manager.get_config(name)
|
||||
add_param(platform_element, name, value)
|
||||
platform_element.append(nem_element)
|
||||
emane_net.setnemid(iface, nem_id)
|
||||
mac = _MAC_PREFIX + ":00:00:"
|
||||
mac += f"{(nem_id >> 8) & 0xFF:02X}:{nem_id & 0xFF:02X}"
|
||||
iface.set_mac(mac)
|
||||
|
||||
doc_name = "platform"
|
||||
for key in sorted(platform_xmls.keys()):
|
||||
platform_element = platform_xmls[key]
|
||||
if key == "host":
|
||||
file_name = "platform.xml"
|
||||
file_path = os.path.join(emane_manager.session.session_dir, file_name)
|
||||
create_file(platform_element, doc_name, file_path)
|
||||
else:
|
||||
file_name = f"platform{key}.xml"
|
||||
file_path = os.path.join(emane_manager.session.session_dir, file_name)
|
||||
linked_node = emane_manager.session.nodes[key]
|
||||
create_file(platform_element, doc_name, file_path, linked_node.server)
|
||||
|
||||
return nem_id
|
||||
server = None
|
||||
if key == "host":
|
||||
file_name = "platform.xml"
|
||||
file_path = os.path.join(emane_manager.session.session_dir, file_name)
|
||||
else:
|
||||
node = iface.node
|
||||
file_name = f"{iface.name}-platform.xml"
|
||||
file_path = os.path.join(node.nodedir, file_name)
|
||||
server = node.server
|
||||
create_file(platform_element, doc_name, file_path, server)
|
||||
|
||||
|
||||
def build_xml_files(emane_manager: "EmaneManager", node: EmaneNet) -> None:
|
||||
def build_model_xmls(
|
||||
manager: "EmaneManager", emane_net: EmaneNet, iface: CoreInterface
|
||||
) -> None:
|
||||
"""
|
||||
Generate emane xml files required for node.
|
||||
|
||||
:param emane_manager: emane manager with emane
|
||||
:param manager: emane manager with emane
|
||||
configurations
|
||||
:param node: node to write platform xml for
|
||||
:param emane_net: emane network associated with interface
|
||||
:param iface: interface to create emane xml for
|
||||
:return: nothing
|
||||
"""
|
||||
logging.debug("building all emane xml for node(%s): %s", node, node.name)
|
||||
if node.model is None:
|
||||
return
|
||||
|
||||
# get model configurations
|
||||
config = emane_manager.get_configs(node.model.id, node.model.name)
|
||||
if not config:
|
||||
return
|
||||
|
||||
# build XML for overall network EMANE configs
|
||||
node.model.build_xml_files(config)
|
||||
|
||||
# build XML for specific interface (NEM) configs
|
||||
# check for interface specific emane configuration and write xml files
|
||||
config = manager.get_iface_config(emane_net, iface)
|
||||
emane_net.model.build_xml_files(config, iface)
|
||||
|
||||
# check transport type needed for interface
|
||||
need_virtual = False
|
||||
need_raw = False
|
||||
vtype = TransportType.VIRTUAL
|
||||
rtype = TransportType.RAW
|
||||
|
||||
for iface in node.get_ifaces():
|
||||
# check for interface specific emane configuration and write xml files
|
||||
config = emane_manager.get_iface_config(node.model.id, iface, node.model.name)
|
||||
if config:
|
||||
node.model.build_xml_files(config, iface)
|
||||
|
||||
# check transport type needed for interface
|
||||
if iface.transport_type == TransportType.VIRTUAL:
|
||||
need_virtual = True
|
||||
vtype = iface.transport_type
|
||||
else:
|
||||
need_raw = True
|
||||
rtype = iface.transport_type
|
||||
|
||||
if iface.transport_type == TransportType.VIRTUAL:
|
||||
need_virtual = True
|
||||
vtype = iface.transport_type
|
||||
else:
|
||||
need_raw = True
|
||||
rtype = iface.transport_type
|
||||
if need_virtual:
|
||||
build_transport_xml(emane_manager, node, vtype)
|
||||
|
||||
build_transport_xml(manager, emane_net, iface, vtype)
|
||||
if need_raw:
|
||||
build_transport_xml(emane_manager, node, rtype)
|
||||
build_transport_xml(manager, emane_net, iface, rtype)
|
||||
|
||||
|
||||
def build_transport_xml(
|
||||
emane_manager: "EmaneManager", node: EmaneNet, transport_type: TransportType
|
||||
manager: "EmaneManager",
|
||||
emane_net: EmaneNet,
|
||||
iface: CoreInterface,
|
||||
transport_type: TransportType,
|
||||
) -> None:
|
||||
"""
|
||||
Build transport xml file for node and transport type.
|
||||
|
||||
:param emane_manager: emane manager with emane
|
||||
configurations
|
||||
:param node: node to write platform xml for
|
||||
:param manager: emane manager with emane configurations
|
||||
:param emane_net: emane network associated with interface
|
||||
:param iface: interface to build transport xml for
|
||||
:param transport_type: transport type to build xml for
|
||||
:return: nothing
|
||||
"""
|
||||
|
@ -318,28 +261,24 @@ def build_transport_xml(
|
|||
name=f"{transport_type.value.capitalize()} Transport",
|
||||
library=f"trans{transport_type.value.lower()}",
|
||||
)
|
||||
|
||||
# add bitrate
|
||||
add_param(transport_element, "bitrate", "0")
|
||||
|
||||
# get emane model cnfiguration
|
||||
config = emane_manager.get_configs(node.id, node.model.name)
|
||||
config = manager.get_iface_config(emane_net, iface)
|
||||
flowcontrol = config.get("flowcontrolenable", "0") == "1"
|
||||
|
||||
if transport_type == TransportType.VIRTUAL:
|
||||
device_path = "/dev/net/tun_flowctl"
|
||||
if not os.path.exists(device_path):
|
||||
device_path = "/dev/net/tun"
|
||||
add_param(transport_element, "devicepath", device_path)
|
||||
|
||||
if flowcontrol:
|
||||
add_param(transport_element, "flowcontrolenable", "on")
|
||||
|
||||
doc_name = "transport"
|
||||
file_name = transport_file_name(node.id, transport_type)
|
||||
file_path = os.path.join(emane_manager.session.session_dir, file_name)
|
||||
node = iface.node
|
||||
file_name = transport_file_name(iface, transport_type)
|
||||
file_path = os.path.join(node.nodedir, file_name)
|
||||
create_file(transport_element, doc_name, file_path)
|
||||
emane_manager.session.distributed.execute(
|
||||
manager.session.distributed.execute(
|
||||
lambda x: create_file(transport_element, doc_name, file_path, x)
|
||||
)
|
||||
|
||||
|
@ -348,7 +287,7 @@ def create_phy_xml(
|
|||
emane_model: "EmaneModel",
|
||||
config: Dict[str, str],
|
||||
file_path: str,
|
||||
server: DistributedServer,
|
||||
server: Optional[DistributedServer],
|
||||
) -> None:
|
||||
"""
|
||||
Create the phy xml document.
|
||||
|
@ -363,25 +302,17 @@ def create_phy_xml(
|
|||
phy_element = etree.Element("phy", name=f"{emane_model.name} PHY")
|
||||
if emane_model.phy_library:
|
||||
phy_element.set("library", emane_model.phy_library)
|
||||
|
||||
add_configurations(
|
||||
phy_element, emane_model.phy_config, config, emane_model.config_ignore
|
||||
)
|
||||
create_file(phy_element, "phy", file_path)
|
||||
if server is not None:
|
||||
create_file(phy_element, "phy", file_path, server)
|
||||
else:
|
||||
create_file(phy_element, "phy", file_path)
|
||||
emane_model.session.distributed.execute(
|
||||
lambda x: create_file(phy_element, "phy", file_path, x)
|
||||
)
|
||||
create_file(phy_element, "phy", file_path, server)
|
||||
|
||||
|
||||
def create_mac_xml(
|
||||
emane_model: "EmaneModel",
|
||||
config: Dict[str, str],
|
||||
file_path: str,
|
||||
server: DistributedServer,
|
||||
server: Optional[DistributedServer],
|
||||
) -> None:
|
||||
"""
|
||||
Create the mac xml document.
|
||||
|
@ -394,22 +325,14 @@ def create_mac_xml(
|
|||
:return: nothing
|
||||
"""
|
||||
if not emane_model.mac_library:
|
||||
raise ValueError("must define emane model library")
|
||||
|
||||
raise CoreError("must define emane model library")
|
||||
mac_element = etree.Element(
|
||||
"mac", name=f"{emane_model.name} MAC", library=emane_model.mac_library
|
||||
)
|
||||
add_configurations(
|
||||
mac_element, emane_model.mac_config, config, emane_model.config_ignore
|
||||
)
|
||||
create_file(mac_element, "mac", file_path)
|
||||
if server is not None:
|
||||
create_file(mac_element, "mac", file_path, server)
|
||||
else:
|
||||
create_file(mac_element, "mac", file_path)
|
||||
emane_model.session.distributed.execute(
|
||||
lambda x: create_file(mac_element, "mac", file_path, x)
|
||||
)
|
||||
create_file(mac_element, "mac", file_path, server)
|
||||
|
||||
|
||||
def create_nem_xml(
|
||||
|
@ -419,7 +342,7 @@ def create_nem_xml(
|
|||
transport_definition: str,
|
||||
mac_definition: str,
|
||||
phy_definition: str,
|
||||
server: DistributedServer,
|
||||
server: Optional[DistributedServer],
|
||||
) -> None:
|
||||
"""
|
||||
Create the nem xml document.
|
||||
|
@ -441,13 +364,7 @@ def create_nem_xml(
|
|||
etree.SubElement(nem_element, "transport", definition=transport_definition)
|
||||
etree.SubElement(nem_element, "mac", definition=mac_definition)
|
||||
etree.SubElement(nem_element, "phy", definition=phy_definition)
|
||||
if server is not None:
|
||||
create_file(nem_element, "nem", nem_file, server)
|
||||
else:
|
||||
create_file(nem_element, "nem", nem_file)
|
||||
emane_model.session.distributed.execute(
|
||||
lambda x: create_file(nem_element, "nem", nem_file, x)
|
||||
)
|
||||
create_file(nem_element, "nem", nem_file, server)
|
||||
|
||||
|
||||
def create_event_service_xml(
|
||||
|
@ -483,81 +400,55 @@ def create_event_service_xml(
|
|||
create_file(event_element, "emaneeventmsgsvc", file_path, server)
|
||||
|
||||
|
||||
def transport_file_name(node_id: int, transport_type: TransportType) -> str:
|
||||
def transport_file_name(iface: CoreInterface, transport_type: TransportType) -> str:
|
||||
"""
|
||||
Create name for a transport xml file.
|
||||
|
||||
:param node_id: node id to generate transport file name for
|
||||
:param iface: interface running emane
|
||||
:param transport_type: transport type to generate transport file
|
||||
:return:
|
||||
:return: transport xml file name
|
||||
"""
|
||||
return f"n{node_id}trans{transport_type.value}.xml"
|
||||
return f"{iface.name}-trans-{transport_type.value}.xml"
|
||||
|
||||
|
||||
def _basename(emane_model: "EmaneModel", iface: CoreInterface = None) -> str:
|
||||
def nem_file_name(iface: CoreInterface) -> str:
|
||||
"""
|
||||
Create name that is leveraged for configuration file creation.
|
||||
Return the string name for the NEM XML file, e.g. "eth0-nem.xml"
|
||||
|
||||
:param emane_model: emane model to create name for
|
||||
:param iface: interface for this model
|
||||
:return: basename used for file creation
|
||||
:param iface: interface running emane
|
||||
:return: nem xm file name
|
||||
"""
|
||||
name = f"n{emane_model.id}"
|
||||
|
||||
if iface:
|
||||
node_id = iface.node.id
|
||||
if emane_model.session.emane.get_iface_config(node_id, iface, emane_model.name):
|
||||
name = iface.localname.replace(".", "_")
|
||||
|
||||
return f"{name}{emane_model.name}"
|
||||
|
||||
|
||||
def nem_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str:
|
||||
"""
|
||||
Return the string name for the NEM XML file, e.g. "n3rfpipenem.xml"
|
||||
|
||||
:param emane_model: emane model to create file
|
||||
:param iface: interface for this model
|
||||
:return: nem xml filename
|
||||
"""
|
||||
basename = _basename(emane_model, iface)
|
||||
append = ""
|
||||
if iface and iface.transport_type == TransportType.RAW:
|
||||
append = "_raw"
|
||||
return f"{basename}nem{append}.xml"
|
||||
append = "-raw"
|
||||
return f"{iface.name}-nem{append}.xml"
|
||||
|
||||
|
||||
def shim_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str:
|
||||
def shim_file_name(iface: CoreInterface = None) -> str:
|
||||
"""
|
||||
Return the string name for the SHIM XML file, e.g. "commeffectshim.xml"
|
||||
Return the string name for the SHIM XML file, e.g. "eth0-shim.xml"
|
||||
|
||||
:param emane_model: emane model to create file
|
||||
:param iface: interface for this model
|
||||
:return: shim xml filename
|
||||
:param iface: interface running emane
|
||||
:return: shim xml file name
|
||||
"""
|
||||
name = _basename(emane_model, iface)
|
||||
return f"{name}shim.xml"
|
||||
return f"{iface.name}-shim.xml"
|
||||
|
||||
|
||||
def mac_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str:
|
||||
def mac_file_name(iface: CoreInterface) -> str:
|
||||
"""
|
||||
Return the string name for the MAC XML file, e.g. "n3rfpipemac.xml"
|
||||
Return the string name for the MAC XML file, e.g. "eth0-mac.xml"
|
||||
|
||||
:param emane_model: emane model to create file
|
||||
:param iface: interface for this model
|
||||
:return: mac xml filename
|
||||
:param iface: interface running emane
|
||||
:return: mac xml file name
|
||||
"""
|
||||
name = _basename(emane_model, iface)
|
||||
return f"{name}mac.xml"
|
||||
return f"{iface.name}-mac.xml"
|
||||
|
||||
|
||||
def phy_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str:
|
||||
def phy_file_name(iface: CoreInterface) -> str:
|
||||
"""
|
||||
Return the string name for the PHY XML file, e.g. "n3rfpipephy.xml"
|
||||
Return the string name for the PHY XML file, e.g. "eth0-phy.xml"
|
||||
|
||||
:param emane_model: emane model to create file
|
||||
:param iface: interface for this model
|
||||
:return: phy xml filename
|
||||
:param iface: interface running emane
|
||||
:return: phy xml file name
|
||||
"""
|
||||
name = _basename(emane_model, iface)
|
||||
return f"{name}phy.xml"
|
||||
return f"{iface.name}-phy.xml"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue