The purpose of this page is to describe how the features and functionality available in OpenStack (using neutron networking) as of the Kilo release. It is intended to serve as a guide for how to deploy IPv6-enabled instances using OpenStack Networking. Where appropriate, features planned for Liberty or beyond may be described.
OpenStack Networking has supported IPv6 tenant subnets in certain configurations since Juno, but the Kilo release adds a number of new features, functionality and bug fixes to make it more robust. The focus of this page will be:
To enable a dual-stack network in OpenStack Networking simply requires creating a subnet with the ip_version field set to 6, then the IPv6 attributes (ipv6_ra_mode and ipv6_address_mode) set. The ipv6_ra_mode and ipv6_address_mode will be described in detail in the next section. Finally, the subnets cidr needs to be provided.
Things not in the scope of this document include:
As of Juno, the OpenStack Networking service (neutron) provides two new attributes to the subnet object, which allows users of the API to configure IPv6 subnets.
There are two IPv6 attributes:
These attributes can be set to the following values:
The attributes can also be left unset.
The ipv6_address_mode attribute is used to control how addressing is handled by OpenStack. There are a number of different ways that guest instances can obtain an IPv6 address, and this attribute exposes these choices to users of the Networking API.
The ipv6_ra_mode attribute is used to control router advertisements for a subnet.
The IPv6 Protocol uses Internet Control Message Protocol packets (ICMPv6) as a way to distribute information about networking. ICMPv6 packets with the type flag set to 134 are called “Router Advertisement” packets, which broadcasts information about the router and the route that can be used by guest instances to send network traffic.
The ipv6_ra_mode is used to specify if the Networking service should transmit ICMPv6 packets, for a subnet.
ipv6 ra mode | ipv6 address mode | radvd A,M,O | External Router A,M,O | Description |
---|---|---|---|---|
N/S | N/S | Off | Not Defined | Backwards compatibility with pre-Juno IPv6 behavior. |
N/S | slaac | Off | 1,0,0 | Guest instance obtains IPv6 address from non-OpenStack router using SLAAC. |
N/S | dhcpv6-stateful | Off | 0,1,1 | Not currently implemented in the reference implementation. |
N/S | dhcpv6-stateless | Off | 1,0,1 | Not currently implemented in the reference implementation. |
slaac | N/S | 1,0,0 | Off | Not currently implemented in the reference implementation. |
dhcpv6-stateful | N/S | 0,1,1 | Off | Not currently implemented in the reference implementation. |
dhcpv6-stateless | N/S | 1,0,1 | Off | Not currently implemented in the reference implementation. |
slaac | slaac | 1,0,0 | Off | Guest instance obtains IPv6 address from OpenStack managed radvd using SLAAC. |
dhcpv6-stateful | dhcpv6-stateful | 0,1,1 | Off | Guest instance obtains IPv6 address from dnsmasq using DHCPv6 stateful and optional info from dnsmasq using DHCPv6. |
dhcpv6-stateless | dhcpv6-stateless | 1,0,1 | Off | Guest instance obtains IPv6 address from OpenStack managed radvd using SLAAC and optional info from dnsmasq using DHCPv6. |
slaac | dhcpv6-stateful | Invalid combination. | ||
slaac | dhcpv6-stateless | Invalid combination. | ||
dhcpv6-stateful | slaac | Invalid combination. | ||
dhcpv6-stateful | dhcpv6-stateless | Invalid combination. | ||
dhcpv6-stateless | slaac | Invalid combination. | ||
dhcpv6-stateless | dhcpv6-stateful | Invalid combination. |
Both the Linux bridge and the Open vSwitch dataplane modules support forwarding IPv6 packets amongst the guests and router ports. Similar to IPv4, there is no special configuration or setup required to enable the dataplane to properly forward packets from the source to the destination using IPv6. Note that these dataplanes will forward Link-local Address (LLA) packets between hosts on the same network just fine without any participation or setup by OpenStack components after the ports are all connected and MAC addresses learned.
There are four methods for a subnet to get its cidr in OpenStack:
In the future, different techniques could be used to allocate subnets to tenants:
Note
That an external DHCPv6 server in theory could override the full address OpenStack assigns based on the EUI-64 address, but that would not be wise as it would not be consistent through the system.
IPv6 supports three different addressing schemes for address configuration and for providing optional network information.
OpenStack can be setup such that OpenStack Networking directly provides RA, DHCP relay and DHCPv6 address and optional information for their networks or this can be delegated to external routers and services based on the drivers that are in use. There are two neutron subnet attributes - ipv6_ra_mode and ipv6_address_mode – that determine how IPv6 addressing and network information is provided to tenant instances:
For the above two attributes to be effective, enable_dhcp must be set to True in file neutron.conf.
When using SLAAC, the currently supported combinations for ipv6_ra_mode and ipv6_address_mode are as follows.
ipv6_ra_mode | ipv6_address_mode | Result |
---|---|---|
Not specified. | SLAAC | Addresses are assigned using EUI-64, and an external router will be used for routing. |
SLAAC | SLAAC | Address are assigned using EUI-64, and OpenStack Networking provides routing. |
Setting ipv6_ra_mode to slaac will result in OpenStack Networking routers being configured to send RA packets, when they are created. This results in the following values set for the address configuration flags in the RA messages:
Neutron networks that contain a SLAAC enabled IPv6 subnet will result in all neutron ports attached to the network receiving IPv6 addresses. This is because when RA broadcast messages are sent out on a neutron network, they are received by all IPv6 capable ports on the network, and each port will then configure an IPv6 address based on the information contained in the RA packet. In some cases, an IPv6 SLAAC address will be added to a port, in addition to other IPv4 and IPv6 addresses that the port already has been assigned.
For DHCPv6-stateless, the currently supported combinations are as follows:
ipv6_ra_mode | ipv6_address_mode | Result |
---|---|---|
DHCPv6-stateless | DHCPv6-stateless | Address and optional information using neutron router and DHCP implementation respectively. |
DHCPv6-stateful | DHCPv6-stateful | Addresses and optional information are assigned using DHCPv6. |
Setting DHCPv6-stateless for ipv6_ra_mode configures the neutron router with radvd agent to send RAs. The table below captures the values set for the address configuration flags in the RA packet in this scenario. Similarly, setting DHCPv6-stateless for ipv6_address_mode configures neutron DHCP implementation to provide the additional network information.
The behavior of the neutron router for IPv6 is different than IPv4 in a few ways.
Internal router ports, that act as default gateway ports for a network, will share a common port for all IPv6 subnets associated with the network. This implies that there will be an IPv6 internal router interface with multiple IPv6 addresses from each of the IPv6 subnets associated with the network and a separate IPv4 internal router interface for the IPv4 subnet. On the other hand, external router ports are allowed to have a dual-stack configuration with both an IPv4 and an IPv6 address assigned to them.
Neutron tenant networks that are assigned Global Unicast Address (GUA) prefixes and addresses don’t require NAT on the neutron router external gateway port to access the outside world. As a consequence of the lack of NAT the external router port doesn’t require a GUA to send and receive to the external networks. This implies a GUA IPv6 subnet prefix is not necessarily needed for the neutron external network. By default, a IPv6 LLA associated with the external gateway port can be used for routing purposes. To handle this scenario, the implementation of router-gateway-set API in neutron has been modified so that an IPv6 subnet is not required for the external network that is associated with the neutron router. The LLA address of the upstream router can be learned in two ways.
Effectively the ipv6_gateway flag takes precedence over an RA that is received from the upstream router. If it is desired to use a GUA next hop that is accomplished by allocating a subnet to the external router port and assigning the upstream routers GUA address as the gateway for the subnet.
Note
That it should be possible for tenants to communicate with each other on an isolated network (a network without a router port) using LLA with little to no participation on the part of OpenStack. The authors of this section have not proven that to be true for all scenarios.
IPv6 does work when the Distributed Virtual Router functionality is enabled, but all ingress/egress traffic is via the centralized router (hence, not distributed). More work is required to fully enable this functionality.
VPNaaS supports IPv6, but support in Kilo and prior releases will have some bugs that may limit how it can be used. More thorough and complete testing and bug fixing is being done as part of the Liberty release. IPv6-based VPN as a service is configured similar to the IPv4 configuration. Either or both the peer_address and the peer_cidr can specified as an IPv6 address. The choice of addressing modes and router modes described above should not impact support.
TODO
FWaaS allows creation of IPv6 based rules.
At the current time OpenStack Networking does not provide any facility to support any flavor of NAT with IPv6. Unlike IPv4 there is no current embedded support for floating IPs with IPv6. It is assumed that the IPv6 addressing amongst the tenants are using GUAs with no overlap across the tenants.
OpenStack currently doesn’t support the privacy extensions defined by RFC 4941. The interface identifier and DUID used must be directly derived from the MAC as described in RFC 2373. The compute hosts must not be setup to utilize the privacy extensions when generating their interface identifier.
There is no provisions for an IPv6-based metadata service similar to what is provided for IPv4. In the case of dual stack Guests though it is always possible to use the IPv4 metadata service instead.
Unlike IPv4 the MTU of a given network can be conveyed in the RA messages sent by the router and not in the DHCP messages. In Kilo the MTU sent by RADVD is always 1500, but in Liberty changes are planned to allow the RA to send the proper MTU of the network.
As of the Kilo release, considerable effort has gone in to ensuring the tenant network can handle dual stack IPv6 and IPv4 transport across the variety of configurations describe above. This same level of scrutiny has not been apply to running the OpenStack control network in a dual stack configuration. Similarly, little scrutiny has gone into ensuring that the OpenStack API endpoints can be accessed via an IPv6 network. At this time, Open vSwitch (OVS) tunnel types - STT, VXLAN, GRE, only support IPv4 endpoints, not IPv6, so a full IPv6-only deployment is not possible with that technology.
From the Liberty release onwards, OpenStack Networking supports IPv6 prefix delegation. This section describes the configuration and workflow steps necessary to use IPv6 prefix delegation to provide automatic allocation of subnet CIDRs. This allows you as the OpenStack administrator to rely on an external (to the OpenStack Networking service) DHCPv6 server to manage your tenant network prefixes.
Note
Prefix delegation will be in the upcoming Liberty release, it is not available in the current OpenStack Kilo release. HA and DVR routers are not currently supported by this feature.
To enable prefix delegation, edit the etc/neutron.conf file:
default_ipv6_subnet_pool = prefix_delegation
Note
If you are not using the default dibbler-based driver for prefix delegation, then you also need to set the driver in etc/neutron.conf:
pd_dhcp_driver = <class path to driver>
Drivers other than the default one may require extra configuration, please refer to Extra configuration
This tells OpenStack Networking to use the prefix delegation mechanism for subnet allocation when the user does not provide a CIDR or subnet pool id when creating a subnet.
To use this feature, you need a prefix delegation capable DHCPv6 server that is reachable from your OpenStack Networking node(s). This could be software running on the OpenStack Networking node(s) or elsewhere, or a physical router. For the purposes of this guide we are using the open-source DHCPv6 server, Dibbler. Dibbler is available in many Linux package managers, or from source at https://github.com/tomaszmrugalski/dibbler.
When using the reference implementation of the OpenStack Networking prefix delegation driver, Dibbler must also be installed on your OpenStack Networking node(s) to serve as a DHCPv6 client. Version 1.0.1 or higher is required.
This guide assumes that you are running a Dibbler server on the network node where the external network bridge exists. If you already have a prefix delegation capable DHCPv6 server in place, then you can skip the following section.
After installing Dibbler, edit the /etc/dibbler/server.conf file:
script "/var/lib/dibbler/pd-server.sh"
iface "br-ex" {
pd-class {
pd-pool 2222:2222:2222::/48
pd-length 64
}
}
The options used in the configuration file above are:
To provide external network access to your instances, your Dibbler server also needs to create new routes for each delegated prefix. This is done using the script file named in the config file above. Edit the /var/lib/dibbler/pd-server.sh file:
if [ "$PREFIX1" != "" ]; then
if [ "$1" == "add" ]; then
sudo ip -6 route add ${PREFIX1}/64 via $REMOTE_ADDR dev $IFACE
fi
if [ "$1" == "delete" ]; then
sudo ip -6 route del ${PREFIX1}/64 via $REMOTE_ADDR dev $IFACE
fi
fi
The variables used in the script file above are:
The above is all you need in this scenario, but more information on installing, configuring, and running Dibbler is available in the Dibbler user guide, at http://klub.com.pl/dhcpv6/doc/dibbler-user.pdf.
To start your Dibbler server, run:
# dibbler-server run
Or to run in headless mode:
# dibbler-server start
When using DevStack, it is important to start your server after the stack.sh script has finished to ensure that the required network interfaces have been created.
First, create a network and IPv6 subnet:
$ neutron net-create ipv6-pd
Created a new network:
+-----------------+--------------------------------------+
| Field | Value |
+-----------------+--------------------------------------+
| admin_state_up | True |
| id | 31ef3e85-111f-4772-8172-8e4a404a7476 |
| mtu | 0 |
| name | ipv6-pd |
| router:external | False |
| shared | False |
| status | ACTIVE |
| subnets | |
| tenant_id | 28b39bcce66e4a648f82e2362b958b60 |
+-----------------+--------------------------------------+
$ neutron subnet-create ipv6-pd --name ipv6-pd-1 --ip_version 6 \
--ipv6_ra_mode slaac --ipv6_address_mode slaac
Created a new subnet:
+-------------------+--------------------------------------------------+
| Field | Value |
+-------------------+--------------------------------------------------+
| allocation_pools | {"start": "::2", "end": "::ffff:ffff:ffff:fffe"} |
| cidr | ::/64 |
| dns_nameservers | |
| enable_dhcp | True |
| gateway_ip | ::1 |
| host_routes | |
| id | ea139dcd-17a3-4f0a-8cca-dff8b4e03f8a |
| ip_version | 6 |
| ipv6_address_mode | slaac |
| ipv6_ra_mode | slaac |
| name | ipv6-pd-1 |
| network_id | 31ef3e85-111f-4772-8172-8e4a404a7476 |
| subnetpool_id | prefix_delegation |
| tenant_id | 28b39bcce66e4a648f82e2362b958b60 |
+-------------------+--------------------------------------------------+
The subnet is initially created with a temporary CIDR before one can be assigned by prefix delegation. Any number of subnets with this temporary CIDR can exist without raising an overlap error. The subnetpool_id is automatically set to prefix_delegation.
To trigger the prefix delegation process, create a router interface between this subnet and a router with an active interface on the external network:
$ neutron router-interface-add cb9b7a2c-0ffa-412f-989a-1e6c60e1c02f \
ea139dcd-17a3-4f0a-8cca-dff8b4e03f8a
Added interface a7e4d663-e3fc-4b8f-909f-865c397a930e to router
cb9b7a2c-0ffa-412f-989a-1e6c60e1c02f.
The prefix delegation mechanism then sends a request via the external network to your prefix delegation server, which replies with the delegated prefix. The subnet is then updated with the new prefix, including issuing new IP addresses to all ports:
$ neutron subnet-show ipv6-pd-1
+-------------------+-------------------------------------------------+
| Field | Value |
+-------------------+-------------------------------------------------+
| allocation_pools | {"start": "2222:2222:2222:6977::2", |
| | "end":"2222:2222:2222:6977:ffff:ffff:ffff:fffe"}|
| cidr | 2222:2222:2222:6977::/64 |
| dns_nameservers | |
| enable_dhcp | True |
| gateway_ip | 2222:2222:2222:6977::1 |
| host_routes | |
| id | ea139dcd-17a3-4f0a-8cca-dff8b4e03f8a |
| ip_version | 6 |
| ipv6_address_mode | slaac |
| ipv6_ra_mode | slaac |
| name | ipv6-pd-1 |
| network_id | 31ef3e85-111f-4772-8172-8e4a404a7476 |
| subnetpool_id | prefix_delegation |
| tenant_id | 28b39bcce66e4a648f82e2362b958b60 |
+-------------------+-------------------------------------------------+
If the prefix delegation server is configured to delegate globally routable prefixes and setup routes, then any instance with a port on this subnet should now have external network access.
Deleting the router interface causes the subnet to be reverted to the temporary CIDR, and all ports have their IPs updated. Prefix leases are released and renewed automatically as necessary.
The following link provides a great step by step tutorial on setting up IPv6 with OpenStack: http://www.debug-all.com/?p=52
To enable the driver for the dhcpv6_pd_agent, set pd_dhcp_driver to this in etc/neutron.conf:
pd_dhcp_driver = neutron_pd_agent
To allow the neutron-pd-agent to communicate with prefix delegation servers, you must set which network interface to use for external communication. In DevStack the default for this is br-ex:
pd_interface = br-ex
Once you have stacked run the command below to start the neutron-pd-agent:
neutron-pd-agent --config-file /etc/neutron/neutron.conf
Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.