Tag Archives: Linux

Deploying IPv6 With OpenStack Provider Networks

Last year I posted on “Tenant IPv6 Deployment in OpenStack Kilo Release” and I also posted on “Using OpenStack Heat to Deploy an IPv6-Enabled Instance”.  Both of those posts were using the Neutron L3 Agent (Tenant routers) for my examples.  In this post I will show the deployment of IPv6 using Provider Networks. There is no specific OpenStack release that I am dictating for this setup. I have used this config on Kilo-to-Newton.

OpenStack Provider Networks with VLANs  allows for the use of VLAN trunks from the upstream Data Center access layer/leaf/ToR switches to the Neutron networks within the OpenStack cloud.  In the use case that I am discussing here, I want to use my Data Center aggregation layer switches as my first-hop layer 3 boundary. I have no use for NAT and I have no use for Neutron L3 agents (specific to running a tenant router).

The following diagram shows the topology that I am using. In this example I have a single All-in-One (AIO) OpenStack node. That node is running on a Cisco UCS C-series with a Cisco VIC which has a VPC configuration to the access layer ToR switches. There are VLAN trunks configured between the ToRs and the Data Center aggregation layer switches (only one shown for simplicity). VLAN 22 (2001:db8:cafe:16::/64) is the VLAN that is used in my examples.  The text box in the diagram shows the NIC layout (ethX<>bonds):

ipv6-provider

I explained a lot about SLAAC, Stateless DHCPv6 and Stateful DHCPv6 Stateful stuff in the blog from May 2015 and I am not rehashing all of that here. Check that post for more details if you are unfamiliar with IPv6 address assignment options. Also, if you want to know more about how Managed (M) and Other (O) flags are used with various IPv6 assignment methods, consult RFC5175.

We are going to jump right into configuration:

Assuming you have a running OpenStack deployment and have followed the guidelines for setting up Neutron to support Provider Networks with VLANs (OVS example, Linux Bridge example), all you have to do is create the provider network and subnet using the IPv6 address assignment method you want (SLAAC, Stateless DHCPv6, Stateful DHCPv6).

Create the Neutron Provider Network with VLAN

In the example below, I am indicating that the router is external (aggregation layer switches), the provider network is of the type VLAN and the VLAN (segmentation_id) associated with this network is VLAN 22:

neutron net-create --router:external --provider:physical_network provider --provider:network_type vlan --provider:segmentation_id=22 --shared external-net

Create the Neutron Subnet using SLAAC

In the example below, I am using SLAAC as the IPv6 address assignment method.  Note: It is very important to indicate the “–allocation-pool” range with provider networks with VLANs because if you don’t then the beginning IPv6 address range will likely cause a DAD (Duplicate Address Detection) failure with IPv6 address already assigned on your upstream VLAN interfaces on the aggregation layer switches.  In this example I am starting the allocation pool range at ::5 so that I do not conflict with addresses on my switches (i.e. ::1 – ::4):

neutron subnet-create external-net --ip-version=6 --ipv6-address-mode=slaac --ipv6-ra-mode=slaac --name=external-subnet-v6 --allocation-pool start=2001:db8:cafe:16::5,end=2001:db8:cafe:16:ffff:ffff:ffff:fffe 2001:db8:cafe:16::/64

Create the Neutron Subnet using Stateless DHCPv6

In the example below, I am using Stateless DHCPv6 as the IPv6 address assignment method.  With Stateless and Stateful DHCPv6 you have the option to add the “–dns-nameserver” flag (since the O-bit [Other configuration] can be set). In this example I am setting 2001:db8:cafe:a::e as the DNS entry which points to my DNS server referenced in the previous diagram.  Again, it is important to setup the “–allocation-pool” range:

neutron subnet-create external-net --ip-version=6 --ipv6-address-mode=dhcpv6-stateless --ipv6-ra-mode=dhcpv6-stateless --name=external-subnet-v6 --allocation-pool start=2001:db8:cafe:16::5,end=2001:db8:cafe:16:ffff:ffff:ffff:fffe 2001:db8:cafe:16::/64 --dns-nameserver 2001:db8:cafe:a::e

Create the Neutron Subnet using Stateful DHCPv6

In the example below, I am using Stateful DHCPv6 as the IPv6 address assignment method.  As was the case with Stateless DHCPv6, Stateful DHCPv6 allows  for the option to add the “–dns-nameserver” flag (since the O-bit can be set):

