def parse_interface(self, node, device_id, interface): """ Each interface can have multiple 'address' elements. """ if_name = interface.getAttribute('name') network = self.find_interface_network_object(interface) if not network: msg = 'skipping node \'%s\' interface \'%s\': ' \ 'unknown network' % (node.name, if_name) logger.warn(msg) assert False # XXX for testing mac, ipv4, ipv6, hostname = self.parse_addresses(interface) if mac: hwaddr = MacAddress.from_string(mac[0]) else: hwaddr = None ifindex = node.newnetif(network, addrlist=ipv4 + ipv6, hwaddr=hwaddr, ifindex=None, ifname=if_name) # TODO: 'hostname' addresses are unused msg = 'node \'%s\' interface \'%s\' connected ' \ 'to network \'%s\'' % (node.name, if_name, network.name) logger.info(msg) # set link parameters for wired links if nodeutils.is_node( network, (NodeTypes.HUB, NodeTypes.PEER_TO_PEER, NodeTypes.SWITCH)): netif = node.netif(ifindex) self.set_wired_link_parameters(network, netif, device_id)
def parse_interface(self, node, device_id, interface): """ Each interface can have multiple 'address' elements. """ if_name = interface.getAttribute('name') network = self.find_interface_network_object(interface) if not network: msg = 'skipping node \'%s\' interface \'%s\': ' \ 'unknown network' % (node.name, if_name) logger.warn(msg) assert False # XXX for testing mac, ipv4, ipv6, hostname = self.parse_addresses(interface) if mac: hwaddr = MacAddress.from_string(mac[0]) else: hwaddr = None ifindex = node.newnetif(network, addrlist=ipv4 + ipv6, hwaddr=hwaddr, ifindex=None, ifname=if_name) # TODO: 'hostname' addresses are unused msg = 'node \'%s\' interface \'%s\' connected ' \ 'to network \'%s\'' % (node.name, if_name, network.name) logger.info(msg) # set link parameters for wired links if nodeutils.is_node(network, (NodeTypes.HUB, NodeTypes.PEER_TO_PEER, NodeTypes.SWITCH)): netif = node.netif(ifindex) self.set_wired_link_parameters(network, netif, device_id)
def newveth(self, ifindex=None, ifname=None, net=None): """ Create a new interface. :param int ifindex: index for the new interface :param str ifname: name for the new interface :param net: network to associate interface with :return: nothing """ with self.lock: if ifindex is None: ifindex = self.newifindex() if ifname is None: ifname = "eth%d" % ifindex sessionid = self.session.short_session_id() try: suffix = "%x.%s.%s" % (self.objid, ifindex, sessionid) except TypeError: suffix = "%s.%s.%s" % (self.objid, ifindex, sessionid) localname = "veth" + suffix if len(localname) >= 16: raise ValueError("interface local name (%s) too long" % localname) name = localname + "p" if len(name) >= 16: raise ValueError("interface name (%s) too long" % name) veth = VEth(node=self, name=name, localname=localname, net=net, start=self.up) if self.up: utils.check_cmd([constants.IP_BIN, "link", "set", veth.name, "netns", str(self.pid)]) self.check_cmd([constants.IP_BIN, "link", "set", veth.name, "name", ifname]) veth.name = ifname if self.up: # TODO: potentially find better way to query interface ID # retrieve interface information output = self.check_cmd(["ip", "link", "show", veth.name]) logger.debug("interface command output: %s", output) output = output.split("\n") veth.flow_id = int(output[0].strip().split(":")[0]) + 1 logger.debug("interface flow index: %s - %s", veth.name, veth.flow_id) veth.hwaddr = MacAddress.from_string(output[1].strip().split()[1]) logger.debug("interface mac: %s - %s", veth.name, veth.hwaddr) try: self.addnetif(veth, ifindex) except ValueError as e: veth.shutdown() del veth raise e return ifindex
def create_interface_data(interface_element): interface_id = int(interface_element.get("id")) name = interface_element.get("name") mac = interface_element.get("mac") if mac: mac = MacAddress.from_string(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") return InterfaceData(interface_id, name, mac, ip4, ip4_mask, ip6, ip6_mask)
def buildplatformxml(self, ctrlnet): """ Build a platform.xml file now that all nodes are configured. """ values = self.getconfig(None, "emane", self.emane_config.getdefaultvalues())[1] nemid = int(self.emane_config.valueof("nem_id_start", values)) platformxmls = {} # assume self._objslock is already held here for key in sorted(self._emane_nodes.keys()): emane_node = self._emane_nodes[key] nems = emane_node.buildplatformxmlentry(self.xmldoc("platform")) for netif in sorted(nems, key=lambda x: x.node.objid): nementry = nems[netif] nementry.setAttribute("id", "%d" % nemid) key = netif.node.objid if netif.transport_type == "raw": key = "host" otadev = ctrlnet.brname eventdev = ctrlnet.brname else: otadev = None eventdev = None if key not in platformxmls: platformxmls[key] = self.newplatformxmldoc( values, otadev, eventdev) doc = platformxmls[key] plat = doc.getElementsByTagName("platform").pop() plat.appendChild(nementry) emane_node.setnemid(netif, nemid) macstr = self._hwaddr_prefix + ":00:00:" macstr += "%02X:%02X" % ((nemid >> 8) & 0xFF, nemid & 0xFF) netif.sethwaddr(MacAddress.from_string(macstr)) nemid += 1 for key in sorted(platformxmls.keys()): if key == "host": self.xmlwrite(platformxmls["host"], "platform.xml") continue self.xmlwrite(platformxmls[key], "platform%d.xml" % key)
def build_node_platform_xml(emane_manager, control_net, node, nem_id, platform_xmls): """ Create platform xml for a specific node. :param core.emane.emanemanager.EmaneManager emane_manager: emane manager with emane configurations :param core.netns.nodes.CtrlNet control_net: control net node for this emane network :param core.emane.nodes.EmaneNode node: node to write platform xml for :param int nem_id: nem id to use for interfaces for this node :param dict platform_xmls: stores platform xml elements to append nem entries to :return: the next nem id that can be used for creating platform xml files :rtype: int """ logging.debug("building emane platform xml for node(%s): %s", node, node.name) nem_entries = {} if node.model is None: logging.warn("warning: EmaneNode %s has no associated model", node.name) return nem_entries for netif in node.netifs(): # build nem xml nem_definition = nem_file_name(node.model, netif) nem_element = etree.Element("nem", id=str(nem_id), name=netif.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.object_id, netif, node.model.name) if is_external(config): nem_element.set("transport", "external") platform_endpoint = "platformendpoint" add_param(nem_element, platform_endpoint, config[platform_endpoint]) transport_endpoint = "transportendpoint" add_param(nem_element, transport_endpoint, config[transport_endpoint]) else: # build transport xml transport_type = netif.transport_type if not transport_type: logging.info("warning: %s interface type unsupported!", netif.name) transport_type = "raw" transport_file = transport_file_name(node.objid, transport_type) transport_element = etree.SubElement(nem_element, "transport", definition=transport_file) # add transport parameter add_param(transport_element, "device", netif.name) # add nem entry nem_entries[netif] = nem_element # merging code key = netif.node.objid if netif.transport_type == "raw": key = "host" otadev = control_net.brname eventdev = control_net.brname else: otadev = None eventdev = None platform_element = platform_xmls.get(key) if platform_element is None: platform_element = etree.Element("platform") if otadev: emane_manager.set_config("otamanagerdevice", otadev) if eventdev: emane_manager.set_config("eventservicedevice", eventdev) # append all platform options (except starting id) to doc for configuration in emane_manager.emane_config.emulator_config: name = configuration.id if name == "platform_id_start": continue value = emane_manager.get_config(name) add_param(platform_element, name, value) # add platform xml platform_xmls[key] = platform_element platform_element.append(nem_element) node.setnemid(netif, nem_id) macstr = _hwaddr_prefix + ":00:00:" macstr += "%02X:%02X" % ((nem_id >> 8) & 0xFF, nem_id & 0xFF) netif.sethwaddr(MacAddress.from_string(macstr)) # increment nem id nem_id += 1 for key in sorted(platform_xmls.keys()): if key == "host": file_name = "platform.xml" else: file_name = "platform%d.xml" % key platform_element = platform_xmls[key] doc_name = "platform" file_path = os.path.join(emane_manager.session.session_dir, file_name) create_file(platform_element, doc_name, file_path) return nem_id
def build_node_platform_xml(emane_manager, control_net, node, nem_id, platform_xmls): """ Create platform xml for a specific node. :param core.emane.emanemanager.EmaneManager emane_manager: emane manager with emane configurations :param core.netns.nodes.CtrlNet control_net: control net node for this emane network :param core.emane.nodes.EmaneNode node: node to write platform xml for :param int nem_id: nem id to use for interfaces for this node :param dict platform_xmls: stores platform xml elements to append nem entries to :return: the next nem id that can be used for creating platform xml files :rtype: int """ logger.debug("building emane platform xml for node(%s): %s", node, node.name) nem_entries = {} if node.model is None: logger.warn("warning: EmaneNode %s has no associated model", node.name) return nem_entries for netif in node.netifs(): # build nem xml nem_definition = nem_file_name(node.model, netif) nem_element = etree.Element("nem", id=str(nem_id), name=netif.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.object_id, netif, node.model.name) if is_external(config): nem_element.set("transport", "external") platform_endpoint = "platformendpoint" add_param(nem_element, platform_endpoint, config[platform_endpoint]) transport_endpoint = "transportendpoint" add_param(nem_element, transport_endpoint, config[transport_endpoint]) else: # build transport xml transport_type = netif.transport_type if not transport_type: logger.info("warning: %s interface type unsupported!", netif.name) transport_type = "raw" transport_file = transport_file_name(node.objid, transport_type) transport_element = etree.SubElement(nem_element, "transport", definition=transport_file) # add transport parameter add_param(transport_element, "device", netif.name) # add nem entry nem_entries[netif] = nem_element # merging code key = netif.node.objid if netif.transport_type == "raw": key = "host" otadev = control_net.brname eventdev = control_net.brname else: otadev = None eventdev = None platform_element = platform_xmls.get(key) if platform_element is None: platform_element = etree.Element("platform") if otadev: emane_manager.set_config("otamanagerdevice", otadev) if eventdev: emane_manager.set_config("eventservicedevice", eventdev) # append all platform options (except starting id) to doc for configuration in emane_manager.emane_config.emulator_config: name = configuration.id if name == "platform_id_start": continue value = emane_manager.get_config(name) add_param(platform_element, name, value) # add platform xml platform_xmls[key] = platform_element platform_element.append(nem_element) node.setnemid(netif, nem_id) macstr = _hwaddr_prefix + ":00:00:" macstr += "%02X:%02X" % ((nem_id >> 8) & 0xFF, nem_id & 0xFF) netif.sethwaddr(MacAddress.from_string(macstr)) # increment nem id nem_id += 1 for key in sorted(platform_xmls.keys()): if key == "host": file_name = "platform.xml" else: file_name = "platform%d.xml" % key platform_element = platform_xmls[key] doc_name = "platform" file_path = os.path.join(emane_manager.session.session_dir, file_name) create_file(platform_element, doc_name, file_path) return nem_id