diff --git a/daemon/core/api/grpc/client.py b/daemon/core/api/grpc/client.py index 3a16d4fd..db908e05 100644 --- a/daemon/core/api/grpc/client.py +++ b/daemon/core/api/grpc/client.py @@ -92,7 +92,7 @@ from core.api.grpc.wlan_pb2 import ( WlanLinkRequest, WlanLinkResponse, ) -from core.emulator.emudata import IpPrefixes +from core.emulator.data import IpPrefixes class InterfaceHelper: @@ -110,27 +110,27 @@ class InterfaceHelper: """ self.prefixes: IpPrefixes = IpPrefixes(ip4_prefix, ip6_prefix) - def create_interface( - self, node_id: int, interface_id: int, name: str = None, mac: str = None + def create_iface( + self, node_id: int, iface_id: int, name: str = None, mac: str = None ) -> core_pb2.Interface: """ Create an interface protobuf object. :param node_id: node id to create interface for - :param interface_id: interface id + :param iface_id: interface id :param name: name of interface :param mac: mac address for interface :return: interface protobuf """ - interface_data = self.prefixes.gen_interface(node_id, name, mac) + iface_data = self.prefixes.gen_iface(node_id, name, mac) return core_pb2.Interface( - id=interface_id, - name=interface_data.name, - ip4=interface_data.ip4, - ip4mask=interface_data.ip4_mask, - ip6=interface_data.ip6, - ip6mask=interface_data.ip6_mask, - mac=interface_data.mac, + id=iface_id, + name=iface_data.name, + ip4=iface_data.ip4, + ip4_mask=iface_data.ip4_mask, + ip6=iface_data.ip6, + ip6_mask=iface_data.ip6_mask, + mac=iface_data.mac, ) @@ -611,8 +611,8 @@ class CoreGrpcClient: session_id: int, node1_id: int, node2_id: int, - interface1: core_pb2.Interface = None, - interface2: core_pb2.Interface = None, + iface1: core_pb2.Interface = None, + iface2: core_pb2.Interface = None, options: core_pb2.LinkOptions = None, ) -> core_pb2.AddLinkResponse: """ @@ -621,8 +621,8 @@ class CoreGrpcClient: :param session_id: session id :param node1_id: node one id :param node2_id: node two id - :param interface1: node one interface data - :param interface2: node two interface data + :param iface1: node one interface data + :param iface2: node two interface data :param options: options for link (jitter, bandwidth, etc) :return: response with result of success or failure :raises grpc.RpcError: when session or one of the nodes don't exist @@ -631,8 +631,8 @@ class CoreGrpcClient: node1_id=node1_id, node2_id=node2_id, type=core_pb2.LinkType.WIRED, - interface1=interface1, - interface2=interface2, + iface1=iface1, + iface2=iface2, options=options, ) request = core_pb2.AddLinkRequest(session_id=session_id, link=link) @@ -644,8 +644,8 @@ class CoreGrpcClient: node1_id: int, node2_id: int, options: core_pb2.LinkOptions, - interface1_id: int = None, - interface2_id: int = None, + iface1_id: int = None, + iface2_id: int = None, ) -> core_pb2.EditLinkResponse: """ Edit a link between nodes. @@ -654,8 +654,8 @@ class CoreGrpcClient: :param node1_id: node one id :param node2_id: node two id :param options: options for link (jitter, bandwidth, etc) - :param interface1_id: node one interface id - :param interface2_id: node two interface id + :param iface1_id: node one interface id + :param iface2_id: node two interface id :return: response with result of success or failure :raises grpc.RpcError: when session or one of the nodes don't exist """ @@ -664,8 +664,8 @@ class CoreGrpcClient: node1_id=node1_id, node2_id=node2_id, options=options, - interface1_id=interface1_id, - interface2_id=interface2_id, + iface1_id=iface1_id, + iface2_id=iface2_id, ) return self.stub.EditLink(request) @@ -674,8 +674,8 @@ class CoreGrpcClient: session_id: int, node1_id: int, node2_id: int, - interface1_id: int = None, - interface2_id: int = None, + iface1_id: int = None, + iface2_id: int = None, ) -> core_pb2.DeleteLinkResponse: """ Delete a link between nodes. @@ -683,8 +683,8 @@ class CoreGrpcClient: :param session_id: session id :param node1_id: node one id :param node2_id: node two id - :param interface1_id: node one interface id - :param interface2_id: node two interface id + :param iface1_id: node one interface id + :param iface2_id: node two interface id :return: response with result of success or failure :raises grpc.RpcError: when session doesn't exist """ @@ -692,8 +692,8 @@ class CoreGrpcClient: session_id=session_id, node1_id=node1_id, node2_id=node2_id, - interface1_id=interface1_id, - interface2_id=interface2_id, + iface1_id=iface1_id, + iface2_id=iface2_id, ) return self.stub.DeleteLink(request) @@ -1028,7 +1028,7 @@ class CoreGrpcClient: return self.stub.GetEmaneModels(request) def get_emane_model_config( - self, session_id: int, node_id: int, model: str, interface_id: int = -1 + self, session_id: int, node_id: int, model: str, iface_id: int = -1 ) -> GetEmaneModelConfigResponse: """ Get emane model configuration for a node or a node's interface. @@ -1036,12 +1036,12 @@ class CoreGrpcClient: :param session_id: session id :param node_id: node id :param model: emane model name - :param interface_id: node interface id + :param iface_id: node interface id :return: response with a list of configuration groups :raises grpc.RpcError: when session doesn't exist """ request = GetEmaneModelConfigRequest( - session_id=session_id, node_id=node_id, model=model, interface=interface_id + session_id=session_id, node_id=node_id, model=model, iface_id=iface_id ) return self.stub.GetEmaneModelConfig(request) @@ -1051,7 +1051,7 @@ class CoreGrpcClient: node_id: int, model: str, config: Dict[str, str] = None, - interface_id: int = -1, + iface_id: int = -1, ) -> SetEmaneModelConfigResponse: """ Set emane model configuration for a node or a node's interface. @@ -1060,12 +1060,12 @@ class CoreGrpcClient: :param node_id: node id :param model: emane model name :param config: emane model configuration - :param interface_id: node interface id + :param iface_id: node interface id :return: response with result of success or failure :raises grpc.RpcError: when session doesn't exist """ model_config = EmaneModelConfig( - node_id=node_id, model=model, config=config, interface_id=interface_id + node_id=node_id, model=model, config=config, iface_id=iface_id ) request = SetEmaneModelConfigRequest( session_id=session_id, emane_model_config=model_config @@ -1128,7 +1128,7 @@ class CoreGrpcClient: ) return self.stub.EmaneLink(request) - def get_interfaces(self) -> core_pb2.GetInterfacesResponse: + def get_ifaces(self) -> core_pb2.GetInterfacesResponse: """ Retrieves a list of interfaces available on the host machine that are not a part of a CORE session. diff --git a/daemon/core/api/grpc/events.py b/daemon/core/api/grpc/events.py index 82cf1eac..75f9eb2e 100644 --- a/daemon/core/api/grpc/events.py +++ b/daemon/core/api/grpc/events.py @@ -15,24 +15,28 @@ from core.emulator.data import ( from core.emulator.session import Session -def handle_node_event(event: NodeData) -> core_pb2.NodeEvent: +def handle_node_event(node_data: NodeData) -> core_pb2.NodeEvent: """ Handle node event when there is a node event - :param event: node data + :param node_data: node data :return: node event that contains node id, name, model, position, and services """ - position = core_pb2.Position(x=event.x_position, y=event.y_position) - geo = core_pb2.Geo(lat=event.latitude, lon=event.longitude, alt=event.altitude) + node = node_data.node + x, y, _ = node.position.get() + position = core_pb2.Position(x=x, y=y) + lon, lat, alt = node.position.get_geo() + geo = core_pb2.Geo(lon=lon, lat=lat, alt=alt) + services = [x.name for x in node.services] node_proto = core_pb2.Node( - id=event.id, - name=event.name, - model=event.model, + id=node.id, + name=node.name, + model=node.type, position=position, geo=geo, - services=event.services, + services=services, ) - return core_pb2.NodeEvent(node=node_proto, source=event.source) + return core_pb2.NodeEvent(node=node_proto, source=node_data.source) def handle_link_event(event: LinkData) -> core_pb2.LinkEvent: @@ -82,7 +86,7 @@ def handle_config_event(event: ConfigData) -> core_pb2.ConfigEvent: data_values=event.data_values, possible_values=event.possible_values, groups=event.groups, - interface=event.interface_number, + iface_id=event.iface_id, network_id=event.network_id, opaque=event.opaque, data_types=event.data_types, diff --git a/daemon/core/api/grpc/grpcutils.py b/daemon/core/api/grpc/grpcutils.py index c9b76b73..d95b7555 100644 --- a/daemon/core/api/grpc/grpcutils.py +++ b/daemon/core/api/grpc/grpcutils.py @@ -11,8 +11,7 @@ from core.api.grpc import common_pb2, core_pb2 from core.api.grpc.services_pb2 import NodeServiceData, ServiceConfig from core.config import ConfigurableOptions from core.emane.nodes import EmaneNet -from core.emulator.data import LinkData -from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions +from core.emulator.data import InterfaceData, LinkData, LinkOptions, NodeOptions from core.emulator.enumerations import LinkTypes, NodeTypes from core.emulator.session import Session from core.nodes.base import CoreNode, NodeBase @@ -35,7 +34,6 @@ def add_node_data(node_proto: core_pb2.Node) -> Tuple[NodeTypes, int, NodeOption name=node_proto.name, model=node_proto.model, icon=node_proto.icon, - opaque=node_proto.opaque, image=node_proto.image, services=node_proto.services, config_services=node_proto.config_services, @@ -52,58 +50,57 @@ def add_node_data(node_proto: core_pb2.Node) -> Tuple[NodeTypes, int, NodeOption return _type, _id, options -def link_interface(interface_proto: core_pb2.Interface) -> InterfaceData: +def link_iface(iface_proto: core_pb2.Interface) -> InterfaceData: """ Create interface data from interface proto. - :param interface_proto: interface proto + :param iface_proto: interface proto :return: interface data """ - interface_data = None - if interface_proto: - name = interface_proto.name if interface_proto.name else None - mac = interface_proto.mac if interface_proto.mac else None - ip4 = interface_proto.ip4 if interface_proto.ip4 else None - ip6 = interface_proto.ip6 if interface_proto.ip6 else None - interface_data = InterfaceData( - id=interface_proto.id, + iface_data = None + if iface_proto: + name = iface_proto.name if iface_proto.name else None + mac = iface_proto.mac if iface_proto.mac else None + ip4 = iface_proto.ip4 if iface_proto.ip4 else None + ip6 = iface_proto.ip6 if iface_proto.ip6 else None + iface_data = InterfaceData( + id=iface_proto.id, name=name, mac=mac, ip4=ip4, - ip4_mask=interface_proto.ip4mask, + ip4_mask=iface_proto.ip4_mask, ip6=ip6, - ip6_mask=interface_proto.ip6mask, + ip6_mask=iface_proto.ip6_mask, ) - return interface_data + return iface_data def add_link_data( link_proto: core_pb2.Link -) -> Tuple[InterfaceData, InterfaceData, LinkOptions]: +) -> Tuple[InterfaceData, InterfaceData, LinkOptions, LinkTypes]: """ Convert link proto to link interfaces and options data. :param link_proto: link proto :return: link interfaces and options """ - interface1_data = link_interface(link_proto.interface1) - interface2_data = link_interface(link_proto.interface2) + iface1_data = link_iface(link_proto.iface1) + iface2_data = link_iface(link_proto.iface2) link_type = LinkTypes(link_proto.type) - options = LinkOptions(type=link_type) - options_data = link_proto.options - if options_data: - options.delay = options_data.delay - options.bandwidth = options_data.bandwidth - options.loss = options_data.loss - options.dup = options_data.dup - options.jitter = options_data.jitter - options.mer = options_data.mer - options.burst = options_data.burst - options.mburst = options_data.mburst - options.unidirectional = options_data.unidirectional - options.key = options_data.key - options.opaque = options_data.opaque - return interface1_data, interface2_data, options + options = LinkOptions() + options_proto = link_proto.options + if options_proto: + options.delay = options_proto.delay + options.bandwidth = options_proto.bandwidth + options.loss = options_proto.loss + options.dup = options_proto.dup + options.jitter = options_proto.jitter + options.mer = options_proto.mer + options.burst = options_proto.burst + options.mburst = options_proto.mburst + options.unidirectional = options_proto.unidirectional + options.key = options_proto.key + return iface1_data, iface2_data, options, link_type def create_nodes( @@ -143,8 +140,8 @@ def create_links( for link_proto in link_protos: node1_id = link_proto.node1_id node2_id = link_proto.node2_id - interface1, interface2, options = add_link_data(link_proto) - args = (node1_id, node2_id, interface1, interface2, options) + iface1, iface2, options, link_type = add_link_data(link_proto) + args = (node1_id, node2_id, iface1, iface2, options, link_type) funcs.append((session.add_link, args, {})) start = time.monotonic() results, exceptions = utils.threadpool(funcs) @@ -167,8 +164,8 @@ def edit_links( for link_proto in link_protos: node1_id = link_proto.node1_id node2_id = link_proto.node2_id - interface1, interface2, options = add_link_data(link_proto) - args = (node1_id, node2_id, interface1.id, interface2.id, options) + iface1, iface2, options, link_type = add_link_data(link_proto) + args = (node1_id, node2_id, iface1.id, iface2.id, options, link_type) funcs.append((session.update_link, args, {})) start = time.monotonic() results, exceptions = utils.threadpool(funcs) @@ -279,16 +276,16 @@ def get_links(node: NodeBase): return links -def get_emane_model_id(node_id: int, interface_id: int) -> int: +def get_emane_model_id(node_id: int, iface_id: int) -> int: """ Get EMANE model id :param node_id: node id - :param interface_id: interface id + :param iface_id: interface id :return: EMANE model id """ - if interface_id >= 0: - return node_id * 1000 + interface_id + if iface_id >= 0: + return node_id * 1000 + iface_id else: return node_id @@ -300,12 +297,39 @@ def parse_emane_model_id(_id: int) -> Tuple[int, int]: :param _id: id to parse :return: node id and interface id """ - interface = -1 + iface_id = -1 node_id = _id if _id >= 1000: - interface = _id % 1000 + iface_id = _id % 1000 node_id = int(_id / 1000) - return node_id, interface + return node_id, iface_id + + +def convert_iface(iface_data: InterfaceData) -> core_pb2.Interface: + return core_pb2.Interface( + id=iface_data.id, + name=iface_data.name, + mac=iface_data.mac, + ip4=iface_data.ip4, + ip4_mask=iface_data.ip4_mask, + ip6=iface_data.ip6, + ip6_mask=iface_data.ip6_mask, + ) + + +def convert_link_options(options_data: LinkOptions) -> core_pb2.LinkOptions: + return core_pb2.LinkOptions( + jitter=options_data.jitter, + key=options_data.key, + mburst=options_data.mburst, + mer=options_data.mer, + loss=options_data.loss, + bandwidth=options_data.bandwidth, + burst=options_data.burst, + delay=options_data.delay, + dup=options_data.dup, + unidirectional=options_data.unidirectional, + ) def convert_link(link_data: LinkData) -> core_pb2.Link: @@ -315,47 +339,19 @@ def convert_link(link_data: LinkData) -> core_pb2.Link: :param link_data: link to convert :return: core protobuf Link """ - interface1 = None - if link_data.interface1_id is not None: - interface1 = core_pb2.Interface( - id=link_data.interface1_id, - name=link_data.interface1_name, - mac=convert_value(link_data.interface1_mac), - ip4=convert_value(link_data.interface1_ip4), - ip4mask=link_data.interface1_ip4_mask, - ip6=convert_value(link_data.interface1_ip6), - ip6mask=link_data.interface1_ip6_mask, - ) - interface2 = None - if link_data.interface2_id is not None: - interface2 = core_pb2.Interface( - id=link_data.interface2_id, - name=link_data.interface2_name, - mac=convert_value(link_data.interface2_mac), - ip4=convert_value(link_data.interface2_ip4), - ip4mask=link_data.interface2_ip4_mask, - ip6=convert_value(link_data.interface2_ip6), - ip6mask=link_data.interface2_ip6_mask, - ) - options = core_pb2.LinkOptions( - opaque=link_data.opaque, - jitter=link_data.jitter, - key=link_data.key, - mburst=link_data.mburst, - mer=link_data.mer, - loss=link_data.loss, - bandwidth=link_data.bandwidth, - burst=link_data.burst, - delay=link_data.delay, - dup=link_data.dup, - unidirectional=link_data.unidirectional, - ) + iface1 = None + if link_data.iface1 is not None: + iface1 = convert_iface(link_data.iface1) + iface2 = None + if link_data.iface2 is not None: + iface2 = convert_iface(link_data.iface2) + options = convert_link_options(link_data.options) return core_pb2.Link( - type=link_data.link_type.value, + type=link_data.type.value, node1_id=link_data.node1_id, node2_id=link_data.node2_id, - interface1=interface1, - interface2=interface2, + iface1=iface1, + iface2=iface2, options=options, network_id=link_data.network_id, label=link_data.label, @@ -440,58 +436,58 @@ def get_service_configuration(service: CoreService) -> NodeServiceData: ) -def interface_to_proto(interface: CoreInterface) -> core_pb2.Interface: +def iface_to_proto(iface: CoreInterface) -> core_pb2.Interface: """ Convenience for converting a core interface to the protobuf representation. - :param interface: interface to convert + :param iface: interface to convert :return: interface proto """ net_id = None - if interface.net: - net_id = interface.net.id + if iface.net: + net_id = iface.net.id ip4 = None - ip4mask = None + ip4_mask = None ip6 = None - ip6mask = None - for addr in interface.addrlist: + ip6_mask = None + for addr in iface.addrlist: network = netaddr.IPNetwork(addr) mask = network.prefixlen ip = str(network.ip) if netaddr.valid_ipv4(ip) and not ip4: ip4 = ip - ip4mask = mask + ip4_mask = mask elif netaddr.valid_ipv6(ip) and not ip6: ip6 = ip - ip6mask = mask + ip6_mask = mask return core_pb2.Interface( - id=interface.netindex, - netid=net_id, - name=interface.name, - mac=str(interface.hwaddr), - mtu=interface.mtu, - flowid=interface.flow_id, + id=iface.node_id, + net_id=net_id, + name=iface.name, + mac=iface.mac, + mtu=iface.mtu, + flow_id=iface.flow_id, ip4=ip4, - ip4mask=ip4mask, + ip4_mask=ip4_mask, ip6=ip6, - ip6mask=ip6mask, + ip6_mask=ip6_mask, ) -def get_nem_id(node: CoreNode, netif_id: int, context: ServicerContext) -> int: +def get_nem_id(node: CoreNode, iface_id: int, context: ServicerContext) -> int: """ Get nem id for a given node and interface id. :param node: node to get nem id for - :param netif_id: id of interface on node to get nem id for + :param iface_id: id of interface on node to get nem id for :param context: request context :return: nem id """ - netif = node.netif(netif_id) - if not netif: - message = f"{node.name} missing interface {netif_id}" + iface = node.ifaces.get(iface_id) + if not iface: + message = f"{node.name} missing interface {iface_id}" context.abort(grpc.StatusCode.NOT_FOUND, message) - net = netif.net + net = iface.net if not isinstance(net, EmaneNet): - message = f"{node.name} interface {netif_id} is not an EMANE network" + message = f"{node.name} interface {iface_id} is not an EMANE network" context.abort(grpc.StatusCode.INVALID_ARGUMENT, message) - return net.getnemid(netif) + return net.getnemid(iface) diff --git a/daemon/core/api/grpc/server.py b/daemon/core/api/grpc/server.py index 8b349b67..1964b6e8 100644 --- a/daemon/core/api/grpc/server.py +++ b/daemon/core/api/grpc/server.py @@ -108,8 +108,7 @@ from core.api.grpc.wlan_pb2 import ( WlanLinkResponse, ) from core.emulator.coreemu import CoreEmu -from core.emulator.data import LinkData -from core.emulator.emudata import LinkOptions, NodeOptions +from core.emulator.data import LinkData, LinkOptions, NodeOptions from core.emulator.enumerations import EventTypes, LinkTypes, MessageFlags from core.emulator.session import NT, Session from core.errors import CoreCommandError, CoreError @@ -246,7 +245,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): config = session.emane.get_configs() config.update(request.emane_config) for config in request.emane_model_configs: - _id = get_emane_model_id(config.node_id, config.interface_id) + _id = get_emane_model_id(config.node_id, config.iface_id) session.emane.set_model_config(_id, config.model, config.config) # wlan configs @@ -625,16 +624,14 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): key = key.split(".") node_id = _INTERFACE_REGEX.search(key[0]).group("node") node_id = int(node_id, base=16) - interface_id = int(key[1], base=16) + iface_id = int(key[1], base=16) session_id = int(key[2], base=16) if session.id != session_id: continue - interface_throughput = ( - throughputs_event.interface_throughputs.add() - ) - interface_throughput.node_id = node_id - interface_throughput.interface_id = interface_id - interface_throughput.throughput = throughput + iface_throughput = throughputs_event.iface_throughputs.add() + iface_throughput.node_id = node_id + iface_throughput.iface_id = iface_id + iface_throughput.throughput = throughput elif key.startswith("b."): try: key = key.split(".") @@ -686,13 +683,13 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): logging.debug("get node: %s", request) session = self.get_session(request.session_id, context) node = self.get_node(session, request.node_id, context, NodeBase) - interfaces = [] - for interface_id in node._netif: - interface = node._netif[interface_id] - interface_proto = grpcutils.interface_to_proto(interface) - interfaces.append(interface_proto) + ifaces = [] + for iface_id in node.ifaces: + iface = node.ifaces[iface_id] + iface_proto = grpcutils.iface_to_proto(iface) + ifaces.append(iface_proto) node_proto = grpcutils.get_node_proto(session, node) - return core_pb2.GetNodeResponse(node=node_proto, interfaces=interfaces) + return core_pb2.GetNodeResponse(node=node_proto, ifaces=ifaces) def MoveNodes( self, @@ -850,18 +847,20 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): node2_id = request.link.node2_id self.get_node(session, node1_id, context, NodeBase) self.get_node(session, node2_id, context, NodeBase) - interface1, interface2, options = grpcutils.add_link_data(request.link) - node1_interface, node2_interface = session.add_link( - node1_id, node2_id, interface1, interface2, options=options + iface1_data, iface2_data, options, link_type = grpcutils.add_link_data( + request.link ) - interface1_proto = None - interface2_proto = None - if node1_interface: - interface1_proto = grpcutils.interface_to_proto(node1_interface) - if node2_interface: - interface2_proto = grpcutils.interface_to_proto(node2_interface) + node1_iface, node2_iface = session.add_link( + node1_id, node2_id, iface1_data, iface2_data, options, link_type + ) + iface1_proto = None + iface2_proto = None + if node1_iface: + iface1_proto = grpcutils.iface_to_proto(node1_iface) + if node2_iface: + iface2_proto = grpcutils.iface_to_proto(node2_iface) return core_pb2.AddLinkResponse( - result=True, interface1=interface1_proto, interface2=interface2_proto + result=True, iface1=iface1_proto, iface2=iface2_proto ) def EditLink( @@ -878,23 +877,22 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): session = self.get_session(request.session_id, context) node1_id = request.node1_id node2_id = request.node2_id - interface1_id = request.interface1_id - interface2_id = request.interface2_id - options_data = request.options + iface1_id = request.iface1_id + iface2_id = request.iface2_id + options_proto = request.options options = LinkOptions( - delay=options_data.delay, - bandwidth=options_data.bandwidth, - loss=options_data.loss, - dup=options_data.dup, - jitter=options_data.jitter, - mer=options_data.mer, - burst=options_data.burst, - mburst=options_data.mburst, - unidirectional=options_data.unidirectional, - key=options_data.key, - opaque=options_data.opaque, + delay=options_proto.delay, + bandwidth=options_proto.bandwidth, + loss=options_proto.loss, + dup=options_proto.dup, + jitter=options_proto.jitter, + mer=options_proto.mer, + burst=options_proto.burst, + mburst=options_proto.mburst, + unidirectional=options_proto.unidirectional, + key=options_proto.key, ) - session.update_link(node1_id, node2_id, interface1_id, interface2_id, options) + session.update_link(node1_id, node2_id, iface1_id, iface2_id, options) return core_pb2.EditLinkResponse(result=True) def DeleteLink( @@ -911,9 +909,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): session = self.get_session(request.session_id, context) node1_id = request.node1_id node2_id = request.node2_id - interface1_id = request.interface1_id - interface2_id = request.interface2_id - session.delete_link(node1_id, node2_id, interface1_id, interface2_id) + iface1_id = request.iface1_id + iface2_id = request.iface2_id + session.delete_link(node1_id, node2_id, iface1_id, iface2_id) return core_pb2.DeleteLinkResponse(result=True) def GetHooks( @@ -1371,7 +1369,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): logging.debug("get emane model config: %s", request) session = self.get_session(request.session_id, context) model = session.emane.models[request.model] - _id = get_emane_model_id(request.node_id, request.interface) + _id = get_emane_model_id(request.node_id, request.iface_id) current_config = session.emane.get_model_config(_id, request.model) config = get_config_options(current_config, model) return GetEmaneModelConfigResponse(config=config) @@ -1390,7 +1388,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): logging.debug("set emane model config: %s", request) session = self.get_session(request.session_id, context) model_config = request.emane_model_config - _id = get_emane_model_id(model_config.node_id, model_config.interface_id) + _id = get_emane_model_id(model_config.node_id, model_config.iface_id) session.emane.set_model_config(_id, model_config.model, model_config.config) return SetEmaneModelConfigResponse(result=True) @@ -1419,12 +1417,9 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): model = session.emane.models[model_name] current_config = session.emane.get_model_config(_id, model_name) config = get_config_options(current_config, model) - node_id, interface = grpcutils.parse_emane_model_id(_id) + node_id, iface_id = grpcutils.parse_emane_model_id(_id) model_config = GetEmaneModelConfigsResponse.ModelConfig( - node_id=node_id, - model=model_name, - interface=interface, - config=config, + node_id=node_id, model=model_name, iface_id=iface_id, config=config ) configs.append(model_config) return GetEmaneModelConfigsResponse(configs=configs) @@ -1489,16 +1484,12 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): :param context: context object :return: get-interfaces response that has all the system's interfaces """ - interfaces = [] - for interface in os.listdir("/sys/class/net"): - if ( - interface.startswith("b.") - or interface.startswith("veth") - or interface == "lo" - ): + ifaces = [] + for iface in os.listdir("/sys/class/net"): + if iface.startswith("b.") or iface.startswith("veth") or iface == "lo": continue - interfaces.append(interface) - return core_pb2.GetInterfacesResponse(interfaces=interfaces) + ifaces.append(iface) + return core_pb2.GetInterfacesResponse(ifaces=ifaces) def EmaneLink( self, request: EmaneLinkRequest, context: ServicerContext @@ -1513,16 +1504,16 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): logging.debug("emane link: %s", request) session = self.get_session(request.session_id, context) nem1 = request.nem1 - emane1, netif = session.emane.nemlookup(nem1) - if not emane1 or not netif: + emane1, iface = session.emane.nemlookup(nem1) + if not emane1 or not iface: context.abort(grpc.StatusCode.NOT_FOUND, f"nem one {nem1} not found") - node1 = netif.node + node1 = iface.node nem2 = request.nem2 - emane2, netif = session.emane.nemlookup(nem2) - if not emane2 or not netif: + emane2, iface = session.emane.nemlookup(nem2) + if not emane2 or not iface: context.abort(grpc.StatusCode.NOT_FOUND, f"nem two {nem2} not found") - node2 = netif.node + node2 = iface.node if emane1.id == emane2.id: if request.linked: @@ -1532,7 +1523,7 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): color = session.get_link_color(emane1.id) link = LinkData( message_type=flag, - link_type=LinkTypes.WIRELESS, + type=LinkTypes.WIRELESS, node1_id=node1.id, node2_id=node2.id, network_id=emane1.id, @@ -1734,21 +1725,19 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): ) node1 = self.get_node(session, request.node1_id, context, CoreNode) node2 = self.get_node(session, request.node2_id, context, CoreNode) - node1_interface, node2_interface = None, None - for net, interface1, interface2 in node1.commonnets(node2): + node1_iface, node2_iface = None, None + for net, iface1, iface2 in node1.commonnets(node2): if net == wlan: - node1_interface = interface1 - node2_interface = interface2 + node1_iface = iface1 + node2_iface = iface2 break result = False - if node1_interface and node2_interface: + if node1_iface and node2_iface: if request.linked: - wlan.link(node1_interface, node2_interface) + wlan.link(node1_iface, node2_iface) else: - wlan.unlink(node1_interface, node2_interface) - wlan.model.sendlinkmsg( - node1_interface, node2_interface, unlink=not request.linked - ) + wlan.unlink(node1_iface, node2_iface) + wlan.model.sendlinkmsg(node1_iface, node2_iface, unlink=not request.linked) result = True return WlanLinkResponse(result=result) @@ -1760,8 +1749,8 @@ class CoreGrpcServer(core_pb2_grpc.CoreApiServicer): for request in request_iterator: session = self.get_session(request.session_id, context) node1 = self.get_node(session, request.node1_id, context, CoreNode) - nem1 = grpcutils.get_nem_id(node1, request.interface1_id, context) + nem1 = grpcutils.get_nem_id(node1, request.iface1_id, context) node2 = self.get_node(session, request.node2_id, context, CoreNode) - nem2 = grpcutils.get_nem_id(node2, request.interface2_id, context) + nem2 = grpcutils.get_nem_id(node2, request.iface2_id, context) session.emane.publish_pathloss(nem1, nem2, request.rx1, request.rx2) return EmanePathlossesResponse() diff --git a/daemon/core/api/tlv/coreapi.py b/daemon/core/api/tlv/coreapi.py index 088a7631..5d0b08e7 100644 --- a/daemon/core/api/tlv/coreapi.py +++ b/daemon/core/api/tlv/coreapi.py @@ -508,18 +508,18 @@ class CoreLinkTlv(CoreTlv): LinkTlvs.EMULATION_ID.value: CoreTlvDataUint32, LinkTlvs.NETWORK_ID.value: CoreTlvDataUint32, LinkTlvs.KEY.value: CoreTlvDataUint32, - LinkTlvs.INTERFACE1_NUMBER.value: CoreTlvDataUint16, - LinkTlvs.INTERFACE1_IP4.value: CoreTlvDataIpv4Addr, - LinkTlvs.INTERFACE1_IP4_MASK.value: CoreTlvDataUint16, - LinkTlvs.INTERFACE1_MAC.value: CoreTlvDataMacAddr, - LinkTlvs.INTERFACE1_IP6.value: CoreTlvDataIPv6Addr, - LinkTlvs.INTERFACE1_IP6_MASK.value: CoreTlvDataUint16, - LinkTlvs.INTERFACE2_NUMBER.value: CoreTlvDataUint16, - LinkTlvs.INTERFACE2_IP4.value: CoreTlvDataIpv4Addr, - LinkTlvs.INTERFACE2_IP4_MASK.value: CoreTlvDataUint16, - LinkTlvs.INTERFACE2_MAC.value: CoreTlvDataMacAddr, - LinkTlvs.INTERFACE2_IP6.value: CoreTlvDataIPv6Addr, - LinkTlvs.INTERFACE2_IP6_MASK.value: CoreTlvDataUint16, + LinkTlvs.IFACE1_NUMBER.value: CoreTlvDataUint16, + LinkTlvs.IFACE1_IP4.value: CoreTlvDataIpv4Addr, + LinkTlvs.IFACE1_IP4_MASK.value: CoreTlvDataUint16, + LinkTlvs.IFACE1_MAC.value: CoreTlvDataMacAddr, + LinkTlvs.IFACE1_IP6.value: CoreTlvDataIPv6Addr, + LinkTlvs.IFACE1_IP6_MASK.value: CoreTlvDataUint16, + LinkTlvs.IFACE2_NUMBER.value: CoreTlvDataUint16, + LinkTlvs.IFACE2_IP4.value: CoreTlvDataIpv4Addr, + LinkTlvs.IFACE2_IP4_MASK.value: CoreTlvDataUint16, + LinkTlvs.IFACE2_MAC.value: CoreTlvDataMacAddr, + LinkTlvs.IFACE2_IP6.value: CoreTlvDataIPv6Addr, + LinkTlvs.IFACE2_IP6_MASK.value: CoreTlvDataUint16, LinkTlvs.INTERFACE1_NAME.value: CoreTlvDataString, LinkTlvs.INTERFACE2_NAME.value: CoreTlvDataString, LinkTlvs.OPAQUE.value: CoreTlvDataString, @@ -577,7 +577,7 @@ class CoreConfigTlv(CoreTlv): ConfigTlvs.POSSIBLE_VALUES.value: CoreTlvDataString, ConfigTlvs.GROUPS.value: CoreTlvDataString, ConfigTlvs.SESSION.value: CoreTlvDataString, - ConfigTlvs.INTERFACE_NUMBER.value: CoreTlvDataUint16, + ConfigTlvs.IFACE_ID.value: CoreTlvDataUint16, ConfigTlvs.NETWORK_ID.value: CoreTlvDataUint32, ConfigTlvs.OPAQUE.value: CoreTlvDataString, } diff --git a/daemon/core/api/tlv/corehandlers.py b/daemon/core/api/tlv/corehandlers.py index 2cd7bfac..d01f15a3 100644 --- a/daemon/core/api/tlv/corehandlers.py +++ b/daemon/core/api/tlv/corehandlers.py @@ -29,8 +29,15 @@ from core.api.tlv.enumerations import ( NodeTlvs, SessionTlvs, ) -from core.emulator.data import ConfigData, EventData, ExceptionData, FileData -from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions +from core.emulator.data import ( + ConfigData, + EventData, + ExceptionData, + FileData, + InterfaceData, + LinkOptions, + NodeOptions, +) from core.emulator.enumerations import ( ConfigDataTypes, EventTypes, @@ -71,7 +78,7 @@ class CoreHandler(socketserver.BaseRequestHandler): MessageTypes.REGISTER.value: self.handle_register_message, MessageTypes.CONFIG.value: self.handle_config_message, MessageTypes.FILE.value: self.handle_file_message, - MessageTypes.INTERFACE.value: self.handle_interface_message, + MessageTypes.INTERFACE.value: self.handle_iface_message, MessageTypes.EVENT.value: self.handle_event_message, MessageTypes.SESSION.value: self.handle_session_message, } @@ -322,7 +329,6 @@ class CoreHandler(socketserver.BaseRequestHandler): """ logging.debug("handling broadcast node: %s", node_data) message = dataconversion.convert_node(node_data) - try: self.sendall(message) except IOError: @@ -336,46 +342,49 @@ class CoreHandler(socketserver.BaseRequestHandler): :return: nothing """ logging.debug("handling broadcast link: %s", link_data) + options_data = link_data.options loss = "" - if link_data.loss is not None: - loss = str(link_data.loss) + if options_data.loss is not None: + loss = str(options_data.loss) dup = "" - if link_data.dup is not None: - dup = str(link_data.dup) + if options_data.dup is not None: + dup = str(options_data.dup) + iface1 = link_data.iface1 + if iface1 is None: + iface1 = InterfaceData() + iface2 = link_data.iface2 + if iface2 is None: + iface2 = InterfaceData() tlv_data = structutils.pack_values( coreapi.CoreLinkTlv, [ (LinkTlvs.N1_NUMBER, link_data.node1_id), (LinkTlvs.N2_NUMBER, link_data.node2_id), - (LinkTlvs.DELAY, link_data.delay), - (LinkTlvs.BANDWIDTH, link_data.bandwidth), + (LinkTlvs.DELAY, options_data.delay), + (LinkTlvs.BANDWIDTH, options_data.bandwidth), (LinkTlvs.LOSS, loss), (LinkTlvs.DUP, dup), - (LinkTlvs.JITTER, link_data.jitter), - (LinkTlvs.MER, link_data.mer), - (LinkTlvs.BURST, link_data.burst), - (LinkTlvs.SESSION, link_data.session), - (LinkTlvs.MBURST, link_data.mburst), - (LinkTlvs.TYPE, link_data.link_type.value), - (LinkTlvs.GUI_ATTRIBUTES, link_data.gui_attributes), - (LinkTlvs.UNIDIRECTIONAL, link_data.unidirectional), - (LinkTlvs.EMULATION_ID, link_data.emulation_id), + (LinkTlvs.JITTER, options_data.jitter), + (LinkTlvs.MER, options_data.mer), + (LinkTlvs.BURST, options_data.burst), + (LinkTlvs.MBURST, options_data.mburst), + (LinkTlvs.TYPE, link_data.type.value), + (LinkTlvs.UNIDIRECTIONAL, options_data.unidirectional), (LinkTlvs.NETWORK_ID, link_data.network_id), - (LinkTlvs.KEY, link_data.key), - (LinkTlvs.INTERFACE1_NUMBER, link_data.interface1_id), - (LinkTlvs.INTERFACE1_IP4, link_data.interface1_ip4), - (LinkTlvs.INTERFACE1_IP4_MASK, link_data.interface1_ip4_mask), - (LinkTlvs.INTERFACE1_MAC, link_data.interface1_mac), - (LinkTlvs.INTERFACE1_IP6, link_data.interface1_ip6), - (LinkTlvs.INTERFACE1_IP6_MASK, link_data.interface1_ip6_mask), - (LinkTlvs.INTERFACE2_NUMBER, link_data.interface2_id), - (LinkTlvs.INTERFACE2_IP4, link_data.interface2_ip4), - (LinkTlvs.INTERFACE2_IP4_MASK, link_data.interface2_ip4_mask), - (LinkTlvs.INTERFACE2_MAC, link_data.interface2_mac), - (LinkTlvs.INTERFACE2_IP6, link_data.interface2_ip6), - (LinkTlvs.INTERFACE2_IP6_MASK, link_data.interface2_ip6_mask), - (LinkTlvs.OPAQUE, link_data.opaque), + (LinkTlvs.KEY, options_data.key), + (LinkTlvs.IFACE1_NUMBER, iface1.id), + (LinkTlvs.IFACE1_IP4, iface1.ip4), + (LinkTlvs.IFACE1_IP4_MASK, iface1.ip4_mask), + (LinkTlvs.IFACE1_MAC, iface1.mac), + (LinkTlvs.IFACE1_IP6, iface1.ip6), + (LinkTlvs.IFACE1_IP6_MASK, iface1.ip6_mask), + (LinkTlvs.IFACE2_NUMBER, iface2.id), + (LinkTlvs.IFACE2_IP4, iface2.ip4), + (LinkTlvs.IFACE2_IP4_MASK, iface2.ip4_mask), + (LinkTlvs.IFACE2_MAC, iface2.mac), + (LinkTlvs.IFACE2_IP6, iface2.ip6), + (LinkTlvs.IFACE2_IP6_MASK, iface2.ip6_mask), ], ) @@ -709,7 +718,6 @@ class CoreHandler(socketserver.BaseRequestHandler): options.icon = message.get_tlv(NodeTlvs.ICON.value) options.canvas = message.get_tlv(NodeTlvs.CANVAS.value) - options.opaque = message.get_tlv(NodeTlvs.OPAQUE.value) options.server = message.get_tlv(NodeTlvs.EMULATION_SERVER.value) services = message.get_tlv(NodeTlvs.SERVICES.value) @@ -749,56 +757,51 @@ class CoreHandler(socketserver.BaseRequestHandler): """ node1_id = message.get_tlv(LinkTlvs.N1_NUMBER.value) node2_id = message.get_tlv(LinkTlvs.N2_NUMBER.value) - interface1_data = InterfaceData( - id=message.get_tlv(LinkTlvs.INTERFACE1_NUMBER.value), + iface1_data = InterfaceData( + id=message.get_tlv(LinkTlvs.IFACE1_NUMBER.value), name=message.get_tlv(LinkTlvs.INTERFACE1_NAME.value), - mac=message.get_tlv(LinkTlvs.INTERFACE1_MAC.value), - ip4=message.get_tlv(LinkTlvs.INTERFACE1_IP4.value), - ip4_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP4_MASK.value), - ip6=message.get_tlv(LinkTlvs.INTERFACE1_IP6.value), - ip6_mask=message.get_tlv(LinkTlvs.INTERFACE1_IP6_MASK.value), + mac=message.get_tlv(LinkTlvs.IFACE1_MAC.value), + ip4=message.get_tlv(LinkTlvs.IFACE1_IP4.value), + ip4_mask=message.get_tlv(LinkTlvs.IFACE1_IP4_MASK.value), + ip6=message.get_tlv(LinkTlvs.IFACE1_IP6.value), + ip6_mask=message.get_tlv(LinkTlvs.IFACE1_IP6_MASK.value), ) - interface2_data = InterfaceData( - id=message.get_tlv(LinkTlvs.INTERFACE2_NUMBER.value), + iface2_data = InterfaceData( + id=message.get_tlv(LinkTlvs.IFACE2_NUMBER.value), name=message.get_tlv(LinkTlvs.INTERFACE2_NAME.value), - mac=message.get_tlv(LinkTlvs.INTERFACE2_MAC.value), - ip4=message.get_tlv(LinkTlvs.INTERFACE2_IP4.value), - ip4_mask=message.get_tlv(LinkTlvs.INTERFACE2_IP4_MASK.value), - ip6=message.get_tlv(LinkTlvs.INTERFACE2_IP6.value), - ip6_mask=message.get_tlv(LinkTlvs.INTERFACE2_IP6_MASK.value), + mac=message.get_tlv(LinkTlvs.IFACE2_MAC.value), + ip4=message.get_tlv(LinkTlvs.IFACE2_IP4.value), + ip4_mask=message.get_tlv(LinkTlvs.IFACE2_IP4_MASK.value), + ip6=message.get_tlv(LinkTlvs.IFACE2_IP6.value), + ip6_mask=message.get_tlv(LinkTlvs.IFACE2_IP6_MASK.value), ) link_type = LinkTypes.WIRED link_type_value = message.get_tlv(LinkTlvs.TYPE.value) if link_type_value is not None: link_type = LinkTypes(link_type_value) - options = LinkOptions(type=link_type) + options = LinkOptions() options.delay = message.get_tlv(LinkTlvs.DELAY.value) options.bandwidth = message.get_tlv(LinkTlvs.BANDWIDTH.value) - options.session = message.get_tlv(LinkTlvs.SESSION.value) options.loss = message.get_tlv(LinkTlvs.LOSS.value) options.dup = message.get_tlv(LinkTlvs.DUP.value) options.jitter = message.get_tlv(LinkTlvs.JITTER.value) options.mer = message.get_tlv(LinkTlvs.MER.value) options.burst = message.get_tlv(LinkTlvs.BURST.value) options.mburst = message.get_tlv(LinkTlvs.MBURST.value) - options.gui_attributes = message.get_tlv(LinkTlvs.GUI_ATTRIBUTES.value) options.unidirectional = message.get_tlv(LinkTlvs.UNIDIRECTIONAL.value) - options.emulation_id = message.get_tlv(LinkTlvs.EMULATION_ID.value) - options.network_id = message.get_tlv(LinkTlvs.NETWORK_ID.value) options.key = message.get_tlv(LinkTlvs.KEY.value) - options.opaque = message.get_tlv(LinkTlvs.OPAQUE.value) if message.flags & MessageFlags.ADD.value: self.session.add_link( - node1_id, node2_id, interface1_data, interface2_data, options + node1_id, node2_id, iface1_data, iface2_data, options, link_type ) elif message.flags & MessageFlags.DELETE.value: self.session.delete_link( - node1_id, node2_id, interface1_data.id, interface2_data.id + node1_id, node2_id, iface1_data.id, iface2_data.id, link_type ) else: self.session.update_link( - node1_id, node2_id, interface1_data.id, interface2_data.id, options + node1_id, node2_id, iface1_data.id, iface2_data.id, options, link_type ) return () @@ -1008,7 +1011,7 @@ class CoreHandler(socketserver.BaseRequestHandler): possible_values=message.get_tlv(ConfigTlvs.POSSIBLE_VALUES.value), groups=message.get_tlv(ConfigTlvs.GROUPS.value), session=message.get_tlv(ConfigTlvs.SESSION.value), - interface_number=message.get_tlv(ConfigTlvs.INTERFACE_NUMBER.value), + iface_id=message.get_tlv(ConfigTlvs.IFACE_ID.value), network_id=message.get_tlv(ConfigTlvs.NETWORK_ID.value), opaque=message.get_tlv(ConfigTlvs.OPAQUE.value), ) @@ -1325,11 +1328,11 @@ class CoreHandler(socketserver.BaseRequestHandler): replies = [] node_id = config_data.node object_name = config_data.object - interface_id = config_data.interface_number + iface_id = config_data.iface_id values_str = config_data.data_values - if interface_id is not None: - node_id = node_id * 1000 + interface_id + if iface_id is not None: + node_id = node_id * 1000 + iface_id logging.debug( "received configure message for %s nodenum: %s", object_name, node_id @@ -1375,11 +1378,11 @@ class CoreHandler(socketserver.BaseRequestHandler): replies = [] node_id = config_data.node object_name = config_data.object - interface_id = config_data.interface_number + iface_id = config_data.iface_id values_str = config_data.data_values - if interface_id is not None: - node_id = node_id * 1000 + interface_id + if iface_id is not None: + node_id = node_id * 1000 + iface_id logging.debug( "received configure message for %s nodenum: %s", object_name, node_id @@ -1407,11 +1410,11 @@ class CoreHandler(socketserver.BaseRequestHandler): replies = [] node_id = config_data.node object_name = config_data.object - interface_id = config_data.interface_number + iface_id = config_data.iface_id values_str = config_data.data_values - if interface_id is not None: - node_id = node_id * 1000 + interface_id + if iface_id is not None: + node_id = node_id * 1000 + iface_id logging.debug( "received configure message for %s nodenum: %s", object_name, node_id @@ -1505,7 +1508,7 @@ class CoreHandler(socketserver.BaseRequestHandler): return () - def handle_interface_message(self, message): + def handle_iface_message(self, message): """ Interface Message handler. @@ -1950,7 +1953,7 @@ class CoreUdpHandler(CoreHandler): MessageTypes.REGISTER.value: self.handle_register_message, MessageTypes.CONFIG.value: self.handle_config_message, MessageTypes.FILE.value: self.handle_file_message, - MessageTypes.INTERFACE.value: self.handle_interface_message, + MessageTypes.INTERFACE.value: self.handle_iface_message, MessageTypes.EVENT.value: self.handle_event_message, MessageTypes.SESSION.value: self.handle_session_message, } diff --git a/daemon/core/api/tlv/dataconversion.py b/daemon/core/api/tlv/dataconversion.py index 876e72a5..8a26300a 100644 --- a/daemon/core/api/tlv/dataconversion.py +++ b/daemon/core/api/tlv/dataconversion.py @@ -8,45 +8,39 @@ from typing import Dict, List from core.api.tlv import coreapi, structutils from core.api.tlv.enumerations import ConfigTlvs, NodeTlvs from core.config import ConfigGroup, ConfigurableOptions -from core.emulator.data import ConfigData +from core.emulator.data import ConfigData, NodeData -def convert_node(node_data): +def convert_node(node_data: NodeData): """ Convenience method for converting NodeData to a packed TLV message. :param core.emulator.data.NodeData node_data: node data to convert :return: packed node message """ - session = None - if node_data.session is not None: - session = str(node_data.session) + node = node_data.node services = None - if node_data.services is not None: - services = "|".join([x for x in node_data.services]) + if node.services is not None: + services = "|".join([x.name for x in node.services]) + server = None + if node.server is not None: + server = node.server.name tlv_data = structutils.pack_values( coreapi.CoreNodeTlv, [ - (NodeTlvs.NUMBER, node_data.id), - (NodeTlvs.TYPE, node_data.node_type.value), - (NodeTlvs.NAME, node_data.name), - (NodeTlvs.IP_ADDRESS, node_data.ip_address), - (NodeTlvs.MAC_ADDRESS, node_data.mac_address), - (NodeTlvs.IP6_ADDRESS, node_data.ip6_address), - (NodeTlvs.MODEL, node_data.model), - (NodeTlvs.EMULATION_ID, node_data.emulation_id), - (NodeTlvs.EMULATION_SERVER, node_data.server), - (NodeTlvs.SESSION, session), - (NodeTlvs.X_POSITION, int(node_data.x_position)), - (NodeTlvs.Y_POSITION, int(node_data.y_position)), - (NodeTlvs.CANVAS, node_data.canvas), - (NodeTlvs.NETWORK_ID, node_data.network_id), + (NodeTlvs.NUMBER, node.id), + (NodeTlvs.TYPE, node.apitype.value), + (NodeTlvs.NAME, node.name), + (NodeTlvs.MODEL, node.type), + (NodeTlvs.EMULATION_SERVER, server), + (NodeTlvs.X_POSITION, int(node.position.x)), + (NodeTlvs.Y_POSITION, int(node.position.y)), + (NodeTlvs.CANVAS, node.canvas), (NodeTlvs.SERVICES, services), - (NodeTlvs.LATITUDE, str(node_data.latitude)), - (NodeTlvs.LONGITUDE, str(node_data.longitude)), - (NodeTlvs.ALTITUDE, str(node_data.altitude)), - (NodeTlvs.ICON, node_data.icon), - (NodeTlvs.OPAQUE, node_data.opaque), + (NodeTlvs.LATITUDE, str(node.position.lat)), + (NodeTlvs.LONGITUDE, str(node.position.lon)), + (NodeTlvs.ALTITUDE, str(node.position.alt)), + (NodeTlvs.ICON, node.icon), ], ) return coreapi.CoreNodeMessage.pack(node_data.message_type.value, tlv_data) @@ -75,7 +69,7 @@ def convert_config(config_data): (ConfigTlvs.POSSIBLE_VALUES, config_data.possible_values), (ConfigTlvs.GROUPS, config_data.groups), (ConfigTlvs.SESSION, session), - (ConfigTlvs.INTERFACE_NUMBER, config_data.interface_number), + (ConfigTlvs.IFACE_ID, config_data.iface_id), (ConfigTlvs.NETWORK_ID, config_data.network_id), (ConfigTlvs.OPAQUE, config_data.opaque), ], diff --git a/daemon/core/api/tlv/enumerations.py b/daemon/core/api/tlv/enumerations.py index 0efb7c99..b4ec254a 100644 --- a/daemon/core/api/tlv/enumerations.py +++ b/daemon/core/api/tlv/enumerations.py @@ -72,18 +72,18 @@ class LinkTlvs(Enum): EMULATION_ID = 0x23 NETWORK_ID = 0x24 KEY = 0x25 - INTERFACE1_NUMBER = 0x30 - INTERFACE1_IP4 = 0x31 - INTERFACE1_IP4_MASK = 0x32 - INTERFACE1_MAC = 0x33 - INTERFACE1_IP6 = 0x34 - INTERFACE1_IP6_MASK = 0x35 - INTERFACE2_NUMBER = 0x36 - INTERFACE2_IP4 = 0x37 - INTERFACE2_IP4_MASK = 0x38 - INTERFACE2_MAC = 0x39 - INTERFACE2_IP6 = 0x40 - INTERFACE2_IP6_MASK = 0x41 + IFACE1_NUMBER = 0x30 + IFACE1_IP4 = 0x31 + IFACE1_IP4_MASK = 0x32 + IFACE1_MAC = 0x33 + IFACE1_IP6 = 0x34 + IFACE1_IP6_MASK = 0x35 + IFACE2_NUMBER = 0x36 + IFACE2_IP4 = 0x37 + IFACE2_IP4_MASK = 0x38 + IFACE2_MAC = 0x39 + IFACE2_IP6 = 0x40 + IFACE2_IP6_MASK = 0x41 INTERFACE1_NAME = 0x42 INTERFACE2_NAME = 0x43 OPAQUE = 0x50 @@ -118,7 +118,7 @@ class ConfigTlvs(Enum): POSSIBLE_VALUES = 0x08 GROUPS = 0x09 SESSION = 0x0A - INTERFACE_NUMBER = 0x0B + IFACE_ID = 0x0B NETWORK_ID = 0x24 OPAQUE = 0x50 diff --git a/daemon/core/configservices/frrservices/services.py b/daemon/core/configservices/frrservices/services.py index c4502f86..8764e32c 100644 --- a/daemon/core/configservices/frrservices/services.py +++ b/daemon/core/configservices/frrservices/services.py @@ -13,33 +13,33 @@ from core.nodes.network import WlanNode GROUP = "FRR" -def has_mtu_mismatch(ifc: CoreInterface) -> bool: +def has_mtu_mismatch(iface: CoreInterface) -> bool: """ Helper to detect MTU mismatch and add the appropriate FRR mtu-ignore command. This is needed when e.g. a node is linked via a GreTap device. """ - if ifc.mtu != 1500: + if iface.mtu != 1500: return True - if not ifc.net: + if not iface.net: return False - for i in ifc.net.netifs(): - if i.mtu != ifc.mtu: + for iface in iface.net.get_ifaces(): + if iface.mtu != iface.mtu: return True return False -def get_min_mtu(ifc): +def get_min_mtu(iface): """ Helper to discover the minimum MTU of interfaces linked with the given interface. """ - mtu = ifc.mtu - if not ifc.net: + mtu = iface.mtu + if not iface.net: return mtu - for i in ifc.net.netifs(): - if i.mtu < mtu: - mtu = i.mtu + for iface in iface.net.get_ifaces(): + if iface.mtu < mtu: + mtu = iface.mtu return mtu @@ -47,10 +47,8 @@ def get_router_id(node: CoreNodeBase) -> str: """ Helper to return the first IPv4 address of a node as its router ID. """ - for ifc in node.netifs(): - if getattr(ifc, "control", False): - continue - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + for a in iface.addrlist: a = a.split("/")[0] if netaddr.valid_ipv4(a): return a @@ -97,25 +95,25 @@ class FRRZebra(ConfigService): want_ip6 = True services.append(service) - interfaces = [] - for ifc in self.node.netifs(): + ifaces = [] + for iface in self.node.get_ifaces(): ip4s = [] ip6s = [] - for x in ifc.addrlist: + for x in iface.addrlist: addr = x.split("/")[0] if netaddr.valid_ipv4(addr): ip4s.append(x) else: ip6s.append(x) - is_control = getattr(ifc, "control", False) - interfaces.append((ifc, ip4s, ip6s, is_control)) + is_control = getattr(iface, "control", False) + ifaces.append((iface, ip4s, ip6s, is_control)) return dict( frr_conf=frr_conf, frr_sbin_search=frr_sbin_search, frr_bin_search=frr_bin_search, frr_state_dir=constants.FRR_STATE_DIR, - interfaces=interfaces, + ifaces=ifaces, want_ip4=want_ip4, want_ip6=want_ip6, services=services, @@ -138,7 +136,7 @@ class FrrService(abc.ABC): ipv6_routing = False @abc.abstractmethod - def frr_interface_config(self, ifc: CoreInterface) -> str: + def frr_iface_config(self, iface: CoreInterface) -> str: raise NotImplementedError @abc.abstractmethod @@ -162,10 +160,8 @@ class FRROspfv2(FrrService, ConfigService): def frr_config(self) -> str: router_id = get_router_id(self.node) addresses = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - for a in ifc.addrlist: + for iface in self.node.get_ifaces(control=False): + for a in iface.addrlist: addr = a.split("/")[0] if netaddr.valid_ipv4(addr): addresses.append(a) @@ -180,8 +176,8 @@ class FRROspfv2(FrrService, ConfigService): """ return self.render_text(text, data) - def frr_interface_config(self, ifc: CoreInterface) -> str: - if has_mtu_mismatch(ifc): + def frr_iface_config(self, iface: CoreInterface) -> str: + if has_mtu_mismatch(iface): return "ip ospf mtu-ignore" else: return "" @@ -203,10 +199,8 @@ class FRROspfv3(FrrService, ConfigService): def frr_config(self) -> str: router_id = get_router_id(self.node) ifnames = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) data = dict(router_id=router_id, ifnames=ifnames) text = """ router ospf6 @@ -218,9 +212,9 @@ class FRROspfv3(FrrService, ConfigService): """ return self.render_text(text, data) - def frr_interface_config(self, ifc: CoreInterface) -> str: - mtu = get_min_mtu(ifc) - if mtu < ifc.mtu: + def frr_iface_config(self, iface: CoreInterface) -> str: + mtu = get_min_mtu(iface) + if mtu < iface.mtu: return f"ipv6 ospf6 ifmtu {mtu}" else: return "" @@ -254,7 +248,7 @@ class FRRBgp(FrrService, ConfigService): """ return self.clean_text(text) - def frr_interface_config(self, ifc: CoreInterface) -> str: + def frr_iface_config(self, iface: CoreInterface) -> str: return "" @@ -279,7 +273,7 @@ class FRRRip(FrrService, ConfigService): """ return self.clean_text(text) - def frr_interface_config(self, ifc: CoreInterface) -> str: + def frr_iface_config(self, iface: CoreInterface) -> str: return "" @@ -304,7 +298,7 @@ class FRRRipng(FrrService, ConfigService): """ return self.clean_text(text) - def frr_interface_config(self, ifc: CoreInterface) -> str: + def frr_iface_config(self, iface: CoreInterface) -> str: return "" @@ -321,10 +315,8 @@ class FRRBabel(FrrService, ConfigService): def frr_config(self) -> str: ifnames = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) text = """ router babel % for ifname in ifnames: @@ -337,8 +329,8 @@ class FRRBabel(FrrService, ConfigService): data = dict(ifnames=ifnames) return self.render_text(text, data) - def frr_interface_config(self, ifc: CoreInterface) -> str: - if isinstance(ifc.net, (WlanNode, EmaneNet)): + def frr_iface_config(self, iface: CoreInterface) -> str: + if isinstance(iface.net, (WlanNode, EmaneNet)): text = """ babel wireless no babel split-horizon @@ -363,9 +355,9 @@ class FRRpimd(FrrService, ConfigService): def frr_config(self) -> str: ifname = "eth0" - for ifc in self.node.netifs(): - if ifc.name != "lo": - ifname = ifc.name + for iface in self.node.get_ifaces(): + if iface.name != "lo": + ifname = iface.name break text = f""" @@ -382,7 +374,7 @@ class FRRpimd(FrrService, ConfigService): """ return self.clean_text(text) - def frr_interface_config(self, ifc: CoreInterface) -> str: + def frr_iface_config(self, iface: CoreInterface) -> str: text = """ ip mfea ip igmp diff --git a/daemon/core/configservices/frrservices/templates/frr.conf b/daemon/core/configservices/frrservices/templates/frr.conf index 748c8692..8e036136 100644 --- a/daemon/core/configservices/frrservices/templates/frr.conf +++ b/daemon/core/configservices/frrservices/templates/frr.conf @@ -1,5 +1,5 @@ -% for ifc, ip4s, ip6s, is_control in interfaces: -interface ${ifc.name} +% for iface, ip4s, ip6s, is_control in ifaces: +interface ${iface.name} % if want_ip4: % for addr in ip4s: ip address ${addr} @@ -12,7 +12,7 @@ interface ${ifc.name} % endif % if not is_control: % for service in services: - % for line in service.frr_interface_config(ifc).split("\n"): + % for line in service.frr_iface_config(iface).split("\n"): ${line} % endfor % endfor diff --git a/daemon/core/configservices/frrservices/templates/frrboot.sh b/daemon/core/configservices/frrservices/templates/frrboot.sh index 3c14cd1a..db47b6d1 100644 --- a/daemon/core/configservices/frrservices/templates/frrboot.sh +++ b/daemon/core/configservices/frrservices/templates/frrboot.sh @@ -98,8 +98,8 @@ confcheck bootfrr # reset interfaces -% for ifc, _, _ , _ in interfaces: -ip link set dev ${ifc.name} down +% for iface, _, _ , _ in ifaces: +ip link set dev ${iface.name} down sleep 1 -ip link set dev ${ifc.name} up +ip link set dev ${iface.name} up % endfor diff --git a/daemon/core/configservices/nrlservices/services.py b/daemon/core/configservices/nrlservices/services.py index 3dddf1ba..ca95b8f6 100644 --- a/daemon/core/configservices/nrlservices/services.py +++ b/daemon/core/configservices/nrlservices/services.py @@ -24,8 +24,8 @@ class MgenSinkService(ConfigService): def data(self) -> Dict[str, Any]: ifnames = [] - for ifc in self.node.netifs(): - name = utils.sysctl_devname(ifc.name) + for iface in self.node.get_ifaces(): + name = utils.sysctl_devname(iface.name) ifnames.append(name) return dict(ifnames=ifnames) @@ -47,10 +47,8 @@ class NrlNhdp(ConfigService): def data(self) -> Dict[str, Any]: has_smf = "SMF" in self.node.config_services ifnames = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) return dict(has_smf=has_smf, ifnames=ifnames) @@ -74,13 +72,11 @@ class NrlSmf(ConfigService): has_olsr = "OLSR" in self.node.config_services ifnames = [] ip4_prefix = None - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) if ip4_prefix: continue - for a in ifc.addrlist: + for a in iface.addrlist: a = a.split("/")[0] if netaddr.valid_ipv4(a): ip4_prefix = f"{a}/{24}" @@ -112,10 +108,8 @@ class NrlOlsr(ConfigService): has_smf = "SMF" in self.node.config_services has_zebra = "zebra" in self.node.config_services ifname = None - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifname = ifc.name + for iface in self.node.get_ifaces(control=False): + ifname = iface.name break return dict(has_smf=has_smf, has_zebra=has_zebra, ifname=ifname) @@ -137,10 +131,8 @@ class NrlOlsrv2(ConfigService): def data(self) -> Dict[str, Any]: has_smf = "SMF" in self.node.config_services ifnames = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) return dict(has_smf=has_smf, ifnames=ifnames) @@ -161,10 +153,8 @@ class OlsrOrg(ConfigService): def data(self) -> Dict[str, Any]: has_smf = "SMF" in self.node.config_services ifnames = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) return dict(has_smf=has_smf, ifnames=ifnames) @@ -199,12 +189,10 @@ class Arouted(ConfigService): def data(self) -> Dict[str, Any]: ip4_prefix = None - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue + for iface in self.node.get_ifaces(control=False): if ip4_prefix: continue - for a in ifc.addrlist: + for a in iface.addrlist: a = a.split("/")[0] if netaddr.valid_ipv4(a): ip4_prefix = f"{a}/{24}" diff --git a/daemon/core/configservices/nrlservices/templates/nrlnhdp.sh b/daemon/core/configservices/nrlservices/templates/nrlnhdp.sh index 00b7e11d..4513dfe9 100644 --- a/daemon/core/configservices/nrlservices/templates/nrlnhdp.sh +++ b/daemon/core/configservices/nrlservices/templates/nrlnhdp.sh @@ -1,7 +1,7 @@ <% - interfaces = "-i " + " -i ".join(ifnames) + ifaces = "-i " + " -i ".join(ifnames) smf = "" if has_smf: smf = "-flooding ecds -smfClient %s_smf" % node.name %> -nrlnhdp -l /var/log/nrlnhdp.log -rpipe ${node.name}_nhdp ${smf} ${interfaces} +nrlnhdp -l /var/log/nrlnhdp.log -rpipe ${node.name}_nhdp ${smf} ${ifaces} diff --git a/daemon/core/configservices/nrlservices/templates/nrlolsrv2.sh b/daemon/core/configservices/nrlservices/templates/nrlolsrv2.sh index d7a8d3b6..81196e26 100644 --- a/daemon/core/configservices/nrlservices/templates/nrlolsrv2.sh +++ b/daemon/core/configservices/nrlservices/templates/nrlolsrv2.sh @@ -1,7 +1,7 @@ <% - interfaces = "-i " + " -i ".join(ifnames) + ifaces = "-i " + " -i ".join(ifnames) smf = "" if has_smf: smf = "-flooding ecds -smfClient %s_smf" % node.name %> -nrlolsrv2 -l /var/log/nrlolsrv2.log -rpipe ${node.name}_olsrv2 -p olsr ${smf} ${interfaces} +nrlolsrv2 -l /var/log/nrlolsrv2.log -rpipe ${node.name}_olsrv2 -p olsr ${smf} ${ifaces} diff --git a/daemon/core/configservices/nrlservices/templates/olsrd.sh b/daemon/core/configservices/nrlservices/templates/olsrd.sh index 076f049b..3040ca6b 100644 --- a/daemon/core/configservices/nrlservices/templates/olsrd.sh +++ b/daemon/core/configservices/nrlservices/templates/olsrd.sh @@ -1,4 +1,4 @@ <% - interfaces = "-i " + " -i ".join(ifnames) + ifaces = "-i " + " -i ".join(ifnames) %> -olsrd ${interfaces} +olsrd ${ifaces} diff --git a/daemon/core/configservices/nrlservices/templates/startsmf.sh b/daemon/core/configservices/nrlservices/templates/startsmf.sh index 67fc0fe6..921568de 100644 --- a/daemon/core/configservices/nrlservices/templates/startsmf.sh +++ b/daemon/core/configservices/nrlservices/templates/startsmf.sh @@ -1,5 +1,5 @@ <% - interfaces = ",".join(ifnames) + ifaces = ",".join(ifnames) arouted = "" if has_arouted: arouted = "tap %s_tap unicast %s push lo,%s resequence on" % (node.name, ip4_prefix, ifnames[0]) @@ -12,4 +12,4 @@ %> #!/bin/sh # auto-generated by NrlSmf service -nrlsmf instance ${node.name}_smf ${interfaces} ${arouted} ${flood} hash MD5 log /var/log/nrlsmf.log < /dev/null > /dev/null 2>&1 & +nrlsmf instance ${node.name}_smf ${ifaces} ${arouted} ${flood} hash MD5 log /var/log/nrlsmf.log < /dev/null > /dev/null 2>&1 & diff --git a/daemon/core/configservices/quaggaservices/services.py b/daemon/core/configservices/quaggaservices/services.py index 32ce99be..19e21476 100644 --- a/daemon/core/configservices/quaggaservices/services.py +++ b/daemon/core/configservices/quaggaservices/services.py @@ -14,33 +14,33 @@ from core.nodes.network import WlanNode GROUP = "Quagga" -def has_mtu_mismatch(ifc: CoreInterface) -> bool: +def has_mtu_mismatch(iface: CoreInterface) -> bool: """ Helper to detect MTU mismatch and add the appropriate OSPF mtu-ignore command. This is needed when e.g. a node is linked via a GreTap device. """ - if ifc.mtu != 1500: + if iface.mtu != 1500: return True - if not ifc.net: + if not iface.net: return False - for i in ifc.net.netifs(): - if i.mtu != ifc.mtu: + for iface in iface.net.get_ifaces(): + if iface.mtu != iface.mtu: return True return False -def get_min_mtu(ifc): +def get_min_mtu(iface: CoreInterface): """ Helper to discover the minimum MTU of interfaces linked with the given interface. """ - mtu = ifc.mtu - if not ifc.net: + mtu = iface.mtu + if not iface.net: return mtu - for i in ifc.net.netifs(): - if i.mtu < mtu: - mtu = i.mtu + for iface in iface.net.get_ifaces(): + if iface.mtu < mtu: + mtu = iface.mtu return mtu @@ -48,10 +48,8 @@ def get_router_id(node: CoreNodeBase) -> str: """ Helper to return the first IPv4 address of a node as its router ID. """ - for ifc in node.netifs(): - if getattr(ifc, "control", False): - continue - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + for a in iface.addrlist: a = a.split("/")[0] if netaddr.valid_ipv4(a): return a @@ -98,25 +96,25 @@ class Zebra(ConfigService): want_ip6 = True services.append(service) - interfaces = [] - for ifc in self.node.netifs(): + ifaces = [] + for iface in self.node.get_ifaces(): ip4s = [] ip6s = [] - for x in ifc.addrlist: + for x in iface.addrlist: addr = x.split("/")[0] if netaddr.valid_ipv4(addr): ip4s.append(x) else: ip6s.append(x) - is_control = getattr(ifc, "control", False) - interfaces.append((ifc, ip4s, ip6s, is_control)) + is_control = getattr(iface, "control", False) + ifaces.append((iface, ip4s, ip6s, is_control)) return dict( quagga_bin_search=quagga_bin_search, quagga_sbin_search=quagga_sbin_search, quagga_state_dir=quagga_state_dir, quagga_conf=quagga_conf, - interfaces=interfaces, + ifaces=ifaces, want_ip4=want_ip4, want_ip6=want_ip6, services=services, @@ -139,7 +137,7 @@ class QuaggaService(abc.ABC): ipv6_routing = False @abc.abstractmethod - def quagga_interface_config(self, ifc: CoreInterface) -> str: + def quagga_iface_config(self, iface: CoreInterface) -> str: raise NotImplementedError @abc.abstractmethod @@ -159,8 +157,8 @@ class Ospfv2(QuaggaService, ConfigService): shutdown = ["killall ospfd"] ipv4_routing = True - def quagga_interface_config(self, ifc: CoreInterface) -> str: - if has_mtu_mismatch(ifc): + def quagga_iface_config(self, iface: CoreInterface) -> str: + if has_mtu_mismatch(iface): return "ip ospf mtu-ignore" else: return "" @@ -168,10 +166,8 @@ class Ospfv2(QuaggaService, ConfigService): def quagga_config(self) -> str: router_id = get_router_id(self.node) addresses = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - for a in ifc.addrlist: + for iface in self.node.get_ifaces(control=False): + for a in iface.addrlist: addr = a.split("/")[0] if netaddr.valid_ipv4(addr): addresses.append(a) @@ -200,9 +196,9 @@ class Ospfv3(QuaggaService, ConfigService): ipv4_routing = True ipv6_routing = True - def quagga_interface_config(self, ifc: CoreInterface) -> str: - mtu = get_min_mtu(ifc) - if mtu < ifc.mtu: + def quagga_iface_config(self, iface: CoreInterface) -> str: + mtu = get_min_mtu(iface) + if mtu < iface.mtu: return f"ipv6 ospf6 ifmtu {mtu}" else: return "" @@ -210,10 +206,8 @@ class Ospfv3(QuaggaService, ConfigService): def quagga_config(self) -> str: router_id = get_router_id(self.node) ifnames = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) data = dict(router_id=router_id, ifnames=ifnames) text = """ router ospf6 @@ -238,14 +232,14 @@ class Ospfv3mdr(Ospfv3): name = "OSPFv3MDR" def data(self) -> Dict[str, Any]: - for ifc in self.node.netifs(): - is_wireless = isinstance(ifc.net, (WlanNode, EmaneNet)) + for iface in self.node.get_ifaces(): + is_wireless = isinstance(iface.net, (WlanNode, EmaneNet)) logging.info("MDR wireless: %s", is_wireless) return dict() - def quagga_interface_config(self, ifc: CoreInterface) -> str: - config = super().quagga_interface_config(ifc) - if isinstance(ifc.net, (WlanNode, EmaneNet)): + def quagga_iface_config(self, iface: CoreInterface) -> str: + config = super().quagga_iface_config(iface) + if isinstance(iface.net, (WlanNode, EmaneNet)): config = self.clean_text( f""" {config} @@ -277,7 +271,7 @@ class Bgp(QuaggaService, ConfigService): def quagga_config(self) -> str: return "" - def quagga_interface_config(self, ifc: CoreInterface) -> str: + def quagga_iface_config(self, iface: CoreInterface) -> str: router_id = get_router_id(self.node) text = f""" ! BGP configuration @@ -313,7 +307,7 @@ class Rip(QuaggaService, ConfigService): """ return self.clean_text(text) - def quagga_interface_config(self, ifc: CoreInterface) -> str: + def quagga_iface_config(self, iface: CoreInterface) -> str: return "" @@ -338,7 +332,7 @@ class Ripng(QuaggaService, ConfigService): """ return self.clean_text(text) - def quagga_interface_config(self, ifc: CoreInterface) -> str: + def quagga_iface_config(self, iface: CoreInterface) -> str: return "" @@ -355,10 +349,8 @@ class Babel(QuaggaService, ConfigService): def quagga_config(self) -> str: ifnames = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) text = """ router babel % for ifname in ifnames: @@ -371,8 +363,8 @@ class Babel(QuaggaService, ConfigService): data = dict(ifnames=ifnames) return self.render_text(text, data) - def quagga_interface_config(self, ifc: CoreInterface) -> str: - if isinstance(ifc.net, (WlanNode, EmaneNet)): + def quagga_iface_config(self, iface: CoreInterface) -> str: + if isinstance(iface.net, (WlanNode, EmaneNet)): text = """ babel wireless no babel split-horizon @@ -397,9 +389,9 @@ class Xpimd(QuaggaService, ConfigService): def quagga_config(self) -> str: ifname = "eth0" - for ifc in self.node.netifs(): - if ifc.name != "lo": - ifname = ifc.name + for iface in self.node.get_ifaces(): + if iface.name != "lo": + ifname = iface.name break text = f""" @@ -416,7 +408,7 @@ class Xpimd(QuaggaService, ConfigService): """ return self.clean_text(text) - def quagga_interface_config(self, ifc: CoreInterface) -> str: + def quagga_iface_config(self, iface: CoreInterface) -> str: text = """ ip mfea ip pim diff --git a/daemon/core/configservices/quaggaservices/templates/Quagga.conf b/daemon/core/configservices/quaggaservices/templates/Quagga.conf index 853b1707..1d69838f 100644 --- a/daemon/core/configservices/quaggaservices/templates/Quagga.conf +++ b/daemon/core/configservices/quaggaservices/templates/Quagga.conf @@ -1,5 +1,5 @@ -% for ifc, ip4s, ip6s, is_control in interfaces: -interface ${ifc.name} +% for iface, ip4s, ip6s, is_control in ifaces: +interface ${iface.name} % if want_ip4: % for addr in ip4s: ip address ${addr} @@ -12,7 +12,7 @@ interface ${ifc.name} % endif % if not is_control: % for service in services: - % for line in service.quagga_interface_config(ifc).split("\n"): + % for line in service.quagga_iface_config(iface).split("\n"): ${line} % endfor % endfor diff --git a/daemon/core/configservices/sercurityservices/services.py b/daemon/core/configservices/sercurityservices/services.py index 17f081cd..6e92bf62 100644 --- a/daemon/core/configservices/sercurityservices/services.py +++ b/daemon/core/configservices/sercurityservices/services.py @@ -78,10 +78,8 @@ class VpnServer(ConfigService): def data(self) -> Dict[str, Any]: address = None - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - for x in ifc.addrlist: + for iface in self.node.get_ifaces(control=False): + for x in iface.addrlist: addr = x.split("/")[0] if netaddr.valid_ipv4(addr): address = addr @@ -134,8 +132,6 @@ class Nat(ConfigService): def data(self) -> Dict[str, Any]: ifnames = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) return dict(ifnames=ifnames) diff --git a/daemon/core/configservices/utilservices/services.py b/daemon/core/configservices/utilservices/services.py index 8ddf1cc7..5aa3bb54 100644 --- a/daemon/core/configservices/utilservices/services.py +++ b/daemon/core/configservices/utilservices/services.py @@ -25,10 +25,10 @@ class DefaultRouteService(ConfigService): def data(self) -> Dict[str, Any]: # only add default routes for linked routing nodes routes = [] - netifs = self.node.netifs(sort=True) - if netifs: - netif = netifs[0] - for x in netif.addrlist: + ifaces = self.node.get_ifaces() + if ifaces: + iface = ifaces[0] + for x in iface.addrlist: net = netaddr.IPNetwork(x).cidr if net.size > 1: router = net[1] @@ -52,10 +52,8 @@ class DefaultMulticastRouteService(ConfigService): def data(self) -> Dict[str, Any]: ifname = None - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifname = ifc.name + for iface in self.node.get_ifaces(control=False): + ifname = iface.name break return dict(ifname=ifname) @@ -76,10 +74,8 @@ class StaticRouteService(ConfigService): def data(self) -> Dict[str, Any]: routes = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - for x in ifc.addrlist: + for iface in self.node.get_ifaces(control=False): + for x in iface.addrlist: addr = x.split("/")[0] if netaddr.valid_ipv6(addr): dst = "3ffe:4::/64" @@ -107,8 +103,8 @@ class IpForwardService(ConfigService): def data(self) -> Dict[str, Any]: devnames = [] - for ifc in self.node.netifs(): - devname = utils.sysctl_devname(ifc.name) + for iface in self.node.get_ifaces(): + devname = utils.sysctl_devname(iface.name) devnames.append(devname) return dict(devnames=devnames) @@ -151,10 +147,8 @@ class DhcpService(ConfigService): def data(self) -> Dict[str, Any]: subnets = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - for x in ifc.addrlist: + for iface in self.node.get_ifaces(control=False): + for x in iface.addrlist: addr = x.split("/")[0] if netaddr.valid_ipv4(addr): net = netaddr.IPNetwork(x) @@ -182,10 +176,8 @@ class DhcpClientService(ConfigService): def data(self) -> Dict[str, Any]: ifnames = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) return dict(ifnames=ifnames) @@ -220,10 +212,8 @@ class PcapService(ConfigService): def data(self) -> Dict[str, Any]: ifnames = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - ifnames.append(ifc.name) + for iface in self.node.get_ifaces(control=False): + ifnames.append(iface.name) return dict() @@ -242,19 +232,17 @@ class RadvdService(ConfigService): modes = {} def data(self) -> Dict[str, Any]: - interfaces = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue + ifaces = [] + for iface in self.node.get_ifaces(control=False): prefixes = [] - for x in ifc.addrlist: + for x in iface.addrlist: addr = x.split("/")[0] if netaddr.valid_ipv6(addr): prefixes.append(x) if not prefixes: continue - interfaces.append((ifc.name, prefixes)) - return dict(interfaces=interfaces) + ifaces.append((iface.name, prefixes)) + return dict(ifaces=ifaces) class AtdService(ConfigService): @@ -294,9 +282,7 @@ class HttpService(ConfigService): modes = {} def data(self) -> Dict[str, Any]: - interfaces = [] - for ifc in self.node.netifs(): - if getattr(ifc, "control", False): - continue - interfaces.append(ifc) - return dict(interfaces=interfaces) + ifaces = [] + for iface in self.node.get_ifaces(control=False): + ifaces.append(iface) + return dict(ifaces=ifaces) diff --git a/daemon/core/configservices/utilservices/templates/index.html b/daemon/core/configservices/utilservices/templates/index.html index aaf9d9fa..bed270ae 100644 --- a/daemon/core/configservices/utilservices/templates/index.html +++ b/daemon/core/configservices/utilservices/templates/index.html @@ -5,8 +5,8 @@ <p>This is the default web page for this server.</p> <p>The web server software is running but no content has been added, yet.</p> <ul> -% for ifc in interfaces: - <li>${ifc.name} - ${ifc.addrlist}</li> +% for iface in ifaces: + <li>${iface.name} - ${iface.addrlist}</li> % endfor </ul> </body> diff --git a/daemon/core/emane/commeffect.py b/daemon/core/emane/commeffect.py index 21252b6f..610099f1 100644 --- a/daemon/core/emane/commeffect.py +++ b/daemon/core/emane/commeffect.py @@ -11,7 +11,7 @@ from lxml import etree from core.config import ConfigGroup, Configuration from core.emane import emanemanifest, emanemodel from core.emane.nodes import EmaneNet -from core.emulator.emudata import LinkOptions +from core.emulator.data import LinkOptions from core.emulator.enumerations import TransportType from core.nodes.interface import CoreInterface from core.xml import emanexml @@ -63,7 +63,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel): return [ConfigGroup("CommEffect SHIM Parameters", 1, len(cls.configurations()))] def build_xml_files( - self, config: Dict[str, str], interface: CoreInterface = None + self, config: Dict[str, str], iface: CoreInterface = None ) -> None: """ Build the necessary nem and commeffect XMLs in the given path. @@ -72,17 +72,17 @@ class EmaneCommEffectModel(emanemodel.EmaneModel): nXXemane_commeffectnem.xml, nXXemane_commeffectshim.xml are used. :param config: emane model configuration for the node and interface - :param interface: interface for the emane node + :param iface: interface for the emane node :return: nothing """ # retrieve xml names - nem_name = emanexml.nem_file_name(self, interface) - shim_name = emanexml.shim_file_name(self, interface) + nem_name = emanexml.nem_file_name(self, iface) + shim_name = emanexml.shim_file_name(self, iface) # create and write nem document nem_element = etree.Element("nem", name=f"{self.name} NEM", type="unstructured") transport_type = TransportType.VIRTUAL - if interface and interface.transport_type == TransportType.RAW: + if iface and iface.transport_type == TransportType.RAW: transport_type = TransportType.RAW transport_file = emanexml.transport_file_name(self.id, transport_type) etree.SubElement(nem_element, "transport", definition=transport_file) @@ -115,7 +115,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel): emanexml.create_file(shim_element, "shim", shim_file) def linkconfig( - self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None + self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None ) -> None: """ Generate CommEffect events when a Link Message is received having @@ -126,7 +126,7 @@ class EmaneCommEffectModel(emanemodel.EmaneModel): logging.warning("%s: EMANE event service unavailable", self.name) return - if netif is None or netif2 is None: + if iface is None or iface2 is None: logging.warning("%s: missing NEM information", self.name) return @@ -134,8 +134,8 @@ class EmaneCommEffectModel(emanemodel.EmaneModel): # TODO: may want to split out seconds portion of delay and jitter event = CommEffectEvent() emane_node = self.session.get_node(self.id, EmaneNet) - nemid = emane_node.getnemid(netif) - nemid2 = emane_node.getnemid(netif2) + nemid = emane_node.getnemid(iface) + nemid2 = emane_node.getnemid(iface2) logging.info("sending comm effect event") event.append( nemid, diff --git a/daemon/core/emane/emanemanager.py b/daemon/core/emane/emanemanager.py index cb978cb9..fc561b5f 100644 --- a/daemon/core/emane/emanemanager.py +++ b/daemon/core/emane/emanemanager.py @@ -111,41 +111,39 @@ class EmaneManager(ModelManager): self.event_device: Optional[str] = None self.emane_check() - def getifcconfig( - self, node_id: int, interface: CoreInterface, model_name: str + def get_iface_config( + self, node_id: int, iface: CoreInterface, model_name: str ) -> Dict[str, str]: """ Retrieve interface configuration or node configuration if not provided. :param node_id: node id - :param interface: node interface + :param iface: node interface :param model_name: model to get configuration for :return: node/interface model configuration """ # use the network-wide config values or interface(NEM)-specific values? - if interface is None: + if iface is None: return self.get_configs(node_id=node_id, config_type=model_name) else: # don"t use default values when interface config is the same as net - # note here that using ifc.node.id as key allows for only one type + # note here that using iface.node.id as key allows for only one type # of each model per node; # TODO: use both node and interface as key - # Adamson change: first check for iface config keyed by "node:ifc.name" + # Adamson change: first check for iface config keyed by "node:iface.name" # (so that nodes w/ multiple interfaces of same conftype can have # different configs for each separate interface) - key = 1000 * interface.node.id - if interface.netindex is not None: - key += interface.netindex + key = 1000 * iface.node.id + if iface.node_id is not None: + key += iface.node_id # try retrieve interface specific configuration, avoid getting defaults config = self.get_configs(node_id=key, config_type=model_name) # otherwise retrieve the interfaces node configuration, avoid using defaults if not config: - config = self.get_configs( - node_id=interface.node.id, config_type=model_name - ) + config = self.get_configs(node_id=iface.node.id, config_type=model_name) # get non interface config, when none found if not config: @@ -265,8 +263,8 @@ class EmaneManager(ModelManager): # assumes self._objslock already held nodes = set() for emane_net in self._emane_nets.values(): - for netif in emane_net.netifs(): - nodes.add(netif.node) + for iface in emane_net.get_ifaces(): + nodes.add(iface.node) return nodes def setup(self) -> int: @@ -352,13 +350,13 @@ class EmaneManager(ModelManager): if self.numnems() > 0: self.startdaemons() - self.installnetifs() + self.install_ifaces() for node_id in self._emane_nets: emane_node = self._emane_nets[node_id] - for netif in emane_node.netifs(): + for iface in emane_node.get_ifaces(): nems.append( - (netif.node.name, netif.name, emane_node.getnemid(netif)) + (iface.node.name, iface.name, emane_node.getnemid(iface)) ) if nems: @@ -392,8 +390,8 @@ class EmaneManager(ModelManager): emane_node.name, ) emane_node.model.post_startup() - for netif in emane_node.netifs(): - netif.setposition() + for iface in emane_node.get_ifaces(): + iface.setposition() def reset(self) -> None: """ @@ -420,7 +418,7 @@ class EmaneManager(ModelManager): logging.info("stopping EMANE daemons") if self.links_enabled(): self.link_monitor.stop() - self.deinstallnetifs() + self.deinstall_ifaces() self.stopdaemons() self.stopeventmonitor() @@ -474,38 +472,38 @@ class EmaneManager(ModelManager): EMANE network and NEM interface. """ emane_node = None - netif = None + iface = None for node_id in self._emane_nets: emane_node = self._emane_nets[node_id] - netif = emane_node.getnemnetif(nemid) - if netif is not None: + iface = emane_node.get_nem_iface(nemid) + if iface is not None: break else: emane_node = None - return emane_node, netif + return emane_node, iface def get_nem_link( self, nem1: int, nem2: int, flags: MessageFlags = MessageFlags.NONE ) -> Optional[LinkData]: - emane1, netif = self.nemlookup(nem1) - if not emane1 or not netif: + emane1, iface = self.nemlookup(nem1) + if not emane1 or not iface: logging.error("invalid nem: %s", nem1) return None - node1 = netif.node - emane2, netif = self.nemlookup(nem2) - if not emane2 or not netif: + node1 = iface.node + emane2, iface = self.nemlookup(nem2) + if not emane2 or not iface: logging.error("invalid nem: %s", nem2) return None - node2 = netif.node + node2 = iface.node color = self.session.get_link_color(emane1.id) return LinkData( message_type=flags, + type=LinkTypes.WIRELESS, node1_id=node1.id, node2_id=node2.id, network_id=emane1.id, - link_type=LinkTypes.WIRELESS, color=color, ) @@ -516,7 +514,7 @@ class EmaneManager(ModelManager): count = 0 for node_id in self._emane_nets: emane_node = self._emane_nets[node_id] - count += len(emane_node.netifs()) + count += len(emane_node.ifaces) return count def buildplatformxml(self, ctrlnet: CtrlNet) -> None: @@ -607,19 +605,19 @@ class EmaneManager(ModelManager): n = node.id # control network not yet started here - self.session.add_remove_control_interface( + self.session.add_remove_control_iface( node, 0, remove=False, conf_required=False ) if otanetidx > 0: logging.info("adding ota device ctrl%d", otanetidx) - self.session.add_remove_control_interface( + self.session.add_remove_control_iface( node, otanetidx, remove=False, conf_required=False ) if eventservicenetidx >= 0: logging.info("adding event service device ctrl%d", eventservicenetidx) - self.session.add_remove_control_interface( + self.session.add_remove_control_iface( node, eventservicenetidx, remove=False, conf_required=False ) @@ -676,23 +674,23 @@ class EmaneManager(ModelManager): except CoreCommandError: logging.exception("error shutting down emane daemons") - def installnetifs(self) -> None: + def install_ifaces(self) -> None: """ Install TUN/TAP virtual interfaces into their proper namespaces now that the EMANE daemons are running. """ for key in sorted(self._emane_nets.keys()): - emane_node = self._emane_nets[key] - logging.info("emane install netifs for node: %d", key) - emane_node.installnetifs() + node = self._emane_nets[key] + logging.info("emane install interface for node(%s): %d", node.name, key) + node.install_ifaces() - def deinstallnetifs(self) -> None: + def deinstall_ifaces(self) -> None: """ Uninstall TUN/TAP virtual interfaces. """ for key in sorted(self._emane_nets.keys()): emane_node = self._emane_nets[key] - emane_node.deinstallnetifs() + emane_node.deinstall_ifaces() def doeventmonitor(self) -> bool: """ @@ -808,12 +806,12 @@ class EmaneManager(ModelManager): Returns True if successfully parsed and a Node Message was sent. """ # convert nemid to node number - _emanenode, netif = self.nemlookup(nemid) - if netif is None: + _emanenode, iface = self.nemlookup(nemid) + if iface is None: logging.info("location event for unknown NEM %s", nemid) return False - n = netif.node.id + n = iface.node.id # convert from lat/long/alt to x,y,z coordinates x, y, z = self.session.location.getxyz(lat, lon, alt) x = int(x) diff --git a/daemon/core/emane/emanemodel.py b/daemon/core/emane/emanemodel.py index 78d5ec5e..43fbc0fb 100644 --- a/daemon/core/emane/emanemodel.py +++ b/daemon/core/emane/emanemodel.py @@ -8,7 +8,7 @@ from typing import Dict, List, Optional, Set from core.config import ConfigGroup, Configuration from core.emane import emanemanifest from core.emane.nodes import EmaneNet -from core.emulator.emudata import LinkOptions +from core.emulator.data import LinkOptions from core.emulator.enumerations import ConfigDataTypes, TransportType from core.errors import CoreError from core.location.mobility import WirelessModel @@ -97,28 +97,28 @@ class EmaneModel(WirelessModel): ] def build_xml_files( - self, config: Dict[str, str], interface: CoreInterface = None + self, config: Dict[str, str], iface: CoreInterface = None ) -> None: """ Builds xml files for this emane model. Creates a nem.xml file that points to both mac.xml and phy.xml definitions. :param config: emane model configuration for the node and interface - :param interface: interface for the emane node + :param iface: interface for the emane node :return: nothing """ - nem_name = emanexml.nem_file_name(self, interface) - mac_name = emanexml.mac_file_name(self, interface) - phy_name = emanexml.phy_file_name(self, interface) + nem_name = emanexml.nem_file_name(self, iface) + mac_name = emanexml.mac_file_name(self, iface) + phy_name = emanexml.phy_file_name(self, iface) # remote server for file server = None - if interface is not None: - server = interface.node.server + if iface is not None: + server = iface.node.server # check if this is external transport_type = TransportType.VIRTUAL - if interface and interface.transport_type == TransportType.RAW: + if iface and iface.transport_type == TransportType.RAW: transport_type = TransportType.RAW transport_name = emanexml.transport_file_name(self.id, transport_type) @@ -144,31 +144,31 @@ class EmaneModel(WirelessModel): """ logging.debug("emane model(%s) has no post setup tasks", self.name) - def update(self, moved: List[CoreNode], moved_netifs: List[CoreInterface]) -> None: + def update(self, moved: List[CoreNode], moved_ifaces: List[CoreInterface]) -> None: """ Invoked from MobilityModel when nodes are moved; this causes emane location events to be generated for the nodes in the moved list, making EmaneModels compatible with Ns2ScriptedMobility. :param moved: moved nodes - :param moved_netifs: interfaces that were moved + :param moved_ifaces: interfaces that were moved :return: nothing """ try: wlan = self.session.get_node(self.id, EmaneNet) - wlan.setnempositions(moved_netifs) + wlan.setnempositions(moved_ifaces) except CoreError: logging.exception("error during update") def linkconfig( - self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None + self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None ) -> None: """ Invoked when a Link Message is received. Default is unimplemented. - :param netif: interface one + :param iface: interface one :param options: options for configuring link - :param netif2: interface two + :param iface2: interface two :return: nothing """ logging.warning("emane model(%s) does not support link config", self.name) diff --git a/daemon/core/emane/linkmonitor.py b/daemon/core/emane/linkmonitor.py index ca9f4493..1a9ac41a 100644 --- a/daemon/core/emane/linkmonitor.py +++ b/daemon/core/emane/linkmonitor.py @@ -212,10 +212,10 @@ class EmaneLinkMonitor: addresses = [] nodes = self.emane_manager.getnodes() for node in nodes: - for netif in node.netifs(): - if isinstance(netif.net, CtrlNet): + for iface in node.get_ifaces(): + if isinstance(iface.net, CtrlNet): ip4 = None - for x in netif.addrlist: + for x in iface.addrlist: address, prefix = x.split("/") if netaddr.valid_ipv4(address): ip4 = address @@ -305,11 +305,11 @@ class EmaneLinkMonitor: color = self.emane_manager.session.get_link_color(emane_id) link_data = LinkData( message_type=message_type, + type=LinkTypes.WIRELESS, label=label, node1_id=node1, node2_id=node2, network_id=emane_id, - link_type=LinkTypes.WIRELESS, color=color, ) self.emane_manager.session.broadcast_link(link_data) diff --git a/daemon/core/emane/nodes.py b/daemon/core/emane/nodes.py index c4c3428b..c28f1382 100644 --- a/daemon/core/emane/nodes.py +++ b/daemon/core/emane/nodes.py @@ -6,9 +6,8 @@ share the same MAC+PHY model. import logging from typing import TYPE_CHECKING, Dict, List, Optional, Tuple, Type -from core.emulator.data import LinkData +from core.emulator.data import LinkData, LinkOptions from core.emulator.distributed import DistributedServer -from core.emulator.emudata import LinkOptions from core.emulator.enumerations import ( LinkTypes, MessageFlags, @@ -64,14 +63,14 @@ class EmaneNet(CoreNetworkBase): self.mobility: Optional[WayPointMobility] = None def linkconfig( - self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None + self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None ) -> None: """ The CommEffect model supports link configuration. """ if not self.model: return - self.model.linkconfig(netif, options, netif2) + self.model.linkconfig(iface, options, iface2) def config(self, conf: str) -> None: self.conf = conf @@ -82,10 +81,10 @@ class EmaneNet(CoreNetworkBase): def shutdown(self) -> None: pass - def link(self, netif1: CoreInterface, netif2: CoreInterface) -> None: + def link(self, iface1: CoreInterface, iface2: CoreInterface) -> None: pass - def unlink(self, netif1: CoreInterface, netif2: CoreInterface) -> None: + def unlink(self, iface1: CoreInterface, iface2: CoreInterface) -> None: pass def linknet(self, net: "CoreNetworkBase") -> CoreInterface: @@ -113,39 +112,33 @@ class EmaneNet(CoreNetworkBase): self.mobility = model(session=self.session, _id=self.id) self.mobility.update_config(config) - def setnemid(self, netif: CoreInterface, nemid: int) -> None: + def setnemid(self, iface: CoreInterface, nemid: int) -> None: """ Record an interface to numerical ID mapping. The Emane controller object manages and assigns these IDs for all NEMs. """ - self.nemidmap[netif] = nemid + self.nemidmap[iface] = nemid - def getnemid(self, netif: CoreInterface) -> Optional[int]: + def getnemid(self, iface: CoreInterface) -> Optional[int]: """ Given an interface, return its numerical ID. """ - if netif not in self.nemidmap: + if iface not in self.nemidmap: return None else: - return self.nemidmap[netif] + return self.nemidmap[iface] - def getnemnetif(self, nemid: int) -> Optional[CoreInterface]: + def get_nem_iface(self, nemid: int) -> Optional[CoreInterface]: """ Given a numerical NEM ID, return its interface. This returns the first interface that matches the given NEM ID. """ - for netif in self.nemidmap: - if self.nemidmap[netif] == nemid: - return netif + for iface in self.nemidmap: + if self.nemidmap[iface] == nemid: + return iface return None - def netifs(self, sort: bool = True) -> List[CoreInterface]: - """ - Retrieve list of linked interfaces sorted by node number. - """ - return sorted(self._netif.values(), key=lambda ifc: ifc.node.id) - - def installnetifs(self) -> None: + def install_ifaces(self) -> None: """ Install TAP devices into their namespaces. This is done after EMANE daemons have been started, because that is their only chance @@ -159,48 +152,48 @@ class EmaneNet(CoreNetworkBase): warntxt += "Python bindings failed to load" logging.error(warntxt) - for netif in self.netifs(): + for iface in self.get_ifaces(): external = self.session.emane.get_config( "external", self.id, self.model.name ) if external == "0": - netif.setaddrs() + iface.setaddrs() if not self.session.emane.genlocationevents(): - netif.poshook = None + iface.poshook = None continue # at this point we register location handlers for generating # EMANE location events - netif.poshook = self.setnemposition - netif.setposition() + iface.poshook = self.setnemposition + iface.setposition() - def deinstallnetifs(self) -> None: + def deinstall_ifaces(self) -> None: """ Uninstall TAP devices. This invokes their shutdown method for any required cleanup; the device may be actually removed when emanetransportd terminates. """ - for netif in self.netifs(): - if netif.transport_type == TransportType.VIRTUAL: - netif.shutdown() - netif.poshook = None + for iface in self.get_ifaces(): + if iface.transport_type == TransportType.VIRTUAL: + iface.shutdown() + iface.poshook = None def _nem_position( - self, netif: CoreInterface + self, iface: CoreInterface ) -> Optional[Tuple[int, float, float, float]]: """ Creates nem position for emane event for a given interface. - :param netif: interface to get nem emane position for + :param iface: interface to get nem emane position for :return: nem position tuple, None otherwise """ - nemid = self.getnemid(netif) - ifname = netif.localname + nemid = self.getnemid(iface) + ifname = iface.localname if nemid is None: logging.info("nemid for %s is unknown", ifname) return - node = netif.node + node = iface.node x, y, z = node.getposition() lat, lon, alt = self.session.location.getgeo(x, y, z) if node.position.alt is not None: @@ -210,30 +203,30 @@ class EmaneNet(CoreNetworkBase): alt = int(round(alt)) return nemid, lon, lat, alt - def setnemposition(self, netif: CoreInterface) -> None: + def setnemposition(self, iface: CoreInterface) -> None: """ Publish a NEM location change event using the EMANE event service. - :param netif: interface to set nem position for + :param iface: interface to set nem position for """ if self.session.emane.service is None: logging.info("position service not available") return - position = self._nem_position(netif) + position = self._nem_position(iface) if position: nemid, lon, lat, alt = position event = LocationEvent() event.append(nemid, latitude=lat, longitude=lon, altitude=alt) self.session.emane.service.publish(0, event) - def setnempositions(self, moved_netifs: List[CoreInterface]) -> None: + def setnempositions(self, moved_ifaces: List[CoreInterface]) -> None: """ Several NEMs have moved, from e.g. a WaypointMobilityModel calculation. Generate an EMANE Location Event having several - entries for each netif that has moved. + entries for each interface that has moved. """ - if len(moved_netifs) == 0: + if len(moved_ifaces) == 0: return if self.session.emane.service is None: @@ -241,8 +234,8 @@ class EmaneNet(CoreNetworkBase): return event = LocationEvent() - for netif in moved_netifs: - position = self._nem_position(netif) + for iface in moved_ifaces: + position = self._nem_position(iface) if position: nemid, lon, lat, alt = position event.append(nemid, latitude=lat, longitude=lon, altitude=alt) diff --git a/daemon/core/emulator/data.py b/daemon/core/emulator/data.py index 819716e3..5b6479ae 100644 --- a/daemon/core/emulator/data.py +++ b/daemon/core/emulator/data.py @@ -1,18 +1,22 @@ """ CORE data objects. """ +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, List, Optional, Tuple -from dataclasses import dataclass -from typing import List, Tuple +import netaddr +from core import utils from core.emulator.enumerations import ( EventTypes, ExceptionLevels, LinkTypes, MessageFlags, - NodeTypes, ) +if TYPE_CHECKING: + from core.nodes.base import CoreNode, NodeBase + @dataclass class ConfigData: @@ -27,7 +31,7 @@ class ConfigData: possible_values: str = None groups: str = None session: int = None - interface_number: int = None + iface_id: int = None network_id: int = None opaque: str = None @@ -68,65 +72,217 @@ class FileData: @dataclass -class NodeData: - message_type: MessageFlags = None - id: int = None - node_type: NodeTypes = None +class NodeOptions: + """ + Options for creating and updating nodes within core. + """ + name: str = None - ip_address: str = None - mac_address: str = None - ip6_address: str = None - model: str = None - emulation_id: int = None - server: str = None - session: int = None - x_position: float = None - y_position: float = None + model: Optional[str] = "PC" canvas: int = None - network_id: int = None - services: List[str] = None - latitude: float = None - longitude: float = None - altitude: float = None icon: str = None - opaque: str = None + services: List[str] = field(default_factory=list) + config_services: List[str] = field(default_factory=list) + x: float = None + y: float = None + lat: float = None + lon: float = None + alt: float = None + server: str = None + image: str = None + emane: str = None + + def set_position(self, x: float, y: float) -> None: + """ + Convenience method for setting position. + + :param x: x position + :param y: y position + :return: nothing + """ + self.x = x + self.y = y + + def set_location(self, lat: float, lon: float, alt: float) -> None: + """ + Convenience method for setting location. + + :param lat: latitude + :param lon: longitude + :param alt: altitude + :return: nothing + """ + self.lat = lat + self.lon = lon + self.alt = alt + + +@dataclass +class NodeData: + """ + Node to broadcast. + """ + + node: "NodeBase" + message_type: MessageFlags = None source: str = None +@dataclass +class InterfaceData: + """ + Convenience class for storing interface data. + """ + + id: int = None + name: str = None + mac: str = None + ip4: str = None + ip4_mask: int = None + ip6: str = None + ip6_mask: int = None + + def get_addresses(self) -> List[str]: + """ + Returns a list of ip4 and ip6 addresses when present. + + :return: list of addresses + """ + addresses = [] + if self.ip4 and self.ip4_mask: + addresses.append(f"{self.ip4}/{self.ip4_mask}") + if self.ip6 and self.ip6_mask: + addresses.append(f"{self.ip6}/{self.ip6_mask}") + return addresses + + +@dataclass +class LinkOptions: + """ + Options for creating and updating links within core. + """ + + delay: int = None + bandwidth: int = None + loss: float = None + dup: int = None + jitter: int = None + mer: int = None + burst: int = None + mburst: int = None + unidirectional: int = None + key: int = None + + @dataclass class LinkData: + """ + Represents all data associated with a link. + """ + message_type: MessageFlags = None + type: LinkTypes = LinkTypes.WIRED label: str = None node1_id: int = None node2_id: int = None - delay: float = None - bandwidth: float = None - loss: float = None - dup: float = None - jitter: float = None - mer: float = None - burst: float = None - session: int = None - mburst: float = None - link_type: LinkTypes = None - gui_attributes: str = None - unidirectional: int = None - emulation_id: int = None network_id: int = None - key: int = None - interface1_id: int = None - interface1_name: str = None - interface1_ip4: str = None - interface1_ip4_mask: int = None - interface1_mac: str = None - interface1_ip6: str = None - interface1_ip6_mask: int = None - interface2_id: int = None - interface2_name: str = None - interface2_ip4: str = None - interface2_ip4_mask: int = None - interface2_mac: str = None - interface2_ip6: str = None - interface2_ip6_mask: int = None - opaque: str = None + iface1: InterfaceData = None + iface2: InterfaceData = None + options: LinkOptions = LinkOptions() color: str = None + + +class IpPrefixes: + """ + Convenience class to help generate IP4 and IP6 addresses for nodes within CORE. + """ + + def __init__(self, ip4_prefix: str = None, ip6_prefix: str = None) -> None: + """ + Creates an IpPrefixes object. + + :param ip4_prefix: ip4 prefix to use for generation + :param ip6_prefix: ip6 prefix to use for generation + :raises ValueError: when both ip4 and ip6 prefixes have not been provided + """ + if not ip4_prefix and not ip6_prefix: + raise ValueError("ip4 or ip6 must be provided") + + self.ip4 = None + if ip4_prefix: + self.ip4 = netaddr.IPNetwork(ip4_prefix) + self.ip6 = None + if ip6_prefix: + self.ip6 = netaddr.IPNetwork(ip6_prefix) + + def ip4_address(self, node_id: int) -> str: + """ + Convenience method to return the IP4 address for a node. + + :param node_id: node id to get IP4 address for + :return: IP4 address or None + """ + if not self.ip4: + raise ValueError("ip4 prefixes have not been set") + return str(self.ip4[node_id]) + + def ip6_address(self, node_id: int) -> str: + """ + Convenience method to return the IP6 address for a node. + + :param node_id: node id to get IP6 address for + :return: IP4 address or None + """ + if not self.ip6: + raise ValueError("ip6 prefixes have not been set") + return str(self.ip6[node_id]) + + def gen_iface(self, node_id: int, name: str = None, mac: str = None): + """ + Creates interface data for linking nodes, using the nodes unique id for + generation, along with a random mac address, unless provided. + + :param node_id: node id to create an interface for + :param name: name to set for interface, default is eth{id} + :param mac: mac address to use for this interface, default is random + generation + :return: new interface data for the provided node + """ + # generate ip4 data + ip4 = None + ip4_mask = None + if self.ip4: + ip4 = self.ip4_address(node_id) + ip4_mask = self.ip4.prefixlen + + # generate ip6 data + ip6 = None + ip6_mask = None + if self.ip6: + ip6 = self.ip6_address(node_id) + ip6_mask = self.ip6.prefixlen + + # random mac + if not mac: + mac = utils.random_mac() + + return InterfaceData( + name=name, ip4=ip4, ip4_mask=ip4_mask, ip6=ip6, ip6_mask=ip6_mask, mac=mac + ) + + def create_iface( + self, node: "CoreNode", name: str = None, mac: str = None + ) -> InterfaceData: + """ + Creates interface data for linking nodes, using the nodes unique id for + generation, along with a random mac address, unless provided. + + :param node: node to create interface for + :param name: name to set for interface, default is eth{id} + :param mac: mac address to use for this interface, default is random + generation + :return: new interface data for the provided node + """ + iface_data = self.gen_iface(node.id, name, mac) + iface_data.id = node.next_iface_id() + return iface_data diff --git a/daemon/core/emulator/distributed.py b/daemon/core/emulator/distributed.py index 75081447..381eb019 100644 --- a/daemon/core/emulator/distributed.py +++ b/daemon/core/emulator/distributed.py @@ -208,7 +208,7 @@ class DistributedController: "local tunnel node(%s) to remote(%s) key(%s)", node.name, host, key ) local_tap = GreTap(session=self.session, remoteip=host, key=key) - local_tap.net_client.set_interface_master(node.brname, local_tap.localname) + local_tap.net_client.set_iface_master(node.brname, local_tap.localname) # server to local logging.info( @@ -217,7 +217,7 @@ class DistributedController: remote_tap = GreTap( session=self.session, remoteip=self.address, key=key, server=server ) - remote_tap.net_client.set_interface_master(node.brname, remote_tap.localname) + remote_tap.net_client.set_iface_master(node.brname, remote_tap.localname) # save tunnels for shutdown tunnel = (local_tap, remote_tap) diff --git a/daemon/core/emulator/emudata.py b/daemon/core/emulator/emudata.py deleted file mode 100644 index 2aecdace..00000000 --- a/daemon/core/emulator/emudata.py +++ /dev/null @@ -1,206 +0,0 @@ -from dataclasses import dataclass, field -from typing import TYPE_CHECKING, List, Optional - -import netaddr - -from core import utils -from core.emulator.enumerations import LinkTypes - -if TYPE_CHECKING: - from core.nodes.base import CoreNode - - -@dataclass -class NodeOptions: - """ - Options for creating and updating nodes within core. - """ - - name: str = None - model: Optional[str] = "PC" - canvas: int = None - icon: str = None - opaque: str = None - services: List[str] = field(default_factory=list) - config_services: List[str] = field(default_factory=list) - x: float = None - y: float = None - lat: float = None - lon: float = None - alt: float = None - emulation_id: int = None - server: str = None - image: str = None - emane: str = None - - def set_position(self, x: float, y: float) -> None: - """ - Convenience method for setting position. - - :param x: x position - :param y: y position - :return: nothing - """ - self.x = x - self.y = y - - def set_location(self, lat: float, lon: float, alt: float) -> None: - """ - Convenience method for setting location. - - :param lat: latitude - :param lon: longitude - :param alt: altitude - :return: nothing - """ - self.lat = lat - self.lon = lon - self.alt = alt - - -@dataclass -class LinkOptions: - """ - Options for creating and updating links within core. - """ - - type: LinkTypes = LinkTypes.WIRED - session: int = None - delay: int = None - bandwidth: int = None - loss: float = None - dup: int = None - jitter: int = None - mer: int = None - burst: int = None - mburst: int = None - gui_attributes: str = None - unidirectional: bool = None - emulation_id: int = None - network_id: int = None - key: int = None - opaque: str = None - - -@dataclass -class InterfaceData: - """ - Convenience class for storing interface data. - """ - - id: int = None - name: str = None - mac: str = None - ip4: str = None - ip4_mask: int = None - ip6: str = None - ip6_mask: int = None - - def get_addresses(self) -> List[str]: - """ - Returns a list of ip4 and ip6 addresses when present. - - :return: list of addresses - """ - addresses = [] - if self.ip4 and self.ip4_mask: - addresses.append(f"{self.ip4}/{self.ip4_mask}") - if self.ip6 and self.ip6_mask: - addresses.append(f"{self.ip6}/{self.ip6_mask}") - return addresses - - -class IpPrefixes: - """ - Convenience class to help generate IP4 and IP6 addresses for nodes within CORE. - """ - - def __init__(self, ip4_prefix: str = None, ip6_prefix: str = None) -> None: - """ - Creates an IpPrefixes object. - - :param ip4_prefix: ip4 prefix to use for generation - :param ip6_prefix: ip6 prefix to use for generation - :raises ValueError: when both ip4 and ip6 prefixes have not been provided - """ - if not ip4_prefix and not ip6_prefix: - raise ValueError("ip4 or ip6 must be provided") - - self.ip4 = None - if ip4_prefix: - self.ip4 = netaddr.IPNetwork(ip4_prefix) - self.ip6 = None - if ip6_prefix: - self.ip6 = netaddr.IPNetwork(ip6_prefix) - - def ip4_address(self, node_id: int) -> str: - """ - Convenience method to return the IP4 address for a node. - - :param node_id: node id to get IP4 address for - :return: IP4 address or None - """ - if not self.ip4: - raise ValueError("ip4 prefixes have not been set") - return str(self.ip4[node_id]) - - def ip6_address(self, node_id: int) -> str: - """ - Convenience method to return the IP6 address for a node. - - :param node_id: node id to get IP6 address for - :return: IP4 address or None - """ - if not self.ip6: - raise ValueError("ip6 prefixes have not been set") - return str(self.ip6[node_id]) - - def gen_interface(self, node_id: int, name: str = None, mac: str = None): - """ - Creates interface data for linking nodes, using the nodes unique id for - generation, along with a random mac address, unless provided. - - :param node_id: node id to create an interface for - :param name: name to set for interface, default is eth{id} - :param mac: mac address to use for this interface, default is random - generation - :return: new interface data for the provided node - """ - # generate ip4 data - ip4 = None - ip4_mask = None - if self.ip4: - ip4 = self.ip4_address(node_id) - ip4_mask = self.ip4.prefixlen - - # generate ip6 data - ip6 = None - ip6_mask = None - if self.ip6: - ip6 = self.ip6_address(node_id) - ip6_mask = self.ip6.prefixlen - - # random mac - if not mac: - mac = utils.random_mac() - - return InterfaceData( - name=name, ip4=ip4, ip4_mask=ip4_mask, ip6=ip6, ip6_mask=ip6_mask, mac=mac - ) - - def create_interface( - self, node: "CoreNode", name: str = None, mac: str = None - ) -> InterfaceData: - """ - Creates interface data for linking nodes, using the nodes unique id for - generation, along with a random mac address, unless provided. - - :param node: node to create interface for - :param name: name to set for interface, default is eth{id} - :param mac: mac address to use for this interface, default is random - generation - :return: new interface data for the provided node - """ - interface_data = self.gen_interface(node.id, name, mac) - interface_data.id = node.newifindex() - return interface_data diff --git a/daemon/core/emulator/session.py b/daemon/core/emulator/session.py index e63c30c7..0b97da93 100644 --- a/daemon/core/emulator/session.py +++ b/daemon/core/emulator/session.py @@ -22,11 +22,13 @@ from core.emulator.data import ( EventData, ExceptionData, FileData, + InterfaceData, LinkData, + LinkOptions, NodeData, + NodeOptions, ) from core.emulator.distributed import DistributedController -from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions from core.emulator.enumerations import ( EventTypes, ExceptionLevels, @@ -203,7 +205,7 @@ class Session: common_networks = node1.commonnets(node1) if not common_networks: raise CoreError("no common network found for wireless link/unlink") - for common_network, interface1, interface2 in common_networks: + for common_network, iface1, iface2 in common_networks: if not isinstance(common_network, (WlanNode, EmaneNet)): logging.info( "skipping common network that is not wireless/emane: %s", @@ -211,40 +213,42 @@ class Session: ) continue if connect: - common_network.link(interface1, interface2) + common_network.link(iface1, iface2) else: - common_network.unlink(interface1, interface2) + common_network.unlink(iface1, iface2) def add_link( self, node1_id: int, node2_id: int, - interface1_data: InterfaceData = None, - interface2_data: InterfaceData = None, + iface1_data: InterfaceData = None, + iface2_data: InterfaceData = None, options: LinkOptions = None, + link_type: LinkTypes = LinkTypes.WIRED, ) -> Tuple[CoreInterface, CoreInterface]: """ Add a link between nodes. :param node1_id: node one id :param node2_id: node two id - :param interface1_data: node one interface + :param iface1_data: node one interface data, defaults to none - :param interface2_data: node two interface + :param iface2_data: node two interface data, defaults to none :param options: data for creating link, defaults to no options + :param link_type: type of link to add :return: tuple of created core interfaces, depending on link """ if not options: options = LinkOptions() node1 = self.get_node(node1_id, NodeBase) node2 = self.get_node(node2_id, NodeBase) - interface1 = None - interface2 = None + iface1 = None + iface2 = None # wireless link - if options.type == LinkTypes.WIRELESS: + if link_type == LinkTypes.WIRELESS: if isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNodeBase): self._link_wireless(node1, node2, connect=True) else: @@ -258,22 +262,22 @@ class Session: logging.info("linking ptp: %s - %s", node1.name, node2.name) start = self.state.should_start() ptp = self.create_node(PtpNet, start) - interface1 = node1.newnetif(ptp, interface1_data) - interface2 = node2.newnetif(ptp, interface2_data) - ptp.linkconfig(interface1, options) + iface1 = node1.new_iface(ptp, iface1_data) + iface2 = node2.new_iface(ptp, iface2_data) + ptp.linkconfig(iface1, options) if not options.unidirectional: - ptp.linkconfig(interface2, options) + ptp.linkconfig(iface2, options) # link node to net elif isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNetworkBase): - interface1 = node1.newnetif(node2, interface1_data) + iface1 = node1.new_iface(node2, iface1_data) if not isinstance(node2, (EmaneNet, WlanNode)): - node2.linkconfig(interface1, options) + node2.linkconfig(iface1, options) # link net to node elif isinstance(node2, CoreNodeBase) and isinstance(node1, CoreNetworkBase): - interface2 = node2.newnetif(node1, interface2_data) + iface2 = node2.new_iface(node1, iface2_data) wireless_net = isinstance(node1, (EmaneNet, WlanNode)) if not options.unidirectional and not wireless_net: - node1.linkconfig(interface2, options) + node1.linkconfig(iface2, options) # network to network elif isinstance(node1, CoreNetworkBase) and isinstance( node2, CoreNetworkBase @@ -281,12 +285,12 @@ class Session: logging.info( "linking network to network: %s - %s", node1.name, node2.name ) - interface1 = node1.linknet(node2) - node1.linkconfig(interface1, options) + iface1 = node1.linknet(node2) + node1.linkconfig(iface1, options) if not options.unidirectional: - interface1.swapparams("_params_up") - node2.linkconfig(interface1, options) - interface1.swapparams("_params_up") + iface1.swapparams("_params_up") + node2.linkconfig(iface1, options) + iface1.swapparams("_params_up") else: raise CoreError( f"cannot link node1({type(node1)}) node2({type(node2)})" @@ -296,19 +300,19 @@ class Session: key = options.key if isinstance(node1, TunnelNode): logging.info("setting tunnel key for: %s", node1.name) - node1.setkey(key, interface1_data) + node1.setkey(key, iface1_data) if isinstance(node2, TunnelNode): logging.info("setting tunnel key for: %s", node2.name) - node2.setkey(key, interface2_data) + node2.setkey(key, iface2_data) self.sdt.add_link(node1_id, node2_id) - return interface1, interface2 + return iface1, iface2 def delete_link( self, node1_id: int, node2_id: int, - interface1_id: int = None, - interface2_id: int = None, + iface1_id: int = None, + iface2_id: int = None, link_type: LinkTypes = LinkTypes.WIRED, ) -> None: """ @@ -316,8 +320,8 @@ class Session: :param node1_id: node one id :param node2_id: node two id - :param interface1_id: interface id for node one - :param interface2_id: interface id for node two + :param iface1_id: interface id for node one + :param iface2_id: interface id for node two :param link_type: link type to delete :return: nothing :raises core.CoreError: when no common network is found for link being deleted @@ -328,9 +332,9 @@ class Session: "deleting link(%s) node(%s):interface(%s) node(%s):interface(%s)", link_type.name, node1.name, - interface1_id, + iface1_id, node2.name, - interface2_id, + iface2_id, ) # wireless link @@ -345,47 +349,41 @@ class Session: # wired link else: if isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNodeBase): - interface1 = node1.netif(interface1_id) - interface2 = node2.netif(interface2_id) - if not interface1: - raise CoreError( - f"node({node1.name}) missing interface({interface1_id})" - ) - if not interface2: - raise CoreError( - f"node({node2.name}) missing interface({interface2_id})" - ) - if interface1.net != interface2.net: + iface1 = node1.get_iface(iface1_id) + iface2 = node2.get_iface(iface2_id) + if iface1.net != iface2.net: raise CoreError( f"node1({node1.name}) node2({node2.name}) " "not connected to same net" ) - ptp = interface1.net - node1.delnetif(interface1_id) - node2.delnetif(interface2_id) + ptp = iface1.net + node1.delete_iface(iface1_id) + node2.delete_iface(iface2_id) self.delete_node(ptp.id) elif isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNetworkBase): - node1.delnetif(interface1_id) + node1.delete_iface(iface1_id) elif isinstance(node2, CoreNodeBase) and isinstance(node1, CoreNetworkBase): - node2.delnetif(interface2_id) + node2.delete_iface(iface2_id) self.sdt.delete_link(node1_id, node2_id) def update_link( self, node1_id: int, node2_id: int, - interface1_id: int = None, - interface2_id: int = None, + iface1_id: int = None, + iface2_id: int = None, options: LinkOptions = None, + link_type: LinkTypes = LinkTypes.WIRED, ) -> None: """ Update link information between nodes. :param node1_id: node one id :param node2_id: node two id - :param interface1_id: interface id for node one - :param interface2_id: interface id for node two + :param iface1_id: interface id for node one + :param iface2_id: interface id for node two :param options: data to update link with + :param link_type: type of link to update :return: nothing :raises core.CoreError: when updating a wireless type link, when there is a unknown link between networks @@ -396,66 +394,66 @@ class Session: node2 = self.get_node(node2_id, NodeBase) logging.info( "update link(%s) node(%s):interface(%s) node(%s):interface(%s)", - options.type.name, + link_type.name, node1.name, - interface1_id, + iface1_id, node2.name, - interface2_id, + iface2_id, ) # wireless link - if options.type == LinkTypes.WIRELESS: + if link_type == LinkTypes.WIRELESS: raise CoreError("cannot update wireless link") else: if isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNodeBase): - interface1 = node1.netif(interface1_id) - interface2 = node2.netif(interface2_id) - if not interface1: + iface1 = node1.ifaces.get(iface1_id) + iface2 = node2.ifaces.get(iface2_id) + if not iface1: raise CoreError( - f"node({node1.name}) missing interface({interface1_id})" + f"node({node1.name}) missing interface({iface1_id})" ) - if not interface2: + if not iface2: raise CoreError( - f"node({node2.name}) missing interface({interface2_id})" + f"node({node2.name}) missing interface({iface2_id})" ) - if interface1.net != interface2.net: + if iface1.net != iface2.net: raise CoreError( f"node1({node1.name}) node2({node2.name}) " "not connected to same net" ) - ptp = interface1.net - ptp.linkconfig(interface1, options, interface2) + ptp = iface1.net + ptp.linkconfig(iface1, options, iface2) if not options.unidirectional: - ptp.linkconfig(interface2, options, interface1) + ptp.linkconfig(iface2, options, iface1) elif isinstance(node1, CoreNodeBase) and isinstance(node2, CoreNetworkBase): - interface = node1.netif(interface1_id) - node2.linkconfig(interface, options) + iface = node1.get_iface(iface1_id) + node2.linkconfig(iface, options) elif isinstance(node2, CoreNodeBase) and isinstance(node1, CoreNetworkBase): - interface = node2.netif(interface2_id) - node1.linkconfig(interface, options) + iface = node2.get_iface(iface2_id) + node1.linkconfig(iface, options) elif isinstance(node1, CoreNetworkBase) and isinstance( node2, CoreNetworkBase ): - interface = node1.getlinknetif(node2) + iface = node1.get_linked_iface(node2) upstream = False - if not interface: + if not iface: upstream = True - interface = node2.getlinknetif(node1) - if not interface: + iface = node2.get_linked_iface(node1) + if not iface: raise CoreError("modify unknown link between nets") if upstream: - interface.swapparams("_params_up") - node1.linkconfig(interface, options) - interface.swapparams("_params_up") + iface.swapparams("_params_up") + node1.linkconfig(iface, options) + iface.swapparams("_params_up") else: - node1.linkconfig(interface, options) + node1.linkconfig(iface, options) if not options.unidirectional: if upstream: - node2.linkconfig(interface, options) + node2.linkconfig(iface, options) else: - interface.swapparams("_params_up") - node2.linkconfig(interface, options) - interface.swapparams("_params_up") + iface.swapparams("_params_up") + node2.linkconfig(iface, options) + iface.swapparams("_params_up") else: raise CoreError( f"cannot update link node1({type(node1)}) node2({type(node2)})" @@ -525,7 +523,6 @@ class Session: # set node attributes node.icon = options.icon node.canvas = options.canvas - node.opaque = options.opaque # set node position and broadcast it self.set_node_position(node, options) @@ -553,7 +550,7 @@ class Session: is_boot_node = isinstance(node, CoreNodeBase) and not isinstance(node, Rj45Node) if self.state == EventTypes.RUNTIME_STATE and is_boot_node: self.write_nodes() - self.add_remove_control_interface(node=node, remove=False) + self.add_remove_control_iface(node=node, remove=False) self.services.boot_services(node) self.sdt.add_node(node) @@ -810,9 +807,9 @@ class Session: :param source: source of broadcast, None by default :return: nothing """ - node_data = node.data(message_type, source) - if not node_data: + if not node.apitype: return + node_data = NodeData(node=node, message_type=message_type, source=source) for handler in self.node_handlers: handler(node_data) @@ -1268,7 +1265,7 @@ class Session: self.emane.shutdown() # update control interface hosts - self.update_control_interface_hosts(remove=True) + self.update_control_iface_hosts(remove=True) # remove all four possible control networks self.add_remove_control_net(0, remove=True) @@ -1314,7 +1311,7 @@ class Session: :return: nothing """ logging.info("booting node(%s): %s", node.name, [x.name for x in node.services]) - self.add_remove_control_interface(node=node, remove=False) + self.add_remove_control_iface(node=node, remove=False) self.services.boot_services(node) node.start_config_services() @@ -1338,7 +1335,7 @@ class Session: total = time.monotonic() - start logging.debug("boot run time: %s", total) if not exceptions: - self.update_control_interface_hosts() + self.update_control_iface_hosts() return exceptions def get_control_net_prefixes(self) -> List[str]: @@ -1356,7 +1353,7 @@ class Session: p0 = p return [p0, p1, p2, p3] - def get_control_net_server_interfaces(self) -> List[str]: + def get_control_net_server_ifaces(self) -> List[str]: """ Retrieve control net server interfaces. @@ -1424,7 +1421,7 @@ class Session: else: 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] + server_iface = self.get_control_net_server_ifaces()[net_index] # return any existing controlnet bridge try: @@ -1465,7 +1462,7 @@ class Session: _id, prefix, updown_script, - server_interface, + server_iface, ) control_net = self.create_node( CtrlNet, @@ -1473,11 +1470,11 @@ class Session: prefix, _id=_id, updown_script=updown_script, - serverintf=server_interface, + serverintf=server_iface, ) return control_net - def add_remove_control_interface( + def add_remove_control_iface( self, node: CoreNode, net_index: int = 0, @@ -1503,27 +1500,27 @@ class Session: if not node: return # ctrl# already exists - if node.netif(control_net.CTRLIF_IDX_BASE + net_index): + if node.ifaces.get(control_net.CTRLIF_IDX_BASE + net_index): return try: ip4 = control_net.prefix[node.id] ip4_mask = control_net.prefix.prefixlen - interface_data = InterfaceData( + iface_data = InterfaceData( id=control_net.CTRLIF_IDX_BASE + net_index, name=f"ctrl{net_index}", mac=utils.random_mac(), ip4=ip4, ip4_mask=ip4_mask, ) - interface = node.newnetif(control_net, interface_data) - interface.control = True + iface = node.new_iface(control_net, iface_data) + iface.control = True except ValueError: msg = f"Control interface not added to node {node.id}. " msg += f"Invalid control network prefix ({control_net.prefix}). " msg += "A longer prefix length may be required for this many nodes." logging.exception(msg) - def update_control_interface_hosts( + def update_control_iface_hosts( self, net_index: int = 0, remove: bool = False ) -> None: """ @@ -1549,9 +1546,9 @@ class Session: return entries = [] - for interface in control_net.netifs(): - name = interface.node.name - for address in interface.addrlist: + for iface in control_net.get_ifaces(): + name = iface.node.name + for address in iface.addrlist: address = address.split("/")[0] entries.append(f"{address} {name}") diff --git a/daemon/core/gui/coreclient.py b/daemon/core/gui/coreclient.py index 5c1c52a0..8b0c423c 100644 --- a/daemon/core/gui/coreclient.py +++ b/daemon/core/gui/coreclient.py @@ -57,8 +57,8 @@ class CoreClient: self.read_config() # helpers - self.interface_to_edge = {} - self.interfaces_manager = InterfaceManager(self.app) + self.iface_to_edge = {} + self.ifaces_manager = InterfaceManager(self.app) # session data self.state = None @@ -91,8 +91,8 @@ class CoreClient: def reset(self): # helpers - self.interfaces_manager.reset() - self.interface_to_edge.clear() + self.ifaces_manager.reset() + self.iface_to_edge.clear() # session data self.canvas_nodes.clear() self.links.clear() @@ -263,7 +263,7 @@ class CoreClient: self.emane_config = response.config # update interface manager - self.interfaces_manager.joined(session.links) + self.ifaces_manager.joined(session.links) # draw session self.app.canvas.reset_and_redraw(session) @@ -278,11 +278,11 @@ class CoreClient: # get emane model config response = self.client.get_emane_model_configs(self.session_id) for config in response.configs: - interface = None - if config.interface != -1: - interface = config.interface + iface_id = None + if config.iface_id != -1: + iface_id = config.iface_id canvas_node = self.canvas_nodes[config.node_id] - canvas_node.emane_model_configs[(config.model, interface)] = dict( + canvas_node.emane_model_configs[(config.model, iface_id)] = dict( config.config ) @@ -460,16 +460,16 @@ class CoreClient: self.app.show_grpc_exception("Edit Node Error", e) def start_session(self) -> core_pb2.StartSessionResponse: - self.interfaces_manager.reset_mac() + self.ifaces_manager.reset_mac() nodes = [x.core_node for x in self.canvas_nodes.values()] links = [] for edge in self.links.values(): link = core_pb2.Link() link.CopyFrom(edge.link) - if link.HasField("interface1") and not link.interface1.mac: - link.interface1.mac = self.interfaces_manager.next_mac() - if link.HasField("interface2") and not link.interface2.mac: - link.interface2.mac = self.interfaces_manager.next_mac() + if link.HasField("iface1") and not link.iface1.mac: + link.iface1.mac = self.ifaces_manager.next_mac() + if link.HasField("iface2") and not link.iface2.mac: + link.iface2.mac = self.ifaces_manager.next_mac() links.append(link) wlan_configs = self.get_wlan_configs_proto() mobility_configs = self.get_mobility_configs_proto() @@ -689,8 +689,8 @@ class CoreClient: self.session_id, link_proto.node1_id, link_proto.node2_id, - link_proto.interface1, - link_proto.interface2, + link_proto.iface1, + link_proto.iface2, link_proto.options, ) logging.debug("create link: %s", response) @@ -733,7 +733,7 @@ class CoreClient: config_proto.node_id, config_proto.model, config_proto.config, - config_proto.interface_id, + config_proto.iface_id, ) if self.emane_config: config = {x: self.emane_config[x].value for x in self.emane_config} @@ -824,31 +824,31 @@ class CoreClient: for edge in edges: del self.links[edge.token] links.append(edge.link) - self.interfaces_manager.removed(links) + self.ifaces_manager.removed(links) - def create_interface(self, canvas_node: CanvasNode) -> core_pb2.Interface: + def create_iface(self, canvas_node: CanvasNode) -> core_pb2.Interface: node = canvas_node.core_node - ip4, ip6 = self.interfaces_manager.get_ips(node) - ip4_mask = self.interfaces_manager.ip4_mask - ip6_mask = self.interfaces_manager.ip6_mask - interface_id = canvas_node.next_interface_id() - name = f"eth{interface_id}" - interface = core_pb2.Interface( - id=interface_id, + ip4, ip6 = self.ifaces_manager.get_ips(node) + ip4_mask = self.ifaces_manager.ip4_mask + ip6_mask = self.ifaces_manager.ip6_mask + iface_id = canvas_node.next_iface_id() + name = f"eth{iface_id}" + iface = core_pb2.Interface( + id=iface_id, name=name, ip4=ip4, - ip4mask=ip4_mask, + ip4_mask=ip4_mask, ip6=ip6, - ip6mask=ip6_mask, + ip6_mask=ip6_mask, ) logging.info( "create node(%s) interface(%s) IPv4(%s) IPv6(%s)", node.name, - interface.name, - interface.ip4, - interface.ip6, + iface.name, + iface.ip4, + iface.ip6, ) - return interface + return iface def create_link( self, edge: CanvasEdge, canvas_src_node: CanvasNode, canvas_dst_node: CanvasNode @@ -861,34 +861,34 @@ class CoreClient: dst_node = canvas_dst_node.core_node # determine subnet - self.interfaces_manager.determine_subnets(canvas_src_node, canvas_dst_node) + self.ifaces_manager.determine_subnets(canvas_src_node, canvas_dst_node) - src_interface = None + src_iface = None if NodeUtils.is_container_node(src_node.type): - src_interface = self.create_interface(canvas_src_node) - self.interface_to_edge[(src_node.id, src_interface.id)] = edge.token + src_iface = self.create_iface(canvas_src_node) + self.iface_to_edge[(src_node.id, src_iface.id)] = edge.token - dst_interface = None + dst_iface = None if NodeUtils.is_container_node(dst_node.type): - dst_interface = self.create_interface(canvas_dst_node) - self.interface_to_edge[(dst_node.id, dst_interface.id)] = edge.token + dst_iface = self.create_iface(canvas_dst_node) + self.iface_to_edge[(dst_node.id, dst_iface.id)] = edge.token link = core_pb2.Link( type=core_pb2.LinkType.WIRED, node1_id=src_node.id, node2_id=dst_node.id, - interface1=src_interface, - interface2=dst_interface, + iface1=src_iface, + iface2=dst_iface, ) # assign after creating link proto, since interfaces are copied - if src_interface: - interface1 = link.interface1 - edge.src_interface = interface1 - canvas_src_node.interfaces[interface1.id] = interface1 - if dst_interface: - interface2 = link.interface2 - edge.dst_interface = interface2 - canvas_dst_node.interfaces[interface2.id] = interface2 + if src_iface: + iface1 = link.iface1 + edge.src_iface = iface1 + canvas_src_node.ifaces[iface1.id] = iface1 + if dst_iface: + iface2 = link.iface2 + edge.dst_iface = iface2 + canvas_dst_node.ifaces[iface2.id] = iface2 edge.set_link(link) self.links[edge.token] = edge logging.info("Add link between %s and %s", src_node.name, dst_node.name) @@ -928,12 +928,12 @@ class CoreClient: continue node_id = canvas_node.core_node.id for key, config in canvas_node.emane_model_configs.items(): - model, interface = key + model, iface_id = key config = {x: config[x].value for x in config} - if interface is None: - interface = -1 + if iface_id is None: + iface_id = -1 config_proto = EmaneModelConfig( - node_id=node_id, interface_id=interface, model=model, config=config + node_id=node_id, iface_id=iface_id, model=model, config=config ) configs.append(config_proto) return configs @@ -1021,19 +1021,19 @@ class CoreClient: return dict(config) def get_emane_model_config( - self, node_id: int, model: str, interface: int = None + self, node_id: int, model: str, iface_id: int = None ) -> Dict[str, common_pb2.ConfigOption]: - if interface is None: - interface = -1 + if iface_id is None: + iface_id = -1 response = self.client.get_emane_model_config( - self.session_id, node_id, model, interface + self.session_id, node_id, model, iface_id ) config = response.config logging.debug( "get emane model config: node id: %s, EMANE model: %s, interface: %s, config: %s", node_id, model, - interface, + iface_id, config, ) return dict(config) diff --git a/daemon/core/gui/dialogs/emaneconfig.py b/daemon/core/gui/dialogs/emaneconfig.py index 000ebb05..8f7ca089 100644 --- a/daemon/core/gui/dialogs/emaneconfig.py +++ b/daemon/core/gui/dialogs/emaneconfig.py @@ -56,7 +56,7 @@ class EmaneModelDialog(Dialog): app: "Application", canvas_node: "CanvasNode", model: str, - interface: int = None, + iface_id: int = None, ): super().__init__( app, f"{canvas_node.core_node.name} {model} Configuration", master=master @@ -64,16 +64,16 @@ class EmaneModelDialog(Dialog): self.canvas_node = canvas_node self.node = canvas_node.core_node self.model = f"emane_{model}" - self.interface = interface + self.iface_id = iface_id self.config_frame = None self.has_error = False try: self.config = self.canvas_node.emane_model_configs.get( - (self.model, self.interface) + (self.model, self.iface_id) ) if not self.config: self.config = self.app.core.get_emane_model_config( - self.node.id, self.model, self.interface + self.node.id, self.model, self.iface_id ) self.draw() except grpc.RpcError as e: @@ -103,7 +103,7 @@ class EmaneModelDialog(Dialog): def click_apply(self): self.config_frame.parse_config() - key = (self.model, self.interface) + key = (self.model, self.iface_id) self.canvas_node.emane_model_configs[key] = self.config self.destroy() diff --git a/daemon/core/gui/dialogs/ipdialog.py b/daemon/core/gui/dialogs/ipdialog.py index 62f5d0ba..d31dcdff 100644 --- a/daemon/core/gui/dialogs/ipdialog.py +++ b/daemon/core/gui/dialogs/ipdialog.py @@ -146,6 +146,6 @@ class IpConfigDialog(Dialog): ip_config.ip6 = self.ip6 ip_config.ip4s = ip4s ip_config.ip6s = ip6s - self.app.core.interfaces_manager.update_ips(self.ip4, self.ip6) + self.app.core.ifaces_manager.update_ips(self.ip4, self.ip6) self.app.save_config() self.destroy() diff --git a/daemon/core/gui/dialogs/linkconfig.py b/daemon/core/gui/dialogs/linkconfig.py index 9c3fc987..adf8156f 100644 --- a/daemon/core/gui/dialogs/linkconfig.py +++ b/daemon/core/gui/dialogs/linkconfig.py @@ -227,21 +227,21 @@ class LinkConfigurationDialog(Dialog): ) link.options.CopyFrom(options) - interface1_id = None - if link.HasField("interface1"): - interface1_id = link.interface1.id - interface2_id = None - if link.HasField("interface2"): - interface2_id = link.interface2.id + iface1_id = None + if link.HasField("iface1"): + iface1_id = link.iface1.id + iface2_id = None + if link.HasField("iface2"): + iface2_id = link.iface2.id if not self.is_symmetric: link.options.unidirectional = True - asym_interface1 = None - if interface1_id: - asym_interface1 = core_pb2.Interface(id=interface1_id) - asym_interface2 = None - if interface2_id: - asym_interface2 = core_pb2.Interface(id=interface2_id) + asym_iface1 = None + if iface1_id: + asym_iface1 = core_pb2.Interface(id=iface1_id) + asym_iface2 = None + if iface2_id: + asym_iface2 = core_pb2.Interface(id=iface2_id) down_bandwidth = get_int(self.down_bandwidth) down_jitter = get_int(self.down_jitter) down_delay = get_int(self.down_delay) @@ -258,8 +258,8 @@ class LinkConfigurationDialog(Dialog): self.edge.asymmetric_link = core_pb2.Link( node1_id=link.node2_id, node2_id=link.node1_id, - interface1=asym_interface1, - interface2=asym_interface2, + iface1=asym_iface1, + iface2=asym_iface2, options=options, ) else: @@ -273,8 +273,8 @@ class LinkConfigurationDialog(Dialog): link.node1_id, link.node2_id, link.options, - interface1_id, - interface2_id, + iface1_id, + iface2_id, ) if self.edge.asymmetric_link: self.app.core.client.edit_link( @@ -282,8 +282,8 @@ class LinkConfigurationDialog(Dialog): link.node2_id, link.node1_id, self.edge.asymmetric_link.options, - interface1_id, - interface2_id, + iface1_id, + iface2_id, ) self.destroy() diff --git a/daemon/core/gui/dialogs/macdialog.py b/daemon/core/gui/dialogs/macdialog.py index caca9fd0..46414cf9 100644 --- a/daemon/core/gui/dialogs/macdialog.py +++ b/daemon/core/gui/dialogs/macdialog.py @@ -55,7 +55,7 @@ class MacConfigDialog(Dialog): if not netaddr.valid_mac(mac): messagebox.showerror("MAC Error", f"{mac} is an invalid mac") else: - self.app.core.interfaces_manager.mac = netaddr.EUI(mac) + self.app.core.ifaces_manager.mac = netaddr.EUI(mac) self.app.guiconfig.mac = mac self.app.save_config() self.destroy() diff --git a/daemon/core/gui/dialogs/nodeconfig.py b/daemon/core/gui/dialogs/nodeconfig.py index 0d46ae06..cec9e9f9 100644 --- a/daemon/core/gui/dialogs/nodeconfig.py +++ b/daemon/core/gui/dialogs/nodeconfig.py @@ -111,7 +111,7 @@ class NodeConfigDialog(Dialog): if self.node.server: server = self.node.server self.server = tk.StringVar(value=server) - self.interfaces = {} + self.ifaces = {} self.draw() def draw(self): @@ -183,53 +183,53 @@ class NodeConfigDialog(Dialog): row += 1 if NodeUtils.is_rj45_node(self.node.type): - response = self.app.core.client.get_interfaces() + response = self.app.core.client.get_ifaces() logging.debug("host machine available interfaces: %s", response) - interfaces = ListboxScroll(frame) - interfaces.listbox.config(state=state) - interfaces.grid( + ifaces = ListboxScroll(frame) + ifaces.listbox.config(state=state) + ifaces.grid( row=row, column=0, columnspan=2, sticky="ew", padx=PADX, pady=PADY ) - for inf in sorted(response.interfaces[:]): - interfaces.listbox.insert(tk.END, inf) + for inf in sorted(response.ifaces[:]): + ifaces.listbox.insert(tk.END, inf) row += 1 - interfaces.listbox.bind("<<ListboxSelect>>", self.interface_select) + ifaces.listbox.bind("<<ListboxSelect>>", self.iface_select) # interfaces - if self.canvas_node.interfaces: - self.draw_interfaces() + if self.canvas_node.ifaces: + self.draw_ifaces() self.draw_spacer() self.draw_buttons() - def draw_interfaces(self): + def draw_ifaces(self): notebook = ttk.Notebook(self.top) notebook.grid(sticky="nsew", pady=PADY) self.top.rowconfigure(notebook.grid_info()["row"], weight=1) state = tk.DISABLED if self.app.core.is_runtime() else tk.NORMAL - for interface_id in sorted(self.canvas_node.interfaces): - interface = self.canvas_node.interfaces[interface_id] + for iface_id in sorted(self.canvas_node.ifaces): + iface = self.canvas_node.ifaces[iface_id] tab = ttk.Frame(notebook, padding=FRAME_PAD) tab.grid(sticky="nsew", pady=PADY) tab.columnconfigure(1, weight=1) tab.columnconfigure(2, weight=1) - notebook.add(tab, text=interface.name) + notebook.add(tab, text=iface.name) row = 0 - emane_node = self.canvas_node.has_emane_link(interface.id) + emane_node = self.canvas_node.has_emane_link(iface.id) if emane_node: emane_model = emane_node.emane.split("_")[1] button = ttk.Button( tab, text=f"Configure EMANE {emane_model}", - command=lambda: self.click_emane_config(emane_model, interface.id), + command=lambda: self.click_emane_config(emane_model, iface.id), ) button.grid(row=row, sticky="ew", columnspan=3, pady=PADY) row += 1 label = ttk.Label(tab, text="MAC") label.grid(row=row, column=0, padx=PADX, pady=PADY) - auto_set = not interface.mac + auto_set = not iface.mac mac_state = tk.DISABLED if auto_set else tk.NORMAL is_auto = tk.BooleanVar(value=auto_set) checkbutton = ttk.Checkbutton( @@ -237,7 +237,7 @@ class NodeConfigDialog(Dialog): ) checkbutton.var = is_auto checkbutton.grid(row=row, column=1, padx=PADX) - mac = tk.StringVar(value=interface.mac) + mac = tk.StringVar(value=iface.mac) entry = ttk.Entry(tab, textvariable=mac, state=mac_state) entry.grid(row=row, column=2, sticky="ew") func = partial(mac_auto, is_auto, entry, mac) @@ -247,8 +247,8 @@ class NodeConfigDialog(Dialog): label = ttk.Label(tab, text="IPv4") label.grid(row=row, column=0, padx=PADX, pady=PADY) ip4_net = "" - if interface.ip4: - ip4_net = f"{interface.ip4}/{interface.ip4mask}" + if iface.ip4: + ip4_net = f"{iface.ip4}/{iface.ip4_mask}" ip4 = tk.StringVar(value=ip4_net) entry = ttk.Entry(tab, textvariable=ip4, state=state) entry.grid(row=row, column=1, columnspan=2, sticky="ew") @@ -257,13 +257,13 @@ class NodeConfigDialog(Dialog): label = ttk.Label(tab, text="IPv6") label.grid(row=row, column=0, padx=PADX, pady=PADY) ip6_net = "" - if interface.ip6: - ip6_net = f"{interface.ip6}/{interface.ip6mask}" + if iface.ip6: + ip6_net = f"{iface.ip6}/{iface.ip6_mask}" ip6 = tk.StringVar(value=ip6_net) entry = ttk.Entry(tab, textvariable=ip6, state=state) entry.grid(row=row, column=1, columnspan=2, sticky="ew") - self.interfaces[interface.id] = InterfaceData(is_auto, mac, ip4, ip6) + self.ifaces[iface.id] = InterfaceData(is_auto, mac, ip4, ip6) def draw_buttons(self): frame = ttk.Frame(self.top) @@ -277,9 +277,9 @@ class NodeConfigDialog(Dialog): button = ttk.Button(frame, text="Cancel", command=self.destroy) button.grid(row=0, column=1, sticky="ew") - def click_emane_config(self, emane_model: str, interface_id: int): + def click_emane_config(self, emane_model: str, iface_id: int): dialog = EmaneModelDialog( - self, self.app, self.canvas_node, emane_model, interface_id + self, self.app, self.canvas_node, emane_model, iface_id ) dialog.show() @@ -309,54 +309,54 @@ class NodeConfigDialog(Dialog): self.canvas_node.image = self.image # update node interface data - for interface in self.canvas_node.interfaces.values(): - data = self.interfaces[interface.id] + for iface in self.canvas_node.ifaces.values(): + data = self.ifaces[iface.id] # validate ip4 ip4_net = data.ip4.get() - if not check_ip4(self, interface.name, ip4_net): + if not check_ip4(self, iface.name, ip4_net): error = True break if ip4_net: - ip4, ip4mask = ip4_net.split("/") - ip4mask = int(ip4mask) + ip4, ip4_mask = ip4_net.split("/") + ip4_mask = int(ip4_mask) else: - ip4, ip4mask = "", 0 - interface.ip4 = ip4 - interface.ip4mask = ip4mask + ip4, ip4_mask = "", 0 + iface.ip4 = ip4 + iface.ip4_mask = ip4_mask # validate ip6 ip6_net = data.ip6.get() - if not check_ip6(self, interface.name, ip6_net): + if not check_ip6(self, iface.name, ip6_net): error = True break if ip6_net: - ip6, ip6mask = ip6_net.split("/") - ip6mask = int(ip6mask) + ip6, ip6_mask = ip6_net.split("/") + ip6_mask = int(ip6_mask) else: - ip6, ip6mask = "", 0 - interface.ip6 = ip6 - interface.ip6mask = ip6mask + ip6, ip6_mask = "", 0 + iface.ip6 = ip6 + iface.ip6_mask = ip6_mask mac = data.mac.get() auto_mac = data.is_auto.get() if not auto_mac and not netaddr.valid_mac(mac): - title = f"MAC Error for {interface.name}" + title = f"MAC Error for {iface.name}" messagebox.showerror(title, "Invalid MAC Address") error = True break elif not auto_mac: mac = netaddr.EUI(mac, dialect=netaddr.mac_unix_expanded) - interface.mac = str(mac) + iface.mac = str(mac) # redraw if not error: self.canvas_node.redraw() self.destroy() - def interface_select(self, event: tk.Event): + def iface_select(self, event: tk.Event): listbox = event.widget cur = listbox.curselection() if cur: - interface = listbox.get(cur[0]) - self.name.set(interface) + iface = listbox.get(cur[0]) + self.name.set(iface) diff --git a/daemon/core/gui/graph/edges.py b/daemon/core/gui/graph/edges.py index 1d2264eb..ac637b28 100644 --- a/daemon/core/gui/graph/edges.py +++ b/daemon/core/gui/graph/edges.py @@ -259,8 +259,8 @@ class CanvasEdge(Edge): Create an instance of canvas edge object """ super().__init__(canvas, src) - self.src_interface = None - self.dst_interface = None + self.src_iface = None + self.dst_iface = None self.text_src = None self.text_dst = None self.link = None @@ -283,25 +283,25 @@ class CanvasEdge(Edge): self.link = link self.draw_labels() - def interface_label(self, interface: core_pb2.Interface) -> str: + def iface_label(self, iface: core_pb2.Interface) -> str: label = "" - if interface.name and self.canvas.show_interface_names.get(): - label = f"{interface.name}" - if interface.ip4 and self.canvas.show_ip4s.get(): + if iface.name and self.canvas.show_iface_names.get(): + label = f"{iface.name}" + if iface.ip4 and self.canvas.show_ip4s.get(): label = f"{label}\n" if label else "" - label += f"{interface.ip4}/{interface.ip4mask}" - if interface.ip6 and self.canvas.show_ip6s.get(): + label += f"{iface.ip4}/{iface.ip4_mask}" + if iface.ip6 and self.canvas.show_ip6s.get(): label = f"{label}\n" if label else "" - label += f"{interface.ip6}/{interface.ip6mask}" + label += f"{iface.ip6}/{iface.ip6_mask}" return label def create_node_labels(self) -> Tuple[str, str]: label1 = None - if self.link.HasField("interface1"): - label1 = self.interface_label(self.link.interface1) + if self.link.HasField("iface1"): + label1 = self.iface_label(self.link.iface1) label2 = None - if self.link.HasField("interface2"): - label2 = self.interface_label(self.link.interface2) + if self.link.HasField("iface2"): + label2 = self.iface_label(self.link.iface2) return label1, label2 def draw_labels(self) -> None: diff --git a/daemon/core/gui/graph/graph.py b/daemon/core/gui/graph/graph.py index 90dcd9f6..269e3973 100644 --- a/daemon/core/gui/graph/graph.py +++ b/daemon/core/gui/graph/graph.py @@ -97,7 +97,7 @@ class CanvasGraph(tk.Canvas): self.show_link_labels = ShowVar(self, tags.LINK_LABEL, value=True) self.show_grid = ShowVar(self, tags.GRIDLINE, value=True) self.show_annotations = ShowVar(self, tags.ANNOTATION, value=True) - self.show_interface_names = BooleanVar(value=False) + self.show_iface_names = BooleanVar(value=False) self.show_ip4s = BooleanVar(value=True) self.show_ip6s = BooleanVar(value=True) @@ -136,7 +136,7 @@ class CanvasGraph(tk.Canvas): self.show_link_labels.set(True) self.show_grid.set(True) self.show_annotations.set(True) - self.show_interface_names.set(False) + self.show_iface_names.set(False) self.show_ip4s.set(True) self.show_ip6s.set(True) @@ -195,19 +195,19 @@ class CanvasGraph(tk.Canvas): return valid_topleft and valid_bottomright def set_throughputs(self, throughputs_event: core_pb2.ThroughputsEvent): - for interface_throughput in throughputs_event.interface_throughputs: - node_id = interface_throughput.node_id - interface_id = interface_throughput.interface_id - throughput = interface_throughput.throughput - interface_to_edge_id = (node_id, interface_id) - token = self.core.interface_to_edge.get(interface_to_edge_id) + for iface_throughput in throughputs_event.iface_throughputs: + node_id = iface_throughput.node_id + iface_id = iface_throughput.iface_id + throughput = iface_throughput.throughput + iface_to_edge_id = (node_id, iface_id) + token = self.core.iface_to_edge.get(iface_to_edge_id) if not token: continue edge = self.edges.get(token) if edge: edge.set_throughput(throughput) else: - del self.core.interface_to_edge[interface_to_edge_id] + del self.core.iface_to_edge[iface_to_edge_id] def draw_grid(self): """ @@ -321,18 +321,16 @@ class CanvasGraph(tk.Canvas): canvas_node2.edges.add(edge) self.edges[edge.token] = edge self.core.links[edge.token] = edge - if link.HasField("interface1"): - interface1 = link.interface1 - self.core.interface_to_edge[(node1.id, interface1.id)] = token - canvas_node1.interfaces[interface1.id] = interface1 - edge.src_interface = interface1 - if link.HasField("interface2"): - interface2 = link.interface2 - self.core.interface_to_edge[ - (node2.id, interface2.id) - ] = edge.token - canvas_node2.interfaces[interface2.id] = interface2 - edge.dst_interface = interface2 + if link.HasField("iface1"): + iface1 = link.iface1 + self.core.iface_to_edge[(node1.id, iface1.id)] = token + canvas_node1.ifaces[iface1.id] = iface1 + edge.src_iface = iface1 + if link.HasField("iface2"): + iface2 = link.iface2 + self.core.iface_to_edge[(node2.id, iface2.id)] = edge.token + canvas_node2.ifaces[iface2.id] = iface2 + edge.dst_iface = iface2 elif link.options.unidirectional: edge = self.edges[token] edge.asymmetric_link = link @@ -513,14 +511,14 @@ class CanvasGraph(tk.Canvas): edge.delete() # update node connected to edge being deleted other_id = edge.src - other_interface = edge.src_interface + other_iface = edge.src_iface if edge.src == object_id: other_id = edge.dst - other_interface = edge.dst_interface + other_iface = edge.dst_iface other_node = self.nodes[other_id] other_node.edges.remove(edge) - if other_interface: - del other_node.interfaces[other_interface.id] + if other_iface: + del other_node.ifaces[other_iface.id] if is_wireless: other_node.delete_antenna() @@ -538,12 +536,12 @@ class CanvasGraph(tk.Canvas): del self.edges[edge.token] src_node = self.nodes[edge.src] src_node.edges.discard(edge) - if edge.src_interface: - del src_node.interfaces[edge.src_interface.id] + if edge.src_iface: + del src_node.ifaces[edge.src_iface.id] dst_node = self.nodes[edge.dst] dst_node.edges.discard(edge) - if edge.dst_interface: - del dst_node.interfaces[edge.dst_interface.id] + if edge.dst_iface: + del dst_node.ifaces[edge.dst_iface.id] src_wireless = NodeUtils.is_wireless_node(src_node.core_node.type) if src_wireless: dst_node.delete_antenna() @@ -963,26 +961,26 @@ class CanvasGraph(tk.Canvas): copy_link = copy_edge.link options = edge.link.options copy_link.options.CopyFrom(options) - interface1_id = None - if copy_link.HasField("interface1"): - interface1_id = copy_link.interface1.id - interface2_id = None - if copy_link.HasField("interface2"): - interface2_id = copy_link.interface2.id + iface1_id = None + if copy_link.HasField("iface1"): + iface1_id = copy_link.iface1.id + iface2_id = None + if copy_link.HasField("iface2"): + iface2_id = copy_link.iface2.id if not options.unidirectional: copy_edge.asymmetric_link = None else: - asym_interface1 = None - if interface1_id: - asym_interface1 = core_pb2.Interface(id=interface1_id) - asym_interface2 = None - if interface2_id: - asym_interface2 = core_pb2.Interface(id=interface2_id) + asym_iface1 = None + if iface1_id: + asym_iface1 = core_pb2.Interface(id=iface1_id) + asym_iface2 = None + if iface2_id: + asym_iface2 = core_pb2.Interface(id=iface2_id) copy_edge.asymmetric_link = core_pb2.Link( node1_id=copy_link.node2_id, node2_id=copy_link.node1_id, - interface1=asym_interface1, - interface2=asym_interface2, + iface1=asym_iface1, + iface2=asym_iface2, options=edge.asymmetric_link.options, ) self.itemconfig( diff --git a/daemon/core/gui/graph/node.py b/daemon/core/gui/graph/node.py index 8ad3f02a..3ba4b3f7 100644 --- a/daemon/core/gui/graph/node.py +++ b/daemon/core/gui/graph/node.py @@ -55,7 +55,7 @@ class CanvasNode: ) self.tooltip = CanvasTooltip(self.canvas) self.edges = set() - self.interfaces = {} + self.ifaces = {} self.wireless_edges = set() self.antennas = [] self.antenna_images = {} @@ -70,9 +70,9 @@ class CanvasNode: self.context = tk.Menu(self.canvas) themes.style_menu(self.context) - def next_interface_id(self) -> int: + def next_iface_id(self) -> int: i = 0 - while i in self.interfaces: + while i in self.ifaces: i += 1 return i @@ -300,16 +300,16 @@ class CanvasNode: dialog = NodeConfigServiceDialog(self.app, self) dialog.show() - def has_emane_link(self, interface_id: int) -> core_pb2.Node: + def has_emane_link(self, iface_id: int) -> core_pb2.Node: result = None for edge in self.edges: if self.id == edge.src: other_id = edge.dst - edge_interface_id = edge.src_interface.id + edge_iface_id = edge.src_iface.id else: other_id = edge.src - edge_interface_id = edge.dst_interface.id - if edge_interface_id != interface_id: + edge_iface_id = edge.dst_iface.id + if edge_iface_id != iface_id: continue other_node = self.canvas.nodes[other_id] if other_node.core_node.type == NodeType.EMANE: diff --git a/daemon/core/gui/interface.py b/daemon/core/gui/interface.py index 34270f56..6c82ca51 100644 --- a/daemon/core/gui/interface.py +++ b/daemon/core/gui/interface.py @@ -12,10 +12,10 @@ if TYPE_CHECKING: from core.gui.graph.node import CanvasNode -def get_index(interface: "core_pb2.Interface") -> Optional[int]: - if not interface.ip4: +def get_index(iface: "core_pb2.Interface") -> Optional[int]: + if not iface.ip4: return None - net = netaddr.IPNetwork(f"{interface.ip4}/{interface.ip4mask}") + net = netaddr.IPNetwork(f"{iface.ip4}/{iface.ip4_mask}") ip_value = net.value cidr_value = net.cidr.value return ip_value - cidr_value @@ -89,43 +89,43 @@ class InterfaceManager: remaining_subnets = set() for edge in self.app.core.links.values(): link = edge.link - if link.HasField("interface1"): - subnets = self.get_subnets(link.interface1) + if link.HasField("iface1"): + subnets = self.get_subnets(link.iface1) remaining_subnets.add(subnets) - if link.HasField("interface2"): - subnets = self.get_subnets(link.interface2) + if link.HasField("iface2"): + subnets = self.get_subnets(link.iface2) remaining_subnets.add(subnets) # remove all subnets from used subnets when no longer present # or remove used indexes from subnet - interfaces = [] + ifaces = [] for link in links: - if link.HasField("interface1"): - interfaces.append(link.interface1) - if link.HasField("interface2"): - interfaces.append(link.interface2) - for interface in interfaces: - subnets = self.get_subnets(interface) + if link.HasField("iface1"): + ifaces.append(link.iface1) + if link.HasField("iface2"): + ifaces.append(link.iface2) + for iface in ifaces: + subnets = self.get_subnets(iface) if subnets not in remaining_subnets: self.used_subnets.pop(subnets.key(), None) else: - index = get_index(interface) + index = get_index(iface) if index is not None: subnets.used_indexes.discard(index) self.current_subnets = None def joined(self, links: List["core_pb2.Link"]) -> None: - interfaces = [] + ifaces = [] for link in links: - if link.HasField("interface1"): - interfaces.append(link.interface1) - if link.HasField("interface2"): - interfaces.append(link.interface2) + if link.HasField("iface1"): + ifaces.append(link.iface1) + if link.HasField("iface2"): + ifaces.append(link.iface2) # add to used subnets and mark used indexes - for interface in interfaces: - subnets = self.get_subnets(interface) - index = get_index(interface) + for iface in ifaces: + subnets = self.get_subnets(iface) + index = get_index(iface) if index is None: continue subnets.used_indexes.add(index) @@ -150,13 +150,13 @@ class InterfaceManager: ip6 = self.current_subnets.ip6[index] return str(ip4), str(ip6) - def get_subnets(self, interface: "core_pb2.Interface") -> Subnets: + def get_subnets(self, iface: "core_pb2.Interface") -> Subnets: ip4_subnet = self.ip4_subnets - if interface.ip4: - ip4_subnet = IPNetwork(f"{interface.ip4}/{interface.ip4mask}").cidr + if iface.ip4: + ip4_subnet = IPNetwork(f"{iface.ip4}/{iface.ip4_mask}").cidr ip6_subnet = self.ip6_subnets - if interface.ip6: - ip6_subnet = IPNetwork(f"{interface.ip6}/{interface.ip6mask}").cidr + if iface.ip6: + ip6_subnet = IPNetwork(f"{iface.ip6}/{iface.ip6_mask}").cidr subnets = Subnets(ip4_subnet, ip6_subnet) return self.used_subnets.get(subnets.key(), subnets) @@ -196,16 +196,16 @@ class InterfaceManager: for edge in canvas_node.edges: src_node = canvas.nodes[edge.src] dst_node = canvas.nodes[edge.dst] - interface = edge.src_interface + iface = edge.src_iface check_node = src_node if src_node == canvas_node: - interface = edge.dst_interface + iface = edge.dst_iface check_node = dst_node if check_node.core_node.id in visited: continue visited.add(check_node.core_node.id) - if interface: - subnets = self.get_subnets(interface) + if iface: + subnets = self.get_subnets(iface) else: subnets = self.find_subnets(check_node, visited) if subnets: diff --git a/daemon/core/gui/menubar.py b/daemon/core/gui/menubar.py index 62a9ceae..cf4216d8 100644 --- a/daemon/core/gui/menubar.py +++ b/daemon/core/gui/menubar.py @@ -139,7 +139,7 @@ class Menubar(tk.Menu): menu.add_checkbutton( label="Interface Names", command=self.click_edge_label_change, - variable=self.canvas.show_interface_names, + variable=self.canvas.show_iface_names, ) menu.add_checkbutton( label="IPv4 Addresses", diff --git a/daemon/core/location/mobility.py b/daemon/core/location/mobility.py index 43996ba3..9bb2966e 100644 --- a/daemon/core/location/mobility.py +++ b/daemon/core/location/mobility.py @@ -13,8 +13,7 @@ from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple from core import utils from core.config import ConfigGroup, ConfigurableOptions, Configuration, ModelManager -from core.emulator.data import EventData, LinkData -from core.emulator.emudata import LinkOptions +from core.emulator.data import EventData, LinkData, LinkOptions from core.emulator.enumerations import ( ConfigDataTypes, EventTypes, @@ -178,7 +177,7 @@ class MobilityManager(ModelManager): self.session.broadcast_event(event_data) def updatewlans( - self, moved: List[CoreNode], moved_netifs: List[CoreInterface] + self, moved: List[CoreNode], moved_ifaces: List[CoreInterface] ) -> None: """ A mobility script has caused nodes in the 'moved' list to move. @@ -186,7 +185,7 @@ class MobilityManager(ModelManager): were to recalculate for each individual node movement. :param moved: moved nodes - :param moved_netifs: moved network interfaces + :param moved_ifaces: moved network interfaces :return: nothing """ for node_id in self.nodes(): @@ -195,7 +194,7 @@ class MobilityManager(ModelManager): except CoreError: continue if node.model: - node.model.update(moved, moved_netifs) + node.model.update(moved, moved_ifaces) class WirelessModel(ConfigurableOptions): @@ -228,12 +227,12 @@ class WirelessModel(ConfigurableOptions): """ return [] - def update(self, moved: List[CoreNode], moved_netifs: List[CoreInterface]) -> None: + def update(self, moved: List[CoreNode], moved_ifaces: List[CoreInterface]) -> None: """ Update this wireless model. :param moved: moved nodes - :param moved_netifs: moved network interfaces + :param moved_ifaces: moved network interfaces :return: nothing """ raise NotImplementedError @@ -301,8 +300,8 @@ class BasicRangeModel(WirelessModel): super().__init__(session, _id) self.session: "Session" = session self.wlan: WlanNode = session.get_node(_id, WlanNode) - self._netifs: Dict[CoreInterface, Tuple[float, float, float]] = {} - self._netifslock: threading.Lock = threading.Lock() + self.iface_to_pos: Dict[CoreInterface, Tuple[float, float, float]] = {} + self.iface_lock: threading.Lock = threading.Lock() self.range: int = 0 self.bw: Optional[int] = None self.delay: Optional[int] = None @@ -333,48 +332,48 @@ class BasicRangeModel(WirelessModel): Apply link parameters to all interfaces. This is invoked from WlanNode.setmodel() after the position callback has been set. """ - with self._netifslock: - for netif in self._netifs: + with self.iface_lock: + for iface in self.iface_to_pos: options = LinkOptions( bandwidth=self.bw, delay=self.delay, loss=self.loss, jitter=self.jitter, ) - self.wlan.linkconfig(netif, options) + self.wlan.linkconfig(iface, options) - def get_position(self, netif: CoreInterface) -> Tuple[float, float, float]: + def get_position(self, iface: CoreInterface) -> Tuple[float, float, float]: """ Retrieve network interface position. - :param netif: network interface position to retrieve + :param iface: network interface position to retrieve :return: network interface position """ - with self._netifslock: - return self._netifs[netif] + with self.iface_lock: + return self.iface_to_pos[iface] - def set_position(self, netif: CoreInterface) -> None: + def set_position(self, iface: CoreInterface) -> None: """ A node has moved; given an interface, a new (x,y,z) position has been set; calculate the new distance between other nodes and link or unlink node pairs based on the configured range. - :param netif: network interface to set position for + :param iface: network interface to set position for :return: nothing """ - x, y, z = netif.node.position.get() - self._netifslock.acquire() - self._netifs[netif] = (x, y, z) + x, y, z = iface.node.position.get() + self.iface_lock.acquire() + self.iface_to_pos[iface] = (x, y, z) if x is None or y is None: - self._netifslock.release() + self.iface_lock.release() return - for netif2 in self._netifs: - self.calclink(netif, netif2) - self._netifslock.release() + for iface2 in self.iface_to_pos: + self.calclink(iface, iface2) + self.iface_lock.release() position_callback = set_position - def update(self, moved: List[CoreNode], moved_netifs: List[CoreInterface]) -> None: + def update(self, moved: List[CoreNode], moved_ifaces: List[CoreInterface]) -> None: """ Node positions have changed without recalc. Update positions from node.position, then re-calculate links for those that have moved. @@ -382,37 +381,37 @@ class BasicRangeModel(WirelessModel): one of the nodes has moved. :param moved: moved nodes - :param moved_netifs: moved network interfaces + :param moved_ifaces: moved network interfaces :return: nothing """ - with self._netifslock: - while len(moved_netifs): - netif = moved_netifs.pop() - nx, ny, nz = netif.node.getposition() - if netif in self._netifs: - self._netifs[netif] = (nx, ny, nz) - for netif2 in self._netifs: - if netif2 in moved_netifs: + with self.iface_lock: + while len(moved_ifaces): + iface = moved_ifaces.pop() + nx, ny, nz = iface.node.getposition() + if iface in self.iface_to_pos: + self.iface_to_pos[iface] = (nx, ny, nz) + for iface2 in self.iface_to_pos: + if iface2 in moved_ifaces: continue - self.calclink(netif, netif2) + self.calclink(iface, iface2) - def calclink(self, netif: CoreInterface, netif2: CoreInterface) -> None: + def calclink(self, iface: CoreInterface, iface2: CoreInterface) -> None: """ Helper used by set_position() and update() to calculate distance between two interfaces and perform linking/unlinking. Sends link/unlink messages and updates the WlanNode's linked dict. - :param netif: interface one - :param netif2: interface two + :param iface: interface one + :param iface2: interface two :return: nothing """ - if netif == netif2: + if iface == iface2: return try: - x, y, z = self._netifs[netif] - x2, y2, z2 = self._netifs[netif2] + x, y, z = self.iface_to_pos[iface] + x2, y2, z2 = self.iface_to_pos[iface2] if x2 is None or y2 is None: return @@ -420,8 +419,8 @@ class BasicRangeModel(WirelessModel): d = self.calcdistance((x, y, z), (x2, y2, z2)) # ordering is important, to keep the wlan._linked dict organized - a = min(netif, netif2) - b = max(netif, netif2) + a = min(iface, iface2) + b = max(iface, iface2) with self.wlan._linked_lock: linked = self.wlan.linked(a, b) @@ -475,42 +474,39 @@ class BasicRangeModel(WirelessModel): self.setlinkparams() def create_link_data( - self, - interface1: CoreInterface, - interface2: CoreInterface, - message_type: MessageFlags, + self, iface1: CoreInterface, iface2: CoreInterface, message_type: MessageFlags ) -> LinkData: """ Create a wireless link/unlink data message. - :param interface1: interface one - :param interface2: interface two + :param iface1: interface one + :param iface2: interface two :param message_type: link message type :return: link data """ color = self.session.get_link_color(self.wlan.id) return LinkData( message_type=message_type, - node1_id=interface1.node.id, - node2_id=interface2.node.id, + type=LinkTypes.WIRELESS, + node1_id=iface1.node.id, + node2_id=iface2.node.id, network_id=self.wlan.id, - link_type=LinkTypes.WIRELESS, color=color, ) def sendlinkmsg( - self, netif: CoreInterface, netif2: CoreInterface, unlink: bool = False + self, iface: CoreInterface, iface2: CoreInterface, unlink: bool = False ) -> None: """ Send a wireless link/unlink API message to the GUI. - :param netif: interface one - :param netif2: interface two + :param iface: interface one + :param iface2: interface two :param unlink: unlink or not :return: nothing """ message_type = MessageFlags.DELETE if unlink else MessageFlags.ADD - link_data = self.create_link_data(netif, netif2, message_type) + link_data = self.create_link_data(iface, iface2, message_type) self.session.broadcast_link(link_data) def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]: @@ -643,17 +639,17 @@ class WayPointMobility(WirelessModel): return return self.run() - # only move netifs attached to self.wlan, or all nodenum in script? + # only move interfaces attached to self.wlan, or all nodenum in script? moved = [] - moved_netifs = [] - for netif in self.wlan.netifs(): - node = netif.node + moved_ifaces = [] + for iface in self.wlan.get_ifaces(): + node = iface.node if self.movenode(node, dt): moved.append(node) - moved_netifs.append(netif) + moved_ifaces.append(iface) # calculate all ranges after moving nodes; this saves calculations - self.session.mobility.updatewlans(moved, moved_netifs) + self.session.mobility.updatewlans(moved, moved_ifaces) # TODO: check session state self.session.event_loop.add_event(0.001 * self.refresh_ms, self.runround) @@ -725,16 +721,16 @@ class WayPointMobility(WirelessModel): :return: nothing """ moved = [] - moved_netifs = [] - for netif in self.wlan.netifs(): - node = netif.node + moved_ifaces = [] + for iface in self.wlan.get_ifaces(): + node = iface.node if node.id not in self.initial: continue x, y, z = self.initial[node.id].coords self.setnodeposition(node, x, y, z) moved.append(node) - moved_netifs.append(netif) - self.session.mobility.updatewlans(moved, moved_netifs) + moved_ifaces.append(iface) + self.session.mobility.updatewlans(moved, moved_ifaces) def addwaypoint( self, diff --git a/daemon/core/nodes/base.py b/daemon/core/nodes/base.py index 6c7ebcf0..8a5c579a 100644 --- a/daemon/core/nodes/base.py +++ b/daemon/core/nodes/base.py @@ -14,8 +14,7 @@ import netaddr from core import utils from core.configservice.dependencies import ConfigServiceDependencies from core.constants import MOUNT_BIN, VNODED_BIN -from core.emulator.data import LinkData, NodeData -from core.emulator.emudata import InterfaceData, LinkOptions +from core.emulator.data import InterfaceData, LinkData, LinkOptions from core.emulator.enumerations import LinkTypes, MessageFlags, NodeTypes from core.errors import CoreCommandError, CoreError from core.nodes.client import VnodeClient @@ -68,11 +67,10 @@ class NodeBase(abc.ABC): self.server: "DistributedServer" = server self.type: Optional[str] = None self.services: CoreServices = [] - self._netif: Dict[int, CoreInterface] = {} - self.ifindex: int = 0 + self.ifaces: Dict[int, CoreInterface] = {} + self.iface_id: int = 0 self.canvas: Optional[int] = None self.icon: Optional[str] = None - self.opaque: Optional[str] = None self.position: Position = Position() self.up: bool = False use_ovs = session.options.get_config("ovs") == "True" @@ -139,103 +137,54 @@ class NodeBase(abc.ABC): """ return self.position.get() - def ifname(self, ifindex: int) -> str: - """ - Retrieve interface name for index. + def get_iface(self, iface_id: int) -> CoreInterface: + if iface_id not in self.ifaces: + raise CoreError(f"node({self.name}) does not have interface({iface_id})") + return self.ifaces[iface_id] - :param ifindex: interface index - :return: interface name + def get_ifaces(self, control: bool = True) -> List[CoreInterface]: """ - return self._netif[ifindex].name + Retrieve sorted list of interfaces, optionally do not include control + interfaces. - def netifs(self, sort: bool = False) -> List[CoreInterface]: + :param control: False to exclude control interfaces, included otherwise + :return: list of interfaces """ - Retrieve network interfaces, sorted if desired. + ifaces = [] + for iface_id in sorted(self.ifaces): + iface = self.ifaces[iface_id] + if not control and getattr(iface, "control", False): + continue + ifaces.append(iface) + return ifaces - :param sort: boolean used to determine if interfaces should be sorted - :return: network interfaces + def get_iface_id(self, iface: CoreInterface) -> int: """ - if sort: - return [self._netif[x] for x in sorted(self._netif)] - else: - return list(self._netif.values()) + Retrieve id for an interface. - def numnetif(self) -> int: - """ - Return the attached interface count. - - :return: number of network interfaces - """ - return len(self._netif) - - def getifindex(self, netif: CoreInterface) -> int: - """ - Retrieve index for an interface. - - :param netif: interface to get index for + :param iface: interface to get id for :return: interface index if found, -1 otherwise """ - for ifindex in self._netif: - if self._netif[ifindex] is netif: - return ifindex - return -1 + for iface_id, local_iface in self.ifaces.items(): + if local_iface is iface: + return iface_id + raise CoreError(f"node({self.name}) does not have interface({iface.name})") - def newifindex(self) -> int: + def next_iface_id(self) -> int: """ Create a new interface index. :return: interface index """ - while self.ifindex in self._netif: - self.ifindex += 1 - ifindex = self.ifindex - self.ifindex += 1 - return ifindex - - def data( - self, message_type: MessageFlags = MessageFlags.NONE, source: str = None - ) -> Optional[NodeData]: - """ - Build a data object for this node. - - :param message_type: purpose for the data object we are creating - :param source: source of node data - :return: node data object - """ - if self.apitype is None: - return None - - x, y, _ = self.getposition() - model = self.type - server = None - if self.server is not None: - server = self.server.name - services = [service.name for service in self.services] - return NodeData( - message_type=message_type, - id=self.id, - node_type=self.apitype, - name=self.name, - emulation_id=self.id, - canvas=self.canvas, - icon=self.icon, - opaque=self.opaque, - x_position=x, - y_position=y, - latitude=self.position.lat, - longitude=self.position.lon, - altitude=self.position.alt, - model=model, - server=server, - services=services, - source=source, - ) + while self.iface_id in self.ifaces: + self.iface_id += 1 + iface_id = self.iface_id + self.iface_id += 1 + return iface_id def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]: """ - Build CORE Link data for this object. There is no default - method for PyCoreObjs as PyCoreNodes do not implement this but - PyCoreNets do. + Build link data for this node. :param flags: message flags :return: list of link data @@ -325,14 +274,14 @@ class CoreNodeBase(NodeBase): raise NotImplementedError @abc.abstractmethod - def newnetif( - self, net: "CoreNetworkBase", interface_data: InterfaceData + def new_iface( + self, net: "CoreNetworkBase", iface_data: InterfaceData ) -> CoreInterface: """ - Create a new network interface. + Create a new interface. :param net: network to associate with - :param interface_data: interface data for new interface + :param iface_data: interface data for new interface :return: interface index """ raise NotImplementedError @@ -399,67 +348,53 @@ class CoreNodeBase(NodeBase): if self.tmpnodedir: self.host_cmd(f"rm -rf {self.nodedir}") - def addnetif(self, netif: CoreInterface, ifindex: int) -> None: + def add_iface(self, iface: CoreInterface, iface_id: int) -> None: """ Add network interface to node and set the network interface index if successful. - :param netif: network interface to add - :param ifindex: interface index + :param iface: network interface to add + :param iface_id: interface id :return: nothing """ - if ifindex in self._netif: - raise ValueError(f"ifindex {ifindex} already exists") - self._netif[ifindex] = netif - netif.netindex = ifindex + if iface_id in self.ifaces: + raise CoreError(f"interface({iface_id}) already exists") + self.ifaces[iface_id] = iface + iface.node_id = iface_id - def delnetif(self, ifindex: int) -> None: + def delete_iface(self, iface_id: int) -> None: """ Delete a network interface - :param ifindex: interface index to delete + :param iface_id: interface index to delete :return: nothing """ - if ifindex not in self._netif: - raise CoreError(f"node({self.name}) ifindex({ifindex}) does not exist") - netif = self._netif.pop(ifindex) - logging.info("node(%s) removing interface(%s)", self.name, netif.name) - netif.detachnet() - netif.shutdown() + if iface_id not in self.ifaces: + raise CoreError(f"node({self.name}) interface({iface_id}) does not exist") + iface = self.ifaces.pop(iface_id) + logging.info("node(%s) removing interface(%s)", self.name, iface.name) + iface.detachnet() + iface.shutdown() - def netif(self, ifindex: int) -> Optional[CoreInterface]: - """ - Retrieve network interface. - - :param ifindex: index of interface to retrieve - :return: network interface, or None if not found - """ - if ifindex in self._netif: - return self._netif[ifindex] - else: - return None - - def attachnet(self, ifindex: int, net: "CoreNetworkBase") -> None: + def attachnet(self, iface_id: int, net: "CoreNetworkBase") -> None: """ Attach a network. - :param ifindex: interface of index to attach + :param iface_id: interface of index to attach :param net: network to attach :return: nothing """ - if ifindex not in self._netif: - raise ValueError(f"ifindex {ifindex} does not exist") - self._netif[ifindex].attachnet(net) + iface = self.get_iface(iface_id) + iface.attachnet(net) - def detachnet(self, ifindex: int) -> None: + def detachnet(self, iface_id: int) -> None: """ Detach network interface. - :param ifindex: interface index to detach + :param iface_id: interface id to detach :return: nothing """ - if ifindex not in self._netif: - raise ValueError(f"ifindex {ifindex} does not exist") - self._netif[ifindex].detachnet() + iface = self.get_iface(iface_id) + iface.detachnet() def setposition(self, x: float = None, y: float = None, z: float = None) -> None: """ @@ -472,8 +407,8 @@ class CoreNodeBase(NodeBase): """ changed = super().setposition(x, y, z) if changed: - for netif in self.netifs(sort=True): - netif.setposition() + for iface in self.get_ifaces(): + iface.setposition() def commonnets( self, node: "CoreNodeBase", want_ctrl: bool = False @@ -488,12 +423,10 @@ class CoreNodeBase(NodeBase): :return: tuples of common networks """ common = [] - for netif1 in self.netifs(): - if not want_ctrl and hasattr(netif1, "control"): - continue - for netif2 in node.netifs(): - if netif1.net == netif2.net: - common.append((netif1.net, netif1, netif2)) + for iface1 in self.get_ifaces(control=want_ctrl): + for iface2 in node.get_ifaces(): + if iface1.net == iface2.net: + common.append((iface1.net, iface1, iface2)) return common @@ -620,8 +553,8 @@ class CoreNode(CoreNodeBase): self._mounts = [] # shutdown all interfaces - for netif in self.netifs(): - netif.shutdown() + for iface in self.get_ifaces(): + iface.shutdown() # kill node process if present try: @@ -636,7 +569,7 @@ class CoreNode(CoreNodeBase): logging.exception("error removing node directory") # clear interface data, close client, and mark self and not up - self._netif.clear() + self.ifaces.clear() self.client.close() self.up = False except OSError: @@ -704,36 +637,36 @@ class CoreNode(CoreNodeBase): self.cmd(f"{MOUNT_BIN} -n --bind {source} {target}") self._mounts.append((source, target)) - def newifindex(self) -> int: + def next_iface_id(self) -> int: """ Retrieve a new interface index. :return: new interface index """ with self.lock: - return super().newifindex() + return super().next_iface_id() - def newveth(self, ifindex: int = None, ifname: str = None) -> int: + def newveth(self, iface_id: int = None, ifname: str = None) -> int: """ Create a new interface. - :param ifindex: index for the new interface + :param iface_id: id for the new interface :param ifname: name for the new interface :return: nothing """ with self.lock: - if ifindex is None: - ifindex = self.newifindex() + if iface_id is None: + iface_id = self.next_iface_id() if ifname is None: - ifname = f"eth{ifindex}" + ifname = f"eth{iface_id}" sessionid = self.session.short_session_id() try: - suffix = f"{self.id:x}.{ifindex}.{sessionid}" + suffix = f"{self.id:x}.{iface_id}.{sessionid}" except TypeError: - suffix = f"{self.id}.{ifindex}.{sessionid}" + suffix = f"{self.id}.{iface_id}.{sessionid}" localname = f"veth{suffix}" if len(localname) >= 16: @@ -758,147 +691,145 @@ class CoreNode(CoreNodeBase): flow_id = self.node_net_client.get_ifindex(veth.name) veth.flow_id = int(flow_id) logging.debug("interface flow index: %s - %s", veth.name, veth.flow_id) - hwaddr = self.node_net_client.get_mac(veth.name) - logging.debug("interface mac: %s - %s", veth.name, hwaddr) - veth.sethwaddr(hwaddr) + mac = self.node_net_client.get_mac(veth.name) + logging.debug("interface mac: %s - %s", veth.name, mac) + veth.set_mac(mac) try: # add network interface to the node. If unsuccessful, destroy the # network interface and raise exception. - self.addnetif(veth, ifindex) + self.add_iface(veth, iface_id) except ValueError as e: veth.shutdown() del veth raise e - return ifindex + return iface_id - def newtuntap(self, ifindex: int = None, ifname: str = None) -> int: + def newtuntap(self, iface_id: int = None, ifname: str = None) -> int: """ Create a new tunnel tap. - :param ifindex: interface index + :param iface_id: interface id :param ifname: interface name :return: interface index """ with self.lock: - if ifindex is None: - ifindex = self.newifindex() + if iface_id is None: + iface_id = self.next_iface_id() if ifname is None: - ifname = f"eth{ifindex}" + ifname = f"eth{iface_id}" sessionid = self.session.short_session_id() - localname = f"tap{self.id}.{ifindex}.{sessionid}" + localname = f"tap{self.id}.{iface_id}.{sessionid}" name = ifname tuntap = TunTap(self.session, self, name, localname, start=self.up) try: - self.addnetif(tuntap, ifindex) + self.add_iface(tuntap, iface_id) except ValueError as e: tuntap.shutdown() del tuntap raise e - return ifindex + return iface_id - def sethwaddr(self, ifindex: int, addr: str) -> None: + def set_mac(self, iface_id: int, mac: str) -> None: """ - Set hardware addres for an interface. + Set hardware address for an interface. - :param ifindex: index of interface to set hardware address for - :param addr: hardware address to set + :param iface_id: id of interface to set hardware address for + :param mac: mac address to set :return: nothing :raises CoreCommandError: when a non-zero exit status occurs """ - addr = utils.validate_mac(addr) - interface = self._netif[ifindex] - interface.sethwaddr(addr) + mac = utils.validate_mac(mac) + iface = self.get_iface(iface_id) + iface.set_mac(mac) if self.up: - self.node_net_client.device_mac(interface.name, addr) + self.node_net_client.device_mac(iface.name, mac) - def addaddr(self, ifindex: int, addr: str) -> None: + def addaddr(self, iface_id: int, addr: str) -> None: """ Add interface address. - :param ifindex: index of interface to add address to + :param iface_id: id of interface to add address to :param addr: address to add to interface :return: nothing """ addr = utils.validate_ip(addr) - interface = self._netif[ifindex] - interface.addaddr(addr) + iface = self.get_iface(iface_id) + iface.addaddr(addr) if self.up: # ipv4 check broadcast = None if netaddr.valid_ipv4(addr): broadcast = "+" - self.node_net_client.create_address(interface.name, addr, broadcast) + self.node_net_client.create_address(iface.name, addr, broadcast) - def deladdr(self, ifindex: int, addr: str) -> None: + def deladdr(self, iface_id: int, addr: str) -> None: """ Delete address from an interface. - :param ifindex: index of interface to delete address from + :param iface_id: id of interface to delete address from :param addr: address to delete from interface :return: nothing :raises CoreCommandError: when a non-zero exit status occurs """ - interface = self._netif[ifindex] - + iface = self.get_iface(iface_id) try: - interface.deladdr(addr) + iface.deladdr(addr) except ValueError: logging.exception("trying to delete unknown address: %s", addr) - if self.up: - self.node_net_client.delete_address(interface.name, addr) + self.node_net_client.delete_address(iface.name, addr) - def ifup(self, ifindex: int) -> None: + def ifup(self, iface_id: int) -> None: """ Bring an interface up. - :param ifindex: index of interface to bring up + :param iface_id: index of interface to bring up :return: nothing """ if self.up: - interface_name = self.ifname(ifindex) - self.node_net_client.device_up(interface_name) + iface = self.get_iface(iface_id) + self.node_net_client.device_up(iface.name) - def newnetif( - self, net: "CoreNetworkBase", interface_data: InterfaceData + def new_iface( + self, net: "CoreNetworkBase", iface_data: InterfaceData ) -> CoreInterface: """ Create a new network interface. :param net: network to associate with - :param interface_data: interface data for new interface + :param iface_data: interface data for new interface :return: interface index """ - addresses = interface_data.get_addresses() + addresses = iface_data.get_addresses() with self.lock: # TODO: emane specific code if net.is_emane is True: - ifindex = self.newtuntap(interface_data.id, interface_data.name) + iface_id = self.newtuntap(iface_data.id, iface_data.name) # TUN/TAP is not ready for addressing yet; the device may # take some time to appear, and installing it into a # namespace after it has been bound removes addressing; # save addresses with the interface now - self.attachnet(ifindex, net) - netif = self.netif(ifindex) - netif.sethwaddr(interface_data.mac) + self.attachnet(iface_id, net) + iface = self.get_iface(iface_id) + iface.set_mac(iface_data.mac) for address in addresses: - netif.addaddr(address) + iface.addaddr(address) else: - ifindex = self.newveth(interface_data.id, interface_data.name) - self.attachnet(ifindex, net) - if interface_data.mac: - self.sethwaddr(ifindex, interface_data.mac) + iface_id = self.newveth(iface_data.id, iface_data.name) + self.attachnet(iface_id, net) + if iface_data.mac: + self.set_mac(iface_id, iface_data.mac) for address in addresses: - self.addaddr(ifindex, address) - self.ifup(ifindex) - netif = self.netif(ifindex) - return netif + self.addaddr(iface_id, address) + self.ifup(iface_id) + iface = self.get_iface(iface_id) + return iface def addfile(self, srcname: str, filename: str) -> None: """ @@ -1041,54 +972,54 @@ class CoreNetworkBase(NodeBase): @abc.abstractmethod def linkconfig( - self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None + self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None ) -> None: """ Configure link parameters by applying tc queuing disciplines on the interface. - :param netif: interface one + :param iface: interface one :param options: options for configuring link - :param netif2: interface two + :param iface2: interface two :return: nothing """ raise NotImplementedError - def getlinknetif(self, net: "CoreNetworkBase") -> Optional[CoreInterface]: + def get_linked_iface(self, net: "CoreNetworkBase") -> Optional[CoreInterface]: """ - Return the interface of that links this net with another net. + Return the interface that links this net with another net. :param net: interface to get link for :return: interface the provided network is linked to """ - for netif in self.netifs(): - if netif.othernet == net: - return netif + for iface in self.get_ifaces(): + if iface.othernet == net: + return iface return None - def attach(self, netif: CoreInterface) -> None: + def attach(self, iface: CoreInterface) -> None: """ Attach network interface. - :param netif: network interface to attach + :param iface: network interface to attach :return: nothing """ - i = self.newifindex() - self._netif[i] = netif - netif.netifi = i + i = self.next_iface_id() + self.ifaces[i] = iface + iface.net_id = i with self._linked_lock: - self._linked[netif] = {} + self._linked[iface] = {} - def detach(self, netif: CoreInterface) -> None: + def detach(self, iface: CoreInterface) -> None: """ Detach network interface. - :param netif: network interface to detach + :param iface: network interface to detach :return: nothing """ - del self._netif[netif.netifi] - netif.netifi = None + del self.ifaces[iface.net_id] + iface.net_id = None with self._linked_lock: - del self._linked[netif] + del self._linked[iface] def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]: """ @@ -1102,84 +1033,63 @@ class CoreNetworkBase(NodeBase): # build a link message from this network node to each node having a # connected interface - for netif in self.netifs(sort=True): - if not hasattr(netif, "node"): - continue + for iface in self.get_ifaces(): uni = False - linked_node = netif.node + linked_node = iface.node if linked_node is None: # two layer-2 switches/hubs linked together via linknet() - if not netif.othernet: + if not iface.othernet: continue - linked_node = netif.othernet + linked_node = iface.othernet if linked_node.id == self.id: continue - netif.swapparams("_params_up") - upstream_params = netif.getparams() - netif.swapparams("_params_up") - if netif.getparams() != upstream_params: + iface.swapparams("_params_up") + upstream_params = iface.getparams() + iface.swapparams("_params_up") + if iface.getparams() != upstream_params: uni = True unidirectional = 0 if uni: unidirectional = 1 - interface2_ip4 = None - interface2_ip4_mask = None - interface2_ip6 = None - interface2_ip6_mask = None - for address in netif.addrlist: + iface2 = InterfaceData( + id=linked_node.get_iface_id(iface), name=iface.name, mac=iface.mac + ) + for address in iface.addrlist: ip, _sep, mask = address.partition("/") mask = int(mask) if netaddr.valid_ipv4(ip): - interface2_ip4 = ip - interface2_ip4_mask = mask + iface2.ip4 = ip + iface2.ip4_mask = mask else: - interface2_ip6 = ip - interface2_ip6_mask = mask + iface2.ip6 = ip + iface2.ip6_mask = mask + options_data = iface.get_link_options(unidirectional) link_data = LinkData( message_type=flags, + type=self.linktype, node1_id=self.id, node2_id=linked_node.id, - link_type=self.linktype, - unidirectional=unidirectional, - interface2_id=linked_node.getifindex(netif), - interface2_name=netif.name, - 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"), - loss=netif.getparam("loss"), + iface2=iface2, + options=options_data, ) - all_links.append(link_data) if not uni: continue - - netif.swapparams("_params_up") + iface.swapparams("_params_up") + options_data = iface.get_link_options(unidirectional) link_data = LinkData( message_type=MessageFlags.NONE, + type=self.linktype, node1_id=linked_node.id, node2_id=self.id, - link_type=self.linktype, - unidirectional=1, - delay=netif.getparam("delay"), - bandwidth=netif.getparam("bw"), - dup=netif.getparam("duplicate"), - jitter=netif.getparam("jitter"), - loss=netif.getparam("loss"), + options=options_data, ) - netif.swapparams("_params_up") - + iface.swapparams("_params_up") all_links.append(link_data) - return all_links diff --git a/daemon/core/nodes/docker.py b/daemon/core/nodes/docker.py index e911db74..1ef814ee 100644 --- a/daemon/core/nodes/docker.py +++ b/daemon/core/nodes/docker.py @@ -141,7 +141,7 @@ class DockerNode(CoreNode): return with self.lock: - self._netif.clear() + self.ifaces.clear() self.client.stop_container() self.up = False diff --git a/daemon/core/nodes/interface.py b/daemon/core/nodes/interface.py index e73e2989..42522362 100644 --- a/daemon/core/nodes/interface.py +++ b/daemon/core/nodes/interface.py @@ -7,8 +7,9 @@ import time from typing import TYPE_CHECKING, Callable, Dict, List, Optional, Tuple from core import utils -from core.emulator.enumerations import MessageFlags, TransportType -from core.errors import CoreCommandError +from core.emulator.data import LinkOptions +from core.emulator.enumerations import TransportType +from core.errors import CoreCommandError, CoreError from core.nodes.netclient import LinuxNetClient, get_net_client if TYPE_CHECKING: @@ -52,16 +53,16 @@ class CoreInterface: self.othernet: Optional[CoreNetworkBase] = None self._params: Dict[str, float] = {} self.addrlist: List[str] = [] - self.hwaddr: Optional[str] = None + self.mac: Optional[str] = None # placeholder position hook self.poshook: Callable[[CoreInterface], None] = lambda x: None # used with EMANE self.transport_type: Optional[TransportType] = None - # node interface index - self.netindex: Optional[int] = None - # net interface index - self.netifi: Optional[int] = None - # index used to find flow data + # id of interface for node + self.node_id: Optional[int] = None + # id of interface for network + self.net_id: Optional[int] = None + # id used to find flow data self.flow_id: Optional[int] = None self.server: Optional["DistributedServer"] = server use_ovs = session.options.get_config("ovs") == "True" @@ -149,16 +150,16 @@ class CoreInterface: """ self.addrlist.remove(addr) - def sethwaddr(self, addr: str) -> None: + def set_mac(self, mac: str) -> None: """ - Set hardware address. + Set mac address. - :param addr: hardware address to set to. + :param mac: mac address to set :return: nothing """ - if addr is not None: - addr = utils.validate_mac(addr) - self.hwaddr = addr + if mac is not None: + mac = utils.validate_mac(mac) + self.mac = mac def getparam(self, key: str) -> float: """ @@ -169,6 +170,34 @@ class CoreInterface: """ return self._params.get(key) + def get_link_options(self, unidirectional: int) -> LinkOptions: + """ + Get currently set params as link options. + + :param unidirectional: unidirectional setting + :return: link options + """ + delay = self.getparam("delay") + if delay is not None: + delay = int(delay) + bandwidth = self.getparam("bw") + if bandwidth is not None: + bandwidth = int(bandwidth) + dup = self.getparam("duplicate") + if dup is not None: + dup = int(dup) + jitter = self.getparam("jitter") + if jitter is not None: + jitter = int(jitter) + return LinkOptions( + delay=delay, + bandwidth=bandwidth, + dup=dup, + jitter=jitter, + loss=self.getparam("loss"), + unidirectional=unidirectional, + ) + def getparams(self) -> List[Tuple[str, float]]: """ Return (key, value) pairs for parameters. @@ -284,19 +313,16 @@ class Veth(CoreInterface): """ if not self.up: return - if self.node: try: self.node.node_net_client.device_flush(self.name) except CoreCommandError: logging.exception("error shutting down interface") - if self.localname: try: self.net_client.delete_device(self.localname) except CoreCommandError: logging.info("link already removed: %s", self.localname) - self.up = False @@ -518,7 +544,7 @@ class GreTap(CoreInterface): if not start: return if remoteip is None: - raise ValueError("missing remote IP required for GRE TAP device") + raise CoreError("missing remote IP required for GRE TAP device") self.net_client.create_gretap(self.localname, remoteip, localip, ttl, key) self.net_client.device_up(self.localname) self.up = True @@ -535,23 +561,4 @@ class GreTap(CoreInterface): self.net_client.delete_device(self.localname) except CoreCommandError: logging.exception("error during shutdown") - self.localname = None - - def data(self, message_type: int) -> None: - """ - Data for a gre tap. - - :param message_type: message type for data - :return: None - """ - return None - - def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List: - """ - Retrieve link data. - - :param flags: link flags - :return: link data - """ - return [] diff --git a/daemon/core/nodes/lxd.py b/daemon/core/nodes/lxd.py index a66791ce..9773cb95 100644 --- a/daemon/core/nodes/lxd.py +++ b/daemon/core/nodes/lxd.py @@ -126,7 +126,7 @@ class LxcNode(CoreNode): return with self.lock: - self._netif.clear() + self.ifaces.clear() self.client.stop_container() self.up = False @@ -215,7 +215,7 @@ class LxcNode(CoreNode): self.client.copy_file(source, filename) self.cmd(f"chmod {mode:o} {filename}") - def addnetif(self, netif: CoreInterface, ifindex: int) -> None: - super().addnetif(netif, ifindex) + def add_iface(self, iface: CoreInterface, iface_id: int) -> None: + super().add_iface(iface, iface_id) # adding small delay to allow time for adding addresses to work correctly time.sleep(0.5) diff --git a/daemon/core/nodes/netclient.py b/daemon/core/nodes/netclient.py index 25a10b99..b6c164b5 100644 --- a/daemon/core/nodes/netclient.py +++ b/daemon/core/nodes/netclient.py @@ -155,14 +155,14 @@ class LinuxNetClient: """ self.run(f"{TC_BIN} qdisc delete dev {device} root") - def checksums_off(self, interface_name: str) -> None: + def checksums_off(self, iface_name: str) -> None: """ Turns interface checksums off. - :param interface_name: interface to update + :param iface_name: interface to update :return: nothing """ - self.run(f"{ETHTOOL_BIN} -K {interface_name} rx off tx off") + self.run(f"{ETHTOOL_BIN} -K {iface_name} rx off tx off") def create_address(self, device: str, address: str, broadcast: str = None) -> None: """ @@ -250,26 +250,26 @@ class LinuxNetClient: self.device_down(name) self.run(f"{IP_BIN} link delete {name} type bridge") - def set_interface_master(self, bridge_name: str, interface_name: str) -> None: + def set_iface_master(self, bridge_name: str, iface_name: str) -> None: """ Assign interface master to a Linux bridge. :param bridge_name: bridge name - :param interface_name: interface name + :param iface_name: interface name :return: nothing """ - self.run(f"{IP_BIN} link set dev {interface_name} master {bridge_name}") - self.device_up(interface_name) + self.run(f"{IP_BIN} link set dev {iface_name} master {bridge_name}") + self.device_up(iface_name) - def delete_interface(self, bridge_name: str, interface_name: str) -> None: + def delete_iface(self, bridge_name: str, iface_name: str) -> None: """ Delete an interface associated with a Linux bridge. :param bridge_name: bridge name - :param interface_name: interface name + :param iface_name: interface name :return: nothing """ - self.run(f"{IP_BIN} link set dev {interface_name} nomaster") + self.run(f"{IP_BIN} link set dev {iface_name} nomaster") def existing_bridges(self, _id: int) -> bool: """ @@ -330,26 +330,26 @@ class OvsNetClient(LinuxNetClient): self.device_down(name) self.run(f"{OVS_BIN} del-br {name}") - def set_interface_master(self, bridge_name: str, interface_name: str) -> None: + def set_iface_master(self, bridge_name: str, iface_name: str) -> None: """ Create an interface associated with a network bridge. :param bridge_name: bridge name - :param interface_name: interface name + :param iface_name: interface name :return: nothing """ - self.run(f"{OVS_BIN} add-port {bridge_name} {interface_name}") - self.device_up(interface_name) + self.run(f"{OVS_BIN} add-port {bridge_name} {iface_name}") + self.device_up(iface_name) - def delete_interface(self, bridge_name: str, interface_name: str) -> None: + def delete_iface(self, bridge_name: str, iface_name: str) -> None: """ Delete an interface associated with a OVS bridge. :param bridge_name: bridge name - :param interface_name: interface name + :param iface_name: interface name :return: nothing """ - self.run(f"{OVS_BIN} del-port {bridge_name} {interface_name}") + self.run(f"{OVS_BIN} del-port {bridge_name} {iface_name}") def existing_bridges(self, _id: int) -> bool: """ diff --git a/daemon/core/nodes/network.py b/daemon/core/nodes/network.py index b85c2eee..f20b6dfb 100644 --- a/daemon/core/nodes/network.py +++ b/daemon/core/nodes/network.py @@ -11,8 +11,7 @@ import netaddr from core import utils from core.constants import EBTABLES_BIN, TC_BIN -from core.emulator.data import LinkData, NodeData -from core.emulator.emudata import InterfaceData, LinkOptions +from core.emulator.data import InterfaceData, LinkData, LinkOptions from core.emulator.enumerations import ( LinkTypes, MessageFlags, @@ -216,20 +215,20 @@ class EbtablesQueue: ] ) # rebuild the chain - for netif1, v in wlan._linked.items(): - for netif2, linked in v.items(): + for iface1, v in wlan._linked.items(): + for oface2, linked in v.items(): if wlan.policy == NetworkPolicy.DROP and linked: self.cmds.extend( [ - f"-A {wlan.brname} -i {netif1.localname} -o {netif2.localname} -j ACCEPT", - f"-A {wlan.brname} -o {netif1.localname} -i {netif2.localname} -j ACCEPT", + f"-A {wlan.brname} -i {iface1.localname} -o {oface2.localname} -j ACCEPT", + f"-A {wlan.brname} -o {iface1.localname} -i {oface2.localname} -j ACCEPT", ] ) elif wlan.policy == NetworkPolicy.ACCEPT and not linked: self.cmds.extend( [ - f"-A {wlan.brname} -i {netif1.localname} -o {netif2.localname} -j DROP", - f"-A {wlan.brname} -o {netif1.localname} -i {netif2.localname} -j DROP", + f"-A {wlan.brname} -i {iface1.localname} -o {oface2.localname} -j DROP", + f"-A {wlan.brname} -o {iface1.localname} -i {oface2.localname} -j DROP", ] ) @@ -347,53 +346,53 @@ class CoreNetwork(CoreNetworkBase): logging.exception("error during shutdown") # removes veth pairs used for bridge-to-bridge connections - for netif in self.netifs(): - netif.shutdown() + for iface in self.get_ifaces(): + iface.shutdown() - self._netif.clear() + self.ifaces.clear() self._linked.clear() del self.session self.up = False - def attach(self, netif: CoreInterface) -> None: + def attach(self, iface: CoreInterface) -> None: """ Attach a network interface. - :param netif: network interface to attach + :param iface: network interface to attach :return: nothing """ if self.up: - netif.net_client.set_interface_master(self.brname, netif.localname) - super().attach(netif) + iface.net_client.set_iface_master(self.brname, iface.localname) + super().attach(iface) - def detach(self, netif: CoreInterface) -> None: + def detach(self, iface: CoreInterface) -> None: """ Detach a network interface. - :param netif: network interface to detach + :param iface: network interface to detach :return: nothing """ if self.up: - netif.net_client.delete_interface(self.brname, netif.localname) - super().detach(netif) + iface.net_client.delete_iface(self.brname, iface.localname) + super().detach(iface) - def linked(self, netif1: CoreInterface, netif2: CoreInterface) -> bool: + def linked(self, iface1: CoreInterface, iface2: CoreInterface) -> bool: """ Determine if the provided network interfaces are linked. - :param netif1: interface one - :param netif2: interface two + :param iface1: interface one + :param iface2: interface two :return: True if interfaces are linked, False otherwise """ # check if the network interfaces are attached to this network - if self._netif[netif1.netifi] != netif1: - raise ValueError(f"inconsistency for netif {netif1.name}") + if self.ifaces[iface1.net_id] != iface1: + raise ValueError(f"inconsistency for interface {iface1.name}") - if self._netif[netif2.netifi] != netif2: - raise ValueError(f"inconsistency for netif {netif2.name}") + if self.ifaces[iface2.net_id] != iface2: + raise ValueError(f"inconsistency for interface {iface2.name}") try: - linked = self._linked[netif1][netif2] + linked = self._linked[iface1][iface2] except KeyError: if self.policy == NetworkPolicy.ACCEPT: linked = True @@ -401,93 +400,93 @@ class CoreNetwork(CoreNetworkBase): linked = False else: raise Exception(f"unknown policy: {self.policy.value}") - self._linked[netif1][netif2] = linked + self._linked[iface1][iface2] = linked return linked - def unlink(self, netif1: CoreInterface, netif2: CoreInterface) -> None: + def unlink(self, iface1: CoreInterface, iface2: CoreInterface) -> None: """ Unlink two interfaces, resulting in adding or removing ebtables filtering rules. - :param netif1: interface one - :param netif2: interface two + :param iface1: interface one + :param iface2: interface two :return: nothing """ with self._linked_lock: - if not self.linked(netif1, netif2): + if not self.linked(iface1, iface2): return - self._linked[netif1][netif2] = False + self._linked[iface1][iface2] = False ebq.ebchange(self) - def link(self, netif1: CoreInterface, netif2: CoreInterface) -> None: + def link(self, iface1: CoreInterface, iface2: CoreInterface) -> None: """ Link two interfaces together, resulting in adding or removing ebtables filtering rules. - :param netif1: interface one - :param netif2: interface two + :param iface1: interface one + :param iface2: interface two :return: nothing """ with self._linked_lock: - if self.linked(netif1, netif2): + if self.linked(iface1, iface2): return - self._linked[netif1][netif2] = True + self._linked[iface1][iface2] = True ebq.ebchange(self) def linkconfig( - self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None + self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None ) -> None: """ Configure link parameters by applying tc queuing disciplines on the interface. - :param netif: interface one + :param iface: interface one :param options: options for configuring link - :param netif2: interface two + :param iface2: interface two :return: nothing """ - devname = netif.localname + devname = iface.localname tc = f"{TC_BIN} qdisc replace dev {devname}" parent = "root" changed = False bw = options.bandwidth - if netif.setparam("bw", bw): + if iface.setparam("bw", bw): # from tc-tbf(8): minimum value for burst is rate / kernel_hz - burst = max(2 * netif.mtu, int(bw / 1000)) + burst = max(2 * iface.mtu, int(bw / 1000)) # max IP payload limit = 0xFFFF tbf = f"tbf rate {bw} burst {burst} limit {limit}" if bw > 0: if self.up: cmd = f"{tc} {parent} handle 1: {tbf}" - netif.host_cmd(cmd) - netif.setparam("has_tbf", True) + iface.host_cmd(cmd) + iface.setparam("has_tbf", True) changed = True - elif netif.getparam("has_tbf") and bw <= 0: + elif iface.getparam("has_tbf") and bw <= 0: if self.up: cmd = f"{TC_BIN} qdisc delete dev {devname} {parent}" - netif.host_cmd(cmd) - netif.setparam("has_tbf", False) + iface.host_cmd(cmd) + iface.setparam("has_tbf", False) # removing the parent removes the child - netif.setparam("has_netem", False) + iface.setparam("has_netem", False) changed = True - if netif.getparam("has_tbf"): + if iface.getparam("has_tbf"): parent = "parent 1:1" netem = "netem" delay = options.delay - changed = max(changed, netif.setparam("delay", delay)) + changed = max(changed, iface.setparam("delay", delay)) loss = options.loss if loss is not None: loss = float(loss) - changed = max(changed, netif.setparam("loss", loss)) + changed = max(changed, iface.setparam("loss", loss)) duplicate = options.dup if duplicate is not None: duplicate = int(duplicate) - changed = max(changed, netif.setparam("duplicate", duplicate)) + changed = max(changed, iface.setparam("duplicate", duplicate)) jitter = options.jitter - changed = max(changed, netif.setparam("jitter", jitter)) + changed = max(changed, iface.setparam("jitter", jitter)) if not changed: return # jitter and delay use the same delay statement @@ -510,19 +509,19 @@ class CoreNetwork(CoreNetworkBase): duplicate_check = duplicate is None or duplicate <= 0 if all([delay_check, jitter_check, loss_check, duplicate_check]): # possibly remove netem if it exists and parent queue wasn't removed - if not netif.getparam("has_netem"): + if not iface.getparam("has_netem"): return if self.up: cmd = f"{TC_BIN} qdisc delete dev {devname} {parent} handle 10:" - netif.host_cmd(cmd) - netif.setparam("has_netem", False) + iface.host_cmd(cmd) + iface.setparam("has_netem", False) elif len(netem) > 1: if self.up: cmd = ( f"{TC_BIN} qdisc replace dev {devname} {parent} handle 10: {netem}" ) - netif.host_cmd(cmd) - netif.setparam("has_netem", True) + iface.host_cmd(cmd) + iface.setparam("has_netem", True) def linknet(self, net: CoreNetworkBase) -> CoreInterface: """ @@ -551,19 +550,19 @@ class CoreNetwork(CoreNetworkBase): if len(name) >= 16: raise ValueError(f"interface name {name} too long") - netif = Veth(self.session, None, name, localname, start=self.up) - self.attach(netif) + iface = Veth(self.session, None, name, localname, start=self.up) + self.attach(iface) if net.up and net.brname: - netif.net_client.set_interface_master(net.brname, netif.name) - i = net.newifindex() - net._netif[i] = netif + iface.net_client.set_iface_master(net.brname, iface.name) + i = net.next_iface_id() + net.ifaces[i] = iface with net._linked_lock: - net._linked[netif] = {} - netif.net = self - netif.othernet = net - return netif + net._linked[iface] = {} + iface.net = self + iface.othernet = net + return iface - def getlinknetif(self, net: CoreNetworkBase) -> Optional[CoreInterface]: + def get_linked_iface(self, net: CoreNetworkBase) -> Optional[CoreInterface]: """ Return the interface of that links this net with another net (that were linked using linknet()). @@ -571,9 +570,9 @@ class CoreNetwork(CoreNetworkBase): :param net: interface to get link for :return: interface the provided network is linked to """ - for netif in self.netifs(): - if netif.othernet == net: - return netif + for iface in self.get_ifaces(): + if iface.othernet == net: + return iface return None def addrconfig(self, addrlist: List[str]) -> None: @@ -619,7 +618,6 @@ class GreTapBridge(CoreNetwork): :param localip: local address :param ttl: ttl value :param key: gre tap key - :param start: start flag :param server: remote server node will run on, default is None for localhost """ @@ -690,17 +688,17 @@ class GreTapBridge(CoreNetwork): ) self.attach(self.gretap) - def setkey(self, key: int, interface_data: InterfaceData) -> None: + def setkey(self, key: int, iface_data: InterfaceData) -> None: """ Set the GRE key used for the GreTap device. This needs to be set prior to instantiating the GreTap device (before addrconfig). :param key: gre key - :param interface_data: interface data for setting up tunnel key + :param iface_data: interface data for setting up tunnel key :return: nothing """ self.grekey = key - addresses = interface_data.get_addresses() + addresses = iface_data.get_addresses() if addresses: self.addrconfig(addresses) @@ -802,7 +800,7 @@ class CtrlNet(CoreNetwork): self.host_cmd(f"{self.updown_script} {self.brname} startup") if self.serverintf: - self.net_client.set_interface_master(self.brname, self.serverintf) + self.net_client.set_iface_master(self.brname, self.serverintf) def shutdown(self) -> None: """ @@ -812,7 +810,7 @@ class CtrlNet(CoreNetwork): """ if self.serverintf is not None: try: - self.net_client.delete_interface(self.brname, self.serverintf) + self.net_client.delete_iface(self.brname, self.serverintf) except CoreCommandError: logging.exception( "error deleting server interface %s from bridge %s", @@ -850,31 +848,16 @@ class PtpNet(CoreNetwork): policy: NetworkPolicy = NetworkPolicy.ACCEPT - def attach(self, netif: CoreInterface) -> None: + def attach(self, iface: CoreInterface) -> None: """ Attach a network interface, but limit attachment to two interfaces. - :param netif: network interface + :param iface: network interface :return: nothing """ - if len(self._netif) >= 2: - raise ValueError( - "Point-to-point links support at most 2 network interfaces" - ) - super().attach(netif) - - def data( - self, message_type: MessageFlags = MessageFlags.NONE, source: str = None - ) -> Optional[NodeData]: - """ - Do not generate a Node Message for point-to-point links. They are - built using a link message instead. - - :param message_type: purpose for the data object we are creating - :param source: source of node data - :return: node data object - """ - return None + if len(self.ifaces) >= 2: + raise CoreError("ptp links support at most 2 network interfaces") + super().attach(iface) def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]: """ @@ -885,87 +868,68 @@ class PtpNet(CoreNetwork): :return: list of link data """ all_links = [] - - if len(self._netif) != 2: + if len(self.ifaces) != 2: return all_links - interface1, interface2 = self._netif.values() + ifaces = self.get_ifaces() + iface1 = ifaces[0] + iface2 = ifaces[1] unidirectional = 0 - if interface1.getparams() != interface2.getparams(): + if iface1.getparams() != iface2.getparams(): unidirectional = 1 - interface1_ip4 = None - interface1_ip4_mask = None - interface1_ip6 = None - interface1_ip6_mask = None - for address in interface1.addrlist: + iface1_data = InterfaceData( + id=iface1.node.get_iface_id(iface1), name=iface1.name, mac=iface1.mac + ) + for address in iface1.addrlist: ip, _sep, mask = address.partition("/") mask = int(mask) if netaddr.valid_ipv4(ip): - interface1_ip4 = ip - interface1_ip4_mask = mask + iface1.ip4 = ip + iface1.ip4_mask = mask else: - interface1_ip6 = ip - interface1_ip6_mask = mask + iface1.ip6 = ip + iface1.ip6_mask = mask - interface2_ip4 = None - interface2_ip4_mask = None - interface2_ip6 = None - interface2_ip6_mask = None - for address in interface2.addrlist: + iface2_data = InterfaceData( + id=iface2.node.get_iface_id(iface2), name=iface2.name, mac=iface2.mac + ) + for address in iface2.addrlist: ip, _sep, mask = address.partition("/") mask = int(mask) if netaddr.valid_ipv4(ip): - interface2_ip4 = ip - interface2_ip4_mask = mask + iface2.ip4 = ip + iface2.ip4_mask = mask else: - interface2_ip6 = ip - interface2_ip6_mask = mask + iface2.ip6 = ip + iface2.ip6_mask = mask + options_data = iface1.get_link_options(unidirectional) link_data = LinkData( message_type=flags, - node1_id=interface1.node.id, - node2_id=interface2.node.id, - link_type=self.linktype, - unidirectional=unidirectional, - delay=interface1.getparam("delay"), - bandwidth=interface1.getparam("bw"), - loss=interface1.getparam("loss"), - dup=interface1.getparam("duplicate"), - jitter=interface1.getparam("jitter"), - interface1_id=interface1.node.getifindex(interface1), - interface1_name=interface1.name, - interface1_mac=interface1.hwaddr, - interface1_ip4=interface1_ip4, - interface1_ip4_mask=interface1_ip4_mask, - interface1_ip6=interface1_ip6, - interface1_ip6_mask=interface1_ip6_mask, - interface2_id=interface2.node.getifindex(interface2), - interface2_name=interface2.name, - interface2_mac=interface2.hwaddr, - interface2_ip4=interface2_ip4, - interface2_ip4_mask=interface2_ip4_mask, - interface2_ip6=interface2_ip6, - interface2_ip6_mask=interface2_ip6_mask, + type=self.linktype, + node1_id=iface1.node.id, + node2_id=iface2.node.id, + iface1=iface1_data, + iface2=iface2_data, + options=options_data, ) all_links.append(link_data) # build a 2nd link message for the upstream link parameters # (swap if1 and if2) if unidirectional: + iface1_data = InterfaceData(id=iface2.node.get_iface_id(iface2)) + iface2_data = InterfaceData(id=iface1.node.get_iface_id(iface1)) + options_data = iface2.get_link_options(unidirectional) link_data = LinkData( message_type=MessageFlags.NONE, - link_type=self.linktype, - node1_id=interface2.node.id, - node2_id=interface1.node.id, - delay=interface2.getparam("delay"), - bandwidth=interface2.getparam("bw"), - loss=interface2.getparam("loss"), - dup=interface2.getparam("duplicate"), - jitter=interface2.getparam("jitter"), - unidirectional=1, - interface1_id=interface2.node.getifindex(interface2), - interface2_id=interface1.node.getifindex(interface1), + type=self.linktype, + node1_id=iface2.node.id, + node2_id=iface1.node.id, + iface1=iface1_data, + iface2=iface2_data, + options=options_data, ) all_links.append(link_data) return all_links @@ -1025,7 +989,6 @@ class WlanNode(CoreNetwork): :param session: core session instance :param _id: node id :param name: node name - :param start: start flag :param server: remote server node will run on, default is None for localhost :param policy: wlan policy @@ -1045,17 +1008,17 @@ class WlanNode(CoreNetwork): self.net_client.disable_mac_learning(self.brname) ebq.ebchange(self) - def attach(self, netif: CoreInterface) -> None: + def attach(self, iface: CoreInterface) -> None: """ Attach a network interface. - :param netif: network interface + :param iface: network interface :return: nothing """ - super().attach(netif) + super().attach(iface) if self.model: - netif.poshook = self.model.position_callback - netif.setposition() + iface.poshook = self.model.position_callback + iface.setposition() def setmodel(self, model: "WirelessModelType", config: Dict[str, str]): """ @@ -1068,9 +1031,9 @@ class WlanNode(CoreNetwork): logging.debug("node(%s) setting model: %s", self.name, model.name) if model.config_type == RegisterTlvs.WIRELESS: self.model = model(session=self.session, _id=self.id) - for netif in self.netifs(): - netif.poshook = self.model.position_callback - netif.setposition() + for iface in self.get_ifaces(): + iface.poshook = self.model.position_callback + iface.setposition() self.updatemodel(config) elif model.config_type == RegisterTlvs.MOBILITY: self.mobility = model(session=self.session, _id=self.id) @@ -1088,8 +1051,8 @@ class WlanNode(CoreNetwork): "node(%s) updating model(%s): %s", self.id, self.model.name, config ) self.model.update_config(config) - for netif in self.netifs(): - netif.setposition() + for iface in self.get_ifaces(): + iface.setposition() def all_link_data(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]: """ diff --git a/daemon/core/nodes/physical.py b/daemon/core/nodes/physical.py index 741fe7d5..0ce8946a 100644 --- a/daemon/core/nodes/physical.py +++ b/daemon/core/nodes/physical.py @@ -9,8 +9,8 @@ from typing import IO, TYPE_CHECKING, List, Optional, Tuple from core import utils from core.constants import MOUNT_BIN, UMOUNT_BIN +from core.emulator.data import InterfaceData, LinkOptions from core.emulator.distributed import DistributedServer -from core.emulator.emudata import InterfaceData, LinkOptions from core.emulator.enumerations import NodeTypes, TransportType from core.errors import CoreCommandError, CoreError from core.nodes.base import CoreNetworkBase, CoreNodeBase @@ -51,8 +51,8 @@ class PhysicalNode(CoreNodeBase): _source, target = self._mounts.pop(-1) self.umount(target) - for netif in self.netifs(): - netif.shutdown() + for iface in self.get_ifaces(): + iface.shutdown() self.rmnodedir() @@ -65,117 +65,115 @@ class PhysicalNode(CoreNodeBase): """ return sh - def sethwaddr(self, ifindex: int, addr: str) -> None: + def set_mac(self, iface_id: int, mac: str) -> None: """ - Set hardware address for an interface. + Set mac address for an interface. - :param ifindex: index of interface to set hardware address for - :param addr: hardware address to set + :param iface_id: index of interface to set hardware address for + :param mac: mac address to set :return: nothing :raises CoreCommandError: when a non-zero exit status occurs """ - addr = utils.validate_mac(addr) - interface = self._netif[ifindex] - interface.sethwaddr(addr) + mac = utils.validate_mac(mac) + iface = self.ifaces[iface_id] + iface.set_mac(mac) if self.up: - self.net_client.device_mac(interface.name, addr) + self.net_client.device_mac(iface.name, mac) - def addaddr(self, ifindex: int, addr: str) -> None: + def addaddr(self, iface_id: int, addr: str) -> None: """ Add an address to an interface. - :param ifindex: index of interface to add address to + :param iface_id: index of interface to add address to :param addr: address to add :return: nothing """ addr = utils.validate_ip(addr) - interface = self._netif[ifindex] + iface = self.get_iface(iface_id) if self.up: - self.net_client.create_address(interface.name, addr) - interface.addaddr(addr) + self.net_client.create_address(iface.name, addr) + iface.addaddr(addr) - def deladdr(self, ifindex: int, addr: str) -> None: + def deladdr(self, iface_id: int, addr: str) -> None: """ Delete an address from an interface. - :param ifindex: index of interface to delete + :param iface_id: index of interface to delete :param addr: address to delete :return: nothing """ - interface = self._netif[ifindex] - + iface = self.ifaces[iface_id] try: - interface.deladdr(addr) + iface.deladdr(addr) except ValueError: logging.exception("trying to delete unknown address: %s", addr) - if self.up: - self.net_client.delete_address(interface.name, addr) + self.net_client.delete_address(iface.name, addr) - def adoptnetif( - self, netif: CoreInterface, ifindex: int, hwaddr: str, addrlist: List[str] + def adopt_iface( + self, iface: CoreInterface, iface_id: int, mac: str, addrlist: List[str] ) -> None: """ When a link message is received linking this node to another part of the emulation, no new interface is created; instead, adopt the - GreTap netif as the node interface. + GreTap interface as the node interface. """ - netif.name = f"gt{ifindex}" - netif.node = self - self.addnetif(netif, ifindex) + iface.name = f"gt{iface_id}" + iface.node = self + self.add_iface(iface, iface_id) # use a more reasonable name, e.g. "gt0" instead of "gt.56286.150" if self.up: - self.net_client.device_down(netif.localname) - self.net_client.device_name(netif.localname, netif.name) - netif.localname = netif.name - if hwaddr: - self.sethwaddr(ifindex, hwaddr) + self.net_client.device_down(iface.localname) + self.net_client.device_name(iface.localname, iface.name) + iface.localname = iface.name + if mac: + self.set_mac(iface_id, mac) for addr in addrlist: - self.addaddr(ifindex, addr) + self.addaddr(iface_id, addr) if self.up: - self.net_client.device_up(netif.localname) + self.net_client.device_up(iface.localname) def linkconfig( - self, netif: CoreInterface, options: LinkOptions, netif2: CoreInterface = None + self, iface: CoreInterface, options: LinkOptions, iface2: CoreInterface = None ) -> None: """ Apply tc queing disciplines using linkconfig. """ linux_bridge = CoreNetwork(self.session) linux_bridge.up = True - linux_bridge.linkconfig(netif, options, netif2) + linux_bridge.linkconfig(iface, options, iface2) del linux_bridge - def newifindex(self) -> int: + def next_iface_id(self) -> int: with self.lock: - while self.ifindex in self._netif: - self.ifindex += 1 - ifindex = self.ifindex - self.ifindex += 1 - return ifindex + while self.iface_id in self.ifaces: + self.iface_id += 1 + iface_id = self.iface_id + self.iface_id += 1 + return iface_id - def newnetif( - self, net: CoreNetworkBase, interface_data: InterfaceData + def new_iface( + self, net: CoreNetworkBase, iface_data: InterfaceData ) -> CoreInterface: logging.info("creating interface") - addresses = interface_data.get_addresses() - ifindex = interface_data.id - if ifindex is None: - ifindex = self.newifindex() - name = interface_data.name + addresses = iface_data.get_addresses() + iface_id = iface_data.id + if iface_id is None: + iface_id = self.next_iface_id() + name = iface_data.name if name is None: - name = f"gt{ifindex}" + name = f"gt{iface_id}" if self.up: # this is reached when this node is linked to a network node # tunnel to net not built yet, so build it now and adopt it _, remote_tap = self.session.distributed.create_gre_tunnel(net, self.server) - self.adoptnetif(remote_tap, ifindex, interface_data.mac, addresses) + self.adopt_iface(remote_tap, iface_id, iface_data.mac, addresses) return remote_tap else: # this is reached when configuring services (self.up=False) - netif = GreTap(node=self, name=name, session=self.session, start=False) - self.adoptnetif(netif, ifindex, interface_data.mac, addresses) - return netif + iface = GreTap(node=self, name=name, session=self.session, start=False) + self.adopt_iface(iface, iface_id, iface_data.mac, addresses) + return iface def privatedir(self, path: str) -> None: if path[0] != "/": @@ -257,10 +255,10 @@ class Rj45Node(CoreNodeBase): will run on, default is None for localhost """ super().__init__(session, _id, name, server) - self.interface = CoreInterface(session, self, name, name, mtu, server) - self.interface.transport_type = TransportType.RAW + self.iface = CoreInterface(session, self, name, name, mtu, server) + self.iface.transport_type = TransportType.RAW self.lock: threading.RLock = threading.RLock() - self.ifindex: Optional[int] = None + self.iface_id: Optional[int] = None self.old_up: bool = False self.old_addrs: List[Tuple[str, Optional[str]]] = [] @@ -273,7 +271,7 @@ class Rj45Node(CoreNodeBase): """ # interface will also be marked up during net.attach() self.savestate() - self.net_client.device_up(self.interface.localname) + self.net_client.device_up(self.iface.localname) self.up = True def shutdown(self) -> None: @@ -285,7 +283,7 @@ class Rj45Node(CoreNodeBase): """ if not self.up: return - localname = self.interface.localname + localname = self.iface.localname self.net_client.device_down(localname) self.net_client.device_flush(localname) try: @@ -295,8 +293,8 @@ class Rj45Node(CoreNodeBase): self.up = False self.restorestate() - def newnetif( - self, net: CoreNetworkBase, interface_data: InterfaceData + def new_iface( + self, net: CoreNetworkBase, iface_data: InterfaceData ) -> CoreInterface: """ This is called when linking with another node. Since this node @@ -304,70 +302,51 @@ class Rj45Node(CoreNodeBase): but attach ourselves to the given network. :param net: new network instance - :param interface_data: interface data for new interface + :param iface_data: interface data for new interface :return: interface index :raises ValueError: when an interface has already been created, one max """ with self.lock: - ifindex = interface_data.id - if ifindex is None: - ifindex = 0 - if self.interface.net is not None: - raise ValueError("RJ45 nodes support at most 1 network interface") - self._netif[ifindex] = self.interface - self.ifindex = ifindex + iface_id = iface_data.id + if iface_id is None: + iface_id = 0 + if self.iface.net is not None: + raise CoreError("RJ45 nodes support at most 1 network interface") + self.ifaces[iface_id] = self.iface + self.iface_id = iface_id if net is not None: - self.interface.attachnet(net) - for addr in interface_data.get_addresses(): + self.iface.attachnet(net) + for addr in iface_data.get_addresses(): self.addaddr(addr) - return self.interface + return self.iface - def delnetif(self, ifindex: int) -> None: + def delete_iface(self, iface_id: int) -> None: """ Delete a network interface. - :param ifindex: interface index to delete + :param iface_id: interface index to delete :return: nothing """ - if ifindex is None: - ifindex = 0 - self._netif.pop(ifindex) - if ifindex == self.ifindex: - self.shutdown() - else: - raise ValueError(f"ifindex {ifindex} does not exist") + self.get_iface(iface_id) + self.ifaces.pop(iface_id) + self.shutdown() - def netif( - self, ifindex: int, net: CoreNetworkBase = None - ) -> Optional[CoreInterface]: - """ - This object is considered the network interface, so we only - return self here. This keeps the RJ45Node compatible with - real nodes. + def get_iface(self, iface_id: int) -> CoreInterface: + if iface_id != self.iface_id or iface_id not in self.ifaces: + raise CoreError(f"node({self.name}) interface({iface_id}) does not exist") + return self.iface - :param ifindex: interface index to retrieve - :param net: network to retrieve - :return: a network interface - """ - if net is not None and net == self.interface.net: - return self.interface - if ifindex is None: - ifindex = 0 - if ifindex == self.ifindex: - return self.interface - return None - - def getifindex(self, netif: CoreInterface) -> Optional[int]: + def get_iface_id(self, iface: CoreInterface) -> Optional[int]: """ Retrieve network interface index. - :param netif: network interface to retrieve + :param iface: network interface to retrieve index for :return: interface index, None otherwise """ - if netif != self.interface: - return None - return self.ifindex + if iface is not self.iface: + raise CoreError(f"node({self.name}) does not have interface({iface.name})") + return self.iface_id def addaddr(self, addr: str) -> None: """ @@ -380,7 +359,7 @@ class Rj45Node(CoreNodeBase): addr = utils.validate_ip(addr) if self.up: self.net_client.create_address(self.name, addr) - self.interface.addaddr(addr) + self.iface.addaddr(addr) def deladdr(self, addr: str) -> None: """ @@ -392,7 +371,7 @@ class Rj45Node(CoreNodeBase): """ if self.up: self.net_client.delete_address(self.name, addr) - self.interface.deladdr(addr) + self.iface.deladdr(addr) def savestate(self) -> None: """ @@ -404,7 +383,7 @@ class Rj45Node(CoreNodeBase): """ self.old_up = False self.old_addrs: List[Tuple[str, Optional[str]]] = [] - localname = self.interface.localname + localname = self.iface.localname output = self.net_client.address_show(localname) for line in output.split("\n"): items = line.split() @@ -429,7 +408,7 @@ class Rj45Node(CoreNodeBase): :return: nothing :raises CoreCommandError: when there is a command exception """ - localname = self.interface.localname + localname = self.iface.localname logging.info("restoring rj45 state: %s", localname) for addr in self.old_addrs: self.net_client.create_address(localname, addr[0], addr[1]) @@ -446,7 +425,7 @@ class Rj45Node(CoreNodeBase): :return: True if position changed, False otherwise """ super().setposition(x, y, z) - self.interface.setposition() + self.iface.setposition() def termcmdstring(self, sh: str) -> str: raise CoreError("rj45 does not support terminal commands") diff --git a/daemon/core/plugins/sdt.py b/daemon/core/plugins/sdt.py index 04fff3e4..84c90730 100644 --- a/daemon/core/plugins/sdt.py +++ b/daemon/core/plugins/sdt.py @@ -314,26 +314,22 @@ class Sdt: :param node_data: node data being updated :return: nothing """ - logging.debug("sdt handle node update: %s - %s", node_data.id, node_data.name) if not self.connect(): return - - # delete node + node = node_data.node + logging.debug("sdt handle node update: %s - %s", node.id, node.name) if node_data.message_type == MessageFlags.DELETE: - self.cmd(f"delete node,{node_data.id}") + self.cmd(f"delete node,{node.id}") else: - x = node_data.x_position - y = node_data.y_position - lat = node_data.latitude - lon = node_data.longitude - alt = node_data.altitude + x, y, _ = node.position.get() + lon, lat, alt = node.position.get_geo() if all([lat is not None, lon is not None, alt is not None]): pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}" - self.cmd(f"node {node_data.id} {pos}") + self.cmd(f"node {node.id} {pos}") elif node_data.message_type == 0: lat, lon, alt = self.session.location.getgeo(x, y, 0) pos = f"pos {lon:.6f},{lat:.6f},{alt:.6f}" - self.cmd(f"node {node_data.id} {pos}") + self.cmd(f"node {node.id} {pos}") def wireless_net_check(self, node_id: int) -> bool: """ diff --git a/daemon/core/services/bird.py b/daemon/core/services/bird.py index 4901ea56..16f0bb84 100644 --- a/daemon/core/services/bird.py +++ b/daemon/core/services/bird.py @@ -35,10 +35,8 @@ class Bird(CoreService): """ Helper to return the first IPv4 address of a node as its router ID. """ - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + for a in iface.addrlist: a = a.split("/")[0] if netaddr.valid_ipv4(a): return a @@ -84,7 +82,7 @@ protocol device { for s in node.services: if cls.name not in s.dependencies: continue - cfg += s.generatebirdconfig(node) + cfg += s.generate_bird_config(node) return cfg @@ -106,11 +104,11 @@ class BirdService(CoreService): meta = "The config file for this service can be found in the bird service." @classmethod - def generatebirdconfig(cls, node): + def generate_bird_config(cls, node): return "" @classmethod - def generatebirdifcconfig(cls, node): + def generate_bird_iface_config(cls, node): """ Use only bare interfaces descriptions in generated protocol configurations. This has the slight advantage of being the same @@ -118,10 +116,8 @@ class BirdService(CoreService): """ cfg = "" - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += ' interface "%s";\n' % ifc.name + for iface in node.get_ifaces(control=False): + cfg += ' interface "%s";\n' % iface.name return cfg @@ -135,7 +131,7 @@ class BirdBgp(BirdService): custom_needed = True @classmethod - def generatebirdconfig(cls, node): + def generate_bird_config(cls, node): return """ /* This is a sample config that should be customized with appropriate AS numbers * and peers; add one section like this for each neighbor */ @@ -165,7 +161,7 @@ class BirdOspf(BirdService): name = "BIRD_OSPFv2" @classmethod - def generatebirdconfig(cls, node): + def generate_bird_config(cls, node): cfg = "protocol ospf {\n" cfg += " export filter {\n" cfg += " if source = RTS_BGP then {\n" @@ -175,7 +171,7 @@ class BirdOspf(BirdService): cfg += " accept;\n" cfg += " };\n" cfg += " area 0.0.0.0 {\n" - cfg += cls.generatebirdifcconfig(node) + cfg += cls.generate_bird_iface_config(node) cfg += " };\n" cfg += "}\n\n" @@ -190,12 +186,12 @@ class BirdRadv(BirdService): name = "BIRD_RADV" @classmethod - def generatebirdconfig(cls, node): + def generate_bird_config(cls, node): cfg = "/* This is a sample config that must be customized */\n" cfg += "protocol radv {\n" cfg += " # auto configuration on all interfaces\n" - cfg += cls.generatebirdifcconfig(node) + cfg += cls.generate_bird_iface_config(node) cfg += " # Advertise DNS\n" cfg += " rdnss {\n" cfg += "# lifetime mult 10;\n" @@ -218,11 +214,11 @@ class BirdRip(BirdService): name = "BIRD_RIP" @classmethod - def generatebirdconfig(cls, node): + def generate_bird_config(cls, node): cfg = "protocol rip {\n" cfg += " period 10;\n" cfg += " garbage time 60;\n" - cfg += cls.generatebirdifcconfig(node) + cfg += cls.generate_bird_iface_config(node) cfg += " honor neighbor;\n" cfg += " authentication none;\n" cfg += " import all;\n" @@ -241,7 +237,7 @@ class BirdStatic(BirdService): custom_needed = True @classmethod - def generatebirdconfig(cls, node): + def generate_bird_config(cls, node): cfg = "/* This is a sample config that must be customized */\n" cfg += "protocol static {\n" cfg += "# route 0.0.0.0/0 via 198.51.100.130; # Default route. Do NOT advertise on BGP !\n" diff --git a/daemon/core/services/emaneservices.py b/daemon/core/services/emaneservices.py index 9d09516e..da438bab 100644 --- a/daemon/core/services/emaneservices.py +++ b/daemon/core/services/emaneservices.py @@ -20,14 +20,14 @@ class EmaneTransportService(CoreService): def generate_config(cls, node, filename): if filename == cls.configs[0]: transport_commands = [] - for interface in node.netifs(sort=True): + for iface in node.get_ifaces(): try: - network_node = node.session.get_node(interface.net.id, EmaneNet) + network_node = node.session.get_node(iface.net.id, EmaneNet) config = node.session.emane.get_configs( network_node.id, network_node.model.name ) if config and emanexml.is_external(config): - nem_id = network_node.getnemid(interface) + nem_id = network_node.getnemid(iface) command = ( "emanetransportd -r -l 0 -d ../transportdaemon%s.xml" % nem_id diff --git a/daemon/core/services/frr.py b/daemon/core/services/frr.py index 9a344339..97a8b334 100644 --- a/daemon/core/services/frr.py +++ b/daemon/core/services/frr.py @@ -59,12 +59,12 @@ class FRRZebra(CoreService): """ # we could verify here that filename == frr.conf cfg = "" - for ifc in node.netifs(): - cfg += "interface %s\n" % ifc.name + for iface in node.get_ifaces(): + cfg += "interface %s\n" % iface.name # include control interfaces in addressing but not routing daemons - if hasattr(ifc, "control") and ifc.control is True: + if hasattr(iface, "control") and iface.control is True: cfg += " " - cfg += "\n ".join(map(cls.addrstr, ifc.addrlist)) + cfg += "\n ".join(map(cls.addrstr, iface.addrlist)) cfg += "\n" continue cfgv4 = "" @@ -74,18 +74,18 @@ class FRRZebra(CoreService): for s in node.services: if cls.name not in s.dependencies: continue - ifccfg = s.generatefrrifcconfig(node, ifc) + iface_config = s.generate_frr_iface_config(node, iface) if s.ipv4_routing: want_ipv4 = True if s.ipv6_routing: want_ipv6 = True - cfgv6 += ifccfg + cfgv6 += iface_config else: - cfgv4 += ifccfg + cfgv4 += iface_config if want_ipv4: ipv4list = filter( - lambda x: netaddr.valid_ipv4(x.split("/")[0]), ifc.addrlist + lambda x: netaddr.valid_ipv4(x.split("/")[0]), iface.addrlist ) cfg += " " cfg += "\n ".join(map(cls.addrstr, ipv4list)) @@ -93,7 +93,7 @@ class FRRZebra(CoreService): cfg += cfgv4 if want_ipv6: ipv6list = filter( - lambda x: netaddr.valid_ipv6(x.split("/")[0]), ifc.addrlist + lambda x: netaddr.valid_ipv6(x.split("/")[0]), iface.addrlist ) cfg += " " cfg += "\n ".join(map(cls.addrstr, ipv6list)) @@ -104,7 +104,7 @@ class FRRZebra(CoreService): for s in node.services: if cls.name not in s.dependencies: continue - cfg += s.generatefrrconfig(node) + cfg += s.generate_frr_config(node) return cfg @staticmethod @@ -237,10 +237,10 @@ bootfrr frr_bin_search, constants.FRR_STATE_DIR, ) - for ifc in node.netifs(): - cfg += f"ip link set dev {ifc.name} down\n" + for iface in node.get_ifaces(): + cfg += f"ip link set dev {iface.name} down\n" cfg += "sleep 1\n" - cfg += f"ip link set dev {ifc.name} up\n" + cfg += f"ip link set dev {iface.name} up\n" return cfg @classmethod @@ -334,10 +334,8 @@ class FrrService(CoreService): """ Helper to return the first IPv4 address of a node as its router ID. """ - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + for a in iface.addrlist: a = a.split("/")[0] if netaddr.valid_ipv4(a): return a @@ -345,16 +343,16 @@ class FrrService(CoreService): return "0.0.0.0" @staticmethod - def rj45check(ifc): + def rj45check(iface): """ Helper to detect whether interface is connected an external RJ45 link. """ - if ifc.net: - for peerifc in ifc.net.netifs(): - if peerifc == ifc: + if iface.net: + for peer_iface in iface.net.get_ifaces(): + if peer_iface == iface: continue - if isinstance(peerifc.node, Rj45Node): + if isinstance(peer_iface.node, Rj45Node): return True return False @@ -363,11 +361,11 @@ class FrrService(CoreService): return "" @classmethod - def generatefrrifcconfig(cls, node, ifc): + def generate_frr_iface_config(cls, node, iface): return "" @classmethod - def generatefrrconfig(cls, node): + def generate_frr_config(cls, node): return "" @@ -385,43 +383,41 @@ class FRROspfv2(FrrService): ipv4_routing = True @staticmethod - def mtucheck(ifc): + def mtucheck(iface): """ Helper to detect MTU mismatch and add the appropriate OSPF mtu-ignore command. This is needed when e.g. a node is linked via a GreTap device. """ - if ifc.mtu != 1500: + if iface.mtu != 1500: # a workaround for PhysicalNode GreTap, which has no knowledge of # the other nodes/nets return " ip ospf mtu-ignore\n" - if not ifc.net: + if not iface.net: return "" - for i in ifc.net.netifs(): - if i.mtu != ifc.mtu: + for iface in iface.net.get_ifaces(): + if iface.mtu != iface.mtu: return " ip ospf mtu-ignore\n" return "" @staticmethod - def ptpcheck(ifc): + def ptpcheck(iface): """ Helper to detect whether interface is connected to a notional point-to-point link. """ - if isinstance(ifc.net, PtpNet): + if isinstance(iface.net, PtpNet): return " ip ospf network point-to-point\n" return "" @classmethod - def generatefrrconfig(cls, node): + def generate_frr_config(cls, node): cfg = "router ospf\n" rtrid = cls.routerid(node) cfg += " router-id %s\n" % rtrid # network 10.0.0.0/24 area 0 - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + for a in iface.addrlist: addr = a.split("/")[0] if not netaddr.valid_ipv4(addr): continue @@ -430,8 +426,8 @@ class FRROspfv2(FrrService): return cfg @classmethod - def generatefrrifcconfig(cls, node, ifc): - return cls.mtucheck(ifc) + def generate_frr_iface_config(cls, node, iface): + return cls.mtucheck(iface) class FRROspfv3(FrrService): @@ -449,57 +445,55 @@ class FRROspfv3(FrrService): ipv6_routing = True @staticmethod - def minmtu(ifc): + def minmtu(iface): """ Helper to discover the minimum MTU of interfaces linked with the given interface. """ - mtu = ifc.mtu - if not ifc.net: + mtu = iface.mtu + if not iface.net: return mtu - for i in ifc.net.netifs(): - if i.mtu < mtu: - mtu = i.mtu + for iface in iface.net.get_ifaces(): + if iface.mtu < mtu: + mtu = iface.mtu return mtu @classmethod - def mtucheck(cls, ifc): + def mtucheck(cls, iface): """ Helper to detect MTU mismatch and add the appropriate OSPFv3 ifmtu command. This is needed when e.g. a node is linked via a GreTap device. """ - minmtu = cls.minmtu(ifc) - if minmtu < ifc.mtu: + minmtu = cls.minmtu(iface) + if minmtu < iface.mtu: return " ipv6 ospf6 ifmtu %d\n" % minmtu else: return "" @staticmethod - def ptpcheck(ifc): + def ptpcheck(iface): """ Helper to detect whether interface is connected to a notional point-to-point link. """ - if isinstance(ifc.net, PtpNet): + if isinstance(iface.net, PtpNet): return " ipv6 ospf6 network point-to-point\n" return "" @classmethod - def generatefrrconfig(cls, node): + def generate_frr_config(cls, node): cfg = "router ospf6\n" rtrid = cls.routerid(node) cfg += " router-id %s\n" % rtrid - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += " interface %s area 0.0.0.0\n" % ifc.name + for iface in node.get_ifaces(control=False): + cfg += " interface %s area 0.0.0.0\n" % iface.name cfg += "!\n" return cfg @classmethod - def generatefrrifcconfig(cls, node, ifc): - return cls.mtucheck(ifc) + def generate_frr_iface_config(cls, node, iface): + return cls.mtucheck(iface) # cfg = cls.mtucheck(ifc) # external RJ45 connections will use default OSPF timers # if cls.rj45check(ifc): @@ -531,7 +525,7 @@ class FRRBgp(FrrService): ipv6_routing = True @classmethod - def generatefrrconfig(cls, node): + def generate_frr_config(cls, node): cfg = "!\n! BGP configuration\n!\n" cfg += "! You should configure the AS number below,\n" cfg += "! along with this router's peers.\n!\n" @@ -555,7 +549,7 @@ class FRRRip(FrrService): ipv4_routing = True @classmethod - def generatefrrconfig(cls, node): + def generate_frr_config(cls, node): cfg = """\ router rip redistribute static @@ -579,7 +573,7 @@ class FRRRipng(FrrService): ipv6_routing = True @classmethod - def generatefrrconfig(cls, node): + def generate_frr_config(cls, node): cfg = """\ router ripng redistribute static @@ -604,18 +598,16 @@ class FRRBabel(FrrService): ipv6_routing = True @classmethod - def generatefrrconfig(cls, node): + def generate_frr_config(cls, node): cfg = "router babel\n" - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += " network %s\n" % ifc.name + for iface in node.get_ifaces(control=False): + cfg += " network %s\n" % iface.name cfg += " redistribute static\n redistribute ipv4 connected\n" return cfg @classmethod - def generatefrrifcconfig(cls, node, ifc): - if ifc.net and isinstance(ifc.net, (EmaneNet, WlanNode)): + def generate_frr_iface_config(cls, node, iface): + if iface.net and isinstance(iface.net, (EmaneNet, WlanNode)): return " babel wireless\n no babel split-horizon\n" else: return " babel wired\n babel split-horizon\n" @@ -633,11 +625,11 @@ class FRRpimd(FrrService): ipv4_routing = True @classmethod - def generatefrrconfig(cls, node): + def generate_frr_config(cls, node): ifname = "eth0" - for ifc in node.netifs(): - if ifc.name != "lo": - ifname = ifc.name + for iface in node.get_ifaces(): + if iface.name != "lo": + ifname = iface.name break cfg = "router mfea\n!\n" cfg += "router igmp\n!\n" @@ -649,7 +641,7 @@ class FRRpimd(FrrService): return cfg @classmethod - def generatefrrifcconfig(cls, node, ifc): + def generate_frr_iface_config(cls, node, iface): return " ip mfea\n ip igmp\n ip pim\n" @@ -668,17 +660,17 @@ class FRRIsis(FrrService): ipv6_routing = True @staticmethod - def ptpcheck(ifc): + def ptpcheck(iface): """ Helper to detect whether interface is connected to a notional point-to-point link. """ - if isinstance(ifc.net, PtpNet): + if isinstance(iface.net, PtpNet): return " isis network point-to-point\n" return "" @classmethod - def generatefrrconfig(cls, node): + def generate_frr_config(cls, node): cfg = "router isis DEFAULT\n" cfg += " net 47.0001.0000.1900.%04x.00\n" % node.id cfg += " metric-style wide\n" @@ -687,9 +679,9 @@ class FRRIsis(FrrService): return cfg @classmethod - def generatefrrifcconfig(cls, node, ifc): + def generate_frr_iface_config(cls, node, iface): cfg = " ip router isis DEFAULT\n" cfg += " ipv6 router isis DEFAULT\n" cfg += " isis circuit-type level-2-only\n" - cfg += cls.ptpcheck(ifc) + cfg += cls.ptpcheck(iface) return cfg diff --git a/daemon/core/services/nrl.py b/daemon/core/services/nrl.py index 3c9f262d..38b90d48 100644 --- a/daemon/core/services/nrl.py +++ b/daemon/core/services/nrl.py @@ -32,10 +32,8 @@ class NrlService(CoreService): prefix of a node, using the supplied prefix length. This ignores the interface's prefix length, so e.g. '/32' can turn into '/24'. """ - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + for a in iface.addrlist: a = a.split("/")[0] if netaddr.valid_ipv4(a): return f"{a}/{prefixlen}" @@ -54,8 +52,8 @@ class MgenSinkService(NrlService): @classmethod def generate_config(cls, node, filename): cfg = "0.0 LISTEN UDP 5000\n" - for ifc in node.netifs(): - name = utils.sysctl_devname(ifc.name) + for iface in node.get_ifaces(): + name = utils.sysctl_devname(iface.name) cfg += "0.0 Join 224.225.1.2 INTERFACE %s\n" % name return cfg @@ -91,11 +89,11 @@ class NrlNhdp(NrlService): cmd += " -flooding ecds" cmd += " -smfClient %s_smf" % node.name - netifs = list(filter(lambda x: not getattr(x, "control", False), node.netifs())) - if len(netifs) > 0: - interfacenames = map(lambda x: x.name, netifs) + ifaces = node.get_ifaces(control=False) + if len(ifaces) > 0: + iface_names = map(lambda x: x.name, ifaces) cmd += " -i " - cmd += " -i ".join(interfacenames) + cmd += " -i ".join(iface_names) return (cmd,) @@ -125,16 +123,16 @@ class NrlSmf(NrlService): cmd = "nrlsmf instance %s_smf" % node.name servicenames = map(lambda x: x.name, node.services) - netifs = list(filter(lambda x: not getattr(x, "control", False), node.netifs())) - if len(netifs) == 0: + ifaces = node.get_ifaces(control=False) + if len(ifaces) == 0: return "" if "arouted" in servicenames: comments += "# arouted service is enabled\n" cmd += " tap %s_tap" % (node.name,) cmd += " unicast %s" % cls.firstipv4prefix(node, 24) - cmd += " push lo,%s resequence on" % netifs[0].name - if len(netifs) > 0: + cmd += " push lo,%s resequence on" % ifaces[0].name + if len(ifaces) > 0: if "NHDP" in servicenames: comments += "# NHDP service is enabled\n" cmd += " ecds " @@ -143,8 +141,8 @@ class NrlSmf(NrlService): cmd += " smpr " else: cmd += " cf " - interfacenames = map(lambda x: x.name, netifs) - cmd += ",".join(interfacenames) + iface_names = map(lambda x: x.name, ifaces) + cmd += ",".join(iface_names) cmd += " hash MD5" cmd += " log /var/log/nrlsmf.log" @@ -171,10 +169,10 @@ class NrlOlsr(NrlService): """ cmd = cls.startup[0] # are multiple interfaces supported? No. - netifs = list(node.netifs()) - if len(netifs) > 0: - ifc = netifs[0] - cmd += " -i %s" % ifc.name + ifaces = node.get_ifaces() + if len(ifaces) > 0: + iface = ifaces[0] + cmd += " -i %s" % iface.name cmd += " -l /var/log/nrlolsrd.log" cmd += " -rpipe %s_olsr" % node.name @@ -215,11 +213,11 @@ class NrlOlsrv2(NrlService): cmd += " -p olsr" - netifs = list(filter(lambda x: not getattr(x, "control", False), node.netifs())) - if len(netifs) > 0: - interfacenames = map(lambda x: x.name, netifs) + ifaces = node.get_ifaces(control=False) + if len(ifaces) > 0: + iface_names = map(lambda x: x.name, ifaces) cmd += " -i " - cmd += " -i ".join(interfacenames) + cmd += " -i ".join(iface_names) return (cmd,) @@ -243,11 +241,11 @@ class OlsrOrg(NrlService): Generate the appropriate command-line based on node interfaces. """ cmd = cls.startup[0] - netifs = list(filter(lambda x: not getattr(x, "control", False), node.netifs())) - if len(netifs) > 0: - interfacenames = map(lambda x: x.name, netifs) + ifaces = node.get_ifaces(control=False) + if len(ifaces) > 0: + iface_names = map(lambda x: x.name, ifaces) cmd += " -i " - cmd += " -i ".join(interfacenames) + cmd += " -i ".join(iface_names) return (cmd,) @@ -607,8 +605,8 @@ class MgenActor(NrlService): comments = "" cmd = "mgenBasicActor.py -n %s -a 0.0.0.0" % node.name - netifs = [x for x in node.netifs() if not getattr(x, "control", False)] - if len(netifs) == 0: + ifaces = node.get_ifaces(control=False) + if len(ifaces) == 0: return "" cfg += comments + cmd + " < /dev/null > /dev/null 2>&1 &\n\n" diff --git a/daemon/core/services/quagga.py b/daemon/core/services/quagga.py index a62cbc5c..41cfa3d8 100644 --- a/daemon/core/services/quagga.py +++ b/daemon/core/services/quagga.py @@ -56,12 +56,12 @@ class Zebra(CoreService): """ # we could verify here that filename == Quagga.conf cfg = "" - for ifc in node.netifs(): - cfg += "interface %s\n" % ifc.name + for iface in node.get_ifaces(): + cfg += "interface %s\n" % iface.name # include control interfaces in addressing but not routing daemons - if hasattr(ifc, "control") and ifc.control is True: + if hasattr(iface, "control") and iface.control is True: cfg += " " - cfg += "\n ".join(map(cls.addrstr, ifc.addrlist)) + cfg += "\n ".join(map(cls.addrstr, iface.addrlist)) cfg += "\n" continue cfgv4 = "" @@ -71,18 +71,18 @@ class Zebra(CoreService): for s in node.services: if cls.name not in s.dependencies: continue - ifccfg = s.generatequaggaifcconfig(node, ifc) + iface_config = s.generate_quagga_iface_config(node, iface) if s.ipv4_routing: want_ipv4 = True if s.ipv6_routing: want_ipv6 = True - cfgv6 += ifccfg + cfgv6 += iface_config else: - cfgv4 += ifccfg + cfgv4 += iface_config if want_ipv4: ipv4list = filter( - lambda x: netaddr.valid_ipv4(x.split("/")[0]), ifc.addrlist + lambda x: netaddr.valid_ipv4(x.split("/")[0]), iface.addrlist ) cfg += " " cfg += "\n ".join(map(cls.addrstr, ipv4list)) @@ -90,7 +90,7 @@ class Zebra(CoreService): cfg += cfgv4 if want_ipv6: ipv6list = filter( - lambda x: netaddr.valid_ipv6(x.split("/")[0]), ifc.addrlist + lambda x: netaddr.valid_ipv6(x.split("/")[0]), iface.addrlist ) cfg += " " cfg += "\n ".join(map(cls.addrstr, ipv6list)) @@ -101,7 +101,7 @@ class Zebra(CoreService): for s in node.services: if cls.name not in s.dependencies: continue - cfg += s.generatequaggaconfig(node) + cfg += s.generate_quagga_config(node) return cfg @staticmethod @@ -252,10 +252,8 @@ class QuaggaService(CoreService): """ Helper to return the first IPv4 address of a node as its router ID. """ - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + for a in iface.addrlist: a = a.split("/")[0] if netaddr.valid_ipv4(a): return a @@ -263,16 +261,16 @@ class QuaggaService(CoreService): return "0.0.0.%d" % node.id @staticmethod - def rj45check(ifc): + def rj45check(iface): """ Helper to detect whether interface is connected an external RJ45 link. """ - if ifc.net: - for peerifc in ifc.net.netifs(): - if peerifc == ifc: + if iface.net: + for peer_iface in iface.net.get_ifaces(): + if peer_iface == iface: continue - if isinstance(peerifc.node, Rj45Node): + if isinstance(peer_iface.node, Rj45Node): return True return False @@ -281,11 +279,11 @@ class QuaggaService(CoreService): return "" @classmethod - def generatequaggaifcconfig(cls, node, ifc): + def generate_quagga_iface_config(cls, node, iface): return "" @classmethod - def generatequaggaconfig(cls, node): + def generate_quagga_config(cls, node): return "" @@ -303,43 +301,41 @@ class Ospfv2(QuaggaService): ipv4_routing = True @staticmethod - def mtucheck(ifc): + def mtucheck(iface): """ Helper to detect MTU mismatch and add the appropriate OSPF mtu-ignore command. This is needed when e.g. a node is linked via a GreTap device. """ - if ifc.mtu != 1500: + if iface.mtu != 1500: # a workaround for PhysicalNode GreTap, which has no knowledge of # the other nodes/nets return " ip ospf mtu-ignore\n" - if not ifc.net: + if not iface.net: return "" - for i in ifc.net.netifs(): - if i.mtu != ifc.mtu: + for iface in iface.net.get_ifaces(): + if iface.mtu != iface.mtu: return " ip ospf mtu-ignore\n" return "" @staticmethod - def ptpcheck(ifc): + def ptpcheck(iface): """ Helper to detect whether interface is connected to a notional point-to-point link. """ - if isinstance(ifc.net, PtpNet): + if isinstance(iface.net, PtpNet): return " ip ospf network point-to-point\n" return "" @classmethod - def generatequaggaconfig(cls, node): + def generate_quagga_config(cls, node): cfg = "router ospf\n" rtrid = cls.routerid(node) cfg += " router-id %s\n" % rtrid # network 10.0.0.0/24 area 0 - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + for a in iface.addrlist: addr = a.split("/")[0] if netaddr.valid_ipv4(addr): cfg += " network %s area 0\n" % a @@ -347,12 +343,12 @@ class Ospfv2(QuaggaService): return cfg @classmethod - def generatequaggaifcconfig(cls, node, ifc): - cfg = cls.mtucheck(ifc) + def generate_quagga_iface_config(cls, node, iface): + cfg = cls.mtucheck(iface) # external RJ45 connections will use default OSPF timers - if cls.rj45check(ifc): + if cls.rj45check(iface): return cfg - cfg += cls.ptpcheck(ifc) + cfg += cls.ptpcheck(iface) return ( cfg + """\ @@ -378,58 +374,56 @@ class Ospfv3(QuaggaService): ipv6_routing = True @staticmethod - def minmtu(ifc): + def minmtu(iface): """ Helper to discover the minimum MTU of interfaces linked with the given interface. """ - mtu = ifc.mtu - if not ifc.net: + mtu = iface.mtu + if not iface.net: return mtu - for i in ifc.net.netifs(): - if i.mtu < mtu: - mtu = i.mtu + for iface in iface.net.get_ifaces(): + if iface.mtu < mtu: + mtu = iface.mtu return mtu @classmethod - def mtucheck(cls, ifc): + def mtucheck(cls, iface): """ Helper to detect MTU mismatch and add the appropriate OSPFv3 ifmtu command. This is needed when e.g. a node is linked via a GreTap device. """ - minmtu = cls.minmtu(ifc) - if minmtu < ifc.mtu: + minmtu = cls.minmtu(iface) + if minmtu < iface.mtu: return " ipv6 ospf6 ifmtu %d\n" % minmtu else: return "" @staticmethod - def ptpcheck(ifc): + def ptpcheck(iface): """ Helper to detect whether interface is connected to a notional point-to-point link. """ - if isinstance(ifc.net, PtpNet): + if isinstance(iface.net, PtpNet): return " ipv6 ospf6 network point-to-point\n" return "" @classmethod - def generatequaggaconfig(cls, node): + def generate_quagga_config(cls, node): cfg = "router ospf6\n" rtrid = cls.routerid(node) cfg += " instance-id 65\n" cfg += " router-id %s\n" % rtrid - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += " interface %s area 0.0.0.0\n" % ifc.name + for iface in node.get_ifaces(control=False): + cfg += " interface %s area 0.0.0.0\n" % iface.name cfg += "!\n" return cfg @classmethod - def generatequaggaifcconfig(cls, node, ifc): - return cls.mtucheck(ifc) + def generate_quagga_iface_config(cls, node, iface): + return cls.mtucheck(iface) class Ospfv3mdr(Ospfv3): @@ -444,9 +438,9 @@ class Ospfv3mdr(Ospfv3): ipv4_routing = True @classmethod - def generatequaggaifcconfig(cls, node, ifc): - cfg = cls.mtucheck(ifc) - if ifc.net is not None and isinstance(ifc.net, (WlanNode, EmaneNet)): + def generate_quagga_iface_config(cls, node, iface): + cfg = cls.mtucheck(iface) + if iface.net is not None and isinstance(iface.net, (WlanNode, EmaneNet)): return ( cfg + """\ @@ -479,7 +473,7 @@ class Bgp(QuaggaService): ipv6_routing = True @classmethod - def generatequaggaconfig(cls, node): + def generate_quagga_config(cls, node): cfg = "!\n! BGP configuration\n!\n" cfg += "! You should configure the AS number below,\n" cfg += "! along with this router's peers.\n!\n" @@ -503,7 +497,7 @@ class Rip(QuaggaService): ipv4_routing = True @classmethod - def generatequaggaconfig(cls, node): + def generate_quagga_config(cls, node): cfg = """\ router rip redistribute static @@ -527,7 +521,7 @@ class Ripng(QuaggaService): ipv6_routing = True @classmethod - def generatequaggaconfig(cls, node): + def generate_quagga_config(cls, node): cfg = """\ router ripng redistribute static @@ -552,18 +546,16 @@ class Babel(QuaggaService): ipv6_routing = True @classmethod - def generatequaggaconfig(cls, node): + def generate_quagga_config(cls, node): cfg = "router babel\n" - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += " network %s\n" % ifc.name + for iface in node.get_ifaces(control=False): + cfg += " network %s\n" % iface.name cfg += " redistribute static\n redistribute connected\n" return cfg @classmethod - def generatequaggaifcconfig(cls, node, ifc): - if ifc.net and ifc.net.linktype == LinkTypes.WIRELESS: + def generate_quagga_iface_config(cls, node, iface): + if iface.net and iface.net.linktype == LinkTypes.WIRELESS: return " babel wireless\n no babel split-horizon\n" else: return " babel wired\n babel split-horizon\n" @@ -581,11 +573,11 @@ class Xpimd(QuaggaService): ipv4_routing = True @classmethod - def generatequaggaconfig(cls, node): + def generate_quagga_config(cls, node): ifname = "eth0" - for ifc in node.netifs(): - if ifc.name != "lo": - ifname = ifc.name + for iface in node.get_ifaces(): + if iface.name != "lo": + ifname = iface.name break cfg = "router mfea\n!\n" cfg += "router igmp\n!\n" @@ -597,5 +589,5 @@ class Xpimd(QuaggaService): return cfg @classmethod - def generatequaggaifcconfig(cls, node, ifc): + def generate_quagga_iface_config(cls, node, iface): return " ip mfea\n ip igmp\n ip pim\n" diff --git a/daemon/core/services/sdn.py b/daemon/core/services/sdn.py index ab46f551..71ab815f 100644 --- a/daemon/core/services/sdn.py +++ b/daemon/core/services/sdn.py @@ -49,10 +49,8 @@ class OvsService(SdnService): cfg += "\n## Now add all our interfaces as ports to the switch\n" portnum = 1 - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - ifnumstr = re.findall(r"\d+", ifc.name) + for iface in node.get_ifaces(control=False): + ifnumstr = re.findall(r"\d+", iface.name) ifnum = ifnumstr[0] # create virtual interfaces @@ -61,18 +59,18 @@ class OvsService(SdnService): # remove ip address of eths because quagga/zebra will assign same IPs to rtr interfaces # or assign them manually to rtr interfaces if zebra is not running - for ifcaddr in ifc.addrlist: - addr = ifcaddr.split("/")[0] + for addr in iface.addrlist: + addr = addr.split("/")[0] if netaddr.valid_ipv4(addr): - cfg += "ip addr del %s dev %s\n" % (ifcaddr, ifc.name) + cfg += "ip addr del %s dev %s\n" % (addr, iface.name) if has_zebra == 0: - cfg += "ip addr add %s dev rtr%s\n" % (ifcaddr, ifnum) + cfg += "ip addr add %s dev rtr%s\n" % (addr, ifnum) elif netaddr.valid_ipv6(addr): - cfg += "ip -6 addr del %s dev %s\n" % (ifcaddr, ifc.name) + cfg += "ip -6 addr del %s dev %s\n" % (addr, iface.name) if has_zebra == 0: - cfg += "ip -6 addr add %s dev rtr%s\n" % (ifcaddr, ifnum) + cfg += "ip -6 addr add %s dev rtr%s\n" % (addr, ifnum) else: - raise ValueError("invalid address: %s" % ifcaddr) + raise ValueError("invalid address: %s" % addr) # add interfaces to bridge # Make port numbers explicit so they're easier to follow in reading the script @@ -102,9 +100,7 @@ class OvsService(SdnService): cfg += "## if the above controller will be present then you probably want to delete them\n" # Setup default flows portnum = 1 - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue + for iface in node.get_ifaces(control=False): cfg += "## Take the data from the CORE interface and put it on the veth and vice versa\n" cfg += ( "ovs-ofctl add-flow ovsbr0 priority=1000,in_port=%d,action=output:%d\n" diff --git a/daemon/core/services/security.py b/daemon/core/services/security.py index eb6545b2..91c942f1 100644 --- a/daemon/core/services/security.py +++ b/daemon/core/services/security.py @@ -131,18 +131,18 @@ class Nat(CoreService): custom_needed = False @classmethod - def generateifcnatrule(cls, ifc, line_prefix=""): + def generate_iface_nat_rule(cls, iface, line_prefix=""): """ Generate a NAT line for one interface. """ cfg = line_prefix + "iptables -t nat -A POSTROUTING -o " - cfg += ifc.name + " -j MASQUERADE\n" + cfg += iface.name + " -j MASQUERADE\n" - cfg += line_prefix + "iptables -A FORWARD -i " + ifc.name + cfg += line_prefix + "iptables -A FORWARD -i " + iface.name cfg += " -m state --state RELATED,ESTABLISHED -j ACCEPT\n" cfg += line_prefix + "iptables -A FORWARD -i " - cfg += ifc.name + " -j DROP\n" + cfg += iface.name + " -j DROP\n" return cfg @classmethod @@ -154,14 +154,12 @@ class Nat(CoreService): cfg += "# generated by security.py\n" cfg += "# NAT out the first interface by default\n" have_nat = False - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue + for iface in node.get_ifaces(control=False): if have_nat: - cfg += cls.generateifcnatrule(ifc, line_prefix="#") + cfg += cls.generate_iface_nat_rule(iface, line_prefix="#") else: have_nat = True - cfg += "# NAT out the " + ifc.name + " interface\n" - cfg += cls.generateifcnatrule(ifc) + cfg += "# NAT out the " + iface.name + " interface\n" + cfg += cls.generate_iface_nat_rule(iface) cfg += "\n" return cfg diff --git a/daemon/core/services/utility.py b/daemon/core/services/utility.py index 8a6e828b..273318e1 100644 --- a/daemon/core/services/utility.py +++ b/daemon/core/services/utility.py @@ -55,8 +55,8 @@ class IPForwardService(UtilService): """ % { "sysctl": constants.SYSCTL_BIN } - for ifc in node.netifs(): - name = utils.sysctl_devname(ifc.name) + for iface in node.get_ifaces(): + name = utils.sysctl_devname(iface.name) cfg += "%s -w net.ipv4.conf.%s.forwarding=1\n" % ( constants.SYSCTL_BIN, name, @@ -77,10 +77,10 @@ class DefaultRouteService(UtilService): @classmethod def generate_config(cls, node, filename): routes = [] - netifs = node.netifs(sort=True) - if netifs: - netif = netifs[0] - for x in netif.addrlist: + ifaces = node.get_ifaces() + if ifaces: + iface = ifaces[0] + for x in iface.addrlist: net = netaddr.IPNetwork(x).cidr if net.size > 1: router = net[1] @@ -104,14 +104,12 @@ class DefaultMulticastRouteService(UtilService): cfg += "# the first interface is chosen below; please change it " cfg += "as needed\n" - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue + for iface in node.get_ifaces(control=False): if os.uname()[0] == "Linux": rtcmd = "ip route add 224.0.0.0/4 dev" else: raise Exception("unknown platform") - cfg += "%s %s\n" % (rtcmd, ifc.name) + cfg += "%s %s\n" % (rtcmd, iface.name) cfg += "\n" break return cfg @@ -129,10 +127,8 @@ class StaticRouteService(UtilService): cfg += "# auto-generated by StaticRoute service (utility.py)\n#\n" cfg += "# NOTE: this service must be customized to be of any use\n" cfg += "# Below are samples that you can uncomment and edit.\n#\n" - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += "\n".join(map(cls.routestr, ifc.addrlist)) + for iface in node.get_ifaces(control=False): + cfg += "\n".join(map(cls.routestr, iface.addrlist)) cfg += "\n" return cfg @@ -259,10 +255,8 @@ max-lease-time 7200; ddns-update-style none; """ - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += "\n".join(map(cls.subnetentry, ifc.addrlist)) + for iface in node.get_ifaces(control=False): + cfg += "\n".join(map(cls.subnetentry, iface.addrlist)) cfg += "\n" return cfg @@ -320,13 +314,11 @@ class DhcpClientService(UtilService): cfg += "side DNS\n# resolution based on the DHCP server response.\n" cfg += "#mkdir -p /var/run/resolvconf/interface\n" - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += "#ln -s /var/run/resolvconf/interface/%s.dhclient" % ifc.name + for iface in node.get_ifaces(control=False): + cfg += "#ln -s /var/run/resolvconf/interface/%s.dhclient" % iface.name cfg += " /var/run/resolvconf/resolv.conf\n" - cfg += "/sbin/dhclient -nw -pf /var/run/dhclient-%s.pid" % ifc.name - cfg += " -lf /var/run/dhclient-%s.lease %s\n" % (ifc.name, ifc.name) + cfg += "/sbin/dhclient -nw -pf /var/run/dhclient-%s.pid" % iface.name + cfg += " -lf /var/run/dhclient-%s.lease %s\n" % (iface.name, iface.name) return cfg @@ -585,10 +577,8 @@ export LANG """ % node.name ) - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - body += "<li>%s - %s</li>\n" % (ifc.name, ifc.addrlist) + for iface in node.get_ifaces(control=False): + body += "<li>%s - %s</li>\n" % (iface.name, iface.addrlist) return "<html><body>%s</body></html>" % body @@ -619,14 +609,14 @@ DUMPOPTS="-s 12288 -C 10 -n" if [ "x$1" = "xstart" ]; then """ - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: + for iface in node.get_ifaces(): + if hasattr(iface, "control") and iface.control is True: cfg += "# " redir = "< /dev/null" cfg += "tcpdump ${DUMPOPTS} -w %s.%s.pcap -i %s %s &\n" % ( node.name, - ifc.name, - ifc.name, + iface.name, + iface.name, redir, ) cfg += """ @@ -654,10 +644,8 @@ class RadvdService(UtilService): using the network address of each interface. """ cfg = "# auto-generated by RADVD service (utility.py)\n" - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - prefixes = list(map(cls.subnetentry, ifc.addrlist)) + for iface in node.get_ifaces(control=False): + prefixes = list(map(cls.subnetentry, iface.addrlist)) if len(prefixes) < 1: continue cfg += ( @@ -670,7 +658,7 @@ interface %s AdvDefaultPreference low; AdvHomeAgentFlag off; """ - % ifc.name + % iface.name ) for prefix in prefixes: if prefix == "": diff --git a/daemon/core/services/xorp.py b/daemon/core/services/xorp.py index 2312e6d4..776b1d16 100644 --- a/daemon/core/services/xorp.py +++ b/daemon/core/services/xorp.py @@ -35,11 +35,11 @@ class XorpRtrmgr(CoreService): invoked here. Filename currently ignored. """ cfg = "interfaces {\n" - for ifc in node.netifs(): - cfg += " interface %s {\n" % ifc.name - cfg += "\tvif %s {\n" % ifc.name - cfg += "".join(map(cls.addrstr, ifc.addrlist)) - cfg += cls.lladdrstr(ifc) + for iface in node.get_ifaces(): + cfg += " interface %s {\n" % iface.name + cfg += "\tvif %s {\n" % iface.name + cfg += "".join(map(cls.addrstr, iface.addrlist)) + cfg += cls.lladdrstr(iface) cfg += "\t}\n" cfg += " }\n" cfg += "}\n\n" @@ -65,11 +65,11 @@ class XorpRtrmgr(CoreService): return cfg @staticmethod - def lladdrstr(ifc): + def lladdrstr(iface): """ helper for adding link-local address entries (required by OSPFv3) """ - cfg = "\t address %s {\n" % ifc.hwaddr.tolinklocal() + cfg = "\t address %s {\n" % netaddr.EUI(iface.mac).eui64() cfg += "\t\tprefix-length: 64\n" cfg += "\t }\n" return cfg @@ -104,15 +104,15 @@ class XorpService(CoreService): return cfg @staticmethod - def mfea(forwarding, ifcs): + def mfea(forwarding, ifaces): """ Helper to add a multicast forwarding engine entry to the config file. """ names = [] - for ifc in ifcs: - if hasattr(ifc, "control") and ifc.control is True: + for iface in ifaces: + if hasattr(iface, "control") and iface.control is True: continue - names.append(ifc.name) + names.append(iface.name) names.append("register_vif") cfg = "plumbing {\n" @@ -148,10 +148,8 @@ class XorpService(CoreService): """ Helper to return the first IPv4 address of a node as its router ID. """ - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + for a in iface.addrlist: a = a.split("/")[0] if netaddr.valid_ipv4(a): return a @@ -184,12 +182,10 @@ class XorpOspfv2(XorpService): cfg += " ospf4 {\n" cfg += "\trouter-id: %s\n" % rtrid cfg += "\tarea 0.0.0.0 {\n" - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += "\t interface %s {\n" % ifc.name - cfg += "\t\tvif %s {\n" % ifc.name - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + cfg += "\t interface %s {\n" % iface.name + cfg += "\t\tvif %s {\n" % iface.name + for a in iface.addrlist: addr = a.split("/")[0] if not netaddr.valid_ipv4(addr): continue @@ -220,11 +216,9 @@ class XorpOspfv3(XorpService): cfg += " ospf6 0 { /* Instance ID 0 */\n" cfg += "\trouter-id: %s\n" % rtrid cfg += "\tarea 0.0.0.0 {\n" - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += "\t interface %s {\n" % ifc.name - cfg += "\t\tvif %s {\n" % ifc.name + for iface in node.get_ifaces(control=False): + cfg += "\t interface %s {\n" % iface.name + cfg += "\t\tvif %s {\n" % iface.name cfg += "\t\t}\n" cfg += "\t }\n" cfg += "\t}\n" @@ -277,12 +271,10 @@ class XorpRip(XorpService): cfg += "\nprotocols {\n" cfg += " rip {\n" cfg += '\texport: "export-connected"\n' - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += "\tinterface %s {\n" % ifc.name - cfg += "\t vif %s {\n" % ifc.name - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + cfg += "\tinterface %s {\n" % iface.name + cfg += "\t vif %s {\n" % iface.name + for a in iface.addrlist: addr = a.split("/")[0] if not netaddr.valid_ipv4(addr): continue @@ -310,12 +302,10 @@ class XorpRipng(XorpService): cfg += "\nprotocols {\n" cfg += " ripng {\n" cfg += '\texport: "export-connected"\n' - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += "\tinterface %s {\n" % ifc.name - cfg += "\t vif %s {\n" % ifc.name - cfg += "\t\taddress %s {\n" % ifc.hwaddr.tolinklocal() + for iface in node.get_ifaces(control=False): + cfg += "\tinterface %s {\n" % iface.name + cfg += "\t vif %s {\n" % iface.name + cfg += "\t\taddress %s {\n" % netaddr.EUI(iface.mac).eui64() cfg += "\t\t disable: false\n" cfg += "\t\t}\n" cfg += "\t }\n" @@ -334,17 +324,15 @@ class XorpPimSm4(XorpService): @classmethod def generatexorpconfig(cls, node): - cfg = cls.mfea("mfea4", node.netifs()) + cfg = cls.mfea("mfea4", node.get_ifaces()) cfg += "\nprotocols {\n" cfg += " igmp {\n" names = [] - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - names.append(ifc.name) - cfg += "\tinterface %s {\n" % ifc.name - cfg += "\t vif %s {\n" % ifc.name + for iface in node.get_ifaces(control=False): + names.append(iface.name) + cfg += "\tinterface %s {\n" % iface.name + cfg += "\t vif %s {\n" % iface.name cfg += "\t\tdisable: false\n" cfg += "\t }\n" cfg += "\t}\n" @@ -394,17 +382,15 @@ class XorpPimSm6(XorpService): @classmethod def generatexorpconfig(cls, node): - cfg = cls.mfea("mfea6", node.netifs()) + cfg = cls.mfea("mfea6", node.get_ifaces()) cfg += "\nprotocols {\n" cfg += " mld {\n" names = [] - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - names.append(ifc.name) - cfg += "\tinterface %s {\n" % ifc.name - cfg += "\t vif %s {\n" % ifc.name + for iface in node.get_ifaces(control=False): + names.append(iface.name) + cfg += "\tinterface %s {\n" % iface.name + cfg += "\t vif %s {\n" % iface.name cfg += "\t\tdisable: false\n" cfg += "\t }\n" cfg += "\t}\n" @@ -459,12 +445,10 @@ class XorpOlsr(XorpService): cfg += "\nprotocols {\n" cfg += " olsr4 {\n" cfg += "\tmain-address: %s\n" % rtrid - for ifc in node.netifs(): - if hasattr(ifc, "control") and ifc.control is True: - continue - cfg += "\tinterface %s {\n" % ifc.name - cfg += "\t vif %s {\n" % ifc.name - for a in ifc.addrlist: + for iface in node.get_ifaces(control=False): + cfg += "\tinterface %s {\n" % iface.name + cfg += "\t vif %s {\n" % iface.name + for a in iface.addrlist: addr = a.split("/")[0] if not netaddr.valid_ipv4(addr): continue diff --git a/daemon/core/xml/corexml.py b/daemon/core/xml/corexml.py index 759de680..190cf8f7 100644 --- a/daemon/core/xml/corexml.py +++ b/daemon/core/xml/corexml.py @@ -6,8 +6,7 @@ from lxml import etree import core.nodes.base import core.nodes.physical from core.emane.nodes import EmaneNet -from core.emulator.data import LinkData -from core.emulator.emudata import InterfaceData, LinkOptions, NodeOptions +from core.emulator.data import InterfaceData, LinkData, LinkOptions, NodeOptions from core.emulator.enumerations import EventTypes, NodeTypes from core.errors import CoreXmlError from core.nodes.base import CoreNodeBase, NodeBase @@ -58,16 +57,16 @@ def add_attribute(element: etree.Element, name: str, value: Any) -> None: element.set(name, str(value)) -def create_interface_data(interface_element: etree.Element) -> InterfaceData: - interface_id = int(interface_element.get("id")) - name = interface_element.get("name") - mac = interface_element.get("mac") - ip4 = interface_element.get("ip4") - ip4_mask = get_int(interface_element, "ip4_mask") - ip6 = interface_element.get("ip6") - ip6_mask = get_int(interface_element, "ip6_mask") +def create_iface_data(iface_element: etree.Element) -> InterfaceData: + iface_id = int(iface_element.get("id")) + name = iface_element.get("name") + mac = iface_element.get("mac") + ip4 = iface_element.get("ip4") + ip4_mask = get_int(iface_element, "ip4_mask") + ip6 = iface_element.get("ip6") + ip6_mask = get_int(iface_element, "ip6_mask") return InterfaceData( - id=interface_id, + id=iface_id, name=name, mac=mac, ip4=ip4, @@ -482,12 +481,10 @@ class CoreXmlWriter: # add link data for link_data in links: # skip basic range links - if link_data.interface1_id is None and link_data.interface2_id is None: + if link_data.iface1 is None and link_data.iface2 is None: continue - link_element = self.create_link_element(link_data) link_elements.append(link_element) - if link_elements.getchildren(): self.scenario.append(link_elements) @@ -495,37 +492,25 @@ class CoreXmlWriter: device = DeviceElement(self.session, node) self.devices.append(device.element) - def create_interface_element( - self, - element_name: str, - node_id: int, - interface_id: int, - mac: str, - ip4: str, - ip4_mask: int, - ip6: str, - ip6_mask: int, + def create_iface_element( + self, element_name: str, node_id: int, iface_data: InterfaceData ) -> etree.Element: - interface = etree.Element(element_name) + iface_element = etree.Element(element_name) node = self.session.get_node(node_id, NodeBase) - interface_name = None if isinstance(node, CoreNodeBase): - node_interface = node.netif(interface_id) - interface_name = node_interface.name - + iface = node.get_iface(iface_data.id) # check if emane interface - if isinstance(node_interface.net, EmaneNet): - nem = node_interface.net.getnemid(node_interface) - add_attribute(interface, "nem", nem) - - add_attribute(interface, "id", interface_id) - add_attribute(interface, "name", interface_name) - add_attribute(interface, "mac", mac) - add_attribute(interface, "ip4", ip4) - add_attribute(interface, "ip4_mask", ip4_mask) - add_attribute(interface, "ip6", ip6) - add_attribute(interface, "ip6_mask", ip6_mask) - return interface + if isinstance(iface.net, EmaneNet): + nem = iface.net.getnemid(iface) + add_attribute(iface_element, "nem", nem) + add_attribute(iface_element, "id", iface_data.id) + add_attribute(iface_element, "name", iface_data.name) + add_attribute(iface_element, "mac", iface_data.mac) + add_attribute(iface_element, "ip4", iface_data.ip4) + add_attribute(iface_element, "ip4_mask", iface_data.ip4_mask) + add_attribute(iface_element, "ip6", iface_data.ip6) + add_attribute(iface_element, "ip6_mask", iface_data.ip6_mask) + return iface_element def create_link_element(self, link_data: LinkData) -> etree.Element: link_element = etree.Element("link") @@ -533,32 +518,18 @@ class CoreXmlWriter: add_attribute(link_element, "node2", link_data.node2_id) # check for interface one - if link_data.interface1_id is not None: - interface1 = self.create_interface_element( - "interface1", - link_data.node1_id, - link_data.interface1_id, - link_data.interface1_mac, - link_data.interface1_ip4, - link_data.interface1_ip4_mask, - link_data.interface1_ip6, - link_data.interface1_ip6_mask, + if link_data.iface1 is not None: + iface1 = self.create_iface_element( + "interface1", link_data.node1_id, link_data.iface1 ) - link_element.append(interface1) + link_element.append(iface1) # check for interface two - if link_data.interface2_id is not None: - interface2 = self.create_interface_element( - "interface2", - link_data.node2_id, - link_data.interface2_id, - link_data.interface2_mac, - link_data.interface2_ip4, - link_data.interface2_ip4_mask, - link_data.interface2_ip6, - link_data.interface2_ip6_mask, + if link_data.iface2 is not None: + iface2 = self.create_iface_element( + "interface2", link_data.node2_id, link_data.iface2 ) - link_element.append(interface2) + link_element.append(iface2) # check for options, don't write for emane/wlan links node1 = self.session.get_node(link_data.node1_id, NodeBase) @@ -566,23 +537,19 @@ class CoreXmlWriter: is_node1_wireless = isinstance(node1, (WlanNode, EmaneNet)) is_node2_wireless = isinstance(node2, (WlanNode, EmaneNet)) if not any([is_node1_wireless, is_node2_wireless]): + options_data = link_data.options options = etree.Element("options") - add_attribute(options, "delay", link_data.delay) - add_attribute(options, "bandwidth", link_data.bandwidth) - add_attribute(options, "loss", link_data.loss) - add_attribute(options, "dup", link_data.dup) - add_attribute(options, "jitter", link_data.jitter) - add_attribute(options, "mer", link_data.mer) - add_attribute(options, "burst", link_data.burst) - add_attribute(options, "mburst", link_data.mburst) - add_attribute(options, "type", link_data.link_type) - add_attribute(options, "gui_attributes", link_data.gui_attributes) - add_attribute(options, "unidirectional", link_data.unidirectional) - add_attribute(options, "emulation_id", link_data.emulation_id) + add_attribute(options, "delay", options_data.delay) + add_attribute(options, "bandwidth", options_data.bandwidth) + add_attribute(options, "loss", options_data.loss) + add_attribute(options, "dup", options_data.dup) + add_attribute(options, "jitter", options_data.jitter) + add_attribute(options, "mer", options_data.mer) + add_attribute(options, "burst", options_data.burst) + add_attribute(options, "mburst", options_data.mburst) + add_attribute(options, "unidirectional", options_data.unidirectional) add_attribute(options, "network_id", link_data.network_id) - add_attribute(options, "key", link_data.key) - add_attribute(options, "opaque", link_data.opaque) - add_attribute(options, "session", link_data.session) + add_attribute(options, "key", options_data.key) if options.items(): link_element.append(options) @@ -940,19 +907,19 @@ class CoreXmlReader: node2_id = get_int(link_element, "node_two") node_set = frozenset((node1_id, node2_id)) - interface1_element = link_element.find("interface1") - if interface1_element is None: - interface1_element = link_element.find("interface_one") - interface1_data = None - if interface1_element is not None: - interface1_data = create_interface_data(interface1_element) + iface1_element = link_element.find("interface1") + if iface1_element is None: + iface1_element = link_element.find("interface_one") + iface1_data = None + if iface1_element is not None: + iface1_data = create_iface_data(iface1_element) - interface2_element = link_element.find("interface2") - if interface2_element is None: - interface2_element = link_element.find("interface_two") - interface2_data = None - if interface2_element is not None: - interface2_data = create_interface_data(interface2_element) + iface2_element = link_element.find("interface2") + if iface2_element is None: + iface2_element = link_element.find("interface_two") + iface2_data = None + if iface2_element is not None: + iface2_data = create_iface_data(iface2_element) options_element = link_element.find("options") options = LinkOptions() @@ -969,21 +936,16 @@ class CoreXmlReader: if options.loss is None: options.loss = get_float(options_element, "per") options.unidirectional = get_int(options_element, "unidirectional") - options.session = options_element.get("session") - options.emulation_id = get_int(options_element, "emulation_id") - options.network_id = get_int(options_element, "network_id") - options.opaque = options_element.get("opaque") - options.gui_attributes = options_element.get("gui_attributes") if options.unidirectional == 1 and node_set in node_sets: logging.info("updating link node1(%s) node2(%s)", node1_id, node2_id) self.session.update_link( - node1_id, node2_id, interface1_data.id, interface2_data.id, options + node1_id, node2_id, iface1_data.id, iface2_data.id, options ) else: logging.info("adding link node1(%s) node2(%s)", node1_id, node2_id) self.session.add_link( - node1_id, node2_id, interface1_data, interface2_data, options + node1_id, node2_id, iface1_data, iface2_data, options ) node_sets.add(node_set) diff --git a/daemon/core/xml/corexmldeployment.py b/daemon/core/xml/corexmldeployment.py index 04915bf1..7954b71a 100644 --- a/daemon/core/xml/corexmldeployment.py +++ b/daemon/core/xml/corexmldeployment.py @@ -24,25 +24,25 @@ def add_address( parent_element: etree.Element, address_type: str, address: str, - interface_name: str = None, + iface_name: str = None, ) -> None: address_element = etree.SubElement(parent_element, "address", type=address_type) address_element.text = address - if interface_name is not None: - address_element.set("iface", interface_name) + if iface_name is not None: + address_element.set("iface", iface_name) def add_mapping(parent_element: etree.Element, maptype: str, mapref: str) -> None: etree.SubElement(parent_element, "mapping", type=maptype, ref=mapref) -def add_emane_interface( +def add_emane_iface( host_element: etree.Element, - netif: CoreInterface, + iface: CoreInterface, platform_name: str = "p1", transport_name: str = "t1", ) -> etree.Element: - nem_id = netif.net.nemidmap[netif] + nem_id = iface.net.nemidmap[iface] host_id = host_element.get("id") # platform data @@ -89,10 +89,10 @@ def get_ipv4_addresses(hostname: str) -> List[Tuple[str, str]]: split = line.split() if not split: continue - interface_name = split[1] + iface_name = split[1] address = split[3] if not address.startswith("127."): - addresses.append((interface_name, address)) + addresses.append((iface_name, address)) return addresses else: # TODO: handle other hosts @@ -112,11 +112,11 @@ class CoreXmlDeployment: device = self.scenario.find(f"devices/device[@name='{name}']") return device - def find_interface(self, device: NodeBase, name: str) -> etree.Element: - interface = self.scenario.find( + def find_iface(self, device: NodeBase, name: str) -> etree.Element: + iface = self.scenario.find( f"devices/device[@name='{device.name}']/interfaces/interface[@name='{name}']" ) - return interface + return iface def add_deployment(self) -> None: physical_host = self.add_physical_host(socket.gethostname()) @@ -136,8 +136,8 @@ class CoreXmlDeployment: add_type(host_element, "physical") # add ipv4 addresses - for interface_name, address in get_ipv4_addresses("localhost"): - add_address(host_element, "IPv4", address, interface_name) + for iface_name, address in get_ipv4_addresses("localhost"): + add_address(host_element, "IPv4", address, iface_name) return host_element @@ -155,15 +155,15 @@ class CoreXmlDeployment: # add host type add_type(host_element, "virtual") - for netif in node.netifs(): + for iface in node.get_ifaces(): emane_element = None - if isinstance(netif.net, EmaneNet): - emane_element = add_emane_interface(host_element, netif) + if isinstance(iface.net, EmaneNet): + emane_element = add_emane_iface(host_element, iface) parent_element = host_element if emane_element is not None: parent_element = emane_element - for address in netif.addrlist: + for address in iface.addrlist: address_type = get_address_type(address) - add_address(parent_element, address_type, address, netif.name) + add_address(parent_element, address_type, address, iface.name) diff --git a/daemon/core/xml/emanexml.py b/daemon/core/xml/emanexml.py index 2589edd9..d716777b 100644 --- a/daemon/core/xml/emanexml.py +++ b/daemon/core/xml/emanexml.py @@ -18,7 +18,7 @@ if TYPE_CHECKING: from core.emane.emanemanager import EmaneManager from core.emane.emanemodel import EmaneModel -_hwaddr_prefix = "02:02" +_MAC_PREFIX = "02:02" def is_external(config: Dict[str, str]) -> bool: @@ -158,19 +158,19 @@ def build_node_platform_xml( logging.warning("warning: EMANE network %s has no associated model", node.name) return nem_id - for netif in node.netifs(): + for iface in node.get_ifaces(): logging.debug( - "building platform xml for interface(%s) nem_id(%s)", netif.name, nem_id + "building platform xml for interface(%s) nem_id(%s)", iface.name, nem_id ) # build nem xml - nem_definition = nem_file_name(node.model, netif) + nem_definition = nem_file_name(node.model, iface) nem_element = etree.Element( - "nem", id=str(nem_id), name=netif.localname, definition=nem_definition + "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.getifcconfig(node.model.id, netif, node.model.name) + config = emane_manager.get_iface_config(node.model.id, iface, node.model.name) if is_external(config): nem_element.set("transport", "external") @@ -180,9 +180,9 @@ def build_node_platform_xml( add_param(nem_element, transport_endpoint, config[transport_endpoint]) else: # build transport xml - transport_type = netif.transport_type + transport_type = iface.transport_type if not transport_type: - logging.info("warning: %s interface type unsupported!", netif.name) + 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( @@ -190,14 +190,14 @@ def build_node_platform_xml( ) # add transport parameter - add_param(transport_element, "device", netif.name) + add_param(transport_element, "device", iface.name) # add nem entry - nem_entries[netif] = nem_element + nem_entries[iface] = nem_element # merging code - key = netif.node.id - if netif.transport_type == TransportType.RAW: + key = iface.node.id + if iface.transport_type == TransportType.RAW: key = "host" otadev = control_net.brname eventdev = control_net.brname @@ -229,10 +229,10 @@ def build_node_platform_xml( platform_element.append(nem_element) - node.setnemid(netif, nem_id) - macstr = _hwaddr_prefix + ":00:00:" + node.setnemid(iface, nem_id) + macstr = _MAC_PREFIX + ":00:00:" macstr += f"{(nem_id >> 8) & 0xFF:02X}:{nem_id & 0xFF:02X}" - netif.sethwaddr(macstr) + iface.set_mac(macstr) # increment nem id nem_id += 1 @@ -280,19 +280,19 @@ def build_xml_files(emane_manager: "EmaneManager", node: EmaneNet) -> None: vtype = TransportType.VIRTUAL rtype = TransportType.RAW - for netif in node.netifs(): + for iface in node.get_ifaces(): # check for interface specific emane configuration and write xml files - config = emane_manager.getifcconfig(node.model.id, netif, node.model.name) + config = emane_manager.get_iface_config(node.model.id, iface, node.model.name) if config: - node.model.build_xml_files(config, netif) + node.model.build_xml_files(config, iface) # check transport type needed for interface - if netif.transport_type == TransportType.VIRTUAL: + if iface.transport_type == TransportType.VIRTUAL: need_virtual = True - vtype = netif.transport_type + vtype = iface.transport_type else: need_raw = True - rtype = netif.transport_type + rtype = iface.transport_type if need_virtual: build_transport_xml(emane_manager, node, vtype) @@ -494,70 +494,70 @@ def transport_file_name(node_id: int, transport_type: TransportType) -> str: return f"n{node_id}trans{transport_type.value}.xml" -def _basename(emane_model: "EmaneModel", interface: CoreInterface = None) -> str: +def _basename(emane_model: "EmaneModel", iface: CoreInterface = None) -> str: """ Create name that is leveraged for configuration file creation. :param emane_model: emane model to create name for - :param interface: interface for this model + :param iface: interface for this model :return: basename used for file creation """ name = f"n{emane_model.id}" - if interface: - node_id = interface.node.id - if emane_model.session.emane.getifcconfig(node_id, interface, emane_model.name): - name = interface.localname.replace(".", "_") + 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", interface: CoreInterface = None) -> str: +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 interface: interface for this model + :param iface: interface for this model :return: nem xml filename """ - basename = _basename(emane_model, interface) + basename = _basename(emane_model, iface) append = "" - if interface and interface.transport_type == TransportType.RAW: + if iface and iface.transport_type == TransportType.RAW: append = "_raw" return f"{basename}nem{append}.xml" -def shim_file_name(emane_model: "EmaneModel", interface: CoreInterface = None) -> str: +def shim_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str: """ Return the string name for the SHIM XML file, e.g. "commeffectshim.xml" :param emane_model: emane model to create file - :param interface: interface for this model + :param iface: interface for this model :return: shim xml filename """ - name = _basename(emane_model, interface) + name = _basename(emane_model, iface) return f"{name}shim.xml" -def mac_file_name(emane_model: "EmaneModel", interface: CoreInterface = None) -> str: +def mac_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str: """ Return the string name for the MAC XML file, e.g. "n3rfpipemac.xml" :param emane_model: emane model to create file - :param interface: interface for this model + :param iface: interface for this model :return: mac xml filename """ - name = _basename(emane_model, interface) + name = _basename(emane_model, iface) return f"{name}mac.xml" -def phy_file_name(emane_model: "EmaneModel", interface: CoreInterface = None) -> str: +def phy_file_name(emane_model: "EmaneModel", iface: CoreInterface = None) -> str: """ Return the string name for the PHY XML file, e.g. "n3rfpipephy.xml" :param emane_model: emane model to create file - :param interface: interface for this model + :param iface: interface for this model :return: phy xml filename """ - name = _basename(emane_model, interface) + name = _basename(emane_model, iface) return f"{name}phy.xml" diff --git a/daemon/examples/configservices/testing.py b/daemon/examples/configservices/testing.py index 948ec739..9706f2c9 100644 --- a/daemon/examples/configservices/testing.py +++ b/daemon/examples/configservices/testing.py @@ -1,7 +1,7 @@ import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode from core.nodes.network import SwitchNode @@ -20,13 +20,13 @@ if __name__ == "__main__": # node one options.config_services = ["DefaultRoute", "IPForward"] node1 = session.add_node(CoreNode, options=options) - interface = prefixes.create_interface(node1) - session.add_link(node1.id, switch.id, interface1_data=interface) + interface = prefixes.create_iface(node1) + session.add_link(node1.id, switch.id, iface1_data=interface) # node two node2 = session.add_node(CoreNode, options=options) - interface = prefixes.create_interface(node2) - session.add_link(node2.id, switch.id, interface1_data=interface) + interface = prefixes.create_iface(node2) + session.add_link(node2.id, switch.id, iface1_data=interface) # start session and run services session.instantiate() diff --git a/daemon/examples/docker/docker2core.py b/daemon/examples/docker/docker2core.py index 8151a590..ae7dae79 100644 --- a/daemon/examples/docker/docker2core.py +++ b/daemon/examples/docker/docker2core.py @@ -1,7 +1,7 @@ import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode from core.nodes.docker import DockerNode @@ -18,11 +18,11 @@ if __name__ == "__main__": # create node one node1 = session.add_node(DockerNode, options=options) - interface1_data = prefixes.create_interface(node1) + interface1_data = prefixes.create_iface(node1) # create node two node2 = session.add_node(CoreNode) - interface2_data = prefixes.create_interface(node2) + interface2_data = prefixes.create_iface(node2) # add link session.add_link(node1.id, node2.id, interface1_data, interface2_data) diff --git a/daemon/examples/docker/docker2docker.py b/daemon/examples/docker/docker2docker.py index a7a70534..308fd00f 100644 --- a/daemon/examples/docker/docker2docker.py +++ b/daemon/examples/docker/docker2docker.py @@ -1,7 +1,7 @@ import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.docker import DockerNode @@ -19,11 +19,11 @@ if __name__ == "__main__": # create node one node1 = session.add_node(DockerNode, options=options) - interface1_data = prefixes.create_interface(node1) + interface1_data = prefixes.create_iface(node1) # create node two node2 = session.add_node(DockerNode, options=options) - interface2_data = prefixes.create_interface(node2) + interface2_data = prefixes.create_iface(node2) # add link session.add_link(node1.id, node2.id, interface1_data, interface2_data) diff --git a/daemon/examples/docker/switch.py b/daemon/examples/docker/switch.py index ef057945..fa9e4e40 100644 --- a/daemon/examples/docker/switch.py +++ b/daemon/examples/docker/switch.py @@ -1,7 +1,7 @@ import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode from core.nodes.docker import DockerNode @@ -23,15 +23,15 @@ if __name__ == "__main__": # node one node1 = session.add_node(DockerNode, options=options) - interface1_data = prefixes.create_interface(node1) + interface1_data = prefixes.create_iface(node1) # node two node2 = session.add_node(DockerNode, options=options) - interface2_data = prefixes.create_interface(node2) + interface2_data = prefixes.create_iface(node2) # node three node_three = session.add_node(CoreNode) - interface_three = prefixes.create_interface(node_three) + interface_three = prefixes.create_iface(node_three) # add links session.add_link(node1.id, switch.id, interface1_data) diff --git a/daemon/examples/grpc/distributed_switch.py b/daemon/examples/grpc/distributed_switch.py index e847016f..0d781c19 100644 --- a/daemon/examples/grpc/distributed_switch.py +++ b/daemon/examples/grpc/distributed_switch.py @@ -47,7 +47,7 @@ def main(args): node1_id = response.node_id # create link - interface1 = interface_helper.create_interface(node1_id, 0) + interface1 = interface_helper.create_iface(node1_id, 0) response = core.add_link(session_id, node1_id, switch_id, interface1) logging.info("created link from node one to switch: %s", response) @@ -59,7 +59,7 @@ def main(args): node2_id = response.node_id # create link - interface1 = interface_helper.create_interface(node2_id, 0) + interface1 = interface_helper.create_iface(node2_id, 0) response = core.add_link(session_id, node2_id, switch_id, interface1) logging.info("created link from node two to switch: %s", response) diff --git a/daemon/examples/grpc/emane80211.py b/daemon/examples/grpc/emane80211.py index 24532266..b8036db0 100644 --- a/daemon/examples/grpc/emane80211.py +++ b/daemon/examples/grpc/emane80211.py @@ -57,10 +57,10 @@ def main(): node2_id = response.node_id # links nodes to switch - interface1 = interface_helper.create_interface(node1_id, 0) + interface1 = interface_helper.create_iface(node1_id, 0) response = core.add_link(session_id, node1_id, emane_id, interface1) logging.info("created link: %s", response) - interface1 = interface_helper.create_interface(node2_id, 0) + interface1 = interface_helper.create_iface(node2_id, 0) response = core.add_link(session_id, node2_id, emane_id, interface1) logging.info("created link: %s", response) diff --git a/daemon/examples/grpc/switch.py b/daemon/examples/grpc/switch.py index 74e315c6..1ed7c684 100644 --- a/daemon/examples/grpc/switch.py +++ b/daemon/examples/grpc/switch.py @@ -53,10 +53,10 @@ def main(): node2_id = response.node_id # links nodes to switch - interface1 = interface_helper.create_interface(node1_id, 0) + interface1 = interface_helper.create_iface(node1_id, 0) response = core.add_link(session_id, node1_id, switch_id, interface1) logging.info("created link: %s", response) - interface1 = interface_helper.create_interface(node2_id, 0) + interface1 = interface_helper.create_iface(node2_id, 0) response = core.add_link(session_id, node2_id, switch_id, interface1) logging.info("created link: %s", response) diff --git a/daemon/examples/grpc/wlan.py b/daemon/examples/grpc/wlan.py index d60ca1be..715d4706 100644 --- a/daemon/examples/grpc/wlan.py +++ b/daemon/examples/grpc/wlan.py @@ -65,10 +65,10 @@ def main(): node2_id = response.node_id # links nodes to switch - interface1 = interface_helper.create_interface(node1_id, 0) + interface1 = interface_helper.create_iface(node1_id, 0) response = core.add_link(session_id, node1_id, wlan_id, interface1) logging.info("created link: %s", response) - interface1 = interface_helper.create_interface(node2_id, 0) + interface1 = interface_helper.create_iface(node2_id, 0) response = core.add_link(session_id, node2_id, wlan_id, interface1) logging.info("created link: %s", response) diff --git a/daemon/examples/lxd/lxd2core.py b/daemon/examples/lxd/lxd2core.py index 49b68943..b41520d8 100644 --- a/daemon/examples/lxd/lxd2core.py +++ b/daemon/examples/lxd/lxd2core.py @@ -1,7 +1,7 @@ import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode from core.nodes.lxd import LxcNode @@ -18,11 +18,11 @@ if __name__ == "__main__": # create node one node1 = session.add_node(LxcNode, options=options) - interface1_data = prefixes.create_interface(node1) + interface1_data = prefixes.create_iface(node1) # create node two node2 = session.add_node(CoreNode) - interface2_data = prefixes.create_interface(node2) + interface2_data = prefixes.create_iface(node2) # add link session.add_link(node1.id, node2.id, interface1_data, interface2_data) diff --git a/daemon/examples/lxd/lxd2lxd.py b/daemon/examples/lxd/lxd2lxd.py index 18af8037..3a55e2e1 100644 --- a/daemon/examples/lxd/lxd2lxd.py +++ b/daemon/examples/lxd/lxd2lxd.py @@ -1,7 +1,7 @@ import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.lxd import LxcNode @@ -19,11 +19,11 @@ if __name__ == "__main__": # create node one node1 = session.add_node(LxcNode, options=options) - interface1_data = prefixes.create_interface(node1) + interface1_data = prefixes.create_iface(node1) # create node two node2 = session.add_node(LxcNode, options=options) - interface2_data = prefixes.create_interface(node2) + interface2_data = prefixes.create_iface(node2) # add link session.add_link(node1.id, node2.id, interface1_data, interface2_data) diff --git a/daemon/examples/lxd/switch.py b/daemon/examples/lxd/switch.py index 31a79887..12767e71 100644 --- a/daemon/examples/lxd/switch.py +++ b/daemon/examples/lxd/switch.py @@ -1,7 +1,7 @@ import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode from core.nodes.lxd import LxcNode @@ -23,15 +23,15 @@ if __name__ == "__main__": # node one node1 = session.add_node(LxcNode, options=options) - interface1_data = prefixes.create_interface(node1) + interface1_data = prefixes.create_iface(node1) # node two node2 = session.add_node(LxcNode, options=options) - interface2_data = prefixes.create_interface(node2) + interface2_data = prefixes.create_iface(node2) # node three node3 = session.add_node(CoreNode) - interface3_data = prefixes.create_interface(node3) + interface3_data = prefixes.create_iface(node3) # add links session.add_link(node1.id, switch.id, interface1_data) diff --git a/daemon/examples/myservices/sample.py b/daemon/examples/myservices/sample.py index 8c6dbe06..e0c9a232 100644 --- a/daemon/examples/myservices/sample.py +++ b/daemon/examples/myservices/sample.py @@ -80,8 +80,8 @@ class MyService(CoreService): if filename == cls.configs[0]: cfg += "# auto-generated by MyService (sample.py)\n" - for ifc in node.netifs(): - cfg += f'echo "Node {node.name} has interface {ifc.name}"\n' + for iface in node.get_ifaces(): + cfg += f'echo "Node {node.name} has interface {iface.name}"\n' elif filename == cls.configs[1]: cfg += "echo hello" diff --git a/daemon/examples/python/distributed_emane.py b/daemon/examples/python/distributed_emane.py index d9b41ea4..4421283f 100644 --- a/daemon/examples/python/distributed_emane.py +++ b/daemon/examples/python/distributed_emane.py @@ -9,7 +9,7 @@ import logging from core.emane.ieee80211abg import EmaneIeee80211abgModel from core.emane.nodes import EmaneNet from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode @@ -59,10 +59,10 @@ def main(args): node2 = session.add_node(CoreNode, options=options) # create node interfaces and link - interface1_data = prefixes.create_interface(node1) - interface2_data = prefixes.create_interface(node2) - session.add_link(node1.id, emane_net.id, interface1_data=interface1_data) - session.add_link(node2.id, emane_net.id, interface1_data=interface2_data) + interface1_data = prefixes.create_iface(node1) + interface2_data = prefixes.create_iface(node2) + session.add_link(node1.id, emane_net.id, iface1_data=interface1_data) + session.add_link(node2.id, emane_net.id, iface1_data=interface2_data) # instantiate session session.instantiate() diff --git a/daemon/examples/python/distributed_lxd.py b/daemon/examples/python/distributed_lxd.py index affb16a8..26f7caa6 100644 --- a/daemon/examples/python/distributed_lxd.py +++ b/daemon/examples/python/distributed_lxd.py @@ -7,7 +7,7 @@ import argparse import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.lxd import LxcNode @@ -48,8 +48,8 @@ def main(args): node2 = session.add_node(LxcNode, options=options) # create node interfaces and link - interface1_data = prefixes.create_interface(node1) - interface2_data = prefixes.create_interface(node2) + interface1_data = prefixes.create_iface(node1) + interface2_data = prefixes.create_iface(node2) session.add_link(node1.id, node2.id, interface1_data, interface2_data) # instantiate session diff --git a/daemon/examples/python/distributed_ptp.py b/daemon/examples/python/distributed_ptp.py index 6bf33474..fe714e1d 100644 --- a/daemon/examples/python/distributed_ptp.py +++ b/daemon/examples/python/distributed_ptp.py @@ -7,7 +7,7 @@ import argparse import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode @@ -48,8 +48,8 @@ def main(args): node2 = session.add_node(CoreNode, options=options) # create node interfaces and link - interface1_data = prefixes.create_interface(node1) - interface2_data = prefixes.create_interface(node2) + interface1_data = prefixes.create_iface(node1) + interface2_data = prefixes.create_iface(node2) session.add_link(node1.id, node2.id, interface1_data, interface2_data) # instantiate session diff --git a/daemon/examples/python/distributed_switch.py b/daemon/examples/python/distributed_switch.py index 8991161e..35de1cad 100644 --- a/daemon/examples/python/distributed_switch.py +++ b/daemon/examples/python/distributed_switch.py @@ -7,7 +7,7 @@ import argparse import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode from core.nodes.network import SwitchNode @@ -52,10 +52,10 @@ def main(args): node2 = session.add_node(CoreNode, options=options) # create node interfaces and link - interface1_data = prefixes.create_interface(node1) - interface2_data = prefixes.create_interface(node2) - session.add_link(node1.id, switch.id, interface1_data=interface1_data) - session.add_link(node2.id, switch.id, interface1_data=interface2_data) + interface1_data = prefixes.create_iface(node1) + interface2_data = prefixes.create_iface(node2) + session.add_link(node1.id, switch.id, iface1_data=interface1_data) + session.add_link(node2.id, switch.id, iface1_data=interface2_data) # instantiate session session.instantiate() diff --git a/daemon/examples/python/emane80211.py b/daemon/examples/python/emane80211.py index d3f6652a..9d6def4a 100644 --- a/daemon/examples/python/emane80211.py +++ b/daemon/examples/python/emane80211.py @@ -10,7 +10,7 @@ import time from core.emane.ieee80211abg import EmaneIeee80211abgModel from core.emane.nodes import EmaneNet from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode @@ -42,8 +42,8 @@ def main(): for i in range(NODES): node = session.add_node(CoreNode, options=options) node.setposition(x=150 * (i + 1), y=150) - interface = prefixes.create_interface(node) - session.add_link(node.id, emane_network.id, interface1_data=interface) + interface = prefixes.create_iface(node) + session.add_link(node.id, emane_network.id, iface1_data=interface) # instantiate session session.instantiate() diff --git a/daemon/examples/python/switch.py b/daemon/examples/python/switch.py index 1b939cd7..f05176a3 100644 --- a/daemon/examples/python/switch.py +++ b/daemon/examples/python/switch.py @@ -6,7 +6,7 @@ interact with the GUI. import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes +from core.emulator.data import IpPrefixes from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode from core.nodes.network import SwitchNode @@ -31,8 +31,8 @@ def main(): # create nodes for _ in range(NODES): node = session.add_node(CoreNode) - interface = prefixes.create_interface(node) - session.add_link(node.id, switch.id, interface1_data=interface) + interface = prefixes.create_iface(node) + session.add_link(node.id, switch.id, iface1_data=interface) # instantiate session session.instantiate() diff --git a/daemon/examples/python/switch_inject.py b/daemon/examples/python/switch_inject.py index 59816b19..18a75a49 100644 --- a/daemon/examples/python/switch_inject.py +++ b/daemon/examples/python/switch_inject.py @@ -8,7 +8,7 @@ same CoreEmu instance the GUI is using. import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes +from core.emulator.data import IpPrefixes from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode from core.nodes.network import SwitchNode @@ -33,8 +33,8 @@ def main(): # create nodes for _ in range(NODES): node = session.add_node(CoreNode) - interface = prefixes.create_interface(node) - session.add_link(node.id, switch.id, interface1_data=interface) + interface = prefixes.create_iface(node) + session.add_link(node.id, switch.id, iface1_data=interface) # instantiate session session.instantiate() diff --git a/daemon/examples/python/wlan.py b/daemon/examples/python/wlan.py index 0302bbd3..de26ab97 100644 --- a/daemon/examples/python/wlan.py +++ b/daemon/examples/python/wlan.py @@ -6,7 +6,7 @@ interact with the GUI. import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import EventTypes from core.location.mobility import BasicRangeModel from core.nodes.base import CoreNode @@ -35,8 +35,8 @@ def main(): options.set_position(0, 0) for _ in range(NODES): node = session.add_node(CoreNode, options=options) - interface = prefixes.create_interface(node) - session.add_link(node.id, wlan.id, interface1_data=interface) + interface = prefixes.create_iface(node) + session.add_link(node.id, wlan.id, iface1_data=interface) # instantiate session session.instantiate() diff --git a/daemon/proto/core/api/grpc/core.proto b/daemon/proto/core/api/grpc/core.proto index 828b41fb..46e1da91 100644 --- a/daemon/proto/core/api/grpc/core.proto +++ b/daemon/proto/core/api/grpc/core.proto @@ -319,12 +319,12 @@ message ThroughputsRequest { message ThroughputsEvent { int32 session_id = 1; repeated BridgeThroughput bridge_throughputs = 2; - repeated InterfaceThroughput interface_throughputs = 3; + repeated InterfaceThroughput iface_throughputs = 3; } message InterfaceThroughput { int32 node_id = 1; - int32 interface_id = 2; + int32 iface_id = 2; double throughput = 3; } @@ -374,7 +374,7 @@ message ConfigEvent { string bitmap = 8; string possible_values = 9; string groups = 10; - int32 interface = 11; + int32 iface_id = 11; int32 network_id = 12; string opaque = 13; } @@ -416,7 +416,7 @@ message GetNodeRequest { message GetNodeResponse { Node node = 1; - repeated Interface interfaces = 2; + repeated Interface ifaces = 2; } message EditNodeRequest { @@ -492,16 +492,16 @@ message AddLinkRequest { message AddLinkResponse { bool result = 1; - Interface interface1 = 2; - Interface interface2 = 3; + Interface iface1 = 2; + Interface iface2 = 3; } message EditLinkRequest { int32 session_id = 1; int32 node1_id = 2; int32 node2_id = 3; - int32 interface1_id = 4; - int32 interface2_id = 5; + int32 iface1_id = 4; + int32 iface2_id = 5; LinkOptions options = 6; } @@ -513,8 +513,8 @@ message DeleteLinkRequest { int32 session_id = 1; int32 node1_id = 2; int32 node2_id = 3; - int32 interface1_id = 4; - int32 interface2_id = 5; + int32 iface1_id = 4; + int32 iface2_id = 5; } message DeleteLinkResponse { @@ -561,7 +561,7 @@ message GetInterfacesRequest { } message GetInterfacesResponse { - repeated string interfaces = 1; + repeated string ifaces = 1; } message ExecuteScriptRequest { @@ -692,21 +692,20 @@ message Node { repeated string services = 6; string emane = 7; string icon = 8; - string opaque = 9; - string image = 10; - string server = 11; - repeated string config_services = 12; - Geo geo = 13; - string dir = 14; - string channel = 15; + string image = 9; + string server = 10; + repeated string config_services = 11; + Geo geo = 12; + string dir = 13; + string channel = 14; } message Link { int32 node1_id = 1; int32 node2_id = 2; LinkType.Enum type = 3; - Interface interface1 = 4; - Interface interface2 = 5; + Interface iface1 = 4; + Interface iface2 = 5; LinkOptions options = 6; int32 network_id = 7; string label = 8; @@ -732,11 +731,11 @@ message Interface { string name = 2; string mac = 3; string ip4 = 4; - int32 ip4mask = 5; + int32 ip4_mask = 5; string ip6 = 6; - int32 ip6mask = 7; - int32 netid = 8; - int32 flowid = 9; + int32 ip6_mask = 7; + int32 net_id = 8; + int32 flow_id = 9; int32 mtu = 10; } diff --git a/daemon/proto/core/api/grpc/emane.proto b/daemon/proto/core/api/grpc/emane.proto index e4189700..ac5456fd 100644 --- a/daemon/proto/core/api/grpc/emane.proto +++ b/daemon/proto/core/api/grpc/emane.proto @@ -32,7 +32,7 @@ message GetEmaneModelsResponse { message GetEmaneModelConfigRequest { int32 session_id = 1; int32 node_id = 2; - int32 interface = 3; + int32 iface_id = 3; string model = 4; } @@ -57,7 +57,7 @@ message GetEmaneModelConfigsResponse { message ModelConfig { int32 node_id = 1; string model = 2; - int32 interface = 3; + int32 iface_id = 3; map<string, common.ConfigOption> config = 4; } repeated ModelConfig configs = 1; @@ -86,7 +86,7 @@ message EmaneLinkResponse { message EmaneModelConfig { int32 node_id = 1; - int32 interface_id = 2; + int32 iface_id = 2; string model = 3; map<string, string> config = 4; } @@ -95,10 +95,10 @@ message EmanePathlossesRequest { int32 session_id = 1; int32 node1_id = 2; float rx1 = 3; - int32 interface1_id = 4; + int32 iface1_id = 4; int32 node2_id = 5; float rx2 = 6; - int32 interface2_id = 7; + int32 iface2_id = 7; } message EmanePathlossesResponse { diff --git a/daemon/scripts/core-route-monitor b/daemon/scripts/core-route-monitor index b12e6205..d644ae1b 100755 --- a/daemon/scripts/core-route-monitor +++ b/daemon/scripts/core-route-monitor @@ -101,8 +101,8 @@ class RouterMonitor: node_map[node.id] = node.channel if self.src_id is None: response = self.core.get_node(self.session, node.id) - for netif in response.interfaces: - if self.src == netif.ip4: + for iface in response.ifaces: + if self.src == iface.ip4: self.src_id = node.id break except grpc.RpcError: diff --git a/daemon/tests/conftest.py b/daemon/tests/conftest.py index 9d54d9c2..be62fc03 100644 --- a/daemon/tests/conftest.py +++ b/daemon/tests/conftest.py @@ -14,8 +14,8 @@ from core.api.grpc.server import CoreGrpcServer from core.api.tlv.corehandlers import CoreHandler from core.emane.emanemanager import EmaneManager from core.emulator.coreemu import CoreEmu +from core.emulator.data import IpPrefixes from core.emulator.distributed import DistributedServer -from core.emulator.emudata import IpPrefixes from core.emulator.enumerations import EventTypes from core.emulator.session import Session from core.nodes.base import CoreNode @@ -89,7 +89,7 @@ def ip_prefixes(): @pytest.fixture(scope="session") -def interface_helper(): +def iface_helper(): return InterfaceHelper(ip4_prefix="10.83.0.0/16") diff --git a/daemon/tests/emane/test_emane.py b/daemon/tests/emane/test_emane.py index 15e3d869..f51e30b9 100644 --- a/daemon/tests/emane/test_emane.py +++ b/daemon/tests/emane/test_emane.py @@ -15,7 +15,7 @@ from core.emane.ieee80211abg import EmaneIeee80211abgModel from core.emane.nodes import EmaneNet from core.emane.rfpipe import EmaneRfPipeModel from core.emane.tdma import EmaneTdmaModel -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.session import Session from core.errors import CoreCommandError, CoreError from core.nodes.base import CoreNode @@ -79,8 +79,8 @@ class TestEmane: for i, node in enumerate([node1, node2]): node.setposition(x=150 * (i + 1), y=150) - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, emane_network.id, interface1_data=interface) + iface_data = ip_prefixes.create_iface(node) + session.add_link(node.id, emane_network.id, iface1_data=iface_data) # instantiate session session.instantiate() @@ -119,8 +119,8 @@ class TestEmane: for i, node in enumerate([node1, node2]): node.setposition(x=150 * (i + 1), y=150) - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, emane_network.id, interface1_data=interface) + iface_data = ip_prefixes.create_iface(node) + session.add_link(node.id, emane_network.id, iface1_data=iface_data) # instantiate session session.instantiate() diff --git a/daemon/tests/test_core.py b/daemon/tests/test_core.py index 626f84a7..2623b0df 100644 --- a/daemon/tests/test_core.py +++ b/daemon/tests/test_core.py @@ -8,7 +8,7 @@ from typing import Type import pytest -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import IpPrefixes, NodeOptions from core.emulator.enumerations import MessageFlags from core.emulator.session import Session from core.errors import CoreCommandError @@ -53,8 +53,8 @@ class TestCore: # link nodes to net node for node in [node1, node2]: - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, net_node.id, interface1_data=interface) + iface_data = ip_prefixes.create_iface(node) + session.add_link(node.id, net_node.id, iface1_data=iface_data) # instantiate session session.instantiate() @@ -80,8 +80,8 @@ class TestCore: # link nodes to ptp net for node in [node1, node2]: - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, ptp_node.id, interface1_data=interface) + iface_data = ip_prefixes.create_iface(node) + session.add_link(node.id, ptp_node.id, iface1_data=iface_data) # get node client for testing client = node1.client @@ -96,9 +96,9 @@ class TestCore: if not request.config.getoption("mock"): assert client.check_cmd("echo hello") == "hello" - def test_netif(self, session: Session, ip_prefixes: IpPrefixes): + def test_iface(self, session: Session, ip_prefixes: IpPrefixes): """ - Test netif methods. + Test interface methods. :param session: session for test :param ip_prefixes: generates ip addresses for nodes @@ -113,8 +113,8 @@ class TestCore: # link nodes to ptp net for node in [node1, node2]: - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, ptp_node.id, interface1_data=interface) + iface = ip_prefixes.create_iface(node) + session.add_link(node.id, ptp_node.id, iface1_data=iface) # instantiate session session.instantiate() @@ -126,19 +126,19 @@ class TestCore: assert node1.commonnets(node2) assert node2.commonnets(node1) - # check we can retrieve netif index - assert node1.ifname(0) - assert node2.ifname(0) + # check we can retrieve interface id + assert 0 in node1.ifaces + assert 0 in node2.ifaces # check interface parameters - interface = node1.netif(0) - interface.setparam("test", 1) - assert interface.getparam("test") == 1 - assert interface.getparams() + iface = node1.get_iface(0) + iface.setparam("test", 1) + assert iface.getparam("test") == 1 + assert iface.getparams() - # delete netif and test that if no longer exists - node1.delnetif(0) - assert not node1.netif(0) + # delete interface and test that if no longer exists + node1.delete_iface(0) + assert 0 not in node1.ifaces def test_wlan_ping(self, session: Session, ip_prefixes: IpPrefixes): """ @@ -160,8 +160,8 @@ class TestCore: # link nodes for node in [node1, node2]: - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, wlan_node.id, interface1_data=interface) + iface_id = ip_prefixes.create_iface(node) + session.add_link(node.id, wlan_node.id, iface1_data=iface_id) # instantiate session session.instantiate() @@ -190,8 +190,8 @@ class TestCore: # link nodes for node in [node1, node2]: - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, wlan_node.id, interface1_data=interface) + iface_id = ip_prefixes.create_iface(node) + session.add_link(node.id, wlan_node.id, iface1_data=iface_id) # configure mobility script for session config = { diff --git a/daemon/tests/test_distributed.py b/daemon/tests/test_distributed.py index 0f4b1731..01362cae 100644 --- a/daemon/tests/test_distributed.py +++ b/daemon/tests/test_distributed.py @@ -1,4 +1,4 @@ -from core.emulator.emudata import NodeOptions +from core.emulator.data import NodeOptions from core.emulator.session import Session from core.nodes.base import CoreNode from core.nodes.network import HubNode diff --git a/daemon/tests/test_grpc.py b/daemon/tests/test_grpc.py index 8beb4b9a..8abf33aa 100644 --- a/daemon/tests/test_grpc.py +++ b/daemon/tests/test_grpc.py @@ -18,8 +18,7 @@ from core.api.tlv.dataconversion import ConfigShim from core.api.tlv.enumerations import ConfigFlags from core.emane.ieee80211abg import EmaneIeee80211abgModel from core.emane.nodes import EmaneNet -from core.emulator.data import EventData, NodeData -from core.emulator.emudata import IpPrefixes, NodeOptions +from core.emulator.data import EventData, IpPrefixes, NodeData, NodeOptions from core.emulator.enumerations import EventTypes, ExceptionLevels, NodeTypes from core.errors import CoreError from core.location.mobility import BasicRangeModel, Ns2ScriptedMobility @@ -42,15 +41,17 @@ class TestGrpc: id=3, type=NodeTypes.WIRELESS_LAN.value, position=position ) nodes = [node1, node2, wlan_node] - interface_helper = InterfaceHelper(ip4_prefix="10.83.0.0/16") - interface1 = interface_helper.create_interface(node1.id, 0) - interface2 = interface_helper.create_interface(node2.id, 0) + iface_helper = InterfaceHelper(ip4_prefix="10.83.0.0/16") + iface1_id = 0 + iface1 = iface_helper.create_iface(node1.id, iface1_id) + iface2_id = 0 + iface2 = iface_helper.create_iface(node2.id, iface2_id) link = core_pb2.Link( type=core_pb2.LinkType.WIRED, node1_id=node1.id, node2_id=node2.id, - interface1=interface1, - interface2=interface2, + iface1=iface1, + iface2=iface2, ) links = [link] hook = core_pb2.Hook( @@ -81,7 +82,7 @@ class TestGrpc: model_config_value = "500000" model_config = EmaneModelConfig( node_id=model_node_id, - interface_id=-1, + iface_id=-1, model=EmaneIeee80211abgModel.name, config={model_config_key: model_config_value}, ) @@ -131,8 +132,8 @@ class TestGrpc: assert node1.id in session.nodes assert node2.id in session.nodes assert wlan_node.id in session.nodes - assert session.nodes[node1.id].netif(0) is not None - assert session.nodes[node2.id].netif(0) is not None + assert iface1_id in session.nodes[node1.id].ifaces + assert iface2_id in session.nodes[node2.id].ifaces hook_file, hook_data = session.hooks[EventTypes.RUNTIME_STATE][0] assert hook_file == hook.file assert hook_data == hook.data @@ -522,8 +523,8 @@ class TestGrpc: session = grpc_server.coreemu.create_session() switch = session.add_node(SwitchNode) node = session.add_node(CoreNode) - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, switch.id, interface) + iface_data = ip_prefixes.create_iface(node) + session.add_link(node.id, switch.id, iface_data) # then with client.context_connect(): @@ -540,17 +541,15 @@ class TestGrpc: session = grpc_server.coreemu.create_session() switch = session.add_node(SwitchNode) node = session.add_node(CoreNode) - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, switch.id, interface) + iface_data = ip_prefixes.create_iface(node) + session.add_link(node.id, switch.id, iface_data) # then with pytest.raises(grpc.RpcError): with client.context_connect(): client.get_node_links(session.id, 3) - def test_add_link( - self, grpc_server: CoreGrpcServer, interface_helper: InterfaceHelper - ): + def test_add_link(self, grpc_server: CoreGrpcServer, iface_helper: InterfaceHelper): # given client = CoreGrpcClient() session = grpc_server.coreemu.create_session() @@ -559,16 +558,16 @@ class TestGrpc: assert len(switch.all_link_data()) == 0 # then - interface = interface_helper.create_interface(node.id, 0) + iface = iface_helper.create_iface(node.id, 0) with client.context_connect(): - response = client.add_link(session.id, node.id, switch.id, interface) + response = client.add_link(session.id, node.id, switch.id, iface) # then assert response.result is True assert len(switch.all_link_data()) == 1 def test_add_link_exception( - self, grpc_server: CoreGrpcServer, interface_helper: InterfaceHelper + self, grpc_server: CoreGrpcServer, iface_helper: InterfaceHelper ): # given client = CoreGrpcClient() @@ -576,10 +575,10 @@ class TestGrpc: node = session.add_node(CoreNode) # then - interface = interface_helper.create_interface(node.id, 0) + iface = iface_helper.create_iface(node.id, 0) with pytest.raises(grpc.RpcError): with client.context_connect(): - client.add_link(session.id, 1, 3, interface) + client.add_link(session.id, 1, 3, iface) def test_edit_link(self, grpc_server: CoreGrpcServer, ip_prefixes: IpPrefixes): # given @@ -587,32 +586,32 @@ class TestGrpc: session = grpc_server.coreemu.create_session() switch = session.add_node(SwitchNode) node = session.add_node(CoreNode) - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, switch.id, interface) + iface = ip_prefixes.create_iface(node) + session.add_link(node.id, switch.id, iface) options = core_pb2.LinkOptions(bandwidth=30000) link = switch.all_link_data()[0] - assert options.bandwidth != link.bandwidth + assert options.bandwidth != link.options.bandwidth # then with client.context_connect(): response = client.edit_link( - session.id, node.id, switch.id, options, interface1_id=interface.id + session.id, node.id, switch.id, options, iface1_id=iface.id ) # then assert response.result is True link = switch.all_link_data()[0] - assert options.bandwidth == link.bandwidth + assert options.bandwidth == link.options.bandwidth def test_delete_link(self, grpc_server: CoreGrpcServer, ip_prefixes: IpPrefixes): # given client = CoreGrpcClient() session = grpc_server.coreemu.create_session() node1 = session.add_node(CoreNode) - interface1 = ip_prefixes.create_interface(node1) + iface1 = ip_prefixes.create_iface(node1) node2 = session.add_node(CoreNode) - interface2 = ip_prefixes.create_interface(node2) - session.add_link(node1.id, node2.id, interface1, interface2) + iface2 = ip_prefixes.create_iface(node2) + session.add_link(node1.id, node2.id, iface1, iface2) link_node = None for node_id in session.nodes: node = session.nodes[node_id] @@ -624,7 +623,7 @@ class TestGrpc: # then with client.context_connect(): response = client.delete_link( - session.id, node1.id, node2.id, interface1.id, interface2.id + session.id, node1.id, node2.id, iface1.id, iface2.id ) # then @@ -729,7 +728,7 @@ class TestGrpc: assert emane_network.id == model_config.node_id assert model_config.model == EmaneIeee80211abgModel.name assert len(model_config.config) > 0 - assert model_config.interface == -1 + assert model_config.iface_id == -1 def test_set_emane_model_config(self, grpc_server: CoreGrpcServer): # given @@ -1028,8 +1027,8 @@ class TestGrpc: session = grpc_server.coreemu.create_session() wlan = session.add_node(WlanNode) node = session.add_node(CoreNode) - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, wlan.id, interface) + iface = ip_prefixes.create_iface(node) + session.add_link(node.id, wlan.id, iface) link_data = wlan.all_link_data()[0] queue = Queue() @@ -1199,9 +1198,10 @@ class TestGrpc: queue = Queue() def node_handler(node_data: NodeData): - assert node_data.longitude == lon - assert node_data.latitude == lat - assert node_data.altitude == alt + n = node_data.node + assert n.position.lon == lon + assert n.position.lat == lat + assert n.position.alt == alt queue.put(node_data) session.node_handlers.append(node_handler) diff --git a/daemon/tests/test_gui.py b/daemon/tests/test_gui.py index d3b9362d..8f01a2bf 100644 --- a/daemon/tests/test_gui.py +++ b/daemon/tests/test_gui.py @@ -107,15 +107,15 @@ class TestGui: switch_id = 2 coretlv.session.add_node(SwitchNode, _id=switch_id) ip_prefix = netaddr.IPNetwork("10.0.0.0/24") - interface1_ip4 = str(ip_prefix[node1_id]) + iface1_ip4 = str(ip_prefix[node1_id]) message = coreapi.CoreLinkMessage.create( MessageFlags.ADD.value, [ (LinkTlvs.N1_NUMBER, node1_id), (LinkTlvs.N2_NUMBER, switch_id), - (LinkTlvs.INTERFACE1_NUMBER, 0), - (LinkTlvs.INTERFACE1_IP4, interface1_ip4), - (LinkTlvs.INTERFACE1_IP4_MASK, 24), + (LinkTlvs.IFACE1_NUMBER, 0), + (LinkTlvs.IFACE1_IP4, iface1_ip4), + (LinkTlvs.IFACE1_IP4_MASK, 24), ], ) @@ -131,15 +131,15 @@ class TestGui: switch_id = 2 coretlv.session.add_node(SwitchNode, _id=switch_id) ip_prefix = netaddr.IPNetwork("10.0.0.0/24") - interface2_ip4 = str(ip_prefix[node1_id]) + iface2_ip4 = str(ip_prefix[node1_id]) message = coreapi.CoreLinkMessage.create( MessageFlags.ADD.value, [ (LinkTlvs.N1_NUMBER, switch_id), (LinkTlvs.N2_NUMBER, node1_id), - (LinkTlvs.INTERFACE2_NUMBER, 0), - (LinkTlvs.INTERFACE2_IP4, interface2_ip4), - (LinkTlvs.INTERFACE2_IP4_MASK, 24), + (LinkTlvs.IFACE2_NUMBER, 0), + (LinkTlvs.IFACE2_IP4, iface2_ip4), + (LinkTlvs.IFACE2_IP4_MASK, 24), ], ) @@ -155,19 +155,19 @@ class TestGui: node2_id = 2 coretlv.session.add_node(CoreNode, _id=node2_id) ip_prefix = netaddr.IPNetwork("10.0.0.0/24") - interface1_ip4 = str(ip_prefix[node1_id]) - interface2_ip4 = str(ip_prefix[node2_id]) + iface1_ip4 = str(ip_prefix[node1_id]) + iface2_ip4 = str(ip_prefix[node2_id]) message = coreapi.CoreLinkMessage.create( MessageFlags.ADD.value, [ (LinkTlvs.N1_NUMBER, node1_id), (LinkTlvs.N2_NUMBER, node2_id), - (LinkTlvs.INTERFACE1_NUMBER, 0), - (LinkTlvs.INTERFACE1_IP4, interface1_ip4), - (LinkTlvs.INTERFACE1_IP4_MASK, 24), - (LinkTlvs.INTERFACE2_NUMBER, 0), - (LinkTlvs.INTERFACE2_IP4, interface2_ip4), - (LinkTlvs.INTERFACE2_IP4_MASK, 24), + (LinkTlvs.IFACE1_NUMBER, 0), + (LinkTlvs.IFACE1_IP4, iface1_ip4), + (LinkTlvs.IFACE1_IP4_MASK, 24), + (LinkTlvs.IFACE2_NUMBER, 0), + (LinkTlvs.IFACE2_IP4, iface2_ip4), + (LinkTlvs.IFACE2_IP4_MASK, 24), ], ) @@ -185,15 +185,15 @@ class TestGui: switch_id = 2 coretlv.session.add_node(SwitchNode, _id=switch_id) ip_prefix = netaddr.IPNetwork("10.0.0.0/24") - interface1_ip4 = str(ip_prefix[node1_id]) + iface1_ip4 = str(ip_prefix[node1_id]) message = coreapi.CoreLinkMessage.create( MessageFlags.ADD.value, [ (LinkTlvs.N1_NUMBER, node1_id), (LinkTlvs.N2_NUMBER, switch_id), - (LinkTlvs.INTERFACE1_NUMBER, 0), - (LinkTlvs.INTERFACE1_IP4, interface1_ip4), - (LinkTlvs.INTERFACE1_IP4_MASK, 24), + (LinkTlvs.IFACE1_NUMBER, 0), + (LinkTlvs.IFACE1_IP4, iface1_ip4), + (LinkTlvs.IFACE1_IP4_MASK, 24), ], ) coretlv.handle_message(message) @@ -201,7 +201,7 @@ class TestGui: all_links = switch_node.all_link_data() assert len(all_links) == 1 link = all_links[0] - assert link.bandwidth is None + assert link.options.bandwidth is None bandwidth = 50000 message = coreapi.CoreLinkMessage.create( @@ -209,7 +209,7 @@ class TestGui: [ (LinkTlvs.N1_NUMBER, node1_id), (LinkTlvs.N2_NUMBER, switch_id), - (LinkTlvs.INTERFACE1_NUMBER, 0), + (LinkTlvs.IFACE1_NUMBER, 0), (LinkTlvs.BANDWIDTH, bandwidth), ], ) @@ -219,7 +219,7 @@ class TestGui: all_links = switch_node.all_link_data() assert len(all_links) == 1 link = all_links[0] - assert link.bandwidth == bandwidth + assert link.options.bandwidth == bandwidth def test_link_delete_node_to_node(self, coretlv: CoreHandler): node1_id = 1 @@ -227,18 +227,18 @@ class TestGui: node2_id = 2 coretlv.session.add_node(CoreNode, _id=node2_id) ip_prefix = netaddr.IPNetwork("10.0.0.0/24") - interface1_ip4 = str(ip_prefix[node1_id]) - interface2_ip4 = str(ip_prefix[node2_id]) + iface1_ip4 = str(ip_prefix[node1_id]) + iface2_ip4 = str(ip_prefix[node2_id]) message = coreapi.CoreLinkMessage.create( MessageFlags.ADD.value, [ (LinkTlvs.N1_NUMBER, node1_id), (LinkTlvs.N2_NUMBER, node2_id), - (LinkTlvs.INTERFACE1_NUMBER, 0), - (LinkTlvs.INTERFACE1_IP4, interface1_ip4), - (LinkTlvs.INTERFACE1_IP4_MASK, 24), - (LinkTlvs.INTERFACE2_IP4, interface2_ip4), - (LinkTlvs.INTERFACE2_IP4_MASK, 24), + (LinkTlvs.IFACE1_NUMBER, 0), + (LinkTlvs.IFACE1_IP4, iface1_ip4), + (LinkTlvs.IFACE1_IP4_MASK, 24), + (LinkTlvs.IFACE2_IP4, iface2_ip4), + (LinkTlvs.IFACE2_IP4_MASK, 24), ], ) coretlv.handle_message(message) @@ -253,8 +253,8 @@ class TestGui: [ (LinkTlvs.N1_NUMBER, node1_id), (LinkTlvs.N2_NUMBER, node2_id), - (LinkTlvs.INTERFACE1_NUMBER, 0), - (LinkTlvs.INTERFACE2_NUMBER, 0), + (LinkTlvs.IFACE1_NUMBER, 0), + (LinkTlvs.IFACE2_NUMBER, 0), ], ) coretlv.handle_message(message) @@ -271,15 +271,15 @@ class TestGui: switch_id = 2 coretlv.session.add_node(SwitchNode, _id=switch_id) ip_prefix = netaddr.IPNetwork("10.0.0.0/24") - interface1_ip4 = str(ip_prefix[node1_id]) + iface1_ip4 = str(ip_prefix[node1_id]) message = coreapi.CoreLinkMessage.create( MessageFlags.ADD.value, [ (LinkTlvs.N1_NUMBER, node1_id), (LinkTlvs.N2_NUMBER, switch_id), - (LinkTlvs.INTERFACE1_NUMBER, 0), - (LinkTlvs.INTERFACE1_IP4, interface1_ip4), - (LinkTlvs.INTERFACE1_IP4_MASK, 24), + (LinkTlvs.IFACE1_NUMBER, 0), + (LinkTlvs.IFACE1_IP4, iface1_ip4), + (LinkTlvs.IFACE1_IP4_MASK, 24), ], ) coretlv.handle_message(message) @@ -292,7 +292,7 @@ class TestGui: [ (LinkTlvs.N1_NUMBER, node1_id), (LinkTlvs.N2_NUMBER, switch_id), - (LinkTlvs.INTERFACE1_NUMBER, 0), + (LinkTlvs.IFACE1_NUMBER, 0), ], ) coretlv.handle_message(message) @@ -307,15 +307,15 @@ class TestGui: switch_id = 2 coretlv.session.add_node(SwitchNode, _id=switch_id) ip_prefix = netaddr.IPNetwork("10.0.0.0/24") - interface1_ip4 = str(ip_prefix[node1_id]) + iface1_ip4 = str(ip_prefix[node1_id]) message = coreapi.CoreLinkMessage.create( MessageFlags.ADD.value, [ (LinkTlvs.N1_NUMBER, node1_id), (LinkTlvs.N2_NUMBER, switch_id), - (LinkTlvs.INTERFACE1_NUMBER, 0), - (LinkTlvs.INTERFACE1_IP4, interface1_ip4), - (LinkTlvs.INTERFACE1_IP4_MASK, 24), + (LinkTlvs.IFACE1_NUMBER, 0), + (LinkTlvs.IFACE1_IP4, iface1_ip4), + (LinkTlvs.IFACE1_IP4_MASK, 24), ], ) coretlv.handle_message(message) @@ -328,7 +328,7 @@ class TestGui: [ (LinkTlvs.N1_NUMBER, switch_id), (LinkTlvs.N2_NUMBER, node1_id), - (LinkTlvs.INTERFACE2_NUMBER, 0), + (LinkTlvs.IFACE2_NUMBER, 0), ], ) coretlv.handle_message(message) diff --git a/daemon/tests/test_links.py b/daemon/tests/test_links.py index 819e2be8..4078d8bc 100644 --- a/daemon/tests/test_links.py +++ b/daemon/tests/test_links.py @@ -1,6 +1,6 @@ from typing import Tuple -from core.emulator.emudata import IpPrefixes, LinkOptions +from core.emulator.data import IpPrefixes, LinkOptions from core.emulator.session import Session from core.nodes.base import CoreNode from core.nodes.network import SwitchNode @@ -14,9 +14,9 @@ def create_ptp_network( node2 = session.add_node(CoreNode) # link nodes to net node - interface1_data = ip_prefixes.create_interface(node1) - interface2_data = ip_prefixes.create_interface(node2) - session.add_link(node1.id, node2.id, interface1_data, interface2_data) + iface1_data = ip_prefixes.create_iface(node1) + iface2_data = ip_prefixes.create_iface(node2) + session.add_link(node1.id, node2.id, iface1_data, iface2_data) # instantiate session session.instantiate() @@ -29,41 +29,41 @@ class TestLinks: # given node1 = session.add_node(CoreNode) node2 = session.add_node(CoreNode) - interface1_data = ip_prefixes.create_interface(node1) - interface2_data = ip_prefixes.create_interface(node2) + iface1_data = ip_prefixes.create_iface(node1) + iface2_data = ip_prefixes.create_iface(node2) # when - session.add_link(node1.id, node2.id, interface1_data, interface2_data) + session.add_link(node1.id, node2.id, iface1_data, iface2_data) # then - assert node1.netif(interface1_data.id) - assert node2.netif(interface2_data.id) + assert node1.get_iface(iface1_data.id) + assert node2.get_iface(iface2_data.id) def test_add_node_to_net(self, session: Session, ip_prefixes: IpPrefixes): # given node1 = session.add_node(CoreNode) node2 = session.add_node(SwitchNode) - interface1_data = ip_prefixes.create_interface(node1) + iface1_data = ip_prefixes.create_iface(node1) # when - session.add_link(node1.id, node2.id, interface1_data=interface1_data) + session.add_link(node1.id, node2.id, iface1_data=iface1_data) # then assert node2.all_link_data() - assert node1.netif(interface1_data.id) + assert node1.get_iface(iface1_data.id) def test_add_net_to_node(self, session: Session, ip_prefixes: IpPrefixes): # given node1 = session.add_node(SwitchNode) node2 = session.add_node(CoreNode) - interface2_data = ip_prefixes.create_interface(node2) + iface2_data = ip_prefixes.create_iface(node2) # when - session.add_link(node1.id, node2.id, interface2_data=interface2_data) + session.add_link(node1.id, node2.id, iface2_data=iface2_data) # then assert node1.all_link_data() - assert node2.netif(interface2_data.id) + assert node2.get_iface(iface2_data.id) def test_add_net_to_net(self, session): # given @@ -85,29 +85,29 @@ class TestLinks: jitter = 10 node1 = session.add_node(CoreNode) node2 = session.add_node(SwitchNode) - interface1_data = ip_prefixes.create_interface(node1) - session.add_link(node1.id, node2.id, interface1_data) - interface1 = node1.netif(interface1_data.id) - assert interface1.getparam("delay") != delay - assert interface1.getparam("bw") != bandwidth - assert interface1.getparam("loss") != loss - assert interface1.getparam("duplicate") != dup - assert interface1.getparam("jitter") != jitter + iface1_data = ip_prefixes.create_iface(node1) + session.add_link(node1.id, node2.id, iface1_data) + iface1 = node1.get_iface(iface1_data.id) + assert iface1.getparam("delay") != delay + assert iface1.getparam("bw") != bandwidth + assert iface1.getparam("loss") != loss + assert iface1.getparam("duplicate") != dup + assert iface1.getparam("jitter") != jitter # when options = LinkOptions( delay=delay, bandwidth=bandwidth, loss=loss, dup=dup, jitter=jitter ) session.update_link( - node1.id, node2.id, interface1_id=interface1_data.id, options=options + node1.id, node2.id, iface1_id=iface1_data.id, options=options ) # then - assert interface1.getparam("delay") == delay - assert interface1.getparam("bw") == bandwidth - assert interface1.getparam("loss") == loss - assert interface1.getparam("duplicate") == dup - assert interface1.getparam("jitter") == jitter + assert iface1.getparam("delay") == delay + assert iface1.getparam("bw") == bandwidth + assert iface1.getparam("loss") == loss + assert iface1.getparam("duplicate") == dup + assert iface1.getparam("jitter") == jitter def test_update_net_to_node(self, session: Session, ip_prefixes: IpPrefixes): # given @@ -118,29 +118,29 @@ class TestLinks: jitter = 10 node1 = session.add_node(SwitchNode) node2 = session.add_node(CoreNode) - interface2_data = ip_prefixes.create_interface(node2) - session.add_link(node1.id, node2.id, interface2_data=interface2_data) - interface2 = node2.netif(interface2_data.id) - assert interface2.getparam("delay") != delay - assert interface2.getparam("bw") != bandwidth - assert interface2.getparam("loss") != loss - assert interface2.getparam("duplicate") != dup - assert interface2.getparam("jitter") != jitter + iface2_data = ip_prefixes.create_iface(node2) + session.add_link(node1.id, node2.id, iface2_data=iface2_data) + iface2 = node2.get_iface(iface2_data.id) + assert iface2.getparam("delay") != delay + assert iface2.getparam("bw") != bandwidth + assert iface2.getparam("loss") != loss + assert iface2.getparam("duplicate") != dup + assert iface2.getparam("jitter") != jitter # when options = LinkOptions( delay=delay, bandwidth=bandwidth, loss=loss, dup=dup, jitter=jitter ) session.update_link( - node1.id, node2.id, interface2_id=interface2_data.id, options=options + node1.id, node2.id, iface2_id=iface2_data.id, options=options ) # then - assert interface2.getparam("delay") == delay - assert interface2.getparam("bw") == bandwidth - assert interface2.getparam("loss") == loss - assert interface2.getparam("duplicate") == dup - assert interface2.getparam("jitter") == jitter + assert iface2.getparam("delay") == delay + assert iface2.getparam("bw") == bandwidth + assert iface2.getparam("loss") == loss + assert iface2.getparam("duplicate") == dup + assert iface2.getparam("jitter") == jitter def test_update_ptp(self, session: Session, ip_prefixes: IpPrefixes): # given @@ -151,83 +151,81 @@ class TestLinks: jitter = 10 node1 = session.add_node(CoreNode) node2 = session.add_node(CoreNode) - interface1_data = ip_prefixes.create_interface(node1) - interface2_data = ip_prefixes.create_interface(node2) - session.add_link(node1.id, node2.id, interface1_data, interface2_data) - interface1 = node1.netif(interface1_data.id) - interface2 = node2.netif(interface2_data.id) - assert interface1.getparam("delay") != delay - assert interface1.getparam("bw") != bandwidth - assert interface1.getparam("loss") != loss - assert interface1.getparam("duplicate") != dup - assert interface1.getparam("jitter") != jitter - assert interface2.getparam("delay") != delay - assert interface2.getparam("bw") != bandwidth - assert interface2.getparam("loss") != loss - assert interface2.getparam("duplicate") != dup - assert interface2.getparam("jitter") != jitter + iface1_data = ip_prefixes.create_iface(node1) + iface2_data = ip_prefixes.create_iface(node2) + session.add_link(node1.id, node2.id, iface1_data, iface2_data) + iface1 = node1.get_iface(iface1_data.id) + iface2 = node2.get_iface(iface2_data.id) + assert iface1.getparam("delay") != delay + assert iface1.getparam("bw") != bandwidth + assert iface1.getparam("loss") != loss + assert iface1.getparam("duplicate") != dup + assert iface1.getparam("jitter") != jitter + assert iface2.getparam("delay") != delay + assert iface2.getparam("bw") != bandwidth + assert iface2.getparam("loss") != loss + assert iface2.getparam("duplicate") != dup + assert iface2.getparam("jitter") != jitter # when options = LinkOptions( delay=delay, bandwidth=bandwidth, loss=loss, dup=dup, jitter=jitter ) - session.update_link( - node1.id, node2.id, interface1_data.id, interface2_data.id, options - ) + session.update_link(node1.id, node2.id, iface1_data.id, iface2_data.id, options) # then - assert interface1.getparam("delay") == delay - assert interface1.getparam("bw") == bandwidth - assert interface1.getparam("loss") == loss - assert interface1.getparam("duplicate") == dup - assert interface1.getparam("jitter") == jitter - assert interface2.getparam("delay") == delay - assert interface2.getparam("bw") == bandwidth - assert interface2.getparam("loss") == loss - assert interface2.getparam("duplicate") == dup - assert interface2.getparam("jitter") == jitter + assert iface1.getparam("delay") == delay + assert iface1.getparam("bw") == bandwidth + assert iface1.getparam("loss") == loss + assert iface1.getparam("duplicate") == dup + assert iface1.getparam("jitter") == jitter + assert iface2.getparam("delay") == delay + assert iface2.getparam("bw") == bandwidth + assert iface2.getparam("loss") == loss + assert iface2.getparam("duplicate") == dup + assert iface2.getparam("jitter") == jitter def test_delete_ptp(self, session: Session, ip_prefixes: IpPrefixes): # given node1 = session.add_node(CoreNode) node2 = session.add_node(CoreNode) - interface1_data = ip_prefixes.create_interface(node1) - interface2_data = ip_prefixes.create_interface(node2) - session.add_link(node1.id, node2.id, interface1_data, interface2_data) - assert node1.netif(interface1_data.id) - assert node2.netif(interface2_data.id) + iface1_data = ip_prefixes.create_iface(node1) + iface2_data = ip_prefixes.create_iface(node2) + session.add_link(node1.id, node2.id, iface1_data, iface2_data) + assert node1.get_iface(iface1_data.id) + assert node2.get_iface(iface2_data.id) # when - session.delete_link(node1.id, node2.id, interface1_data.id, interface2_data.id) + session.delete_link(node1.id, node2.id, iface1_data.id, iface2_data.id) # then - assert not node1.netif(interface1_data.id) - assert not node2.netif(interface2_data.id) + assert iface1_data.id not in node1.ifaces + assert iface2_data.id not in node2.ifaces def test_delete_node_to_net(self, session: Session, ip_prefixes: IpPrefixes): # given node1 = session.add_node(CoreNode) node2 = session.add_node(SwitchNode) - interface1_data = ip_prefixes.create_interface(node1) - session.add_link(node1.id, node2.id, interface1_data) - assert node1.netif(interface1_data.id) + iface1_data = ip_prefixes.create_iface(node1) + session.add_link(node1.id, node2.id, iface1_data) + assert node1.get_iface(iface1_data.id) # when - session.delete_link(node1.id, node2.id, interface1_id=interface1_data.id) + session.delete_link(node1.id, node2.id, iface1_id=iface1_data.id) # then - assert not node1.netif(interface1_data.id) + assert iface1_data.id not in node1.ifaces def test_delete_net_to_node(self, session: Session, ip_prefixes: IpPrefixes): # given node1 = session.add_node(SwitchNode) node2 = session.add_node(CoreNode) - interface2_data = ip_prefixes.create_interface(node2) - session.add_link(node1.id, node2.id, interface2_data=interface2_data) - assert node2.netif(interface2_data.id) + iface2_data = ip_prefixes.create_iface(node2) + session.add_link(node1.id, node2.id, iface2_data=iface2_data) + assert node2.get_iface(iface2_data.id) # when - session.delete_link(node1.id, node2.id, interface2_id=interface2_data.id) + session.delete_link(node1.id, node2.id, iface2_id=iface2_data.id) # then - assert not node2.netif(interface2_data.id) + assert iface2_data.id not in node2.ifaces diff --git a/daemon/tests/test_nodes.py b/daemon/tests/test_nodes.py index 0cbdb8ae..8af2e895 100644 --- a/daemon/tests/test_nodes.py +++ b/daemon/tests/test_nodes.py @@ -1,6 +1,6 @@ import pytest -from core.emulator.emudata import InterfaceData, NodeOptions +from core.emulator.data import InterfaceData, NodeOptions from core.emulator.session import Session from core.errors import CoreError from core.nodes.base import CoreNode @@ -49,57 +49,57 @@ class TestNodes: with pytest.raises(CoreError): session.get_node(node.id, CoreNode) - def test_node_sethwaddr(self, session: Session): + def test_node_set_mac(self, session: Session): # given node = session.add_node(CoreNode) switch = session.add_node(SwitchNode) - interface_data = InterfaceData() - interface = node.newnetif(switch, interface_data) + iface_data = InterfaceData() + iface = node.new_iface(switch, iface_data) mac = "aa:aa:aa:ff:ff:ff" # when - node.sethwaddr(interface.netindex, mac) + node.set_mac(iface.node_id, mac) # then - assert interface.hwaddr == mac + assert iface.mac == mac - def test_node_sethwaddr_exception(self, session: Session): + def test_node_set_mac_exception(self, session: Session): # given node = session.add_node(CoreNode) switch = session.add_node(SwitchNode) - interface_data = InterfaceData() - interface = node.newnetif(switch, interface_data) + iface_data = InterfaceData() + iface = node.new_iface(switch, iface_data) mac = "aa:aa:aa:ff:ff:fff" # when with pytest.raises(CoreError): - node.sethwaddr(interface.netindex, mac) + node.set_mac(iface.node_id, mac) def test_node_addaddr(self, session: Session): # given node = session.add_node(CoreNode) switch = session.add_node(SwitchNode) - interface_data = InterfaceData() - interface = node.newnetif(switch, interface_data) + iface_data = InterfaceData() + iface = node.new_iface(switch, iface_data) addr = "192.168.0.1/24" # when - node.addaddr(interface.netindex, addr) + node.addaddr(iface.node_id, addr) # then - assert interface.addrlist[0] == addr + assert iface.addrlist[0] == addr def test_node_addaddr_exception(self, session): # given node = session.add_node(CoreNode) switch = session.add_node(SwitchNode) - interface_data = InterfaceData() - interface = node.newnetif(switch, interface_data) + iface_data = InterfaceData() + iface = node.new_iface(switch, iface_data) addr = "256.168.0.1/24" # when with pytest.raises(CoreError): - node.addaddr(interface.netindex, addr) + node.addaddr(iface.node_id, addr) @pytest.mark.parametrize("net_type", NET_TYPES) def test_net(self, session, net_type): diff --git a/daemon/tests/test_xml.py b/daemon/tests/test_xml.py index 0b44a354..91b598f3 100644 --- a/daemon/tests/test_xml.py +++ b/daemon/tests/test_xml.py @@ -3,7 +3,7 @@ from xml.etree import ElementTree import pytest -from core.emulator.emudata import IpPrefixes, LinkOptions, NodeOptions +from core.emulator.data import IpPrefixes, LinkOptions, NodeOptions from core.emulator.enumerations import EventTypes from core.emulator.session import Session from core.errors import CoreError @@ -73,8 +73,8 @@ class TestXml: # link nodes to ptp net for node in [node1, node2]: - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, ptp_node.id, interface1_data=interface) + iface_data = ip_prefixes.create_iface(node) + session.add_link(node.id, ptp_node.id, iface1_data=iface_data) # instantiate session session.instantiate() @@ -128,8 +128,8 @@ class TestXml: # link nodes to ptp net for node in [node1, node2]: - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, ptp_node.id, interface1_data=interface) + iface_data = ip_prefixes.create_iface(node) + session.add_link(node.id, ptp_node.id, iface1_data=iface_data) # set custom values for node service session.services.set_service(node1.id, SshService.name) @@ -197,8 +197,8 @@ class TestXml: # link nodes for node in [node1, node2]: - interface = ip_prefixes.create_interface(node) - session.add_link(node.id, wlan_node.id, interface1_data=interface) + iface_data = ip_prefixes.create_iface(node) + session.add_link(node.id, wlan_node.id, iface1_data=iface_data) # instantiate session session.instantiate() @@ -299,7 +299,7 @@ class TestXml: """ # create nodes node1 = session.add_node(CoreNode) - interface1_data = ip_prefixes.create_interface(node1) + iface1_data = ip_prefixes.create_iface(node1) switch = session.add_node(SwitchNode) # create link @@ -309,7 +309,7 @@ class TestXml: options.jitter = 10 options.delay = 30 options.dup = 5 - session.add_link(node1.id, switch.id, interface1_data, options=options) + session.add_link(node1.id, switch.id, iface1_data, options=options) # instantiate session session.instantiate() @@ -347,11 +347,11 @@ class TestXml: node = session.nodes[node_id] links += node.all_link_data() link = links[0] - assert options.loss == link.loss - assert options.bandwidth == link.bandwidth - assert options.jitter == link.jitter - assert options.delay == link.delay - assert options.dup == link.dup + assert options.loss == link.options.loss + assert options.bandwidth == link.options.bandwidth + assert options.jitter == link.options.jitter + assert options.delay == link.options.delay + assert options.dup == link.options.dup def test_link_options_ptp( self, session: Session, tmpdir: TemporaryFile, ip_prefixes: IpPrefixes @@ -365,9 +365,9 @@ class TestXml: """ # create nodes node1 = session.add_node(CoreNode) - interface1_data = ip_prefixes.create_interface(node1) + iface1_data = ip_prefixes.create_iface(node1) node2 = session.add_node(CoreNode) - interface2_data = ip_prefixes.create_interface(node2) + iface2_data = ip_prefixes.create_iface(node2) # create link options = LinkOptions() @@ -376,7 +376,7 @@ class TestXml: options.jitter = 10 options.delay = 30 options.dup = 5 - session.add_link(node1.id, node2.id, interface1_data, interface2_data, options) + session.add_link(node1.id, node2.id, iface1_data, iface2_data, options) # instantiate session session.instantiate() @@ -414,11 +414,11 @@ class TestXml: node = session.nodes[node_id] links += node.all_link_data() link = links[0] - assert options.loss == link.loss - assert options.bandwidth == link.bandwidth - assert options.jitter == link.jitter - assert options.delay == link.delay - assert options.dup == link.dup + assert options.loss == link.options.loss + assert options.bandwidth == link.options.bandwidth + assert options.jitter == link.options.jitter + assert options.delay == link.options.delay + assert options.dup == link.options.dup def test_link_options_bidirectional( self, session: Session, tmpdir: TemporaryFile, ip_prefixes: IpPrefixes @@ -432,9 +432,9 @@ class TestXml: """ # create nodes node1 = session.add_node(CoreNode) - interface1_data = ip_prefixes.create_interface(node1) + iface1_data = ip_prefixes.create_iface(node1) node2 = session.add_node(CoreNode) - interface2_data = ip_prefixes.create_interface(node2) + iface2_data = ip_prefixes.create_iface(node2) # create link options1 = LinkOptions() @@ -444,7 +444,7 @@ class TestXml: options1.loss = 10.5 options1.dup = 5 options1.jitter = 5 - session.add_link(node1.id, node2.id, interface1_data, interface2_data, options1) + session.add_link(node1.id, node2.id, iface1_data, iface2_data, options1) options2 = LinkOptions() options2.unidirectional = 1 options2.bandwidth = 10000 @@ -453,7 +453,7 @@ class TestXml: options2.dup = 10 options2.jitter = 10 session.update_link( - node2.id, node1.id, interface2_data.id, interface1_data.id, options2 + node2.id, node1.id, iface2_data.id, iface1_data.id, options2 ) # instantiate session @@ -494,13 +494,13 @@ class TestXml: assert len(links) == 2 link1 = links[0] link2 = links[1] - assert options1.bandwidth == link1.bandwidth - assert options1.delay == link1.delay - assert options1.loss == link1.loss - assert options1.dup == link1.dup - assert options1.jitter == link1.jitter - assert options2.bandwidth == link2.bandwidth - assert options2.delay == link2.delay - assert options2.loss == link2.loss - assert options2.dup == link2.dup - assert options2.jitter == link2.jitter + assert options1.bandwidth == link1.options.bandwidth + assert options1.delay == link1.options.delay + assert options1.loss == link1.options.loss + assert options1.dup == link1.options.dup + assert options1.jitter == link1.options.jitter + assert options2.bandwidth == link2.options.bandwidth + assert options2.delay == link2.options.delay + assert options2.loss == link2.options.loss + assert options2.dup == link2.options.dup + assert options2.jitter == link2.options.jitter diff --git a/docs/scripting.md b/docs/scripting.md index 59bc02ae..f65d66a3 100644 --- a/docs/scripting.md +++ b/docs/scripting.md @@ -36,7 +36,7 @@ interact with the GUI. import logging from core.emulator.coreemu import CoreEmu -from core.emulator.emudata import IpPrefixes +from core.emulator.data import IpPrefixes from core.emulator.enumerations import EventTypes from core.nodes.base import CoreNode from core.nodes.network import SwitchNode @@ -61,8 +61,8 @@ def main(): # create nodes for _ in range(NODES): node = session.add_node(CoreNode) - interface = prefixes.create_interface(node) - session.add_link(node.id, switch.id, interface1_data=interface) + interface = prefixes.create_iface(node) + session.add_link(node.id, switch.id, iface1_data=interface) # instantiate session session.instantiate() diff --git a/docs/services.md b/docs/services.md index 9f47ae48..2ce52e99 100644 --- a/docs/services.md +++ b/docs/services.md @@ -263,7 +263,7 @@ class MyService(CoreService): if filename == cls.configs[0]: cfg += "# auto-generated by MyService (sample.py)\n" - for ifc in node.netifs(): + for ifc in node.get_ifaces(): cfg += f'echo "Node {node.name} has interface {ifc.name}"\n' elif filename == cls.configs[1]: cfg += "echo hello"