def addNetns(ipr, network_id, vlan, mtu):
    #Create the namespace
    pyroute_utils.createNetNS("net-{}".format(network_id))
    ns = pyroute_utils.getNetNS("net-{}".format(network_id))

    #Create the LXB
    pyroute_utils.createLink(ns, 'lxb', 'bridge')
    pyroute_utils.createLink(ns,
                             'lxb.{}'.format(vlan),
                             "vlan",
                             link='lxb',
                             vlan_id=vlan)

    #Set the OVS port in the namespace
    idx_in = pyroute_utils.setNetNS(
        ipr,
        "net-{}".format(network_id),
        interfaceName=pyroute_utils.IN_PORT_ROOT.format(network_id))
    idx_out = pyroute_utils.setNetNS(
        ipr,
        "net-{}".format(network_id),
        interfaceName=pyroute_utils.OUT_PORT_ROOT.format(network_id))

    #Add them to the bridge
    pyroute_utils.addIfBr(ns, ifIdx=idx_in, brName='lxb')[1]
    idx_lxb = pyroute_utils.addIfBr(ns, ifIdx=idx_out, brName='lxb')[1]

    #Set the MTU
    pyroute_utils.setMtu(ns, pyroute_utils.IN_PORT_ROOT.format(network_id),
                         mtu)
    pyroute_utils.setMtu(ns, pyroute_utils.OUT_PORT_ROOT.format(network_id),
                         mtu)
    pyroute_utils.setMtu(ns, 'lxb', mtu)
    pyroute_utils.setMtu(ns, 'lxb.{}'.format(network_id), mtu)

    #Set everything up
    pyroute_utils.setUp(ns, idx=idx_in)
    pyroute_utils.setUp(ns, idx=idx_out)
    pyroute_utils.setUp(ns, idx=idx_lxb)
    ns.close()

    #TODO make sure netns use of libc does not create issue with aiohttp or aioamqp
    with netns.NetNS("net-{}".format(network_id)):
        iptables.addRules(iptables.defInputOutputDrop())
        iptables.addRules(iptables.defNoTrack())
        utils.execute("sysctl -w net.ipv6.conf.lxb.disable_ipv6=1")
        utils.execute(
            "sysctl -w net.ipv6.conf.lxb/{}.disable_ipv6=1".format(vlan))

    return
Exemplo n.º 2
0
    def del_proxy(self, **kwargs):
        if kwargs["peer_vni"] not in self.proxies:
            raise ValueError("MPTCP proxy not found")
        proxy = self.proxies[kwargs["peer_vni"]]

        #Delete the network infrastructure
        self.del_proxy_wan(proxy)
        self.del_proxy_lan(proxy)

        #del the flows for this proxy
        self.of_manager.del_proxy(proxy.ovs_port_id, proxy.peer_vni)

        #Delete the namespace
        netns_name = "mptcp-{}".format(proxy.peer_vni)
        netns = pyroute_utils.getNetNS(netns_name)
        netns.close()
        netns.remove()

        del self.proxies[kwargs["peer_vni"]]

        proxy.nsp_redir.terminate()
        proxy.nsp_redir.kill()
        proxy.nsp_server.terminate()
        proxy.nsp_server.kill()
Exemplo n.º 3
0
    def add_proxy_lan(self, proxy):
        if_name = "mptcp{}".format(proxy.peer_vni)
        netns_name = "mptcp-{}".format(proxy.peer_vni)
        netns = pyroute_utils.getNetNS(netns_name)

        #Create the ovs internal port
        #Need to always recreate it because if the port was in a namespace,
        # and the namespace was deleted, the port will exist in OVS, not in
        # the root namespace.
        self.ovs_manager.add_internal_port(self.ovs_manager.dp_mptcp,
                                           if_name,
                                           vlan=proxy.peer_vni,
                                           recreate=True)
        proxy.ovs_port_id = self.ovs_manager.find_port(if_name)

        #put it in the namespace
        ns_if_idx = pyroute_utils.setNetNS(self.ipr,
                                           netns_name,
                                           interfaceName=if_name)
        pyroute_utils.setUp(netns, idx=ns_if_idx)

        #Set the address on the lan side
        proxy.int_address = self.get_next_addr_int()
        address = proxy.int_address.exploded
        pyroute_utils.add_address(netns, ns_if_idx, address,
                                  self.internal_netmask)

        #Find the mac address
        proxy.int_mac_address = pyroute_utils.getInterfaceMac(netns, ns_if_idx)
        if not proxy.int_mac_address:
            raise ValueError("Unable to find the mac address")

        #Set a rule so that traffic from the IP goes to a separate table
        pyroute_utils.add_rule(netns,
                               table=proxy.routing_table_id,
                               src=address)

        #Add the link route and the default route
        pyroute_utils.add_route(
            netns,
            dst=self.internal_net.with_prefixlen,
            proto="static",
            scope="link",
            prefsrc=address,
            table=proxy.routing_table_id,
            oif=ns_if_idx,
        )
        pyroute_utils.add_route(netns,
                                gateway=self.internal_gateway.exploded,
                                table=proxy.routing_table_id)

        #Set the static arp entry for the fake gateway on lan
        utils.execute("ip netns exec {} arp -s {} E1:8E:36:8C:F6:0D".format(
            netns_name, self.internal_gateway.exploded))
        proxy.routing_table_id += 1

        #add the TCP redirect
        with NetNS(netns_name):
            iptables.addRules(
                iptables.def_REDIRECT(if_name, proxy.self_port_lan))
        netns.close()
