IPv6 standards allow for multiple IPv6 prefixes and addresses to be associated with a given interface. This blueprint defines how multiple IPv6 prefixes and/or addresses per Neutron port will be supported in OpenStack, and describes how this differs from the IPv4 implementation.
Some possible use cases include:
Considerations for IPv6
There are some differences between IPv6 and IPv4 which need to be considered when deciding how multiple IPv6 prefixes and addresses should be configured and supported in Neutron, and how closely the IPv6 implementation will follow the IPv4 paradigm:
IPv6 addresses are more abundant. That means:
IPv6 provides two main mechanisms for assigning IP addresses:
With the current Neutron implementation, a subnet is configured for SLAAC vs. DHCPv6 stateful/stateless address mode when the subnet is created by setting the “ipv6_ra_mode” and “ipv6_address_mode” attributes in a subnet-create API call. These attributes were added with the blueprint listed in [Ref-5]. Attribute values are described in [Ref-7].
For the purposes of this design specification, the term “SLAAC-enabled” subnets will be used to refer to subnets that are configured for either SLAAC or DHCPv6-stateless address modes.
The important aspect of SLAAC addressing to consider here is that RA messages are multicast (on the all nodes multicast channel) to all IPv6-capable nodes on a link. What this means in an OpenStack instance is that whenever a subnet is created with SLAAC address generation mode, all IPv6-capable hosts/VMs which are created on that network will receive periodic RA messages which include the associated prefix for that subnet (along with prefixes for all other SLAAC-enabled subnets on that network). The host will therefore generate an address using that subnet/prefix, regardless of whether the associated port-create API calls (and any follow-up port-update API calls) for that VM happen to specify that the subnet should be associated with that port.
Theoretically, it would be possible to selectively enable/disable delivery of RA prefix assignments on a per-port, per-subnet basis by configuring radvd so that RA messages are delivered per subnet via unicast, but this implementation would be rather complex and would not scale well in a large network because of the added messaging and processing required, and would go against the automatic nature of SLAAC.
Port creation with explicit list of fixed IPs:
With the current Neutron implementation, when a port is created with an explicit list of fixed IPs, IPs from the following subnets on the associated network will be associated with the port:
What is missing is that SLAAC-enabled subnets are not implicitly included for association with the port, even though IPv6-enabled VMs will be automatically generating SLAAC addresses for those subnets based on RA messages that they receive.
Port creation without explicit list of fixed IPs:
With the current Neutron implementation, when a port is created without an explicit list of fixed IPs, IPs from the following subnets on the associated network are associated with the port:
What could be considered here is whether all DHCPv6-stateful subnets should also be implicitly included for allocation and association with the port (along with SLAAC-enabled subnets), since IPv6 addresses are more plentiful. However, this would be quite a shift from the IPv4 model, so it would be safer and less confusing to stay with the current implementation.
With the current Neutron implementation, when a port is updated, IPs from the following subnets on the associated network are associated with the port:
What’s arguably broken here is that any existing association with addresses from SLAAC-enabled subnets that are not explicitly included in the fixed_ips list of a port update request will be forgotten (deleted), even though the port will continue to use the SLAAC addresses as long as the source of IPv6 RA messages (radvd process) continues to send RA messages to all IPv6-enabled hosts via the all-nodes multicast channel.
Router interface create
Layer 3 (L3) agent limits the number of IP addresses that is initially associated with an internal router interface (gateway port) to a maximum of one IP address per family (i.e. up to one IPv4 address and up to one IPv6 address).
For externally-facing gateway ports, the number of IP addresses is further restricted to a single IP address, either IPv4 or IPv6 [Ref-1].
The change described in [Ref-1], which is currently abandoned, was an attempt to relax this restriction so that up to one IPv4 address and up to one IPv6 address would be allowed per external gateway port.
This blueprint will include the change described in [Ref-1], and will also relax the restrictions for internal router ports by allowing multiple IPv6 addresses per internal router port.
Port Create API Call
The definition/syntax of the Neutron port-create API request/response messages will not be changed for this blueprint. However, the way in which this API call will be used, and the way that Neutron handles this call when IPv6 subnets are included in the associated network, will represent a small shift from the IPv4 model. The change in behavior will revolve around the notion that if a network includes a SLAAC-enabled subnet, then all ports on the network will get an address from that subnet automatically. The changes can be summarized:
Port Update API Call
Similar to the port-create API call, the definition/syntax of the Neutron port-update API request/response messages will not change, but the way in which this API call is used and the way that Neutron handles these requests will change for IPv6 subnets/addresses. The change in behavior will revolve around the notion that if a network includes a SLAAC-enabled subnet, then all ports on the network will get an address from that subnet automatically. The following changes will apply:
Subnet Create API Call
When a SLAAC-enabled subnet is created after ports have already been created on a given network, and that subnet relies on a provider source for RA messages (as opposed to an OpenStack reference RADVD process; this is selected via “ipv6_ra_mode” and “ipv6_address_mode” attributes in the subnet-create API call), then the associated IPv6-capable hosts on the network will be expected to automatically generate SLAAC addresses based on prefixes advertised by the provider’s source of RA messages. In order to keep in sync with these generated addresses, the subnet create processing will need to be modified to add entries in the IPAllocations table for all existing ports on the network in order to associate the ports with addresses on the SLAAC-enabled subnet.
Limits on Number of IP Addresses per Router Interface
Externally-facing gateway ports: As discussed in the Problem Definition section, this blueprint will relax the restrictions imposed by the Neutron L3 agent on externally-facing gateway ports by allowing up to one IPv4 address and up to one IPv6 address per port.
Internal router ports: This blueprint will relax restrictions imposed on internal router ports by allowing multiple IPv6 addresses on each internal router port. For IPv4 subnets, no change will be made, that is, separate router interfaces will be required for each IPv4 subnet that requires a gateway IP address.
The handling for the router interface create API call will be changed so that IPv6 subnets on a given network will share one internal router port per router to which they are attached. That is, when the router interface create API is called for an IPv6 subnet, a check will be performed to see if there is already an internal router interface on that router that supports a gateway address for one of the other IPv6 subnets in the network. If so, the new IPv6 gateway IP address will be added to that existing interface, rather than having a new router interface created.
No data model changes are anticipated.
As discussed in earlier sections, the definition/syntax of the port-create, port-update, and subnet-delete API calls will not be changed, but the way in which these API calls are used and the way that Neutron handles these API calls will be modified for IPv6 subnets as compared to IPv4 subnets. In particular, ports will be automatically associated with addresses from all SLAAC-enabled subnets within the port’s network as part of port create and port update operations, and the port create and port update responses will automatically include those SLAAC addresses in the list of fixed_ips.
There may be some risk associated with opening up an OpenStack cloud to IPv6 RA messages (e.g. spoofed RA messages may modify the network), but this is a concern for basic SLAAC implementation, and not something that is being introduced with this blueprint.
No changes anticipated.
Nothing more than what was discussed in the “REST API Impact” section.
No significant performance impact expected.
Yes, this effects the Neutron reference IPv6 implementation.
Deployers will need to understand that IPv6 addresses will be automatically and implicitly generated on every port on a network for every SLAAC-enabled subnet in that network. This should not come as no surprise, since SLAAC is an autoconfiguration mechanism.
Developers of L3 services may need to incorporate some of the behavior changes proposed in the blueprint with respect to port creation when IPv6 subnets are involved to ensure that management plane behavior properly reflects the way that SLAAC works. The implementation for this blueprint will be incorporated into common framework database classes, so services that derive from these classes should automatically inherit this behavior.
This blueprint is a natural progression from the addition of RADVD and IPv6 SLAAC support to the Neutron reference design. It is an attempt to reconcile some inconsistencies between the way that IPv6 SLAAC works and what IP addresses are implicitly associated when a port is created without an explicit list of fixed IPs in the current design.
This has not been discussed on mailing lists, but the blueprint and associated patch set have been up for review since mid-Juno. This was added as an etherpad agenda item to discuss at the Atlanta summit during the IPv6 design session, but unfortunately the design session ended before we got to this item.
As an alternative to what is being proposed, it would be possible to avoid the automatic nature of RA prefix assignments by configuring radvd so that RA messages are delivered on a per-port, per-subnet basis via unicast. Ports that explicitly include a given SLAAC-enabled subnet would then be sent an RA unicast that includes an advertisement of that subnet, and ports that don’t explicitly include the SLAAC subnet would not receive an RA unicast (or would receive an RA that doesn’t include the subnet). However, this approach would be rather complex and error prone, and would go against the automatic nature of SLAAC. Also, this approach would not add much value given that IPv6 addresses can already be selectively assigned on a subnet by using DHCPv6-stateful.
Testing for API behavior will be incorporated into the Neutron in-tree API tests, so no out-of-tree Tempest API tests will be added.
A Tempest network scenario test will be added to check dataplane connectivity when multiple addresses per port are in use:
- Create an internal router port with 1 IPv4, 1 SLAAC, and 1 DHCPv6 subnet.
- Create an instance using all three subnets.
- From the instance, ping the gateway IP address for each of the three subnets.
- From the instance, ping an external gateway port.
No functional tests needed.
The Neutron API v2 reference documentation may need to be modified to reflect the expected behavior with respect to implicit IPv6 address assignments for port-create, port-update, and subnet delete (although the documentation doesn’t go into this much detail):
https://wiki.openstack.org/wiki/Neutron/APIv2-specification#Create_Port https://wiki.openstack.org/wiki/Neutron/APIv2-specification#Update_Port https://wiki.openstack.org/wiki/Neutron/APIv2-specification#Delete_Subnet
None needed beyond Neutron API v2 documentation changes listed above.
|[Ref-1]||(1, 2, 3) Neutron Blueprint: Allow multiple subnets on gateway|
|[Ref-2]||RFC 4862: IPv6 Stateless Address Autoconfiguration|
|[Ref-3]||RFC 4861: Neighbor Discovery for IP version 6 (IPv6)|
|[Ref-4]||DevStack Blueprint: Add IPv6 support|
|[Ref-5]||Neutron Blueprint: Two Attributes Proposal to Control IPv6 RA Announcement and Address Assignment|
|[Ref-6]||Neutron Blueprint: Provider Networking - upstream SLAAC support|
|[Ref-7]||OpenStack Neutron IPv6 Address Mode Attributes Table|
|[Ref-8]||RFC 4291: IP Version 6 Addressing Architecture|