自動將物理網路介面移動到命名空間
我希望我係統上的所有物理介面都存在於稱為“物理”的特定網路命名空間中。
ip link set enp2s0 netns physical
使用和之類的命令手動移動設備很容易iw phy phy0 set netns name physical
,但我希望這在啟動時和執行時連接的任何設備上都自動發生。似乎實現這一點的最佳方法是通過 udev 規則,或者可能是一些 systemd 魔法。
我的第一個想法只是編寫一個執行適當命令的 udev 規則,但我遇到了幾個我無法通過搜尋回答的問題:
- 如何區分物理介面和虛擬介面?
- 如何區分 WLAN 介面以便發出
iw
命令而不是ip
命令?- 如何獲取 WLAN phy 的名稱以便將其傳遞給
iw
命令?我希望上述內容相對簡單,但我在
udevadm info
.
這些資訊中的大部分都可以從以下位置檢索
/sys
:1a。
/sys/class/net/
:網路設備列表,包括所有類型1b。
/sys/devices/virtual/net/
:虛擬網路設備列表:包括lo
,隧道,veth,網橋……所以如果它在前者但不是這個,它應該是物理的。
- 如果設備是現代無線設備(驅動程序),它將具有條目
/sys/class/net/<device>/phy82011/name
,例如:$ grep -s --with-filename '' /sys/class/net/*/phy80211/name /sys/class/net/wlan0/phy80211/name:phy0 /sys/class/net/wlan1/phy80211/name:phy1 /sys/class/net/wlan2/phy80211/name:phy2
因此,通過從環境中執行適當的腳本
udev
並與來自 的那些目錄和文件進行比較/sys
,您應該擁有執行此操作所需的所有資訊。順便說一句,如果以後要在這些設備上工作,您只需更改網路命名空間(例如using
nsenter --net=/var/run/netns/physical
),/sys
仍將位於主機的掛載命名空間中,並且不會反映這些設備的到來,而是會顯示它們失踪。使用ip netns exec physical command
很好,它確實會更改掛載命名空間並/sys
為您重新掛載。
根據 AB 的回答,我想出了以下規則:
SUBSYSTEM=="net", ACTION=="add", DEVPATH!="/devices/virtual/*", TAG+="systemd", ENV{SYSTEMD_WANTS}="physical-namespace@.service"
DEVPATH!="/devices/virtual/*
是只抓物理設備的關鍵。physical-namespace@.service
是將介面移動到所需命名空間 (physical
) 的一次性服務:[Unit] Description=Move interface to physical namespace Requires=netns@physical.service After=netns@physical.service [Service] Type=oneshot ExecStart=/usr/local/sbin/move-netif %I physical
(
netns@.service
只需創建給定名稱的網路命名空間。)最後,
move-netif
負責弄清楚如何移動界面:#!/bin/bash devpath="$1" target_ns="$2" if [[ -e "$devpath/phy80211" ]]; then phy="$(basename "$(readlink "$devpath/phy80211")")" iw phy "$phy" set netns name "$target_ns" else ifname="$(basename "$devpath")" ip link set "$ifname" netns "$target_ns" fi