neutron subnet-create external-net --ip-version=6 --ipv6-address-mode=dhcpv6-stateful --ipv6-ra-mode=dhcpv6-stateful --name=external-subnet-v6 --allocation-pool start=2001:db8:cafe:16::5,end=2001:db8:cafe:16:ffff:ffff:ffff:fffe 2001:db8:cafe:16::/64 --dns-nameserver 2001:db8:cafe:a::e

Example Configuration for the upstream Data Center aggregation layer switch (VLAN interfaces shown):

SLAAC:

This example shows VLAN22 with an IPv6 address of 2001:db8:cafe:16::1/64. HSRPv2 is used as the First-Hop Redundancy Protocol.

interface Vlan22
 description Provider Network trunked for C7-os-1
 ip address 172.16.22.2 255.255.255.0
 ipv6 address 2001:DB8:CAFE:16::1/64
 standby version 2
 standby 2 ipv6 autoconfig
 standby 2 timers msec 250 msec 750
 standby 2 priority 110
 standby 2 preempt
 standby 2 authentication OPEN

Stateless DHCPv6:

This example is the same as the previous one with the exception of the “ipv6 nd other-config-flag” being set. This flat sets the O-bit which allows for the DNS option (or other options) to be sent to the VM in the Router Advertisement (RA).

interface Vlan22
 description Provider Network trunked for C7-os-1
 ip address 172.16.22.2 255.255.255.0
 ipv6 address 2001:DB8:CAFE:16::1/64
 ipv6 nd other-config-flag
 standby version 2
 standby 2 ipv6 autoconfig
 standby 2 timers msec 250 msec 750
 standby 2 priority 110
 standby 2 preempt
 standby 2 authentication OPEN

Stateful DHCPv6:

This example is also the same as the first one with the exception of the “ipv6 nd managed-config-flag” being set. This sets the M (Managed) and O (other) bits. The M-bit indicates that the addressing comes from DHCPv6 (Not SLAAC) and that the host wants options (DNS):

interface Vlan22
 description Provider Network trunked for C7-os-1
 ip address 172.16.22.2 255.255.255.0
 ipv6 address 2001:DB8:CAFE:16::1/64
 ipv6 nd managed-config-flag
 standby version 2
 standby 2 ipv6 autoconfig
 standby 2 timers msec 250 msec 750
 standby 2 priority 110
 standby 2 preempt
 standby 2 authentication OPEN

Consult my previous blog post on the stuff that you need to be aware of on the Linux VM side of things when you enable Stateless DHCPv6 and Stateful DHCPv6.

Have fun!

 

VMware Fusion 8 Pro – IPv6 NAT

I just upgraded to VMware Fusion 8 Pro and noticed that there was a new feature in there for IPv6 NAT. You all know my views on NAT, especially IPv6 NAT but we won’t get into all of that here. 🙂

It looks as though you have to be on Fusion 8 Pro to get this feature. It is super simple to enable.

Below is a basic view of my topology.  My Mac (using the en0 adapter) has an IPv6 address from my local CPE (connected to Comcast).  I have a Linux VM attached to a custom network (vmnet2) that has the IPv4 subnet of 172.16.1.0/24 and the autogenerated (by Fusion) Unique Local IPv6 prefix of FD15:4BA5:5A2B:1002::/64
diagram-fusion-v6-nat

Here is what the Linux host looks like prior to enabling IPv6 NAT:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:2e:cf:c0 brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.129/24 brd 172.16.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe2e:cfc0/64 scope link
       valid_lft forever preferred_lft forever

In VMware Fusion 8 Pro, you can enable IPv6 NAT for a network by going into VMware Fusion > Preferences > Network > then select the custom network that you want to enable IPv6 NAT on. The graphic shown below is what my vmnet2 network looks like:
screenshot_130

With IPv6 NAT enabled, the Linux host now has an IPv6 address:

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:2e:cf:c0 brd ff:ff:ff:ff:ff:ff
    inet 172.16.1.129/24 brd 172.16.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fd15:4ba5:5a2b:1002:24fd:5bf0:baba:4866/64 scope global temporary dynamic
       valid_lft 86398sec preferred_lft 14398sec
    inet6 fd15:4ba5:5a2b:1002:20c:29ff:fe2e:cfc0/64 scope global dynamic
       valid_lft 86398sec preferred_lft 14398sec
    inet6 fe80::20c:29ff:fe2e:cfc0/64 scope link
       valid_lft forever preferred_lft forever

You can see that the Linux host gets two addresses out of the ULA prefix that was autogenerated by Fusion (see the graphic). The first address is the IPv6 privacy extension address and the second is the EUI-64 derived IPv6 address.

I can now ping from the Linux host to the outside (via IPv6 NAT):

localadmin@v6-nat-demo:~$ ping6 -n www.google.com
PING www.google.com(2607:f8b0:400f:803::2004) 56 data bytes
64 bytes from 2607:f8b0:400f:803::2004: icmp_seq=1 ttl=255 time=12.7 ms
64 bytes from 2607:f8b0:400f:803::2004: icmp_seq=2 ttl=255 time=15.0 ms
64 bytes from 2607:f8b0:400f:803::2004: icmp_seq=3 ttl=255 time=14.8 ms

Ping, the ultimate test of success, works. 🙂

Thanks,
Shannon

Tenant IPv6 Deployment in OpenStack Kilo Release

You folks know that I have been dancing to the IPv6 music for the last 12 years or so. IPv6 is so popular that I still earn about 75 cents a month on my book royalties. 🙂

I have been fairly disappointed in the deployment of IPv6 in an OpenStack environment.  Many individuals and companies have beat on IPv6 over the past couple of years to get it to where it is today in OpenStack and we should all be super greatful.  In this post I will go over some design and deployment considerations for IPv6 in the OpenStack Kilo release.

Note: I refer to the term “tenant” vs. what OpenStack calls a “project”.

Cloud and IPv6

IPv6 has had a rough go of it over the many years it has been around. It is usually a rough go when you try to inject it into any cloud deployment. And I do mean ANY cloud deployment.  The hard stuff with cloud and IPv6 includes (not an exhaustive list):

  • API Endpoints – Enabling IPv6 on the non-Tenant-facing portion of the cloud stack
  • Provisioning, Orchestration and Management – This includes CI/CD, bare-metal provisioning (i.e. Cobbler, Ironic), automation tools such as Ansible, Puppet, etc.. and the overall Data Center management tools
  • Management/communication protocol interoperability and support of IPv6
  • Support for IPv6 in both virtual and physical networking
  • Oh, let’s not forget – expertise

In this post I am not going to address all of the above as none of us have that kind of time.  What I will talk about is making a choice to enable ALL of OpenStack for IPv6 or settling for the really important part, which is the tenant-facing part and how that looks when configured.

There are two common ways of embracing IPv6 within OpenStack (I am not discussing IPv6-only options here):

  • Dual Stack everything
  • Conditional Dual Stack

Figure 1 shows an example of a “dual stack everything” approach. It is what is sounds like. Everything in the entire stack is both IPv4 and IPv6 enabled.  This includes the API endpoints, the DBs, the tools and systems that surround OpenStack (i.e. provisioning and automation).  This, kids, can be a real pain in the butt, especially if this is a brownfield deployment where you have to go in an muck around with database entries for IPv6 and so on.

Figure 1. Dual Stack Everything

ds-everything

This is where “conditional dual stack” comes in.  It allows you to control when and where IPv6 is enabled.  In many cases, it is just in the tenant space, at least initially.

Figure 2 shows an example of where we have an IPv4-only OpenStack control plane (API/DB/etc) but dual stack for anything that faces something a tenant would see/control/interact with.  Optionally, this is where you can begin experimenting (I stress that word) with IPv6-only tenant networks.

Figure 2. Conditional Dual Stack

conditional

 

No matter which path you go down (and there are variances to the two I have pointed out here), you will end up dealing with IPv6 in the tenant space.  So, let’s talk about that part.

Tenant IPv6 Address Options

There are many combinations to IPv6 address assignment and even the types of addresses you can use.  For tenant address types you can use:

You can use those independently or together.  As far as planning out the use of GUA, ULA or combination of the two you have to think about the requirements of the tenant.  Most of the time the tenant has no clue what ‘routable’ means or NAT and they shouldn’t.  In the context of IPv6, we don’t want to do NAT, ever. Well, with one exception – we may need, for a very temporary use case, NAT64 where we translating incoming IPv6 connections into back-end IPv4-only nodes.  This is an entirely different use case than wanting to translate between two IPv6 address spaces.  Don’t do that. 🙂

