Until now I just used qemus user space networking backend (SLIRP) because it's pretty simple to configure and I only needed it for tiny downloads and stuff. But now I want to have a VM that should have performant networking that I want to tunnel via wireguard.
I believe for this I need to set up a TAP device.
ip tuntap add dev vm0 mode tap user vm group kvm multi_queue
ip link set dev vm0 up
ip addr add dev vm0 10.0.0.1/24
And I have to tell qemu to use this device instead of SLIRP.
-netdev tap,id=netdev0,ifname=vm0,script=no,downscript=no,queues=5
-device virtio-net-pci,netdev=netdev0,vectors=12
I use multi_queue for performance and the number of vectors in the virtio-net-pci device should be (N*2)+2 when N is the number of queues.[1]
[1] https://www.linux-kvm.org/page/Multiqueue#Enable_MQ_feature
On the VM I set the network device to manual IP with 10.0.0.2/24 and gateway at 10.0.0.1.
I have my wireguard set up to put its routing to routing table 10 so I also add a rule for everything coming from vm0 to use that routing table.
ip rule add iif vm0 lookup 10
After setting up NAT I now have my VM communicate with the internet via wireguard and a tap device and better performance.