def __init__(self, first_node, second_node): # first node and second are from InterNode type self.first_node = first_node self.first_interface = None self.second_node = second_node self.second_interface = None self.link_options = LinkOptions() self.is_in_CORE = False ## Flag gets set to true when the link is added to the actual underlying CORE session # This is useful later when adding new links from the API and having to update all of the physical connections. # Is used in the _set_up_physical_link method. # If either of the nodes is a physical node then set phyiscal flag of the node if (self.first_node.is_physical == True or self.second_node.is_physical == True): self.has_physical = True else: self.has_physical = False # Add each of the nodes to the others "neighbours" list first_node.neighbours.append(second_node) second_node.neighbours.append(first_node) ## create interface for FIRST node if (first_node.type == NodeTypes.RJ45): interface_data = InterfaceData(*[None] * 7) self.first_interface = interface_data elif (first_node.type == NodeTypes.SWITCH): self.first_interface = None second_node.has_switch_connection = True else: interface = Topology.prefixes.create_interface( first_node.CORE_node) self.first_interface = interface # Add interface to the nodes "interface" dictionary - This helps track which interface was used for which link first_node.interfaces[second_node] = self.first_interface # Repeat for SECOND node if (second_node.type == NodeTypes.RJ45): interface_data = InterfaceData(*[None] * 7) self.second_interface = interface_data elif (second_node.type == NodeTypes.SWITCH): first_node.has_switch_connection = True self.second_interface = None else: interface = Topology.prefixes.create_interface( second_node.CORE_node) self.second_interface = interface second_node.interfaces[first_node] = self.second_interface
def link_interface(interface_proto: core_pb2.Interface) -> InterfaceData: """ Create interface data from interface proto. :param interface_proto: interface proto :return: interface data """ interface = None if interface_proto: name = interface_proto.name if name == "": name = None mac = interface_proto.mac if mac == "": mac = None interface = InterfaceData( _id=interface_proto.id, name=name, mac=mac, ip4=interface_proto.ip4, ip4_mask=interface_proto.ip4mask, ip6=interface_proto.ip6, ip6_mask=interface_proto.ip6mask, ) return interface
def newnetif(self, net: CoreNetworkBase, interface: InterfaceData) -> int: """ This is called when linking with another node. Since this node represents an interface, we do not create another object here, but attach ourselves to the given network. :param net: new network instance :param interface: interface data for new interface :return: interface index :raises ValueError: when an interface has already been created, one max """ with self.lock: ifindex = interface.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 if net is not None: self.interface.attachnet(net) for addr in interface.get_addresses(): self.addaddr(addr) return ifindex
def link_interface(interface_proto): """ Create interface data from interface proto. :param core_pb2.Interface interface_proto: interface proto :return: interface data :rtype: InterfaceData """ interface = None if interface_proto: name = interface_proto.name if name == "": name = None mac = interface_proto.mac if mac == "": mac = None else: mac = MacAddress.from_string(mac) interface = InterfaceData( _id=interface_proto.id, name=name, mac=mac, ip4=interface_proto.ip4, ip4_mask=interface_proto.ip4mask, ip6=interface_proto.ip6, ip6_mask=interface_proto.ip6mask, ) return interface
def newnetif(self, net: "CoreNetworkBase", interface: InterfaceData) -> int: """ Create a new network interface. :param net: network to associate with :param interface: interface data for new interface :return: interface index """ addresses = interface.get_addresses() with self.lock: # TODO: emane specific code if net.is_emane is True: ifindex = self.newtuntap(interface.id, interface.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.mac) for address in addresses: netif.addaddr(address) return ifindex else: ifindex = self.newveth(interface.id, interface.name) self.attachnet(ifindex, net) if interface.mac: self.sethwaddr(ifindex, interface.mac) for address in addresses: self.addaddr(ifindex, address) self.ifup(ifindex) return ifindex
def create_CORE_interface(self): if (self.is_physical): ## create interface with empty InterfaceData interface = InterfaceData(*[None] * 7) else: interface = Topology.prefixes.create_interface(currentNode) return interface
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") return InterfaceData(interface_id, name, mac, ip4, ip4_mask, ip6, ip6_mask)
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 test_node_addaddr_exception(self, session): # given node = session.add_node(CoreNode) switch = session.add_node(SwitchNode) interface_data = InterfaceData() index = node.newnetif(switch, interface_data) node.netif(index) addr = "256.168.0.1/24" # when with pytest.raises(CoreError): node.addaddr(index, addr)
def test_node_sethwaddr_exception(self, session: Session): # given node = session.add_node(CoreNode) switch = session.add_node(SwitchNode) interface_data = InterfaceData() index = node.newnetif(switch, interface_data) node.netif(index) mac = "aa:aa:aa:ff:ff:fff" # when with pytest.raises(CoreError): node.sethwaddr(index, mac)
def test_node_addaddr(self, session: Session): # given node = session.add_node(CoreNode) switch = session.add_node(SwitchNode) interface_data = InterfaceData() index = node.newnetif(switch, interface_data) interface = node.netif(index) addr = "192.168.0.1/24" # when node.addaddr(index, addr) # then assert interface.addrlist[0] == addr
def test_node_sethwaddr(self, session: Session): # given node = session.add_node(CoreNode) switch = session.add_node(SwitchNode) interface_data = InterfaceData() index = node.newnetif(switch, interface_data) interface = node.netif(index) mac = "aa:aa:aa:ff:ff:ff" # when node.sethwaddr(index, mac) # then assert interface.hwaddr == mac
def newnetif(self, net: CoreNetworkBase, interface: InterfaceData) -> int: logging.info("creating interface") addresses = interface.get_addresses() ifindex = interface.id if ifindex is None: ifindex = self.newifindex() name = interface.name if name is None: name = f"gt{ifindex}" 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.mac, addresses) return ifindex 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.mac, addresses) return ifindex
def AddLink(self, request, context): logging.debug("add link: %s", request) session = self.get_session(request.session_id, context) # validate node exist self.get_node(session, request.link.node_one_id, context) self.get_node(session, request.link.node_two_id, context) node_one_id = request.link.node_one_id node_two_id = request.link.node_two_id interface_one = None interface_one_data = request.link.interface_one if interface_one_data: name = interface_one_data.name if name == "": name = None mac = interface_one_data.mac if mac == "": mac = None else: mac = MacAddress.from_string(mac) interface_one = InterfaceData( _id=interface_one_data.id, name=name, mac=mac, ip4=interface_one_data.ip4, ip4_mask=interface_one_data.ip4mask, ip6=interface_one_data.ip6, ip6_mask=interface_one_data.ip6mask, ) interface_two = None interface_two_data = request.link.interface_two if interface_two_data: name = interface_two_data.name if name == "": name = None mac = interface_two_data.mac if mac == "": mac = None else: mac = MacAddress.from_string(mac) interface_two = InterfaceData( _id=interface_two_data.id, name=name, mac=mac, ip4=interface_two_data.ip4, ip4_mask=interface_two_data.ip4mask, ip6=interface_two_data.ip6, ip6_mask=interface_two_data.ip6mask, ) link_type = None link_type_value = request.link.type if link_type_value is not None: link_type = LinkTypes(link_type_value) options_data = request.link.options link_options = LinkOptions(_type=link_type) if options_data: link_options.delay = options_data.delay link_options.bandwidth = options_data.bandwidth link_options.per = options_data.per link_options.dup = options_data.dup link_options.jitter = options_data.jitter link_options.mer = options_data.mer link_options.burst = options_data.burst link_options.mburst = options_data.mburst link_options.unidirectional = options_data.unidirectional link_options.key = options_data.key link_options.opaque = options_data.opaque session.add_link(node_one_id, node_two_id, interface_one, interface_two, link_options=link_options) return core_pb2.AddLinkResponse(result=True)