コード例 #1
0
    def activate_interface(self, interface):
        """
        moves the interface to the CNI netnt, rename it, set the IP address, and
        the GW.
        """

        _, netns = os.path.split(self.netns)
        iproute_ns = NetNS(netns)
        veth_index = get_iface_index(interface.veth.name, self.iproute)

        actived_idxs = iproute_ns.link_lookup(operstate="UP")
        if (veth_index in actived_idxs):
            return

        logger.info("Move interface {}/{} to netns {}".format(
            interface.veth.name, veth_index, netns))
        self.iproute.link('set', index=veth_index, net_ns_fd=netns)

        # configure and activate interfaces inside the netns
        iproute_ns.link('set', index=veth_index, ifname=self.interface)
        lo_idx = iproute_ns.link_lookup(ifname="lo")[0]
        iproute_ns.link('set', index=lo_idx, state='up')

        iproute_ns.link('set', index=veth_index, state='up')

        iproute_ns.addr('add',
                        index=veth_index,
                        address=interface.address.ip_address,
                        prefixlen=int(interface.address.ip_prefix))
        iproute_ns.route('add', gateway=interface.address.gateway_ip)

        # Disable TSO and checksum offload as xdp currently does not support
        logger.info("Disable tso for pod")
        cmd = "ip netns exec {} ethtool -K {} tso off gso off ufo off".format(
            netns, "eth0")
        rc, text = run_cmd(cmd)
        logger.info("Executed cmd {} tso rc: {} text {}".format(cmd, rc, text))
        logger.info("Disable rx tx offload for pod")
        cmd = "ip netns exec {} ethtool --offload {} rx off tx off".format(
            netns, "eth0")
        rc, text = run_cmd(cmd)
        logger.info("Executed cmd {} rc: {} text {}".format(cmd, rc, text))
コード例 #2
0
    def connect_nodes_to_switch(self):
        """
        This will create veth pairs for all links definid in the network config.
        Each veth will also be moved to the correct network namespace.
        """
        client_low = docker.APIClient()
        self.start_containers()

        ip = IPRoute()

        # Check if netns folder exists. If not, create one for netns to look intp
        if not os.path.exists("/var/run/netns"):
            os.mkdir("/var/run/netns")

        for link in self.network_config["links"]:
            device1 = link["device1"]
            device2 = link["device2"]
            pid_device1 = client_low.inspect_container(device1)["State"]["Pid"]
            pid_device2 = client_low.inspect_container(device2)["State"]["Pid"]

            # Interface names. Naming convention will be different dempending on connection type
            iface_device1 = ""
            iface_device2 = ""

            # If connectiong to switch. Make sure it is setup
            if link["type"] == "Node_to_Switch":
                switch_is_setup = os.path.exists(f"/proc/{pid_device2}/ns/net")
                # Wait until switch is setup
                max_wait_seconds = 10
                seconds_waited = 0
                while not switch_is_setup and seconds_waited <= max_wait_seconds:
                    switch_is_setup = os.path.exists(f"/proc/{pid_device2}/ns/net")
                    time.sleep(1)
                    seconds_waited += 1

                # Check if namespaces are addad. If not add simlinuk to namespace
                if not os.path.islink(f"/var/run/netns/{device1}"):
                    os.symlink(
                        f"/proc/{pid_device1}/ns/net",
                        f"/var/run/netns/{device1}",
                    )

                if not os.path.islink(f"/var/run/netns/{device2}"):
                    if not os.path.exists(f"/var/run/netns/{device2}"):
                        os.symlink(
                            f"/proc/{pid_device2}/ns/net",
                            f"/var/run/netns/{device2}",
                        )

                iface_device1 = f"{link['device1']}_{link['device1_port']}"
                iface_device2 = f"{link['device2']}_{link['device2_port']}"

                # Create Veth pair and put them in the right namespace
                ip.link("add", ifname=iface_device1, peer=iface_device2, kind="veth")

                id_node = ip.link_lookup(ifname=iface_device1)[0]
                ip.link("set", index=id_node, state="up")
                ip.link("set", index=id_node, net_ns_fd=link["device1"])

                id_switch = ip.link_lookup(ifname=iface_device2)[0]
                ip.link("set", index=id_switch, state="up")
                ip.link("set", index=id_switch, net_ns_fd=link["device2"])

                # Start all veth port in Nodes
                ns = NetNS(device1)
                ns.link("set", index=id_node, state="up")
                if "ipv4_addr" in self.network_config["nodes"][device1]:
                    ns.addr(
                        "add",
                        index=id_node,
                        address=self.network_config["nodes"][device1]["ipv4_addr"],
                        prefixlen=24,
                    )
                if "ipv6_addr" in link:
                    continue

            if link["type"] == "Switch_to_Switch":
                switch_is_setup1 = os.path.exists(f"/proc/{pid_device1}/ns/net")
                switch_is_setup2 = os.path.exists(f"/proc/{pid_device2}/ns/net")

                max_wait_seconds = 10
                seconds_waited = 0
                while not switch_is_setup1 and switch_is_setup2:
                    switch_is_setup1 = os.path.exists(f"/proc/{pid_device1}/ns/net")
                    switch_is_setup2 = os.path.exists(f"/proc/{pid_device2}/ns/net")
                    time.sleep(1)
                    seconds_waited += 1

                # Check if namespaces are addad. If not add simlink to namespace
                if not os.path.islink(f"/var/run/netns/{device1}"):
                    os.symlink(
                        f"/proc/{pid_device1}/ns/net",
                        f"/var/run/netns/{device1}",
                    )

                if not os.path.islink(f"/var/run/netns/{device2}"):
                    if not os.path.exists(f"/var/run/netns/{device2}"):
                        os.symlink(
                            f"/proc/{pid_device2}/ns/net",
                            f"/var/run/netns/{device2}",
                        )

                iface_switch1 = f"{link['device1']}_{link['device1_port']}"
                iface_switch2 = f"{link['device2']}_{link['device2_port']}"

                # Create Veth pair and put them in the right namespace
                ip.link("add", ifname=iface_switch1, peer=iface_switch2, kind="veth")
                id_switch1 = ip.link_lookup(ifname=iface_switch1)[0]
                ip.link("set", index=id_switch1, state="up")
                ip.link("set", index=id_switch1, net_ns_fd=link["device1"])

                id_switch2 = ip.link_lookup(ifname=iface_switch2)[0]
                ip.link("set", index=id_switch2, state="up")
                ip.link("set", index=id_switch2, net_ns_fd=link["device2"])

        # Start all veth in all the switches
        for switch in self.switches:
            ns = NetNS(switch.name)
            net_interfaces = ns.get_links()

            for interface in net_interfaces[2:]:
                iface_name = interface["attrs"][0][1]
                id_switch = ns.link_lookup(ifname=iface_name)[0]
                ns.link("set", index=id_switch, state="up")