Пример #1
0
def link_config(network,
                interface,
                link_options,
                devname=None,
                interface_two=None):
    """
    Convenience method for configuring a link,

    :param network: network to configure link for
    :param interface: interface to configure
    :param core.emulator.emudata.LinkOptions link_options: data to configure link with
    :param str devname: device name, default is None
    :param interface_two: other interface associated, default is None
    :return: nothing
    """
    config = {
        "netif": interface,
        "bw": link_options.bandwidth,
        "delay": link_options.delay,
        "loss": link_options.per,
        "duplicate": link_options.dup,
        "jitter": link_options.jitter,
        "netif2": interface_two,
    }

    # hacky check here, because physical and emane nodes do not conform to the same linkconfig interface
    if not nodeutils.is_node(network, [NodeTypes.EMANE, NodeTypes.PHYSICAL]):
        config["devname"] = devname

    network.linkconfig(**config)
Пример #2
0
    def waitfordevicenode(self):
        """
        Check for presence of a node device - tap device may not appear right away waits.

        :return: nothing
        """
        logging.debug("waiting for device node: %s", self.name)

        def nodedevexists():
            args = [constants.IP_BIN, "link", "show", self.name]
            return self.node.cmd(args)

        count = 0
        while True:
            result = self.waitfor(nodedevexists)
            if result:
                break

            # check if this is an EMANE interface; if so, continue
            # waiting if EMANE is still running
            # TODO: remove emane code
            should_retry = count < 5
            is_emane_node = nodeutils.is_node(self.net, NodeTypes.EMANE)
            is_emane_running = self.node.session.emane.emanerunning(self.node)
            if all([should_retry, is_emane_node, is_emane_running]):
                count += 1
            else:
                raise RuntimeError("node device failed to exist")
Пример #3
0
    def add_virtual_host(self, physical_host, node):
        if not isinstance(node, CoreNodeBase):
            raise TypeError("invalid node type: %s" % node)

        # create virtual host element
        host_id = "%s/%s" % (physical_host.get("id"), node.name)
        host_element = etree.SubElement(physical_host,
                                        "testHost",
                                        id=host_id,
                                        name=node.name)

        # add host type
        add_type(host_element, "virtual")

        for netif in node.netifs():
            emane_element = None
            if nodeutils.is_node(netif.net, NodeTypes.EMANE):
                emane_element = add_emane_interface(host_element, netif)

            parent_element = host_element
            if emane_element is not None:
                parent_element = emane_element

            for address in netif.addrlist:
                address_type = get_address_type(address)
                add_address(parent_element, address_type, address, netif.name)
Пример #4
0
 def ptpcheck(ifc):
     """
     Helper to detect whether interface is connected to a notional
     point-to-point link.
     """
     if nodeutils.is_node(ifc.net, NodeTypes.PEER_TO_PEER):
         return "  ipv6 ospf6 network point-to-point\n"
     return ""
Пример #5
0
    def sendobjs(self):
        """
        Session has already started, and the SDT3D GUI later connects.
        Send all node and link objects for display. Otherwise, nodes and
        links will only be drawn when they have been updated (e.g. moved).

        :return: nothing
        """
        nets = []
        with self.session._nodes_lock:
            for node_id in self.session.nodes:
                node = self.session.nodes[node_id]
                if isinstance(node, CoreNetworkBase):
                    nets.append(node)
                if not isinstance(node, NodeBase):
                    continue
                (x, y, z) = node.getposition()
                if x is None or y is None:
                    continue
                self.updatenode(
                    node.id,
                    MessageFlags.ADD.value,
                    x,
                    y,
                    z,
                    node.name,
                    node.type,
                    node.icon,
                )
            for nodenum in sorted(self.remotes.keys()):
                r = self.remotes[nodenum]
                x, y, z = r.pos
                self.updatenode(nodenum, MessageFlags.ADD.value, x, y, z,
                                r.name, r.type, r.icon)

            for net in nets:
                all_links = net.all_link_data(flags=MessageFlags.ADD.value)
                for link_data in all_links:
                    is_wireless = nodeutils.is_node(
                        net, (NodeTypes.WIRELESS_LAN, NodeTypes.EMANE))
                    wireless_link = link_data.message_type == LinkTypes.WIRELESS.value
                    if is_wireless and link_data.node1_id == net.id:
                        continue

                    self.updatelink(
                        link_data.node1_id,
                        link_data.node2_id,
                        MessageFlags.ADD.value,
                        wireless_link,
                    )

            for n1num in sorted(self.remotes.keys()):
                r = self.remotes[n1num]
                for n2num, wireless_link in r.links:
                    self.updatelink(n1num, n2num, MessageFlags.ADD.value,
                                    wireless_link)
Пример #6
0
    def setup(self):
        """
        Populate self._objs with EmaneNodes; perform distributed setup;
        associate models with EmaneNodes from self.config. Returns
        Emane.(SUCCESS, NOT_NEEDED, NOT_READY) in order to delay session
        instantiation.
        """
        logging.debug("emane setup")

        # TODO: drive this from the session object
        with self.session._nodes_lock:
            for node_id in self.session.nodes:
                node = self.session.nodes[node_id]
                if nodeutils.is_node(node, NodeTypes.EMANE):
                    logging.debug("adding emane node: id(%s) name(%s)", node.id, node.name)
                    self.add_node(node)

            if not self._emane_nodes:
                logging.debug("no emane nodes in session")
                return EmaneManager.NOT_NEEDED

        # control network bridge required for EMANE 0.9.2
        # - needs to be configured before checkdistributed() for distributed
        # - needs to exist when eventservice binds to it (initeventservice)
        if self.session.master:
            otadev = self.get_config("otamanagerdevice")
            netidx = self.session.get_control_net_index(otadev)
            logging.debug("emane ota manager device: index(%s) otadev(%s)", netidx, otadev)
            if netidx < 0:
                logging.error("EMANE cannot start, check core config. invalid OTA device provided: %s", otadev)
                return EmaneManager.NOT_READY

            ctrlnet = self.session.add_remove_control_net(net_index=netidx, remove=False, conf_required=False)
            self.distributedctrlnet(ctrlnet)
            eventdev = self.get_config("eventservicedevice")
            logging.debug("emane event service device: eventdev(%s)", eventdev)
            if eventdev != otadev:
                netidx = self.session.get_control_net_index(eventdev)
                logging.debug("emane event service device index: %s", netidx)
                if netidx < 0:
                    logging.error("EMANE cannot start, check core config. invalid event service device: %s", eventdev)
                    return EmaneManager.NOT_READY

                ctrlnet = self.session.add_remove_control_net(net_index=netidx, remove=False, conf_required=False)
                self.distributedctrlnet(ctrlnet)

        if self.checkdistributed():
            # we are slave, but haven't received a platformid yet
            platform_id_start = "platform_id_start"
            default_values = self.emane_config.default_values()
            value = self.get_config(platform_id_start)
            if value == default_values[platform_id_start]:
                return EmaneManager.NOT_READY

        self.check_node_models()
        return EmaneManager.SUCCESS
Пример #7
0
 def rj45check(ifc):
     """
     Helper to detect whether interface is connected an external RJ45
     link.
     """
     if ifc.net:
         for peerifc in ifc.net.netifs():
             if peerifc == ifc:
                 continue
             if nodeutils.is_node(peerifc, NodeTypes.RJ45):
                 return True
     return False
Пример #8
0
    def newnetif(self,
                 net=None,
                 addrlist=None,
                 hwaddr=None,
                 ifindex=None,
                 ifname=None):
        """
        Create a new network interface.

        :param core.nodes.base.CoreNetworkBase net: network to associate with
        :param list addrlist: addresses to add on the interface
        :param core.nodes.ipaddress.MacAddress hwaddr: hardware address to set for interface
        :param int ifindex: index of interface to create
        :param str ifname: name for interface
        :return: interface index
        :rtype: int
        """
        if not addrlist:
            addrlist = []

        with self.lock:
            # TODO: see if you can move this to emane specific code
            if nodeutils.is_node(net, NodeTypes.EMANE):
                ifindex = self.newtuntap(ifindex=ifindex,
                                         ifname=ifname,
                                         net=net)
                # TUN/TAP is not ready for addressing yet; the device may
                #   take some time to appear, and installing it into a
                #   namespace after it has been bound removes addressing;
                #   save addresses with the interface now
                self.attachnet(ifindex, net)
                netif = self.netif(ifindex)
                netif.sethwaddr(hwaddr)
                for address in utils.make_tuple(addrlist):
                    netif.addaddr(address)
                return ifindex
            else:
                ifindex = self.newveth(ifindex=ifindex, ifname=ifname, net=net)

            if net is not None:
                self.attachnet(ifindex, net)

            if hwaddr:
                self.sethwaddr(ifindex, hwaddr)

            for address in utils.make_tuple(addrlist):
                self.addaddr(ifindex, address)

            self.ifup(ifindex)
            return ifindex