With all of that said, I tend to see two of MANY address options in production deployments:

  • Cloud provider assigned addressing – Provider owns and assigns IPv6 addressing
  • Tenant-provided addressing – Tenant brings their own IPv6 addressing and the cloud provider has to route it

What I mean by “cloud provider assigned addressing” is that the owner of the system (the cloud provider – which could be a public provider or just an Enterprise IT shop) will obtain a Provider Independent (PI) or Provider Assigned (PA) IPv6 address block, design an address plan and then assign blocks out of that plan to each tenant. This works well, is easy to do and is the way you should do it.

Tenant-provided addressing is possible, but messy.  In the Enterprise space, this is not something that usually happens unless you are dealing with a merger & acquisition (M&A) situation where an acquired company wants their existing IPv6 addressing to be used in the acquiring company’s cloud service.  This is something that is requested when an Enterprise or another SP is using another public cloud provider.  Again, it is totally doable but it requires a lot of planning with BGP, address space design, etc..

From an address assignment perspective, you can use:

  • Static/manual configuration
  • StateLess Address AutoConfiguration (SLAAC) – IPv6 prefix (i.e /64) is assigned to the end node via a router advertisement (RA) and the node self-constructs the interface ID (IID) portion of the address (i.e. the last /64 bits)
  • Stateful DHCPv6 – Just like IPv4 DHCP, a DHCPv6 server hands out full IPv6 addressing and any configured options
  • Stateless DHCPv6 – A combination of SLAAC (for address assignment) and DHCPv6 (for option assignment – DNS name, domain name)

In the OpenStack Kilo release we have functional support for SLAAC, Stateful DHCPv6 and Stateless DHCPv6.  I will cover the configuration of all three in this post.

Example Topology

The lab setup I am using for this post includes:

  • Kilo
  • Devstack – only because I did this testing before packages were available for RDO/Packstack, Ubuntu/Juju/MaaS or any other intaller
  • All-in-one node (although in another lab I have I did this same setup on 7 nodes and it worked as expected)
  • The lab I did this test in did not have external IPv6 connectivity to the Internet, but I do have IPv6 throughout that lab so I could verify proper routing beyond OpenStack

Figure 3 shows a basic topology of the example setup.  The all-in-one (AIO) has a management network interface (eth0) and an OpenStack public network interface (eth1).  Both interfaces are connected to a Top-of-Rack (ToR) switch which has an uplink to the Data Center Aggregation Layer switches (via trunked VLANs).  The Aggregation Layer switches have VLAN interfaces for each network and are providing IPv4 and IPv6 routing for the rest of the lab. There are IPv6 routes configured on the Aggregation Layer switches for each IPv6 prefix within the OpenStack tenant space.  Off of the ToR is a DNS server that is IPv4 and IPv6 enabled.

Figure 3. Example Topology

topo

Before I walk through each address assignment type, I will create the public network and subnets as the cloud admin. This can be done in the dashboard or via the Neutron client CLI. In this example a “public” network is created and the upstream Data Center L3 switches (–router:external) will be used as the gateway. An IPv4 subnet is created with an allocation range so that the addresses assigned do not collide with IPv4 addresses assigned on the Data Center L3 switches. An IPv6 subnet is created which also has an allocation range defined. If you have an upstream gateway address that is not .1 (v4) or ::1 (v6) then you need to identify the real gateway address using the “–gateway” option:

neutron net-create public --router:external

neutron subnet-create --name public-subnet --allocation-pool start=172.16.12.5,end=172.16.12.254 public 172.16.12.0/24

neutron subnet-create --ip-version=6 --name=public-v6-subnet --allocation-pool start=2001:db8:cafe:d::5,end=2001:db8:cafe:d:ffff:ffff:ffff:fffe --disable-dhcp public 2001:db8:cafe:d::/64

Let’s walk through SLAAC, Stateful DHCPv6 and Stateless DHCPv6.

SLAAC

Figure 4 gives a topology view of the SLAAC example I am referencing.  The Neutron router has a private network with IPv4 and IPv6 subnets and a public network with gateway connections (Also, dual stack) to the Data Center. The instance will have a dual stack connection and receive DHCPv4 address assigned from DNSMASQ and IPv6 address assignment via radvd in SLAAC mode:

Figure 4. SLAAC Topology Example

slaac-topo

When you use SLAAC mode in the tenant space, the Router Advertisement Daemon (radvd) is used to send router advertisements (RAs) in response to Router Solicitations (RS) as well as at a regular interval.  When you create a Neutron network and subnet for IPv6 you have to select the “IPv6 Address Configuration Mode” from the “Subnet Details” screen in the dashboard. In this case you would select “SLAAC: Address discovered from OpenStack Router”.  If you were doing this via CLI, you would use the option arguments of “–ipv6-address-mode=slaac –ipv6-ra-mode=slaac” when you create the subnet.  In the example below, a new Neutron network (“private”) is created along with the IPv6 subnet creation (IPv4 subnet creation is not shown). The option arguments are added to identify SLAAC mode. Also, no DNS servers are added here as that information for IPv6 would not get injected into the instance and the instance (since it is set for SLAAC-only) would not ask for DNS and other options:

neutron net-create private
 
neutron subnet-create --ip-version=6 --name=private_v6_subnet --ipv6-address-mode=slaac --ipv6-ra-mode=slaac private 2001:db8:cafe::/64

Created a new subnet:
+-------------------+----------------------------------------------------------------+
| Field             | Value                                                          |
+-------------------+----------------------------------------------------------------+
| allocation_pools  | {"start": "2001:db8:cafe::2", "end": "2001:db8:cafe:0:ffff:ffff:ffff:fffe"}|
| cidr              | 2001:db8:cafe::/64                                             |
| dns_nameservers   |                                                                |
| enable_dhcp       | True                                                           |
| gateway_ip        | 2001:db8:cafe::1                                               |
| host_routes       |                                                                |
| id                | 42cc3dbc-938b-4ad6-b12e-59aef7618477                           |
| ip_version        | 6                                                              |
| ipv6_address_mode | slaac                                                          |
| ipv6_ra_mode      | slaac                                                          |
| name              | private_v6_subnet                                              |
| network_id        | 7166ce15-c581-4195-9479-ad2283193d06                           |
| subnetpool_id     |                                                                |
| tenant_id         | f057804eb39b4618b40e06196e16265b                               |
+-------------------+----------------------------------------------------------------+

Inside the tenant (as a tenant member or admin) a Neutron router needs to be created along with attaching the router to the public network and the two subnets:

neutron router-create router

neutron router-gateway-set router public

neutron router-interface-add router private_v4_subnet

neutron router-interface-add router private_v6_subnet

When an instance boots inside the tenant and attaches to the “private” network it will have access to both the IPv4 and the IPv6 subnets that were defined previously. Note: Both Windows (since Windows 7/Server 2008) and Linux (from a long time ago) support SLAAC out of the box just so basic IPv6 protocol support is enabled.  The instance will receive and IPv4 address via DNSMASQ and an IPv6 address via radvd. Note: The host will NOT receive any kind of IPv6 DNS entry from OpenStack. There are a couple of considerations to understand with this. An instance can get both IPv4 and IPv6 DNS information for a host over IPv4 transport. You don’t need to access a DNS server natively over IPv6 in order to receive IPv6 host information in a lookup. But, if you do want to have an IPv6 entry in the /etc/resolv.conf file then, in SLAAC mode, you will need to configure it manually, setup cloud-init to inject it or just bake that entry into the image that is booted.

A highly summarized view of a tcpdump capture reveals the basic flow of a SLAAC exchange.  The ICMPv6 Flags field states “none” and the Prefix Information Flag field has “auto” enabled. The combination of “none” (Managed and Other bits = 0) and “auto” (Auto bit = 1) indicates SLAAC is used and DHCPv6 is not used. You can read more on this in RFC 4861:

IP6 (hlim 255, next-header ICMPv6 (58) payload length: 16) fe80::f816:3eff:fe79:5acc > ff02::2: [icmp6 sum ok] ICMP6, router solicitation, length 16
	  source link-address option (1), length 8 (1): fa:16:3e:79:5a:cc
	    0x0000:  fa16 3e79 5acc

IP6 (hlim 255, next-header ICMPv6 (58) payload length: 56) fe80::f816:3eff:fec3:17b4 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 56
	hop limit 64, Flags [none], pref medium, router lifetime 30s, reachable time 0s, retrans time 0s
	  prefix info option (3), length 32 (4): 2001:db8:cafe::/64, Flags [onlink, auto], valid time 86400s, pref. time 14400s
	    0x0000:  40c0 0001 5180 0000 3840 0000 0000 2001
	    0x0010:  0db8 cafe 0000 0000 0000 0000 0000
	  source link-address option (1), length 8 (1): fa:16:3e:c3:17:b4
	    0x0000:  fa16 3ec3 17b4

The instance will send out a router solicitation and the router will reply with a router advertisement. In that RA, the router will send various bits of information (various lifetimes and other stuff) and, in the case of SLAAC, it will send out a “Flags [none]”, indicating that it is not giving out anything other than a prefix. In that RA is the prefix from the subnet that was configured earlier (2001:db8:cafe::/64). The instance will use that prefix, along with its own IID (discussed earlier) to come up with a valid 128-bit IPv6 address. The instance will use the router’s link-local address as its gateway.  After the host has the IPv6 address it will go through a series of events such as Duplicate Address Detection (DAD) and so on. I won’t be explaining all of that stuff here. 😉

Stateful DHCPv6

Figure 5 is a topology view of the Stateful DHCPv6 layout. It is pretty much the same as with SLAAC only using a different IPv4 and IPv6 prefix.

Figure 5. Stateful DHCPv6 Topology Example

stateful-topo

Just like with SLAAC mode, radvd is used with Stateful DHCPv6 mode.  Instead of using the prefix announcement (Auto bit set to 1) in the RA to assist with IPv6 address assignment (SLAAC mode), Stateful DHCPv6 uses the Managed bit (set to 1) and the Auto bit (set to 0) to instruct the instance to perform a  DHCPv6 solicit for both address assignment and other options.

Configuring OpenStack to use Stateful DHCPv6 is done using the same process as was shown in the SLAAC example only with different options. In the dashboard, “DHCPv6 stateful: Address discovered from OpenStack DHCP” is selected in the “subnet details” screen.  Unlike with SLAAC, a DNS name server entry can be added and it will be sent to the instance.  If the Neutron client CLI is used then the option arguments would be: “–ipv6-address-mode=dhcpv6-stateful –ipv6-ra-mode=dhcpv6-stateful”.  Here’s an example:

neutron net-create private-dhcpv6
 
neutron subnet-create --ip-version=6 --name=private_dhcpv6_subnet --ipv6-address-mode=dhcpv6-stateful --ipv6-ra-mode=dhcpv6-stateful private-dhcpv6 2001:db8:cafe:1::/64 --dns-nameserver 2001:db8:cafe:a::e
Created a new subnet:
+-------------------+----------------------------------------------------------------+
| Field             | Value                                                          |
+-------------------+----------------------------------------------------------------+
| allocation_pools  | {"start": "2001:db8:cafe:1::2", "end": "2001:db8:cafe:1:ffff:ffff:ffff:fffe"} |
| cidr              | 2001:db8:cafe:1::/64                                           |
| dns_nameservers   | 2001:db8:cafe:a::e                                             |
| enable_dhcp       | True                                                           |
| gateway_ip        | 2001:db8:cafe:1::1                                             |
| host_routes       |                                                                |
| id                | 545ea206-9d14-4dca-8bae-7940719bdab5                           |
| ip_version        | 6                                                              |
| ipv6_address_mode | dhcpv6-stateful                                                |
| ipv6_ra_mode      | dhcpv6-stateful                                                |
| name              | private_dhcpv6_subnet                                          |
| network_id        | 55ed8333-2876-400a-92c1-ef49bc10aa2b                           |
| subnetpool_id     |                                                                |
| tenant_id         | f057804eb39b4618b40e06196e16265b                               |
+-------------------+----------------------------------------------------------------+

After performing “neutron router-interface-add” for each subnet (see SLAAC example), it’s time to setup the instance operating system for DHCPv6 operation. To learn about how Microsoft Windows supports IPv6 address assignment check out this blog.  No Linux version that I have ever worked with is configured, by default, to use DHCPv6.  For Ubuntu you have to add the “inet6 dhcp” line in the /etc/network/interfaces file:

auto eth0
iface eth0 inet dhcp
iface eth0 inet6 dhcp

I have tested CentOS 7 and Fedora 21 in this test bed and the following configuration works on those (add to the appropriate interface in /etc/sysconfig/network-scripts/):

IPV6INIT="yes"
DHCPV6C="yes"

