I'm recently trying to load XDP program inside a QEMU VM (with virtio-net-pci
as NIC driver, and tap device as the backend). It seems that by doing so my NIC is required to features vCPU*2 of queues, which can be done by declaring it at QEMU startup command (... -netdev tap,queues=<N> ...
). If I didn't declare the NIC with enough amount of the queues and trying to load the XDP program, I get the following kernel message and error:
[ 8.663795] virtio_net virtio0 eth0: request 2 queues but max is 1
RTNETLINK answers: Cannot allocate memory
This is totally not a problem so far, though idk why this is required (I've successfully load the same XDP program on my host machine, which has only single queue).
But my goal is have QEMU to use my custom tap device, which has connected to a bridge on the host. Instead of letting QEMU to create a new one for me.
In order to use the custom tap device, I start the VM with following command:
sudo qemu-system-x86_64 -hda output/images/node_rootfs.ext2 -enable-kvm -echr 2 --nographic \
-netdev tap,script=no,downscript=no,id=xcxc,ifname=tap0,queues=4 -device virtio-net-pci,netdev=xcxc,mq=on \
-cpu host \
-smp 2 \
-m 512 \
-kernel output/images/bzImage -append "root=/dev/sda rw nokaslr"
where tap0
is the so called custom tap device.
The above QEMU command won't start the VM, and the error message is:
qemu-system-x86_64: could not configure /dev/net/tun (tap0): Invalid argument
By removing the option ifname=tap0
or queues=4
, it boots properly.
It seems that it's telling me I can't declare a NIC with multi-queue and a bridged tap device at the same time. But what is awkward is that I need the XDP program executing on the bridged tap device.
Does anyone have idea why a bridged tap device can't live with multi-queue enabled NIC?
P.S. kernel version: 5.4.33
QEMU version: 4.2.0 (Debian 1:4.2-3ubuntu6.2)
Thank you for reading my question!
Turns out QEMU doesn't allow specifying
ifname
in the option directly. Instead, this should be done with the script (optionscript=/path/to/script
anddownscript=/path/to/script
).IOW, the tap device should be configured within the script, instead of creating one manually and pass it with option
ifname
.