Пример #9
0
    def generatequaggaifcconfig(cls, node, ifc):
        cfg = cls.mtucheck(ifc)
        # Uncomment the following line to use Address Family Translation for IPv4
        cfg += "  ipv6 ospf6 instance-id 65\n"
        if ifc.net is not None and nodeutils.is_node(
                ifc.net, (NodeTypes.WIRELESS_LAN, NodeTypes.EMANE)):
            return (cfg + """\
  ipv6 ospf6 hello-interval 2
  ipv6 ospf6 dead-interval 6
  ipv6 ospf6 retransmit-interval 5
  ipv6 ospf6 network manet-designated-router
  ipv6 ospf6 diffhellos
  ipv6 ospf6 adjacencyconnectivity uniconnected
  ipv6 ospf6 lsafullness mincostlsa
""")
        else:
            return cfg
Пример #10
0
    def GetSession(self, request, context):
        logging.debug("get session: %s", request)
        session = self.get_session(request.session_id, context)

        links = []
        nodes = []
        for _id in session.nodes:
            node = session.nodes[_id]
            if not isinstance(node.id, int):
                continue

            node_type = nodeutils.get_node_type(node.__class__).value
            model = getattr(node, "type", None)
            position = core_pb2.Position(x=node.position.x,
                                         y=node.position.y,
                                         z=node.position.z)

            services = getattr(node, "services", [])
            if services is None:
                services = []
            services = [x.name for x in services]

            emane_model = None
            if nodeutils.is_node(node, NodeTypes.EMANE):
                emane_model = node.model.name

            node_proto = core_pb2.Node(id=node.id,
                                       name=node.name,
                                       emane=emane_model,
                                       model=model,
                                       type=node_type,
                                       position=position,
                                       services=services)
            nodes.append(node_proto)

            node_links = get_links(session, node)
            links.extend(node_links)

        session_proto = core_pb2.Session(state=session.state,
                                         nodes=nodes,
                                         links=links)
        return core_pb2.GetSessionResponse(session=session_proto)
Пример #11
0
    def wlancheck(self, nodenum):
        """
        Helper returns True if a node number corresponds to a WlanNode or EmaneNode.

        :param int nodenum: node id to check
        :return: True if node is wlan or emane, False otherwise
        :rtype: bool
        """
        if nodenum in self.remotes:
            node_type = self.remotes[nodenum].type
            if node_type in ("wlan", "emane"):
                return True
        else:
            try:
                n = self.session.get_node(nodenum)
            except CoreError:
                return False
            if nodeutils.is_node(n, (NodeTypes.WIRELESS_LAN, NodeTypes.EMANE)):
                return True
        return False
Пример #12
0
    def write_nodes(self):
        self.networks = etree.SubElement(self.scenario, "networks")
        self.devices = etree.SubElement(self.scenario, "devices")

        links = []
        for node_id in self.session.nodes:
            node = self.session.nodes[node_id]
            # network node
            is_network_or_rj45 = isinstance(node,
                                            (core.nodes.base.CoreNetworkBase,
                                             core.nodes.physical.Rj45Node))
            is_controlnet = nodeutils.is_node(node, NodeTypes.CONTROL_NET)
            if is_network_or_rj45 and not is_controlnet:
                self.write_network(node)
            # device node
            elif isinstance(node, core.nodes.base.CoreNodeBase):
                self.write_device(node)

            # add known links
            links.extend(node.all_link_data(0))

        return links
Пример #13
0
    def create_interface_element(self, element_name, node_id, interface_id,
                                 mac, ip4, ip4_mask, ip6, ip6_mask):
        interface = etree.Element(element_name)
        node = self.session.get_node(node_id)
        interface_name = None
        if not isinstance(node, CoreNetworkBase):
            node_interface = node.netif(interface_id)
            interface_name = node_interface.name

            # check if emane interface
            if nodeutils.is_node(node_interface.net, NodeTypes.EMANE):
                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
Пример #14
0
    def GetNode(self, request, context):
        logging.debug("get node: %s", request)
        session = self.get_session(request.session_id, context)
        node = self.get_node(session, request.node_id, context)

        interfaces = []
        for interface_id in node._netif:
            interface = node._netif[interface_id]
            net_id = None
            if interface.net:
                net_id = interface.net.id
            interface_proto = core_pb2.Interface(id=interface_id,
                                                 netid=net_id,
                                                 name=interface.name,
                                                 mac=str(interface.hwaddr),
                                                 mtu=interface.mtu,
                                                 flowid=interface.flow_id)
            interfaces.append(interface_proto)

        emane_model = None
        if nodeutils.is_node(node, NodeTypes.EMANE):
            emane_model = node.model.name

        services = [x.name for x in getattr(node, "services", [])]
        position = core_pb2.Position(x=node.position.x,
                                     y=node.position.y,
                                     z=node.position.z)
        node_type = nodeutils.get_node_type(node.__class__).value
        node = core_pb2.Node(id=node.id,
                             name=node.name,
                             type=node_type,
                             emane=emane_model,
                             model=node.type,
                             position=position,
                             services=services)

        return core_pb2.GetNodeResponse(node=node, interfaces=interfaces)
Пример #15
0
    def generate_config(cls, node, filename):
        if filename == cls.configs[0]:
            transport_commands = []
            for interface in node.netifs(sort=True):
                network_node = node.session.get_node(interface.net.id)
                if nodeutils.is_node(network_node, NodeTypes.EMANE):
                    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)
                        command = (
                            "emanetransportd -r -l 0 -d ../transportdaemon%s.xml"
                            % nem_id)
                        transport_commands.append(command)
            transport_commands = "\n".join(transport_commands)
            return """
emanegentransportxml -o ../ ../platform%s.xml
%s
""" % (
                node.id,
                transport_commands,
            )
        else:
            raise ValueError
Пример #16
0
    def addnettunnel(self, node_id):
        """
        Add network tunnel between node and broker.

        :param int node_id: node id of network to add tunnel to
        :return: list of gre taps
        :rtype: list
        """
        try:
            net = self.session.get_node(node_id)
            logging.info("adding net tunnel for: id(%s) %s", node_id, net)
        except KeyError:
            raise KeyError("network node %s not found" % node_id)

        # add other nets here that do not require tunnels
        if nodeutils.is_node(net, NodeTypes.EMANE_NET):
            logging.warning("emane network does not require a tunnel")
            return None

        server_interface = getattr(net, "serverintf", None)
        if nodeutils.is_node(
                net, NodeTypes.CONTROL_NET) and server_interface is not None:
            logging.warning(
                "control networks with server interfaces do not need a tunnel")
            return None

        servers = self.getserversbynode(node_id)
        if len(servers) < 2:
            logging.warning("not enough servers to create a tunnel: %s",
                            servers)
            return None

        hosts = []
        for server in servers:
            if server.host is None:
                continue
            logging.info("adding server host for net tunnel: %s", server.host)
            hosts.append(server.host)

        if len(hosts) == 0:
            for session_client in self.session_clients:
                # get IP address from API message sender (master)
                if session_client.client_address != "":
                    address = session_client.client_address[0]
                    logging.info("adding session_client host: %s", address)
                    hosts.append(address)

        r = []
        for host in hosts:
            if self.myip:
                # we are the remote emulation server
                myip = self.myip
            else:
                # we are the session master
                myip = host
            key = self.tunnelkey(node_id, IpAddress.to_int(myip))
            if key in self.tunnels.keys():
                logging.info(
                    "tunnel already exists, returning existing tunnel: %s",
                    key)
                gt = self.tunnels[key]
                r.append(gt)
                continue
            logging.info("adding tunnel for net %s to %s with key %s", node_id,
                         host, key)
            gt = GreTap(node=None,
                        name=None,
                        session=self.session,
                        remoteip=host,
                        key=key)
            self.tunnels[key] = gt
            r.append(gt)
            # attaching to net will later allow gt to be destroyed
            # during net.shutdown()
            net.attach(gt)

        return r