Exemplo n.º 4
0
    def add_proxy_wan(self, proxy):
        default = False

        #For each public interface of the host, create a pair of veth and
        # configure the routing properly
        for external_interface in self.networks:
            mptcp_net = self.networks[external_interface]

            veth_name = "mptcp{}s{}".format(proxy.peer_vni, external_interface)
            veth_ns_name = "mptcp{}n{}".format(proxy.peer_vni,
                                               external_interface)
            netns_name = "mptcp-{}".format(proxy.peer_vni)
            netns = pyroute_utils.getNetNS(netns_name)

            #Try to delete existing link to remove unknown configs
            try:
                idx = pyroute_utils.getLink(self.ipr, veth_name)
                pyroute_utils.delLink(self.ipr, idx=idx)
            except:
                pass
            #Create the veth pair
            if_idx = pyroute_utils.createLink(self.ipr,
                                              veth_name,
                                              "veth",
                                              peerName=veth_ns_name)
            #put it in the namespace
            ns_if_idx = pyroute_utils.setNetNS(self.ipr,
                                               netns_name,
                                               interfaceName=veth_ns_name)
            pyroute_utils.setUp(netns, idx=ns_if_idx)
            pyroute_utils.setUp(self.ipr, idx=if_idx)

            #Get the IP address and configure it
            proxy.ext_addresses[mptcp_net.name] = mptcp_net.get_next_addr()
            address = proxy.ext_addresses[mptcp_net.name].exploded
            pyroute_utils.add_address(netns, ns_if_idx, address,
                                      mptcp_net.net_mask)

            #If that was the first address, use it as default route
            if not default:
                pyroute_utils.add_route(netns,
                                        gateway=mptcp_net.gateway.exploded)
                default = True

            #Set a rule so that traffic from that IP goes to a separate table
            pyroute_utils.add_rule(netns,
                                   table=proxy.routing_table_id,
                                   src=address)

            #Add the link route and the default route
            pyroute_utils.add_route(
                netns,
                dst=mptcp_net.network.with_prefixlen,
                proto="static",
                scope="link",
                prefsrc=address,
                table=proxy.routing_table_id,
                oif=ns_if_idx,
            )
            pyroute_utils.add_route(netns,
                                    gateway=mptcp_net.gateway.exploded,
                                    table=proxy.routing_table_id)
            proxy.routing_table_id += 1

            #Connect the other side of the veth
            pyroute_utils.setUp(self.ipr, idx=mptcp_net.bridge_idx)
            pyroute_utils.addIfBr(self.ipr,
                                  ifIdx=if_idx,
                                  brIdx=mptcp_net.bridge_idx)

            if mptcp_net.nated:
                # add the iptables DNAT rule on ext interface
                iptables.addRules(
                    iptables.def_DNAT(external_interface, proxy.self_port_wan,
                                      address, proxy.self_port_wan))

                #Create a dummy with the address to trick the mptcp stack
                dum_name = "dum{}".format(external_interface)
                dum_idx = pyroute_utils.createLink(
                    netns,
                    dum_name,
                    type="dummy",
                )

                #Set the address
                pyroute_utils.setUp(netns, idx=dum_idx)
                pyroute_utils.flush_addresses(netns, dum_idx)
                pyroute_utils.add_address(netns, dum_idx,
                                          mptcp_net.external_ip.exploded, 32)

            netns.close()
def removeNetns(network_id):
    ns = pyroute_utils.getNetNS("net-{}".format(network_id))
    pyroute_utils.delNetNS(ns)
    logging.debug("Network {} namespace removed".format(network_id))