Linux

無需猜測即可獲取與 macvtap 關聯的 /dev/tapX

  • April 19, 2020

按照指南設置macvtap效果很好。

該指南的摘錄如下所示:

# ip link add link eth1 name macvtap0 type macvtap
# ip link set macvtap0 address 1a:46:0b:ca:bc:7b up
# ip link show macvtap0

然後該指南繼續解釋您可以執行以下操作:

#qemu-system-x86_64 -net nic,model=virtio,addr=1a:46:0b:ca:bc:7b -net tap,fd=3 3<>/dev/tap11

如果您macvtap最終使用/dev/tap11.

但是你如何檢查哪個/dev/tapX介面實際分配給了macvtap0上面?

我有很多服務在我的機器上隨機設置水龍頭設備。而且我無法猜測我的特定的最終是哪一個。

我希望通過以下方式啟動 qemu 機器:

   -netdev tap,ifname="macvtap0",id=network0,script=no,downscript=no \
   -device i82559b,netdev=network0,mac=${MAC}

macvtap0可以,我剛剛創建的設備在哪裡。

但是,這給了我:

qemu-system-x86_64: could not configure /dev/net/tun (macvtap0): Invalid argument

本文概述:如何找到tap介面與其文件描述符之間的聯繫?- 他們描述了一種通過訪問 PID 並檢查關聯的文件描述符來做到這一點的方法,對我來說,這裡的問題是 qemu 沒有設置設備,我是。並且沒有與之相關的PID。

Sow如何獲取與新創建的介面/dev關聯的文件句柄?macvtap

**編輯:**我已經解決了幾天這個問題,但我剛剛意識到我忘了檢查/sys/class/net/macvtap0/,並且有一個/tap2設備。顯然,我需要遍歷所有內容仍然找到匹配的名稱regex(tap[0-9]+)。這會起作用,但不確定這是最好/正確的方法。

設備名稱是根據介面索引創建的:

snprintf(tap_name, IFNAMSIZ, "tap%d", dev->ifindex);

$$ … $$

      devt = MKDEV(MAJOR(macvtap_major), vlantap->tap.minor);
      classdev = device_create(&macvtap_class, &dev->dev, devt,
                   dev, tap_name);

如果存在 OP 的ip link show macvtap0答案,它很可能會以:

11: macvtap0@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 [...]
$ echo /dev/tap$(cat /sys/class/net/macvtap0/ifindex)
/dev/tap11

如果您不想依賴似乎沒有正式記錄的這個特定屬性(整個樹中不存在macvtaplinux/Documentation/這個詞),您可以依賴於/sys(似乎也沒有為macvtap正式記錄):

這些資訊在macvtap/*子目錄中可用。請注意,這tap11是單個條目的符號連結macvtap/tap11,由於它在哪裡不切實際,所以應該忽略它(但不是它指向的目錄)。

  • 從網路介面名稱中找到設備節點條目名稱:

    1. /sys/class/net/macvtap0/macvtap/*有一個條目,即分接設備名稱,它是一個目錄:
    $ printf '/dev/%s\n' "$(basename /sys/class/net/macvtap0/macvtap/*)"
    /dev/tap11
    

    intf_to_devtap可以使用呼叫的函式:

    intf_to_devtap () {
        [ -e "/sys/class/net/$1/macvtap" ] || return 1
        printf '/dev/%s\n' "$(basename /sys/class/net/$1/macvtap/*)"
    }
    

    對於 OP 的情況:

    $ intf_to_devtap macvtap0
    /dev/tap11
    
    1. dev輸入主要:次要
    $ cat /sys/class/net/macvtap0/macvtap/*/dev
    242:1
    

    如果在多個網路命名空間中創建了macvtap ,每個命名空間具有相同的介面索引,則此屬性(以及下面的等效項uevent)是唯一保證唯一的,從而導致設備節點名稱衝突。衝突範例(之前沒有創建macvtap設備時):

    # ip netns add collision1; ip netns add collision2
    # ip -n collision1 link add type dummy; ip -n collision2 link add type dummy
    # ip -n collision1 link add link dummy0 type macvtap
    # ls -l /dev/tap*
    crw-------. 1 root root 242, 1 Apr 19 21:24 /dev/tap3
    # ip -n collision2 link add link dummy0 type macvtap
    # ls -l /dev/tap*
    crw-------. 1 root root 242, 1 Apr 19 21:24 /dev/tap3
    

    沒有出現第二個點擊條目。這是因為當第二個網路命名空間也創建了一個索引為 3 的介面(lo=1、dummy0=2、macvtap0=3)時發生了衝突,並且沒有創建第二個設備條目,/dev因為已經存在同名文件。同樣為了準確處理網路設備而ip netns重新/sys安裝,可以驗證實際上存在兩個分接設備,即使第二個沒有“映射”:

    # ip netns exec collision1 sh -c 'cat /sys/class/net/macvtap0/macvtap/*/dev'
    242:1
    # ip netns exec collision2 sh -c 'cat /sys/class/net/macvtap0/macvtap/*/dev'
    242:2
    

    因此,即使一半的資訊與此不匹配,仍然可以通過“映射”然後使用設備來使用第二個macvtap/sys介面後端,例如:

    # mknod /dev/tap3b c 242 2
    

    或使用更詳細的名稱,例如/dev/tap-VM1-intfA. 3. uevent條目,同時給出主要:次要和名稱:

    $ cat /sys/class/net/macvtap0/macvtap/*/uevent
    MAJOR=242
    MINOR=1
    DEVNAME=tap11
    
  • 開發條目到介面名稱:

/dev/tap11

/dev/tap11-> /sys/class/macvtap/tap11-> /sys/devices/virtual/net/macvtap0/macvtap/tap11。請注意,/sys/class/net/macvtap0before 實際上是指向/sys/devices/virtual/net/macvtap0.

還是在最後一個目錄下,device入口是介面目錄的符號連結,所以我們在最後/sys/class/macvtap/tap11/device->/sys/devices/virtual/net/macvtap0

devtap_to_intf可以使用呼叫的函式:

devtap_to_intf () {
   [ -c "$1" ] || [ -c "/dev/$1" ] || return 1
   local path="$(readlink -e "/sys/class/macvtap/${1#/dev/}/device")"
   printf '%s\n' "${path#/sys/devices/virtual/net/}"
}

對於OP的情況:

$ devtap_to_intf /dev/tap11
macvtap0

引用自:https://unix.stackexchange.com/questions/561201