python pyroute2 将 WiFi 接口移至网络命名空间

问题描述 投票:0回答:1

我想使用 python pyroute2 在 Linux 上发现 USB WiFi 加密狗并将其移动到网络命名空间中。

我可以使用以太网接口来做到这一点,但我知道如果它是 wifi 接口,我必须使用 PHY 通过 pyroute2 来移动它。我检查了文档,但没有看到如何执行此操作的示例。

以下是我到目前为止所拥有的。如何使用 pyroute2 将我的 USB WiFi 适配器移至网络命名空间?

# Inspect networking interfaces
import netifaces

# Setup netowrking namespaces
from pyroute2 import NetNS, NSPopen, netns, IPDB
from pyroute2 import IW
from pyroute2 import IPRoute
from pyroute2.netlink import NetlinkError

# Get a list of all the network interfaces
interfaces = netifaces.interfaces()

# Manage interfaces
ipdb = IPDB()

# Loop over all the interfaces and print their details
for iface in interfaces:
    iface_details = netifaces.ifaddresses(iface)
    if iface.find("wlxc") >= 0:

        print(f"Found USB Wi-Fi interface: {iface} with details: {iface_details}")

        # Truncate the long name
        truncated_name = iface[-8:-1]

        # Create a networking namespace
        ipdb_netns = IPDB(nl=NetNS(truncated_name))

        # Command to run
        program_command = ["ifconfig"]

        # Get the interface
        print(f"Truncated name is: {truncated_name}")
        link_iface = ipdb.interfaces[iface]
        print(f"Link interface: {link_iface} ...")

        # Look for the wireless index
        ip = IPRoute()
        iw = IW()
        index = ip.link_lookup(ifname=iface)[0]
        try:
            wifi_if = iw.get_interface_by_ifindex(index)
            print(f"Wireless interface: {wifi_if}")

            with ipdb.interfaces[iface] as if_to_move:
                print(f"Moving interface: {if_to_move} to: {truncated_name}")
                if_to_move.net_ns_fd = truncated_name
            print(f"Done moving to: {truncated_name} ...")
        except NetlinkError as e:
            if e.code == 19:  # 19 'No such device'
                print("not a wireless interface")
        finally:
            iw.close()
            ip.close()

错误:

Found USB Wi-Fi interface: wlxc87f548d9633 with details: {17: [{'addr': 'c8:7f:54:8d:96:33', 'broadcast': 'ff:ff:ff:ff:ff:ff'}]}
Truncated name is: 548d963
Link interface: {'address': 'c8:7f:54:8d:96:33', 'broadcast': 'ff:ff:ff:ff:ff:ff', 'ifname': 'wlxc87f548d9633', 'mtu': 1500, 'qdisc': 'noqueue', 'txqlen': 1000, 'operstate': 'DOWN', 'linkmode': 1, 'group': 0, 'promiscuity': 0, 'num_tx_queues': 1, 'num_rx_queues': 1, 'carrier': 0, 'carrier_changes': 1, 'proto_down': 0, 'gso_max_segs': 65535, 'gso_max_size': 65536, 'xdp': {'attrs': [('IFLA_XDP_ATTACHED', None)]}, 'carrier_up_count': 0, 'carrier_down_count': 1, 'min_mtu': 256, 'max_mtu': 2304, 'perm_address': 'c8:7f:54:8d:96:33', 'parent_dev_name': '3-3:1.0', 'parent_dev_bus_name': 'usb', 'index': 10, 'flags': 4099, 'ipdb_scope': 'system', 'ipdb_priority': 0, 'vlans': (), 'ipaddr': (), 'ports': (), 'family': 0, 'ifi_type': 1, 'state': 'up', 'neighbours': ()} ...
Wireless interface: ({'cmd': 7, 'version': 1, 'reserved': 0, 'attrs': [('NL80211_ATTR_IFINDEX', 10), ('NL80211_ATTR_IFNAME', 'wlxc87f548d9633'), ('NL80211_ATTR_WIPHY', 1), ('NL80211_ATTR_IFTYPE', 2), ('NL80211_ATTR_WDEV', 4294967297), ('NL80211_ATTR_MAC', 'c8:7f:54:8d:96:33'), ('NL80211_ATTR_GENERATION', 17), ('NL80211_ATTR_4ADDR', '00'), ('NL80211_ATTR_WIPHY_TX_POWER_LEVEL', 1600), ('NL80211_ATTR_TXQ_STATS', '08:00:01:00:00:00:00:00:08:00:02:00:00:00:00:00:08:00:03:00:00:00:00:00:08:00:04:00:00:00:00:00:08:00:05:00:00:00:00:00:08:00:06:00:00:00:00:00:08:00:08:00:00:00:00:00:08:00:09:00:00:00:00:00:08:00:0a:00:00:00:00:00')], 'header': {'length': 188, 'type': 34, 'flags': 0, 'sequence_number': 255, 'pid': 14840, 'error': None, 'target': 'localhost', 'stats': Stats(qsize=0, delta=0, delay=0)}, 'event': 'NL80211_CMD_NEW_INTERFACE'},)
Moving interface: {'address': 'c8:7f:54:8d:96:33', 'broadcast': 'ff:ff:ff:ff:ff:ff', 'ifname': 'wlxc87f548d9633', 'mtu': 1500, 'qdisc': 'noqueue', 'txqlen': 1000, 'operstate': 'DOWN', 'linkmode': 1, 'group': 0, 'promiscuity': 0, 'num_tx_queues': 1, 'num_rx_queues': 1, 'carrier': 0, 'carrier_changes': 1, 'proto_down': 0, 'gso_max_segs': 65535, 'gso_max_size': 65536, 'xdp': {'attrs': [('IFLA_XDP_ATTACHED', None)]}, 'carrier_up_count': 0, 'carrier_down_count': 1, 'min_mtu': 256, 'max_mtu': 2304, 'perm_address': 'c8:7f:54:8d:96:33', 'parent_dev_name': '3-3:1.0', 'parent_dev_bus_name': 'usb', 'index': 10, 'flags': 4099, 'ipdb_scope': 'system', 'ipdb_priority': 0, 'vlans': (), 'ipaddr': (), 'ports': (), 'family': 0, 'ifi_type': 1, 'state': 'up', 'neighbours': ()} to: 548d963
fail <class 'NoneType'>
fail <class 'NoneType'>
python python-3.x linux namespaces pyroute2
1个回答
0
投票