Included below is a highly summarized output from a tcpdump capture of a Stateful DHCPv6 exchange.  There is a lot more going on here than in the SLAAC example.  Just like the SLAAC example, there is a RS/RA exchange but that is where the similarity ends.  In the RA below, the ICMPv6 Flags field is set to “managed” (M bit = 1). Note: that when the M bit is set to 1, the O bit, per RFC 4861 is redundant and can be ignored.  The instance will receive the RA and see that the “managed” flag is set and will then begin the DHCPv6 client process.  The instance will send a DHCPv6 Solicit to the ‘all DHCP servers’ well-known IPv6 multicast address (ff02::1:2).  Radvd will do a DHCPv6 advertise with all of the good stuff (address and options). The instance will do a DHCPv6 request for options (it processed the address info from the advertise) and the server will finish the sequence with a DHCPv6 reply.  You can read a summary view of this process here:

IP6 (hlim 255, next-header ICMPv6 (58) payload length: 24) fe80::f816:3eff:fe77:e5a0 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 24
	hop limit 64, Flags [managed], pref medium, router lifetime 30s, reachable time 0s, retrans time 0s
	  source link-address option (1), length 8 (1): fa:16:3e:77:e5:a0
	    0x0000:  fa16 3e77 e5a0

IP6 (hlim 1, next-header UDP (17) payload length: 64) fe80::f816:3eff:fe22:386b.546 > ff02::1:2.547: [udp sum ok] dhcp6 solicit (xid=85680b (client-ID hwaddr/time type 1 time 482446373 fa163e22386b) (option-request DNS-server DNS-search-list Client-FQDN SNTP-servers) (elapsed-time 101) (IA_NA IAID:1042430059 T1:3600 T2:5400))

IP6 (class 0xc0, hlim 64, next-header UDP (17) payload length: 175) fe80::f816:3eff:fe06:176f.547 > fe80::f816:3eff:fe22:386b.546: [udp sum ok] dhcp6 advertise (xid=85680b (client-ID hwaddr/time type 1 time 482446373 fa163e22386b) (server-ID hwaddr type 1 fa163e06176f) (IA_NA IAID:1042430059 T1:43200 T2:75600 (IA_ADDR 2001:db8:cafe:1::4 pltime:86400 vltime:86400)) (status-code success) (preference 255) (DNS-search-list openstacklocal.) (DNS-server 2001:db8:cafe:a::e) (Client-FQDN))

IP6 (hlim 1, next-header UDP (17) payload length: 106) fe80::f816:3eff:fe22:386b.546 > ff02::1:2.547: [udp sum ok] dhcp6 request (xid=9cb172 (client-ID hwaddr/time type 1 time 482446373 fa163e22386b) (server-ID hwaddr type 1 fa163e06176f) (option-request DNS-server DNS-search-list Client-FQDN SNTP-servers) (elapsed-time 0) (IA_NA IAID:1042430059 T1:3600 T2:5400 (IA_ADDR 2001:db8:cafe:1::4 pltime:7200 vltime:7500)))

IP6 (class 0xc0, hlim 64, next-header UDP (17) payload length: 186) fe80::f816:3eff:fe06:176f.547 > fe80::f816:3eff:fe22:386b.546: [udp sum ok] dhcp6 reply (xid=9cb172 (client-ID hwaddr/time type 1 time 482446373 fa163e22386b) (server-ID hwaddr type 1 fa163e06176f) (IA_NA IAID:1042430059 T1:3600 T2:6300 (IA_ADDR 2001:db8:cafe:1::4 pltime:7200 vltime:7500)) (status-code success) (DNS-search-list openstacklocal.) (DNS-server 2001:db8:cafe:a::e) (Client-FQDN))

Stateless DHCPv6

Stateless DHCPv6 is a combo of SLAAC (for address assignment) and DHCPv6 (for options).  For the sake of consistency with the last two sections, here is a topology sample for Stateless DHCPv6:

Figure 6. Stateless DHCPv6 Sample Topology

stateless-topo

The configuration of Stateless DHCPv6 is similar to that of Stateful DHCPv6.  In the dashboard, select “DHCPv6 stateless: Address discovered from OpenStack Router and additional information from OpenStack DHCP” from the “subnet details” screen.  The options argument changes if using the Neutron client CLI: “–ipv6-address-mode=dhcpv6-stateless –ipv6-ra-mode=dhcpv6-stateless private-dhcpv6-stateless”.  Here is an example:

