Qemu support rootless mode routing of network packets through the host using Slirp, you only need to give the right options to qemu to set this up, without having to tinker with tap interfaces or iptables.
However, using it for IPv6 can be a bit more challenging, especially since the documentation lacks IPv6 examples.
The Qemu options look like this -device virtio-net-pci,netdev=n0,mac=52:54:12:34:56:00 -netdev user,id=n0,ipv4=off,ipv6=on,ipv6-net=??. The only unknown is what to put for ipv6-net.
One would guess that using a Unique Local Address would work, but Qemu will only route packets out of the guest for IPs in the specified network.
The trick is to give ::/0 for the network, this way Qemu will route everything out of the guest.
Test
We download an Ubuntu cloud image, mask systemd-networkd-wait-online and change the root password with libguestfs1:
virt-customize -a jammy-server-cloudimg-amd64-disk-kvm.img --run-command 'systemctl mask systemd-networkd-wait-online.service'
virt-customize -a jammy-server-cloudimg-amd64-disk-kvm.img --root-password password:rootThen we run:
qemu-system-${HOSTTYPE} -m 2G -nographic -serial mon:stdio -nodefaults -enable-kvm -drive file=jammy-server-cloudimg-amd64-disk-kvm.img,format=qcow2 -device virtio-net-pci,netdev=n0,mac=52:54:12:34:56:00 -netdev user,id=n0,ipv4=off,ipv6=on,ipv6-net=::/0 # Press CTRL+a CTRL+x to quit qemuSetup network in guest:
root@ubuntu:~# ip link set ens2 up # Bring iface up
root@ubuntu:~# echo 'nameserver 2606:4700:4700::1111' > /etc/resolv.conf # use cloudflare DNSWe get an IPv6 and route are configured:
root@ubuntu:~# ip -6 --brief a # we get an ipv6
root@ubuntu:~# ip -6 r
Ping doesn't work2:
root@ubuntu:~# ping google.com
But curl does:
root@ubuntu:~# curl -v ifconfig.me
> GET / HTTP/1.1
> Host: ifconfig.me
> User-Agent: curl/7.81.0
> Accept: */*
>
After bringing up the iface, we get an ip on ::/0, we use cloudflare nameserver and can use curl to get our IPv6.
We end up with the host IPv6 because it goes trough Slirp.
Debug
You can also add -object filter-dump,id=d0,netdev=n0,file=dump.pcap to get a pcap file of the VM network.
That's all for today, have fun with IPv6. Despite my best efforts, I couldn't make cloud-init work. Maybe it could have its own blog post, but today we're only interested in the Qemu IPv6 Slirp stack. ↩ https://github.com/qemu/libslirp/blob/v4.7.0/src/ip6_icmp.c#L419. ↩