2

I installed Debian virtual machine with virt-install in a way that guest got one Ethernet interface named vnet0:

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

$ 

This can be confirmed when inspecting the qemu command line:

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

However, there is a TAP device in host machine with the same vnet0 name:

$ 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
$ 

..but with different MAC address:

$ 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
$ 

How exactly are the virtual-machine interface and the TAP device in host machine connected? Or is there only one TAP device? If yes, then how are the MAC addresses different?

1 Answer 1

3
+200

How exactly are the virtual-machine interface and the TAP device in host machine connected?

qemu (or a wrapper program that starts qemu or another simulator) first opens the /dev/net/tun device multiplexer. That returns a file descriptor, which could be attached to a TAP interface by calling ioctl(TUNSETIFF) on that fd with the name of the TAP interface in the ifreq->ifr.name field.

That will fail if the TAP interface with that name was already attached in this manner.

The fd could be then used to write packets which will appear on the TAP interface as if received from the remote side, and read packets which were routed through the TAP interface by the kernel.

If the calling process has the CAP_NET_ADMIN capability (eg is root), and a TAP interface with that name does not already exist, it will be automatically created. If no name is given, the first free name will be used.

The fact that /dev/net/tun is a multiplexer means that an open() on it will return each time a handle to a different "remote half". And that "remote half" could be attached to a single TAP interface.

Also, just like any other file descriptor, that could be passed down to another program, if that program is able to use it in this way (as qemu is with its -netdev tap,fd=FD option).

See an example of a very simple opentap function in this answer.

More details + sample code in the tuntap.txt from the kernel documentation.

Or is there only one TAP device? If yes, then how are the MAC addresses different?

No, there is a separate device for each client. The way you could connect multiple TAP devices to the same interface is by using a bridge on the host.

However, there is a TAP device in host machine with the same vnet0 name ... ..but with different MAC address:

The interface on the host and that on the guest are completely different; think of it as of a virtual UTP cable -- with each device at both ends having its own MAC.

The -device ...,mac=... sets the hardware address of the emulated device on the guest, not of the TAP device on the host.

2
  • Thanks! So based on the output of my initial post, the quemu has created a tap interface named vnet0 and /dev/net/tun returned a file descriptor 27 for that vnet0 interface? And now the qemu connects the virtualized Ethernet adapter of guest with the vnet0 interface in host machine with -netdev tap,fd=27,id=hostnet0 command line option?
    – Martin
    Apr 28, 2019 at 17:24
  • 1
    No, the program that started qemu (virt-manager ?) opened /dev/net/tun, did all the necessary setup (connected it to vnet0, etc) and then passed the open file descriptor to qemu, telling it that the fd is 27 via the ,fd=27 option (processes inherit open fds through fork and exec). Then qemu implements the emulated interface in the guest by ultimately writing and reading raw ethernet frames to that 27 fd. That's just one way to do it -- qemu also knows how to interface to /dev/net/tun itself.
    – user313992
    Apr 28, 2019 at 17:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .