Currently there is no IPv6 support in Basic Networking in CloudStack. It is all IPv4-only and with the depletion of IPv4 it's desirable that CloudStack supports IPv6 on all network types.
The goals for IPv6 in Basic Networking are:
This document only covers IPv6 connectivity for Instances. It does not cover:
The goal is Q1 2016 to have a working IPv6 implementation where Instances obtain a /128, but also get a subnet routed. A /56 for example.
The diagram below shows how this would work:
A few things are required for this to work:
When a Instance boots it sends out a Router Solicitation and it gets the information from both routers. This is done by the Network Stack of the Instance and is supported by all major Operating Systems.
Using SLAAC (Stateless Autoconfiguration) the host generates a IPv6 address based on its MAC address. As CloudStack we know what the address is going to be.
In CloudStack we configured the /64 we have on the Layer 2 network and since CloudStack also generates the MAC address we can calculate which IPv6 address the Instance gets.
RFC4862: https://tools.ietf.org/html/rfc4862
This is then programmed into the Security Groups. By default we allow:
ICMP is a essential part of IPv6. Blocking ICMP will break IPv6.
A route table on the Instance might look like this:
2a00:f10:101::/64 dev eth0 proto kernel metric 256 expires 2591994sec
fe80::/64 dev eth0 proto kernel metric 256
default via fe80::20c:dbff:fef9:cf00 dev eth0 proto ra metric 1024 expires 54sec hoplimit 64
default via fe80::212:f2ff:fe9c:3300 dev eth0 proto ra metric 1024 expires 46sec hoplimit 64
Here it has two default routes via both routers.
The Instance now has a single /128 address, but we also want to route a subnet to the Instance.
The Instance can now use a DHCPv6 Client to ask for prefix delegation. It does NOT need to request an address, it just needs a Prefix to be delegated to it.
An example dhcp6c.conf:
interface eth0 {
send ia-pd 1;
request domain-name-servers;
request domain-name;
};
This DHCPv6 request is picked up by the routers and relayed to the DHCPv6 server.
This DHCPv6 server then replies with a /56 (configured by us) out of the /40 routed to the routers (also configured in CloudStack).
The routers see this reply come back and add a route (pseudo) to their routing table:
$ ipv6 route add 2a00:f10:201:fa42:/56 fe80::5054:8fff:fe9f:af61
The reply is now relayed back to the Instance.
In CloudStack we pre configured a few things:
Under DHCPv4 you could identify a client based on it's MAC Address, but DHCPv6 uses DUUID: Definition of the UUID-Based DHCPv6 Unique Identifier (DUID-UUID)
RFC6355: https://tools.ietf.org/html/rfc6355
In this case we decide to use DUID-LL, which is identifying a client based on the Link-Layer address (MAC) of a client.
Since CloudStack is under control of generating the MAC address of the Instance we can also calculate the DUID-LL in advance and program that into the DHCPv6 server's database.
It is however up to the client to send the proper DUID! Unknown DUIDs coming it should not get a reply.
When an Instance is deployed we pick a new /56 from the /40 and record that in the database of the DHCPv6 server.
We also allow this /56 in the Security Group of the Instance (ip6tables on the hypervisor).
Now, when the client sends the proper DUID-LL it obtains a reply with a prefix. The prefix is also added to the routing tables of the routers.
The prefix is now usable on the Instance.