QEMU/KVM IPv6 Support

Overview
You have rented a whole server in a data centre somewhere and are running a few Kernel Virtual Machines (KVMs). Your provider gives you a single IPv4 address and a IPv6 /64 subnet. Its a nuisance to use IPv4 with non standard ports on the KVMs and you are too parsimonious to invest in more IPv4 addresses, its a hobby server after all. You get a single IPv4 address and a whole IPv6 /64 subnet, since your provider cannot give you any less.

Lets put the KVMs onto IPv6 so that they have global scope IPv6 addresses.

This guide is written around the use of libvirtd

Prerequsites

 * A working Gentoo host with IPv6 Support
 * One or more Gentoo KVM Guests with IPv6 Support
 * A IPv6 /64 prefix, like 2001:db8:dead:beef::/64
 * IPv6 working on the host

IPv6 support means USE="ipv6" in make.conf, kernel IPv6 support and packages like iproute2 installed. Other than iproute2, this is the Gentoo default.

Getting Started
on the hosts and KVM.

Do check that it is built with USE=ipv6. If emerge shows that its a rebuild, press n.

The Host Setup
Your KVM setup will have created an interface called virbr0.

The settings for this are stored in etc/libvirt/qemu/networks/default. You might want to backup this file before you start.

Edit virbr0
Stop the network, so you can edit the settings file. Don't even think of using $EDITOR

Add the following two lines above the existing closing tag.

Use your own /64 and make up your own prefix extension.

 

virsh net-edit will syntax check your edit and complain loudly if you mess up. This adds an IPv6 address to virbr0.

If you want to use DHCP for IPv6 in your KVMs, you probably don't, you can add a range statement here too. The range must be part of the prefix being assigned to virbr0

   Restart the network

Check virbr0
Notice that the interface virbr0 has aquired a /96 from your /64. That's as many IP addresses as there is in the entire IPv4 address space.

You also have a self assigned link local IP, where wwww:xxxx:yyyy:zzzz is related to the virbr0 MAC addr.

It's a really good idea not to use addresses from 2001:db8:dead:beef:fe::/96 outside of virbr0

IPv6 Address and Default Route
The KVM IPv6 setup is static. You could install a IPv6 aware DHCP client but they tend to support all the IPv6 auto configuration. I have not tested any in a KVM, so its left as an exercise for the reader.

Choose an IPv6 address in the 2001:db8:dead:beef:fe::/96 prefix but not 2001:db8:dead:beef:fe::2 which is virbr0. There are plenty to choose from, and use it in your config_eth0= statement as in the example below. You can still use dhcpcd for IPv4 if you wish.

The default route is a bit harder. Its the virbr0 link address. You can discover that with the ping all routers multicast.

In theory, you can use any router that responds. You should use virbr0 as its your next hop. That's the fe80::wwww:xxxx:yyyy:zzzz response.

When you are done restart eth0.

That should all work, test it.

Testing
For IPv4, test with

For IPv6, test with

That all looks good but its not quite working as it should.

Nameservers
You only have IPv4 name servers in /etc/resolv.conf. That may not matter, they will still return IPv6 addresses for host that have them. However, one day, (not soon) IPv4 will be switched off and your KVM will not be able to reach any nameservers.

/etc/resolv.conf can contain up to three IPv4 nameservers and three IPv6 nameservers. Copy over the IPv6 nameservers from the hosts /etc/resolv.conf or use some of the public IPv6 nameservers. Google has one.

Footnote for the Curious
The 2001:db8::/32 prefix is reserved for use in documentation, its not supposed to be routable. You won't find any of my hosts there.