neutron net-create private-dhcpv6-stateless

neutron subnet-create --ip-version=6 --name=private_dhcpv6_stateless_subnet --ipv6-address-mode=dhcpv6-stateless --ipv6-ra-mode=dhcpv6-stateless private-dhcpv6-stateless 2001:db8:cafe:2::/64 --dns-nameserver 2001:db8:cafe:a::e
Created a new subnet:
+-------------------+--------------------------------------------------------------+
| Field             | Value                                                        |
+-------------------+--------------------------------------------------------------+
| allocation_pools  | {"start": "2001:db8:cafe:2::2", "end": "2001:db8:cafe:2:ffff:ffff:ffff:fffe"} |
| cidr              | 2001:db8:cafe:2::/64                                         |
| dns_nameservers   | 2001:db8:cafe:a::e                                           |
| enable_dhcp       | True                                                         |
| gateway_ip        | 2001:db8:cafe:2::1                                           |
| host_routes       |                                                              |
| id                | edd1d404-e949-4cdf-9812-334bbf0e5cec                         |
| ip_version        | 6                                                            |
| ipv6_address_mode | dhcpv6-stateless                                             |
| ipv6_ra_mode      | dhcpv6-stateless                                             |
| name              | private_dhcpv6_stateless_subnet                              |
| network_id        | f65c6e60-d31e-4a1c-8136-599c3855b86a                         |
| subnetpool_id     |                                                              |
| tenant_id         | f057804eb39b4618b40e06196e16265b                             |
+-------------------+--------------------------------------------------------------+

After performing “neutron router-interface-add” for each subnet (again, see the SLAAC example), edits need to be made to the instance operating system for Stateless DHCPv6 operation. In the Ubuntu /etc/network/interfaces file, ensure the “inet6” line is set to “auto” and enable the stateless flag:

iface eth0 inet6 auto
dhcp 1

Again, I only tested CentOS7 and Fedora 21 with this setup so your mileage may vary but for those OSes, set the following for the appropriate interface in /etc/sysconfig/network-scripts/:

IPV6INIT="yes"
DHCPV6C="yes"
DHCPV6C_OPTIONS="-S"

Below is the output from tcpdump for the Stateless DHCPv6 exchange.  Radvd sends out the RS with the ICMPv6 Flags field set with the O bit set to 1 and the Prefix Information Flag field has “auto” enabled. This combination basically says “I, the router, will provide you, the instance,  a prefix via SLAAC and you come back asking for options”.  The instance will issue a “dhcp6 inf-req” to get the options and radvd will reply:

IP6 (hlim 255, next-header ICMPv6 (58) payload length: 56) fe80::f816:3eff:fec1:bc52 > ff02::1: [icmp6 sum ok] ICMP6, router advertisement, length 56
	hop limit 64, Flags [other stateful], pref medium, router lifetime 30s, reachable time 0s, retrans time 0s
	  prefix info option (3), length 32 (4): 2001:db8:cafe:2::/64, Flags [onlink, auto], valid time 86400s, pref. time 14400s
	    0x0000:  40c0 0001 5180 0000 3840 0000 0000 2001
	    0x0010:  0db8 cafe 0002 0000 0000 0000 0000
	  source link-address option (1), length 8 (1): fa:16:3e:c1:bc:52
	    0x0000:  fa16 3ec1 bc52

IP6 (hlim 1, next-header UDP (17) payload length: 44) fe80::f816:3eff:fefe:d157.546 > ff02::1:2.547: [udp sum ok] dhcp6 inf-req (xid=d2dbc8 (client-ID hwaddr type 1 fa163efed157) (option-request DNS-server DNS-search-list Client-FQDN SNTP-servers) (elapsed-time 94))

IP6 (class 0xc0, hlim 64, next-header UDP (17) payload length: 88) fe80::f816:3eff:fe2d:a6de.547 > fe80::f816:3eff:fefe:d157.546: [udp sum ok] dhcp6 reply (xid=d2dbc8 (client-ID hwaddr type 1 fa163efed157) (server-ID hwaddr type 1 fa163e2da6de) (DNS-search-list openstacklocal.) (DNS-server 2001:db8:cafe:a::e) (lifetime 86400))

I am sorry for the legnth of the blog post. In retrospect I should have broken this post into multiple posts but oh well.

I hope this was helpful.

Cheers,
Shannon