Networking

了解 virt-install 如何將主機中的乙太網介面與任務中的乙太網介面連接起來?

  • April 28, 2019

我安裝 Debian 虛擬機virt-install的方式是讓來賓獲得一個名為的乙太網介面vnet0

$ virsh domiflist git-server
Interface  Type       Source     Model       MAC
-------------------------------------------------------
vnet0      bridge     br-ext     rtl8139     52:54:00:a8:32:d7

$ 

這可以在檢查qemu命令行時確認:

-netdev tap,fd=27,id=hostnet0 -device rtl8139,netdev=hostnet0,id=net0,mac=52:54:00:a8:32:d7,bus=pci.0,addr=0x2

但是,主機中有一個同名的 TAP 設備vnet0

$ ethtool -i vnet0                                                                                  
driver: tun
version: 1.6
firmware-version: 
expansion-rom-version: 
bus-info: tap
supports-statistics: no
supports-test: no
supports-eeprom-access: no
supports-register-dump: no
supports-priv-flags: no
$ 

..但具有不同的MAC地址:

$ ip l sh vnet0                                                                                     
56: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br-ext state UNKNOWN mode DEFAULT group default qlen 1000
   link/ether fe:54:00:a8:32:d7 brd ff:ff:ff:ff:ff:ff
$ 

虛擬機介面和主機中的 TAP 設備究竟是如何連接的?還是只有一台 TAP 設備?如果是,那麼 MAC 地址有何不同?

虛擬機介面和主機中的 TAP 設備究竟是如何連接的?

qemu(或啟動的包裝程序qemu或另一個模擬器)首先打開/dev/net/tun設備多路復用器。這將返回一個文件描述符,可以通過ioctl(TUNSETIFF)在欄位中使用 TAP 介面的名稱呼叫該 fd來將其附加到 TAP 介面ifreq->ifr.name

如果已以這種方式附加了具有該名稱的 TAP 介面,則該操作將失敗。

然後 fd 可用於寫入將出現在 TAP 介面上的數據包,就像從遠端端接收到的一樣,並讀取核心通過 TAP 介面路由的數據包。

如果呼叫程序具有CAP_NET_ADMIN能力(例如 is root),並且具有該名稱的 TAP 介面尚不存在,則會自動創建該介面。如果沒有給出名稱,將使用第一個空閒名稱。

作為多路復用器的事實/dev/net/tun意味著open()每次將句柄返回到不同的“遠端一半”時,它都會返回。而那個“遠端一半”可以連接到單個 TAP 介面。

此外,就像任何其他文件描述符一樣,如果該程序能夠以這種方式使用它(qemu與其-netdev tap,fd=FD選項一樣),則可以將其傳遞給另一個程序。

opentap在這個答案中查看一個非常簡單的函式範例。

更多細節 +核心文件中tuntap.txt中的範常式式碼。

還是只有一台 TAP 設備?如果是,那麼 MAC 地址有何不同?

不,每個客戶都有一個單獨的設備。將多個 TAP 設備連接到同一介面的方法是使用主機上的網橋。

但是,主機中有一個 TAP 設備具有相同的 vnet0 名稱 … ..但具有不同的 MAC 地址:

主機上的界面和來賓上的界面完全不同;把它想像成一條虛擬的 UTP 電纜——兩端的每個設備都有自己的 MAC。

設置來賓-device ...,mac=...上模擬設備的硬體地址,而不是主機上的 TAP 設備的硬體地址。

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