您正在使用

IPDB(nl=NetNS(truncated_name))
创建一个新的网络命名空间,然后尝试使用
with ipdb.interfaces[iface] as if_to_move:
上下文管理器将接口移动到新的命名空间,但这似乎不起作用。
使用
if_to_move.net_ns_fd = truncated_name
,假设这会将接口移动到新的命名空间,可能适用于以太网接口。但由于 WiFi 接口与无线 PHY(物理层实体)相关,因此需要不同的处理。

您应该首先使用其

ifname
或索引来识别 WiFi 接口(例如,请参阅“如何使用 pyroute2 IPDB 函数从内核获取接口名称?”,还有 IPRoute 模块) .
然后创建一个新的网络命名空间或识别现有的网络命名空间。并将 WiFi 接口移至新的网络命名空间。

from pyroute2 import NetNS, IPDB, IW, IPRoute

# Get a list of all the network interfaces
interfaces = netifaces.interfaces()

# Create a new network namespace or identify an existing one
net_namespace = 'my_new_namespace'
netns.create(net_namespace)

# Managing network interfaces
with IPDB() as ipdb:
    for iface in interfaces:
        if iface.startswith("wl"):
            print(f"Found USB Wi-Fi interface: {iface}")
            
            # Get the interface index
            with IPRoute() as ip:
                index = ip.link_lookup(ifname=iface)[0]

            # Move the interface to the new network namespace
            with ipdb.interfaces[iface] as i:
                i.net_ns_fd = net_namespace
                print(f"Moved {iface} to {net_namespace}")

# Close IPDB
ipdb.release()

这应该将您的 USB WiFi 适配器移至指定的网络命名空间。

[ Updated Setup ]
┌──────────────┐       ┌───────────────────┐
│ USB WiFi     ├──────►│ New Namespace     │
│ Dongle       │       │ (my_new_namespace)│
└──────────────┘       └───────────────────┘

我没有创建新的命名空间作为 IPDB 实例的一部分,而是使用

netns.create(net_namespace)
显式创建或标识命名空间。这种方法更清晰,并且分离了命名空间创建和接口操作的关注点。

然后,我使用

with IPDB() as ipdb:
来管理接口,并使用
with ipdb.interfaces[iface] as i:
来处理要移动的接口(来自“将接口移动到命名空间”)。

© www.soinside.com 2019 - 2024. All rights reserved.