Add IPv6 support to devstack infrastructure

By default, most Openstack services are bound to 0.0.0.0
and service endpoints are registered as IPv4 addresses.
With this change we introduce two new variables to control
this behavior:

SERVICE_IP_VERSION - can either be "4" or "6".

When set to "4" (default if not set) devstack will operate
as today - most services will open listen sockets on 0.0.0.0
and service endpoints will be registered using HOST_IP as the
address.

When set to "6" devstack services will open listen sockets on ::
and service endpoints will be registered using HOST_IPV6 as the
address.

There is no support for "4+6", more work is required for that.

HOST_IPV6 - if SERVICE_IP_VERSION=6 this must be an IPv6
address configured on the system.

Some existing services, like the Openvswitch agent, will continue
to use IPv4 addresses for things like tunnel endpoints.  This is
a current restriction in the code and can be updated at a later
time.  This change is just a first step to supporting IPv6-only
control and data planes in devstack.

This change is also partly based on two previous patches,
https://review.openstack.org/#/c/140519/ and
https://review.openstack.org/#/c/176898/

Change-Id: I5c0b775490ce54ab104fd5e89b20fb700212ae74
Co-Authored-By: Sean Collins <sean@coreitpro.com>
Co-Authored-By: Baodong Li <baoli@cisco.com>
Co-Authored-By: Sridhar Gaddam <sridhar.gaddam@enovance.com>
Co-Authored-By: Adam Kacmarsky <adam.kacmarsky@hp.com>
Co-Authored-By: Jeremy Alvis <jeremy.alvis@hp.com>
diff --git a/functions-common b/functions-common
index 483b1fa..39c1bfc 100644
--- a/functions-common
+++ b/functions-common
@@ -46,7 +46,8 @@
 # Save these variables to .stackenv
 STACK_ENV_VARS="BASE_SQL_CONN DATA_DIR DEST ENABLED_SERVICES HOST_IP \
     KEYSTONE_AUTH_PROTOCOL KEYSTONE_AUTH_URI KEYSTONE_SERVICE_URI \
-    LOGFILE OS_CACERT SERVICE_HOST SERVICE_PROTOCOL STACK_USER TLS_IP"
+    LOGFILE OS_CACERT SERVICE_HOST SERVICE_PROTOCOL STACK_USER TLS_IP \
+    HOST_IPV6"
 
 
 # Saves significant environment variables to .stackenv for later use
@@ -578,13 +579,14 @@
     local floating_range=$2
     local host_ip_iface=$3
     local host_ip=$4
+    local af=$5
 
     # Search for an IP unless an explicit is set by ``HOST_IP`` environment variable
     if [ -z "$host_ip" -o "$host_ip" == "dhcp" ]; then
         host_ip=""
         # Find the interface used for the default route
-        host_ip_iface=${host_ip_iface:-$(ip route | awk '/default/ {print $5}' | head -1)}
-        local host_ips=$(LC_ALL=C ip -f inet addr show ${host_ip_iface} | awk '/inet/ {split($2,parts,"/");  print parts[1]}')
+        host_ip_iface=${host_ip_iface:-$(ip -f $af route | awk '/default/ {print $5}' | head -1)}
+        local host_ips=$(LC_ALL=C ip -f $af addr show ${host_ip_iface} | awk /$af'/ {split($2,parts,"/");  print parts[1]}')
         local ip
         for ip in $host_ips; do
             # Attempt to filter out IP addresses that are part of the fixed and
@@ -593,6 +595,10 @@
             # will be printed and the first IP from the interface will be used.
             # If that is not correct set ``HOST_IP`` in ``localrc`` to the correct
             # address.
+            if [[ "$af" == "inet6" ]]; then
+                host_ip=$ip
+                break;
+            fi
             if ! (address_in_net $ip $fixed_range || address_in_net $ip $floating_range); then
                 host_ip=$ip
                 break;