Beispiel #1
0
 def new_iface(self, net: CoreNetworkBase,
               iface_data: InterfaceData) -> CoreInterface:
     logging.info("creating interface")
     ips = iface_data.get_ips()
     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{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.adopt_iface(remote_tap, iface_id, iface_data.mac, ips)
         return remote_tap
     else:
         # this is reached when configuring services (self.up=False)
         iface = GreTap(node=self,
                        name=name,
                        session=self.session,
                        start=False)
         self.adopt_iface(iface, iface_id, iface_data.mac, ips)
         return iface
Beispiel #2
0
    def new_iface(self, net: "CoreNetworkBase",
                  iface_data: InterfaceData) -> CoreInterface:
        """
        Create a new network interface.

        :param net: network to associate with
        :param iface_data: interface data for new interface
        :return: interface index
        """
        with self.lock:
            if net.has_custom_iface:
                return net.custom_iface(self, iface_data)
            else:
                iface_id = iface_data.id
                if iface_id is not None and iface_id in self.ifaces:
                    raise CoreError(
                        f"node({self.name}) already has interface({iface_id})")
                iface_id = self.newveth(iface_id, iface_data.name,
                                        iface_data.mtu)
                self.attachnet(iface_id, net)
                if iface_data.mac:
                    self.set_mac(iface_id, iface_data.mac)
                for ip in iface_data.get_ips():
                    self.add_ip(iface_id, ip)
                self.ifup(iface_id)
                return self.get_iface(iface_id)
Beispiel #3
0
    def new_iface(self, net: CoreNetworkBase,
                  iface_data: InterfaceData) -> CoreInterface:
        """
        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 iface_data: interface data for new interface
        :return: interface index
        :raises ValueError: when an interface has already been created, one max
        """
        with self.lock:
            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.iface.attachnet(net)
            for ip in iface_data.get_ips():
                self.add_ip(ip)
            return self.iface
Beispiel #4
0
    def test_node_set_mac_exception(self, session: Session, mac: str):
        # given
        node = session.add_node(CoreNode)
        switch = session.add_node(SwitchNode)
        iface_data = InterfaceData()
        iface = node.new_iface(switch, iface_data)

        # when
        with pytest.raises(CoreError):
            node.set_mac(iface.node_id, mac)
Beispiel #5
0
    def links(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
        """
        Build CORE API TLVs for a point-to-point link. One Link message
        describes this network.

        :param flags: message flags
        :return: list of link data
        """
        all_links = []
        if len(self.ifaces) != 2:
            return all_links
        ifaces = self.get_ifaces()
        iface1 = ifaces[0]
        iface2 = ifaces[1]
        unidirectional = 0 if iface1.local_options == iface2.local_options else 1
        iface1_data = iface1.get_data()
        iface2_data = iface2.get_data()
        link_data = LinkData(
            message_type=flags,
            type=self.linktype,
            node1_id=iface1.node.id,
            node2_id=iface2.node.id,
            iface1=iface1_data,
            iface2=iface2_data,
            options=iface1.local_options,
        )
        link_data.options.unidirectional = unidirectional
        all_links.append(link_data)
        # build a 2nd link message for the upstream link parameters
        # (swap if1 and if2)
        if unidirectional:
            link_data = LinkData(
                message_type=MessageFlags.NONE,
                type=self.linktype,
                node1_id=iface2.node.id,
                node2_id=iface1.node.id,
                iface1=InterfaceData(id=iface2_data.id),
                iface2=InterfaceData(id=iface1_data.id),
                options=iface2.local_options,
            )
            link_data.options.unidirectional = unidirectional
            all_links.append(link_data)
        return all_links
Beispiel #6
0
    def test_node_add_ip_exception(self, session):
        # given
        node = session.add_node(CoreNode)
        switch = session.add_node(SwitchNode)
        iface_data = InterfaceData()
        iface = node.new_iface(switch, iface_data)
        ip = "256.168.0.1/24"

        # when
        with pytest.raises(CoreError):
            node.add_ip(iface.node_id, ip)
Beispiel #7
0
    def test_node_set_mac(self, session: Session, mac: str, expected: str):
        # given
        node = session.add_node(CoreNode)
        switch = session.add_node(SwitchNode)
        iface_data = InterfaceData()
        iface = node.new_iface(switch, iface_data)

        # when
        node.set_mac(iface.node_id, mac)

        # then
        assert str(iface.mac) == expected
Beispiel #8
0
    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 iface_data: interface data for setting up tunnel key
        :return: nothing
        """
        self.grekey = key
        ips = iface_data.get_ips()
        if ips:
            self.add_ips(ips)
Beispiel #9
0
 def custom_iface(self, node: CoreNode, iface_data: InterfaceData) -> CoreInterface:
     # 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
     iface_id = node.newtuntap(iface_data.id, iface_data.name)
     node.attachnet(iface_id, self)
     iface = node.get_iface(iface_id)
     iface.set_mac(iface_data.mac)
     for ip in iface_data.get_ips():
         iface.add_ip(ip)
     if self.session.state == EventTypes.RUNTIME_STATE:
         self.session.emane.start_iface(self, iface)
     return iface
Beispiel #10
0
    def test_node_add_ip(self, session: Session, ip: str, expected: str,
                         is_ip6: bool):
        # given
        node = session.add_node(CoreNode)
        switch = session.add_node(SwitchNode)
        iface_data = InterfaceData()
        iface = node.new_iface(switch, iface_data)

        # when
        node.add_ip(iface.node_id, ip)

        # then
        if is_ip6:
            assert str(iface.get_ip6()) == expected
        else:
            assert str(iface.get_ip4()) == expected
Beispiel #11
0
def iface_to_data(iface: CoreInterface) -> InterfaceData:
    ip4 = iface.get_ip4()
    ip4_addr = str(ip4.ip) if ip4 else None
    ip4_mask = ip4.prefixlen if ip4 else None
    ip6 = iface.get_ip6()
    ip6_addr = str(ip6.ip) if ip6 else None
    ip6_mask = ip6.prefixlen if ip6 else None
    return InterfaceData(
        id=iface.node_id,
        name=iface.name,
        mac=str(iface.mac),
        ip4=ip4_addr,
        ip4_mask=ip4_mask,
        ip6=ip6_addr,
        ip6_mask=ip6_mask,
    )
Beispiel #12
0
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=iface_id,
        name=name,
        mac=mac,
        ip4=ip4,
        ip4_mask=ip4_mask,
        ip6=ip6,
        ip6_mask=ip6_mask,
    )
Beispiel #13
0
    def new_iface(self, net: "CoreNetworkBase",
                  iface_data: InterfaceData) -> CoreInterface:
        """
        Create a new network interface.

        :param net: network to associate with
        :param iface_data: interface data for new interface
        :return: interface index
        """
        with self.lock:
            if net.has_custom_iface:
                return net.custom_iface(self, iface_data)
            else:
                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 ip in iface_data.get_ips():
                    self.add_ip(iface_id, ip)
                self.ifup(iface_id)
                return self.get_iface(iface_id)
Beispiel #14
0
def link_iface(iface_proto: core_pb2.Interface) -> InterfaceData:
    """
    Create interface data from interface proto.

    :param iface_proto: interface proto
    :return: interface data
    """
    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=iface_proto.ip4_mask,
            ip6=ip6,
            ip6_mask=iface_proto.ip6_mask,
        )
    return iface_data
Beispiel #15
0
    def get_data(self) -> InterfaceData:
        """
        Retrieve the data representation of this interface.

        :return: interface data
        """
        if self.node:
            iface_id = self.node.get_iface_id(self)
        else:
            iface_id = self.othernet.get_iface_id(self)
        data = InterfaceData(id=iface_id,
                             name=self.name,
                             mac=str(self.mac) if self.mac else None)
        ip4 = self.get_ip4()
        if ip4:
            data.ip4 = str(ip4.ip)
            data.ip4_mask = ip4.prefixlen
        ip6 = self.get_ip6()
        if ip6:
            data.ip6 = str(ip6.ip)
            data.ip6_mask = ip6.prefixlen
        return data
Beispiel #16
0
    def links(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
        """
        Build CORE API TLVs for a point-to-point link. One Link message
        describes this network.

        :param flags: message flags
        :return: list of link data
        """
        all_links = []
        if len(self.ifaces) != 2:
            return all_links

        ifaces = self.get_ifaces()
        iface1 = ifaces[0]
        iface2 = ifaces[1]
        unidirectional = 0
        if iface1.getparams() != iface2.getparams():
            unidirectional = 1

        mac = str(iface1.mac) if iface1.mac else None
        iface1_data = InterfaceData(id=iface1.node.get_iface_id(iface1),
                                    name=iface1.name,
                                    mac=mac)
        ip4 = iface1.get_ip4()
        if ip4:
            iface1_data.ip4 = str(ip4.ip)
            iface1_data.ip4_mask = ip4.prefixlen
        ip6 = iface1.get_ip6()
        if ip6:
            iface1_data.ip6 = str(ip6.ip)
            iface1_data.ip6_mask = ip6.prefixlen

        mac = str(iface2.mac) if iface2.mac else None
        iface2_data = InterfaceData(id=iface2.node.get_iface_id(iface2),
                                    name=iface2.name,
                                    mac=mac)
        ip4 = iface2.get_ip4()
        if ip4:
            iface2_data.ip4 = str(ip4.ip)
            iface2_data.ip4_mask = ip4.prefixlen
        ip6 = iface2.get_ip6()
        if ip6:
            iface2_data.ip6 = str(ip6.ip)
            iface2_data.ip6_mask = ip6.prefixlen

        options_data = iface1.get_link_options(unidirectional)
        link_data = LinkData(
            message_type=flags,
            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,
                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
Beispiel #17
0
    def links(self, flags: MessageFlags = MessageFlags.NONE) -> List[LinkData]:
        """
        Build link data objects for this network. Each link object describes a link
        between this network and a node.

        :param flags: message type
        :return: list of link data
        """
        all_links = []

        # build a link message from this network node to each node having a
        # connected interface
        for iface in self.get_ifaces():
            uni = False
            linked_node = iface.node
            if linked_node is None:
                # two layer-2 switches/hubs linked together via linknet()
                if not iface.othernet:
                    continue
                linked_node = iface.othernet
                if linked_node.id == self.id:
                    continue
                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

            mac = str(iface.mac) if iface.mac else None
            iface2_data = InterfaceData(id=linked_node.get_iface_id(iface),
                                        name=iface.name,
                                        mac=mac)
            ip4 = iface.get_ip4()
            if ip4:
                iface2_data.ip4 = str(ip4.ip)
                iface2_data.ip4_mask = ip4.prefixlen
            ip6 = iface.get_ip6()
            if ip6:
                iface2_data.ip6 = str(ip6.ip)
                iface2_data.ip6_mask = ip6.prefixlen

            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,
                iface2=iface2_data,
                options=options_data,
            )
            all_links.append(link_data)

            if not uni:
                continue
            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,
                options=options_data,
            )
            iface.swapparams("_params_up")
            all_links.append(link_data)
        return all_links