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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
    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
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
    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)
Ejemplo n.º 11
0
    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
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
 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
Ejemplo n.º 14
0
    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)