Merge "Support Glance CORS options in devstack configuration"
diff --git a/Makefile b/Makefile
index a94d60a..970d800 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@
 DEST=/opt/stack
 
 all:
-	echo "This just saved you from a terrible mistake!"
+	@echo "This just saved you from a terrible mistake!"
 
 # Do Some Work
 stack:
diff --git a/clean.sh b/clean.sh
index 1176134..0641bff 100755
--- a/clean.sh
+++ b/clean.sh
@@ -49,6 +49,7 @@
 source $TOP_DIR/lib/cinder
 source $TOP_DIR/lib/swift
 source $TOP_DIR/lib/heat
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 
 set -o xtrace
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 1f5797c..1161b34 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -36,10 +36,6 @@
 
 -  **local** - extracts ``localrc`` from ``local.conf`` before
    ``stackrc`` is sourced
--  **pre-install** - runs after the system packages are installed but
-   before any of the source repositories are installed
--  **install** - runs immediately after the repo installations are
-   complete
 -  **post-config** - runs after the layer 2 services are configured and
    before they are started
 -  **extra** - runs after services are started and before any files in
@@ -427,6 +423,9 @@
 
       LIBS_FROM_GIT=python-keystoneclient,oslo.config
 
+Setting the variable to ``ALL`` will activate the download for all
+libraries.
+
 Virtual Environments
 --------------------
 
diff --git a/doc/source/guides/lxc.rst b/doc/source/guides/lxc.rst
index a719d60..9549ed2 100644
--- a/doc/source/guides/lxc.rst
+++ b/doc/source/guides/lxc.rst
@@ -88,7 +88,7 @@
 
 You can also ssh into your container. On your host, run
 ``sudo lxc-info -n devstack`` to get the IP address (e.g. 
-``ssh ubuntu@$(sudo lxc-info -n p2 | awk '/IP/ { print $2 }')``).
+``ssh ubuntu@$(sudo lxc-info -n devstack | awk '/IP/ { print $2 }')``).
 
 Run Devstack
 -------------
diff --git a/doc/source/guides/neutron.rst b/doc/source/guides/neutron.rst
index a834314..c5b1634 100644
--- a/doc/source/guides/neutron.rst
+++ b/doc/source/guides/neutron.rst
@@ -88,7 +88,6 @@
         FIXED_RANGE="10.0.0.0/24"
         Q_FLOATING_ALLOCATION_POOL=start=172.18.161.250,end=172.18.161.254
         PUBLIC_NETWORK_GATEWAY="172.18.161.1"
-        Q_L3_ENABLED=True
         PUBLIC_INTERFACE=eth0
 
         # Open vSwitch provider networking configuration
@@ -362,6 +361,8 @@
 DevStack Configuration
 ----------------------
 
+.. _ovs-provider-network-controller:
+
 The following is a snippet of the DevStack configuration on the
 controller node.
 
@@ -387,7 +388,6 @@
         OVS_PHYSICAL_BRIDGE=br-ex
 
         Q_USE_PROVIDER_NETWORKING=True
-        Q_L3_ENABLED=False
 
         # Do not use Nova-Network
         disable_service n-net
@@ -434,13 +434,12 @@
         OVS_PHYSICAL_BRIDGE=br-ex
         PUBLIC_INTERFACE=eth1
         Q_USE_PROVIDER_NETWORKING=True
-        Q_L3_ENABLED=False
 
 Compute node 2's configuration will be exactly the same, except
 ``HOST_IP`` will be ``10.0.0.4``
 
 When DevStack is configured to use provider networking (via
-``Q_USE_PROVIDER_NETWORKING`` is True and ``Q_L3_ENABLED`` is False) -
+``Q_USE_PROVIDER_NETWORKING`` is True) -
 DevStack will automatically add the network interface defined in
 ``PUBLIC_INTERFACE`` to the ``OVS_PHYSICAL_BRIDGE``
 
@@ -543,7 +542,6 @@
     FIXED_RANGE="10.0.0.0/24"
     Q_FLOATING_ALLOCATION_POOL=start=172.18.161.250,end=172.18.161.254
     PUBLIC_NETWORK_GATEWAY="172.18.161.1"
-    Q_L3_ENABLED=True
     PUBLIC_INTERFACE=eth0
 
     Q_USE_PROVIDERNET_FOR_PUBLIC=True
@@ -553,3 +551,101 @@
     LB_PHYSICAL_INTERFACE=eth0
     PUBLIC_PHYSICAL_NETWORK=default
     LB_INTERFACE_MAPPINGS=default:eth0
+
+Using MacVTap instead of Open vSwitch
+------------------------------------------
+
+Security groups are not supported by the MacVTap agent. Due to that, devstack
+configures the NoopFirewall driver on the compute node.
+
+MacVTap agent does not support l3, dhcp and metadata agent. Due to that you can
+chose between the following deployment scenarios:
+
+Single node with provider networks using config drive and external l3, dhcp
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This scenario applies, if l3 and dhcp services are provided externally, or if
+you do not require them.
+
+
+::
+
+    [[local|localrc]]
+    HOST_IP=10.0.0.2
+    SERVICE_HOST=10.0.0.2
+    MYSQL_HOST=10.0.0.2
+    RABBIT_HOST=10.0.0.2
+    ADMIN_PASSWORD=secret
+    MYSQL_PASSWORD=secret
+    RABBIT_PASSWORD=secret
+    SERVICE_PASSWORD=secret
+
+    Q_ML2_PLUGIN_MECHANISM_DRIVERS=macvtap
+    Q_USE_PROVIDER_NETWORKING=True
+
+    #Enable Neutron services
+    disable_service n-net
+    enable_plugin neutron git://git.openstack.org/openstack/neutron
+    ENABLED_SERVICES+=,q-agt,q-svc
+
+    ## MacVTap agent options
+    Q_AGENT=macvtap
+    PHYSICAL_NETWORK=default
+
+    FIXED_RANGE="203.0.113.0/24"
+    NETWORK_GATEWAY=203.0.113.1
+    PROVIDER_SUBNET_NAME="provider_net"
+    PROVIDER_NETWORK_TYPE="vlan"
+    SEGMENTATION_ID=2010
+
+    [[post-config|/$Q_PLUGIN_CONF_FILE]]
+    [macvtap]
+    physical_interface_mappings = $PHYSICAL_NETWORK:eth1
+
+    [[post-config|$NOVA_CONF]]
+    force_config_drive = True
+
+
+Multi node with MacVTap compute node
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+This scenario applies, if you require OpenStack provided l3, dhcp or metadata
+services. Those are hosted on a separate controller and network node, running
+some other l2 agent technology (in this example Open vSwitch). This node needs
+to be configured for VLAN tenant networks.
+
+For OVS, a similar configuration like described in the
+:ref:`OVS Provider Network <ovs-provider-network-controller>` section can be
+used. Just add the the following line to this local.conf, which also loads
+the MacVTap mechanism driver:
+
+::
+
+    [[local|localrc]]
+    ...
+    Q_ML2_PLUGIN_MECHANISM_DRIVERS=openvswitch,linuxbridge,macvtap
+    ...
+
+For the MacVTap compute node, use this local.conf:
+
+::
+
+    HOST_IP=10.0.0.3
+    SERVICE_HOST=10.0.0.2
+    MYSQL_HOST=10.0.0.2
+    RABBIT_HOST=10.0.0.2
+    ADMIN_PASSWORD=secret
+    MYSQL_PASSWORD=secret
+    RABBIT_PASSWORD=secret
+    SERVICE_PASSWORD=secret
+
+    # Services that a compute node runs
+    disable_all_services
+    enable_plugin neutron git://git.openstack.org/openstack/neutron
+    ENABLED_SERVICES+=n-cpu,q-agt
+
+    ## MacVTap agent options
+    Q_AGENT=macvtap
+    PHYSICAL_NETWORK=default
+
+    [[post-config|/$Q_PLUGIN_CONF_FILE]]
+    [macvtap]
+    physical_interface_mappings = $PHYSICAL_NETWORK:eth1
diff --git a/doc/source/index.rst b/doc/source/index.rst
index c4a7c59..68ec174 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -63,15 +63,12 @@
 
        devstack/tools/create-stack-user.sh; su stack
 
-#. Start the install
+#. Start the install, this will take a few minutes.
 
    ::
 
        cd devstack; ./stack.sh
 
-   It takes a few minutes, we recommend `reading the
-   script <stack.sh.html>`__ while it is building.
-
 Guides
 ======
 
diff --git a/doc/source/plugin-registry.rst b/doc/source/plugin-registry.rst
index 835d043..0ceb829 100644
--- a/doc/source/plugin-registry.rst
+++ b/doc/source/plugin-registry.rst
@@ -30,6 +30,7 @@
 app-catalog-ui                         `git://git.openstack.org/openstack/app-catalog-ui <https://git.openstack.org/cgit/openstack/app-catalog-ui>`__
 astara                                 `git://git.openstack.org/openstack/astara <https://git.openstack.org/cgit/openstack/astara>`__
 barbican                               `git://git.openstack.org/openstack/barbican <https://git.openstack.org/cgit/openstack/barbican>`__
+bilean                                 `git://git.openstack.org/openstack/bilean <https://git.openstack.org/cgit/openstack/bilean>`__
 blazar                                 `git://git.openstack.org/openstack/blazar <https://git.openstack.org/cgit/openstack/blazar>`__
 broadview-collector                    `git://git.openstack.org/openstack/broadview-collector <https://git.openstack.org/cgit/openstack/broadview-collector>`__
 ceilometer                             `git://git.openstack.org/openstack/ceilometer <https://git.openstack.org/cgit/openstack/ceilometer>`__
@@ -60,16 +61,21 @@
 gce-api                                `git://git.openstack.org/openstack/gce-api <https://git.openstack.org/cgit/openstack/gce-api>`__
 gnocchi                                `git://git.openstack.org/openstack/gnocchi <https://git.openstack.org/cgit/openstack/gnocchi>`__
 group-based-policy                     `git://git.openstack.org/openstack/group-based-policy <https://git.openstack.org/cgit/openstack/group-based-policy>`__
+higgins                                `git://git.openstack.org/openstack/higgins <https://git.openstack.org/cgit/openstack/higgins>`__
 ironic                                 `git://git.openstack.org/openstack/ironic <https://git.openstack.org/cgit/openstack/ironic>`__
 ironic-inspector                       `git://git.openstack.org/openstack/ironic-inspector <https://git.openstack.org/cgit/openstack/ironic-inspector>`__
+ironic-staging-drivers                 `git://git.openstack.org/openstack/ironic-staging-drivers <https://git.openstack.org/cgit/openstack/ironic-staging-drivers>`__
 kingbird                               `git://git.openstack.org/openstack/kingbird <https://git.openstack.org/cgit/openstack/kingbird>`__
 kuryr                                  `git://git.openstack.org/openstack/kuryr <https://git.openstack.org/cgit/openstack/kuryr>`__
 magnum                                 `git://git.openstack.org/openstack/magnum <https://git.openstack.org/cgit/openstack/magnum>`__
 magnum-ui                              `git://git.openstack.org/openstack/magnum-ui <https://git.openstack.org/cgit/openstack/magnum-ui>`__
 manila                                 `git://git.openstack.org/openstack/manila <https://git.openstack.org/cgit/openstack/manila>`__
 mistral                                `git://git.openstack.org/openstack/mistral <https://git.openstack.org/cgit/openstack/mistral>`__
+monasca-analytics                      `git://git.openstack.org/openstack/monasca-analytics <https://git.openstack.org/cgit/openstack/monasca-analytics>`__
 monasca-api                            `git://git.openstack.org/openstack/monasca-api <https://git.openstack.org/cgit/openstack/monasca-api>`__
+monasca-ceilometer                     `git://git.openstack.org/openstack/monasca-ceilometer <https://git.openstack.org/cgit/openstack/monasca-ceilometer>`__
 monasca-log-api                        `git://git.openstack.org/openstack/monasca-log-api <https://git.openstack.org/cgit/openstack/monasca-log-api>`__
+monasca-transform                      `git://git.openstack.org/openstack/monasca-transform <https://git.openstack.org/cgit/openstack/monasca-transform>`__
 murano                                 `git://git.openstack.org/openstack/murano <https://git.openstack.org/cgit/openstack/murano>`__
 networking-6wind                       `git://git.openstack.org/openstack/networking-6wind <https://git.openstack.org/cgit/openstack/networking-6wind>`__
 networking-bagpipe                     `git://git.openstack.org/openstack/networking-bagpipe <https://git.openstack.org/cgit/openstack/networking-bagpipe>`__
@@ -79,6 +85,7 @@
 networking-cisco                       `git://git.openstack.org/openstack/networking-cisco <https://git.openstack.org/cgit/openstack/networking-cisco>`__
 networking-fortinet                    `git://git.openstack.org/openstack/networking-fortinet <https://git.openstack.org/cgit/openstack/networking-fortinet>`__
 networking-generic-switch              `git://git.openstack.org/openstack/networking-generic-switch <https://git.openstack.org/cgit/openstack/networking-generic-switch>`__
+networking-huawei                      `git://git.openstack.org/openstack/networking-huawei <https://git.openstack.org/cgit/openstack/networking-huawei>`__
 networking-infoblox                    `git://git.openstack.org/openstack/networking-infoblox <https://git.openstack.org/cgit/openstack/networking-infoblox>`__
 networking-l2gw                        `git://git.openstack.org/openstack/networking-l2gw <https://git.openstack.org/cgit/openstack/networking-l2gw>`__
 networking-midonet                     `git://git.openstack.org/openstack/networking-midonet <https://git.openstack.org/cgit/openstack/networking-midonet>`__
@@ -86,6 +93,7 @@
 networking-nec                         `git://git.openstack.org/openstack/networking-nec <https://git.openstack.org/cgit/openstack/networking-nec>`__
 networking-odl                         `git://git.openstack.org/openstack/networking-odl <https://git.openstack.org/cgit/openstack/networking-odl>`__
 networking-ofagent                     `git://git.openstack.org/openstack/networking-ofagent <https://git.openstack.org/cgit/openstack/networking-ofagent>`__
+networking-onos                        `git://git.openstack.org/openstack/networking-onos <https://git.openstack.org/cgit/openstack/networking-onos>`__
 networking-ovn                         `git://git.openstack.org/openstack/networking-ovn <https://git.openstack.org/cgit/openstack/networking-ovn>`__
 networking-ovs-dpdk                    `git://git.openstack.org/openstack/networking-ovs-dpdk <https://git.openstack.org/cgit/openstack/networking-ovs-dpdk>`__
 networking-plumgrid                    `git://git.openstack.org/openstack/networking-plumgrid <https://git.openstack.org/cgit/openstack/networking-plumgrid>`__
@@ -98,6 +106,7 @@
 neutron-lbaas-dashboard                `git://git.openstack.org/openstack/neutron-lbaas-dashboard <https://git.openstack.org/cgit/openstack/neutron-lbaas-dashboard>`__
 neutron-vpnaas                         `git://git.openstack.org/openstack/neutron-vpnaas <https://git.openstack.org/cgit/openstack/neutron-vpnaas>`__
 nova-docker                            `git://git.openstack.org/openstack/nova-docker <https://git.openstack.org/cgit/openstack/nova-docker>`__
+nova-lxd                               `git://git.openstack.org/openstack/nova-lxd <https://git.openstack.org/cgit/openstack/nova-lxd>`__
 nova-powervm                           `git://git.openstack.org/openstack/nova-powervm <https://git.openstack.org/cgit/openstack/nova-powervm>`__
 octavia                                `git://git.openstack.org/openstack/octavia <https://git.openstack.org/cgit/openstack/octavia>`__
 osprofiler                             `git://git.openstack.org/openstack/osprofiler <https://git.openstack.org/cgit/openstack/osprofiler>`__
diff --git a/doc/source/plugins.rst b/doc/source/plugins.rst
index 83e5609..70469d6 100644
--- a/doc/source/plugins.rst
+++ b/doc/source/plugins.rst
@@ -99,6 +99,8 @@
       should exist at this point.
    -  **extra** - Called near the end after layer 1 and 2 services have
       been started.
+   - **test-config** Called at the end of devstack used to configure tempest
+      or any other test environments
 
 -  **unstack** - Called by ``unstack.sh`` before other services are shut
    down.
diff --git a/exercises/boot_from_volume.sh b/exercises/boot_from_volume.sh
index 5409859..84ac08f 100755
--- a/exercises/boot_from_volume.sh
+++ b/exercises/boot_from_volume.sh
@@ -32,6 +32,7 @@
 
 # Import project functions
 source $TOP_DIR/lib/cinder
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 
 # Import configuration
diff --git a/exercises/floating_ips.sh b/exercises/floating_ips.sh
index 4b72a00..485208b 100755
--- a/exercises/floating_ips.sh
+++ b/exercises/floating_ips.sh
@@ -31,6 +31,7 @@
 source $TOP_DIR/openrc
 
 # Import project functions
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 
 # Import exercise configuration
diff --git a/exercises/neutron-adv-test.sh b/exercises/neutron-adv-test.sh
index a3128a8..8115006 100755
--- a/exercises/neutron-adv-test.sh
+++ b/exercises/neutron-adv-test.sh
@@ -37,6 +37,7 @@
 source $TOP_DIR/openrc
 
 # Import neutron functions
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 
 # If neutron is not enabled we exit with exitcode 55, which means exercise is skipped.
diff --git a/exercises/volumes.sh b/exercises/volumes.sh
index f95c81f..0de1226 100755
--- a/exercises/volumes.sh
+++ b/exercises/volumes.sh
@@ -32,6 +32,7 @@
 
 # Import project functions
 source $TOP_DIR/lib/cinder
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 
 # Import exercise configuration
diff --git a/extras.d/80-tempest.sh b/extras.d/80-tempest.sh
index fcf79bd..6a3d121 100644
--- a/extras.d/80-tempest.sh
+++ b/extras.d/80-tempest.sh
@@ -13,6 +13,8 @@
     elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
         echo_summary "Initializing Tempest"
         configure_tempest
+        echo_summary "Installing Tempest Plugins"
+        install_tempest_plugins
     elif [[ "$1" == "stack" && "$2" == "post-extra" ]]; then
         # local.conf Tempest option overrides
         :
diff --git a/files/apache-keystone.template b/files/apache-keystone.template
index 428544f..8a4b0f0 100644
--- a/files/apache-keystone.template
+++ b/files/apache-keystone.template
@@ -44,8 +44,8 @@
     WSGIPassAuthorization On
 </Location>
 
-Alias /identity_admin %KEYSTONE_BIN%/keystone-wsgi-admin
-<Location /identity_admin>
+Alias /identity_v2_admin %KEYSTONE_BIN%/keystone-wsgi-admin
+<Location /identity_v2_admin>
     SetHandler wsgi-script
     Options +ExecCGI
 
diff --git a/files/rpms/general b/files/rpms/general
index 2d4a97a..ee2e8a0 100644
--- a/files/rpms/general
+++ b/files/rpms/general
@@ -7,9 +7,9 @@
 gettext  # used for compiling message catalogs
 git-core
 graphviz # needed only for docs
-iptables-services  # NOPRIME f22,f23
+iptables-services  # NOPRIME f22,f23,f24
 java-1.7.0-openjdk-headless  # NOPRIME rhel7
-java-1.8.0-openjdk-headless  # NOPRIME f22,f23
+java-1.8.0-openjdk-headless  # NOPRIME f22,f23,f24
 libffi-devel
 libjpeg-turbo-devel # Pillow 3.0.0
 libxml2-devel # lxml
diff --git a/files/rpms/nova b/files/rpms/nova
index 0312e85..594393e 100644
--- a/files/rpms/nova
+++ b/files/rpms/nova
@@ -7,7 +7,7 @@
 genisoimage # required for config_drive
 iptables
 iputils
-kernel-modules # dist:f22,f23
+kernel-modules # dist:f22,f23,f24
 kpartx
 kvm # NOPRIME
 libvirt-bin # NOPRIME
diff --git a/files/rpms/swift b/files/rpms/swift
index 46dc59d..1e05167 100644
--- a/files/rpms/swift
+++ b/files/rpms/swift
@@ -2,7 +2,7 @@
 liberasurecode-devel
 memcached
 pyxattr
-rsync-daemon # dist:f22,f23
+rsync-daemon # dist:f22,f23,f24
 sqlite
 xfsprogs
 xinetd
diff --git a/functions b/functions
index 1bfb8a5..aa12e1e 100644
--- a/functions
+++ b/functions
@@ -41,6 +41,9 @@
     file=${file#$RC_DIR/}
     printf "%-40s " "$file:${called[1]}:${called[0]}"
 }
+# PS4 is exported to child shells and uses the 'short_source' function, so
+# export it so child shells have access to the 'short_source' function also.
+export -f short_source
 
 
 # Retrieve an image from a URL and upload into Glance.
@@ -83,7 +86,7 @@
     # OpenVZ-format images are provided as .tar.gz, but not decompressed prior to loading
     if [[ "$image_url" =~ 'openvz' ]]; then
         image_name="${image_fname%.tar.gz}"
-        openstack --os-cloud=devstack-admin image create "$image_name" --public --container-format ami --disk-format ami < "${image}"
+        openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name" --public --container-format ami --disk-format ami < "${image}"
         return
     fi
 
@@ -197,7 +200,7 @@
         vmdk_adapter_type="${props[1]:-$vmdk_adapter_type}"
         vmdk_net_adapter="${props[2]:-$vmdk_net_adapter}"
 
-        openstack --os-cloud=devstack-admin image create "$image_name" --public --container-format bare --disk-format vmdk --property vmware_disktype="$vmdk_disktype" --property vmware_adaptertype="$vmdk_adapter_type" --property hw_vif_model="$vmdk_net_adapter" < "${image}"
+        openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name" --public --container-format bare --disk-format vmdk --property vmware_disktype="$vmdk_disktype" --property vmware_adaptertype="$vmdk_adapter_type" --property hw_vif_model="$vmdk_net_adapter" < "${image}"
         return
     fi
 
@@ -214,7 +217,7 @@
             force_vm_mode="--property vm_mode=xen"
         fi
         openstack \
-            --os-cloud=devstack-admin \
+            --os-cloud=devstack-admin --os-region-name="$REGION_NAME" \
             image create \
             "$image_name" --public \
             --container-format=ovf --disk-format=vhd \
@@ -228,7 +231,7 @@
     if [[ "$image_url" =~ '.xen-raw.tgz' ]]; then
         image_name="${image_fname%.xen-raw.tgz}"
         openstack \
-            --os-cloud=devstack-admin \
+            --os-cloud=devstack-admin --os-region-name="$REGION_NAME" \
             image create \
             "$image_name" --public \
             --container-format=tgz --disk-format=raw \
@@ -244,7 +247,7 @@
         fi
 
         openstack \
-            --os-cloud=devstack-admin \
+            --os-cloud=devstack-admin --os-region-name="$REGION_NAME" \
             image create \
             "$image_name" --public \
             --container-format=bare --disk-format=ploop \
@@ -295,6 +298,12 @@
             container_format=bare
             unpack=zcat
             ;;
+        *.img.bz2)
+            image_name=$(basename "$image" ".img.bz2")
+            disk_format=qcow2
+            container_format=bare
+            unpack=bunzip2
+            ;;
         *.qcow2)
             image_name=$(basename "$image" ".qcow2")
             disk_format=qcow2
@@ -327,9 +336,11 @@
 
     if [ "$container_format" = "bare" ]; then
         if [ "$unpack" = "zcat" ]; then
-            openstack --os-cloud=devstack-admin image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < <(zcat --force "${image}")
+            openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < <(zcat --force "${image}")
+        elif [ "$unpack" = "bunzip2" ]; then
+            openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < <(bunzip2 -cdk "${image}")
         else
-            openstack --os-cloud=devstack-admin image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < "${image}"
+            openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < "${image}"
         fi
     else
         # Use glance client to add the kernel the root filesystem.
@@ -337,12 +348,12 @@
         # kernel for use when uploading the root filesystem.
         local kernel_id="" ramdisk_id="";
         if [ -n "$kernel" ]; then
-            kernel_id=$(openstack --os-cloud=devstack-admin image create "$image_name-kernel" $img_property --public --container-format aki --disk-format aki < "$kernel" | grep ' id ' | get_field 2)
+            kernel_id=$(openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name-kernel" $img_property --public --container-format aki --disk-format aki < "$kernel" | grep ' id ' | get_field 2)
         fi
         if [ -n "$ramdisk" ]; then
-            ramdisk_id=$(openstack --os-cloud=devstack-admin image create "$image_name-ramdisk" $img_property --public --container-format ari --disk-format ari < "$ramdisk" | grep ' id ' | get_field 2)
+            ramdisk_id=$(openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name-ramdisk" $img_property --public --container-format ari --disk-format ari < "$ramdisk" | grep ' id ' | get_field 2)
         fi
-        openstack --os-cloud=devstack-admin image create "${image_name%.img}" $img_property --public --container-format ami --disk-format ami ${kernel_id:+--property kernel_id=$kernel_id} ${ramdisk_id:+--property ramdisk_id=$ramdisk_id} < "${image}"
+        openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "${image_name%.img}" $img_property --public --container-format ami --disk-format ami ${kernel_id:+--property kernel_id=$kernel_id} ${ramdisk_id:+--property ramdisk_id=$ramdisk_id} < "${image}"
     fi
 }
 
@@ -500,61 +511,6 @@
 }
 
 
-# This function recursively compares versions, and is not meant to be
-# called by anything other than vercmp_numbers below. This function does
-# not work with alphabetic versions.
-#
-# _vercmp_r sep ver1 ver2
-function _vercmp_r {
-    typeset sep
-    typeset -a ver1=() ver2=()
-    sep=$1; shift
-    ver1=("${@:1:sep}")
-    ver2=("${@:sep+1}")
-
-    if ((ver1 > ver2)); then
-        echo 1; return 0
-    elif ((ver2 > ver1)); then
-        echo -1; return 0
-    fi
-
-    if ((sep <= 1)); then
-        echo 0; return 0
-    fi
-
-    _vercmp_r $((sep-1)) "${ver1[@]:1}" "${ver2[@]:1}"
-}
-
-
-# This function compares two versions and is meant to be called by
-# external callers. Please note the function assumes non-alphabetic
-# versions. For example, this will work:
-#
-#   vercmp_numbers 1.10 1.4
-#
-# The above will return "1", as 1.10 is greater than 1.4.
-#
-#   vercmp_numbers 5.2 6.4
-#
-# The above will return "-1", as 5.2 is less than 6.4.
-#
-#   vercmp_numbers 4.0 4.0
-#
-# The above will return "0", as the versions are equal.
-#
-# vercmp_numbers ver1 ver2
-function vercmp_numbers {
-    typeset v1=$1 v2=$2 sep
-    typeset -a ver1 ver2
-
-    deprecated "vercmp_numbers is deprecated for more generic vercmp"
-
-    IFS=. read -ra ver1 <<< "$v1"
-    IFS=. read -ra ver2 <<< "$v2"
-
-    _vercmp_r "${#ver1[@]}" "${ver1[@]}" "${ver2[@]}"
-}
-
 # vercmp ver1 op ver2
 #  Compare VER1 to VER2
 #   - op is one of < <= == >= >
diff --git a/functions-common b/functions-common
index e44fea1..3fdd71b 100644
--- a/functions-common
+++ b/functions-common
@@ -380,6 +380,7 @@
         DISTRO="sle${os_RELEASE%.*}"
     elif [[ "$os_VENDOR" =~ (Red.*Hat) || \
         "$os_VENDOR" =~ (CentOS) || \
+        "$os_VENDOR" =~ (Scientific) || \
         "$os_VENDOR" =~ (OracleServer) || \
         "$os_VENDOR" =~ (Virtuozzo) ]]; then
         # Drop the . release as we assume it's compatible
@@ -2063,14 +2064,14 @@
         # TODO(dtroyer): Remove these legacy special-cases after the is_XXX_enabled()
         #                are implemented
 
-        [[ ${service} == n-cell-* && ${ENABLED_SERVICES} =~ "n-cell" ]] && enabled=0
-        [[ ${service} == n-cpu-* && ${ENABLED_SERVICES} =~ "n-cpu" ]] && enabled=0
-        [[ ${service} == "nova" && ${ENABLED_SERVICES} =~ "n-" ]] && enabled=0
-        [[ ${service} == "glance" && ${ENABLED_SERVICES} =~ "g-" ]] && enabled=0
-        [[ ${service} == "neutron" && ${ENABLED_SERVICES} =~ "q-" ]] && enabled=0
-        [[ ${service} == "trove" && ${ENABLED_SERVICES} =~ "tr-" ]] && enabled=0
-        [[ ${service} == "swift" && ${ENABLED_SERVICES} =~ "s-" ]] && enabled=0
-        [[ ${service} == s-* && ${ENABLED_SERVICES} =~ "swift" ]] && enabled=0
+        [[ ${service} == n-cell-* && ,${ENABLED_SERVICES} =~ ,"n-cell" ]] && enabled=0
+        [[ ${service} == n-cpu-* && ,${ENABLED_SERVICES} =~ ,"n-cpu" ]] && enabled=0
+        [[ ${service} == "nova" && ,${ENABLED_SERVICES} =~ ,"n-" ]] && enabled=0
+        [[ ${service} == "glance" && ,${ENABLED_SERVICES} =~ ,"g-" ]] && enabled=0
+        [[ ${service} == "neutron" && ,${ENABLED_SERVICES} =~ ,"q-" ]] && enabled=0
+        [[ ${service} == "trove" && ,${ENABLED_SERVICES} =~ ,"tr-" ]] && enabled=0
+        [[ ${service} == "swift" && ,${ENABLED_SERVICES} =~ ,"s-" ]] && enabled=0
+        [[ ${service} == s-* && ,${ENABLED_SERVICES} =~ ,"swift" ]] && enabled=0
     done
 
     $xtrace
@@ -2263,11 +2264,12 @@
 # Service wrapper to restart services
 # restart_service service-name
 function restart_service {
-    if is_ubuntu; then
-        sudo /usr/sbin/service $1 restart
+    if [ -x /bin/systemctl ]; then
+        sudo /bin/systemctl restart $1
     else
-        sudo /sbin/service $1 restart
+        sudo service $1 restart
     fi
+
 }
 
 # Only change permissions of a file or directory if it is not on an
@@ -2285,20 +2287,20 @@
 # Service wrapper to start services
 # start_service service-name
 function start_service {
-    if is_ubuntu; then
-        sudo /usr/sbin/service $1 start
+    if [ -x /bin/systemctl ]; then
+        sudo /bin/systemctl start $1
     else
-        sudo /sbin/service $1 start
+        sudo service $1 start
     fi
 }
 
 # Service wrapper to stop services
 # stop_service service-name
 function stop_service {
-    if is_ubuntu; then
-        sudo /usr/sbin/service $1 stop
+    if [ -x /bin/systemctl ]; then
+        sudo /bin/systemctl stop $1
     else
-        sudo /sbin/service $1 stop
+        sudo service $1 stop
     fi
 }
 
@@ -2369,7 +2371,7 @@
 function time_stop {
     local name
     local end_time
-    local elpased_time
+    local elapsed_time
     local total
     local start_time
 
diff --git a/inc/python b/inc/python
index 495150d..e013dfa 100644
--- a/inc/python
+++ b/inc/python
@@ -192,7 +192,7 @@
 function use_library_from_git {
     local name=$1
     local enabled=1
-    [[ ,${LIBS_FROM_GIT}, =~ ,${name}, ]] && enabled=0
+    [[ ${LIBS_FROM_GIT} = 'ALL' ]] || [[ ,${LIBS_FROM_GIT}, =~ ,${name}, ]] && enabled=0
     return $enabled
 }
 
diff --git a/lib/ceph b/lib/ceph
index 3e0839a..e999647 100644
--- a/lib/ceph
+++ b/lib/ceph
@@ -116,7 +116,7 @@
 
 # check_os_support_ceph() - Check if the operating system provides a decent version of Ceph
 function check_os_support_ceph {
-    if [[ ! ${DISTRO} =~ (trusty|f22|f23) ]]; then
+    if [[ ! ${DISTRO} =~ (trusty|f22|f23|f24) ]]; then
         echo "WARNING: your distro $DISTRO does not provide (at least) the Firefly release. Please use Ubuntu Trusty or Fedora 20 (and higher)"
         if [[ "$FORCE_CEPH_INSTALL" != "yes" ]]; then
             die $LINENO "If you wish to install Ceph on this distribution anyway run with FORCE_CEPH_INSTALL=yes"
diff --git a/lib/cinder b/lib/cinder
index 607a6f8..0ebf195 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -40,6 +40,7 @@
 # set up default directories
 GITDIR["python-cinderclient"]=$DEST/python-cinderclient
 GITDIR["os-brick"]=$DEST/os-brick
+GITDIR["python-brick-cinderclient-ext"]=$DEST/python-brick-cinderclient-ext
 CINDER_DIR=$DEST/cinder
 
 # Cinder virtual environment
@@ -269,6 +270,7 @@
     iniset $CINDER_CONF DEFAULT state_path $CINDER_STATE_PATH
     iniset $CINDER_CONF oslo_concurrency lock_path $CINDER_STATE_PATH
     iniset $CINDER_CONF DEFAULT periodic_interval $CINDER_PERIODIC_INTERVAL
+    iniset $CINDER_CONF DEFAULT my_ip "$HOST_IP"
 
     iniset $CINDER_CONF DEFAULT os_region_name "$REGION_NAME"
 
@@ -342,6 +344,10 @@
         iniset $CINDER_CONF DEFAULT glance_ca_certificates_file $SSL_BUNDLE_FILE
     fi
 
+    if [ "$GLANCE_V1_ENABLED" != "True" ]; then
+        iniset $CINDER_CONF DEFAULT glance_api_version 2
+    fi
+
     # Register SSL certificates if provided
     if is_ssl_enabled_service cinder; then
         ensure_certificates CINDER
@@ -415,7 +421,7 @@
         recreate_database cinder
 
         # Migrate cinder database
-        $CINDER_BIN_DIR/cinder-manage db sync
+        $CINDER_BIN_DIR/cinder-manage --config-file $CINDER_CONF db sync
     fi
 
     if is_service_enabled c-vol && [[ -n "$CINDER_ENABLED_BACKENDS" ]]; then
@@ -466,6 +472,11 @@
 
 # install_cinderclient() - Collect source and prepare
 function install_cinderclient {
+    if use_library_from_git "python-brick-cinderclient-ext"; then
+        git_clone_by_name "python-brick-cinderclient-ext"
+        setup_dev_lib "python-brick-cinderclient-ext"
+    fi
+
     if use_library_from_git "python-cinderclient"; then
         git_clone_by_name "python-cinderclient"
         setup_dev_lib "python-cinderclient"
@@ -560,7 +571,7 @@
         local be be_name
         for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
             be_name=${be##*:}
-            openstack volume type create --property volume_backend_name="${be_name}" ${be_name}
+            openstack --os-region-name="$REGION_NAME" volume type create --property volume_backend_name="${be_name}" ${be_name}
         done
     fi
 }
diff --git a/lib/dlm b/lib/dlm
index 74eb67e..e391535 100644
--- a/lib/dlm
+++ b/lib/dlm
@@ -93,6 +93,8 @@
     if is_dlm_enabled; then
         if is_ubuntu; then
             install_package zookeeperd
+        elif is_fedora; then
+            install_package zookeeper
         else
             die $LINENO "Don't know how to install zookeeper on this platform"
         fi
diff --git a/lib/glance b/lib/glance
index ce5f867..8d95aad 100644
--- a/lib/glance
+++ b/lib/glance
@@ -57,6 +57,7 @@
 GLANCE_SWIFT_STORE_CONF=$GLANCE_CONF_DIR/glance-swift-store.conf
 GLANCE_GLARE_CONF=$GLANCE_CONF_DIR/glance-glare.conf
 GLANCE_GLARE_PASTE_INI=$GLANCE_CONF_DIR/glance-glare-paste.ini
+GLANCE_V1_ENABLED=${GLANCE_V1_ENABLED:-True}
 
 if is_ssl_enabled_service "glance" || is_service_enabled tls-proxy; then
     GLANCE_SERVICE_PROTOCOL="https"
@@ -134,6 +135,12 @@
         iniset $GLANCE_API_CONF DEFAULT disk_formats "ami,ari,aki,vhd,vmdk,raw,qcow2,vdi,iso,ploop"
     fi
 
+    # NOTE(flaper87): To uncomment as soon as all services consuming Glance are
+    # able to consume V2 entirely.
+    if [ "$GLANCE_V1_ENABLED" != "True" ]; then
+        iniset $GLANCE_API_CONF DEFAULT enable_v1_api False
+    fi
+
     # Store specific configs
     iniset $GLANCE_API_CONF glance_store filesystem_store_datadir $GLANCE_IMAGE_DIR/
     if is_service_enabled g-glare; then
@@ -341,10 +348,10 @@
     recreate_database glance
 
     # Migrate glance database
-    $GLANCE_BIN_DIR/glance-manage db_sync
+    $GLANCE_BIN_DIR/glance-manage --config-file $GLANCE_CONF_DIR/glance-api.conf db_sync
 
     # Load metadata definitions
-    $GLANCE_BIN_DIR/glance-manage db_load_metadefs
+    $GLANCE_BIN_DIR/glance-manage --config-file $GLANCE_CONF_DIR/glance-api.conf db_load_metadefs
 
     create_glance_cache_dir
 }
@@ -369,11 +376,6 @@
 
     git_clone $GLANCE_REPO $GLANCE_DIR $GLANCE_BRANCH
 
-    if is_service_enabled g-search; then
-        ${TOP_DIR}/pkg/elasticsearch.sh download
-        ${TOP_DIR}/pkg/elasticsearch.sh install
-    fi
-
     setup_develop $GLANCE_DIR
 }
 
@@ -393,7 +395,7 @@
         die $LINENO "g-api did not start"
     fi
 
-    #Start g-glare after g-reg/g-api/g-search
+    #Start g-glare after g-reg/g-api
     if is_service_enabled g-glare; then
         run_process g-glare "$GLANCE_BIN_DIR/glance-glare --config-file=$GLANCE_CONF_DIR/glance-glare.conf"
         echo "Waiting for Glare [g-glare] ($GLANCE_GLARE_HOSTPORT) to start..."
diff --git a/lib/heat b/lib/heat
index 4326321..c841e0a 100644
--- a/lib/heat
+++ b/lib/heat
@@ -156,7 +156,7 @@
     # If HEAT_DEFERRED_AUTH is unset or explicitly set to trusts, configure
     # the section for the client plugin associated with the trustee
     if [ -z "$HEAT_DEFERRED_AUTH" -o "trusts" == "$HEAT_DEFERRED_AUTH" ]; then
-        iniset $HEAT_CONF trustee auth_plugin password
+        iniset $HEAT_CONF trustee auth_type password
         iniset $HEAT_CONF trustee auth_url $KEYSTONE_AUTH_URI
         iniset $HEAT_CONF trustee username $HEAT_TRUSTEE_USER
         iniset $HEAT_CONF trustee password $HEAT_TRUSTEE_PASSWORD
@@ -241,7 +241,7 @@
     # (re)create heat database
     recreate_database heat
 
-    $HEAT_BIN_DIR/heat-manage db_sync
+    $HEAT_BIN_DIR/heat-manage --config-file $HEAT_CONF db_sync
     create_heat_cache_dir
 }
 
diff --git a/lib/horizon b/lib/horizon
index abc1f6d..0517e32 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -96,7 +96,7 @@
     _horizon_config_set $local_settings "" OPENSTACK_HOST \"${KEYSTONE_SERVICE_HOST}\"
 
     _horizon_config_set $local_settings "" OPENSTACK_API_VERSIONS {\"identity\":3}
-    _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}:${KEYSTONE_SERVICE_PORT}/v3\""
+    _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_URI}/v3\""
 
     if [ -f $SSL_BUNDLE_FILE ]; then
         _horizon_config_set $local_settings "" OPENSTACK_SSL_CACERT \"${SSL_BUNDLE_FILE}\"
diff --git a/lib/keystone b/lib/keystone
index 542bd05..6198e43 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -122,8 +122,14 @@
 fi
 
 # complete URIs
-KEYSTONE_AUTH_URI=${KEYSTONE_AUTH_PROTOCOL}://${KEYSTONE_AUTH_HOST}:${KEYSTONE_AUTH_PORT}
-KEYSTONE_SERVICE_URI=${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}:${KEYSTONE_SERVICE_PORT}
+if [ "$KEYSTONE_DEPLOY" == "mod_wsgi" ]; then
+    # If running in Apache, use path access rather than port.
+    KEYSTONE_AUTH_URI=${KEYSTONE_AUTH_PROTOCOL}://${KEYSTONE_AUTH_HOST}/identity_v2_admin
+    KEYSTONE_SERVICE_URI=${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}/identity
+else
+    KEYSTONE_AUTH_URI=${KEYSTONE_AUTH_PROTOCOL}://${KEYSTONE_AUTH_HOST}:${KEYSTONE_AUTH_PORT}
+    KEYSTONE_SERVICE_URI=${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}:${KEYSTONE_SERVICE_PORT}
+fi
 
 # V3 URIs
 KEYSTONE_AUTH_URI_V3=$KEYSTONE_AUTH_URI/v3
@@ -240,7 +246,7 @@
     # Enable caching
     iniset $KEYSTONE_CONF cache enabled "True"
     iniset $KEYSTONE_CONF cache backend "oslo_cache.memcache_pool"
-    iniset $KEYSTONE_CONF cache memcache_servers $SERVICE_HOST:11211
+    iniset $KEYSTONE_CONF cache memcache_servers localhost:11211
 
     # Do not cache the catalog backend due to https://bugs.launchpad.net/keystone/+bug/1537617
     iniset $KEYSTONE_CONF catalog caching "False"
@@ -259,7 +265,15 @@
         # Set the service ports for a proxy to take the originals
         service_port=$KEYSTONE_SERVICE_PORT_INT
         auth_port=$KEYSTONE_AUTH_PORT_INT
+    fi
 
+    # Override the endpoints advertised by keystone (the public_endpoint and
+    # admin_endpoint) so that clients use the correct endpoint. By default, the
+    # keystone server uses the public_port and admin_port which isn't going to
+    # work when you want to use a different port (in the case of proxy), or you
+    # don't want the port (in the case of putting keystone on a path in
+    # apache).
+    if is_service_enabled tls-proxy || [ "$KEYSTONE_DEPLOY" == "mod_wsgi" ]; then
         iniset $KEYSTONE_CONF DEFAULT public_endpoint $KEYSTONE_SERVICE_URI
         iniset $KEYSTONE_CONF DEFAULT admin_endpoint $KEYSTONE_AUTH_URI
     fi
@@ -304,10 +318,10 @@
         fi
 
         iniset "$KEYSTONE_PUBLIC_UWSGI_FILE" uwsgi wsgi-file "$KEYSTONE_BIN_DIR/keystone-wsgi-public"
-        iniset "$KEYSTONE_PUBLIC_UWSGI_FILE" uwsgi threads $(nproc)
+        iniset "$KEYSTONE_PUBLIC_UWSGI_FILE" uwsgi processes $(nproc)
 
         iniset "$KEYSTONE_ADMIN_UWSGI_FILE" uwsgi wsgi-file "$KEYSTONE_BIN_DIR/keystone-wsgi-admin"
-        iniset "$KEYSTONE_ADMIN_UWSGI_FILE" uwsgi threads $API_WORKERS
+        iniset "$KEYSTONE_ADMIN_UWSGI_FILE" uwsgi processes $API_WORKERS
 
         # Common settings
         for file in "$KEYSTONE_PUBLIC_UWSGI_FILE" "$KEYSTONE_ADMIN_UWSGI_FILE"; do
@@ -334,7 +348,7 @@
     # Configure the project created by the 'keystone-manage bootstrap' as the cloud-admin project.
     # The users from this project are globally admin as before, but it also
     # allows policy changes in order to clarify the adminess scope.
-    iniset $KEYSTONE_CONF resource admin_project_domain_name default
+    iniset $KEYSTONE_CONF resource admin_project_domain_name Default
     iniset $KEYSTONE_CONF resource admin_project_name admin
 }
 
@@ -376,7 +390,7 @@
 
     # Create service project/role
     get_or_create_domain "$SERVICE_DOMAIN_NAME"
-    get_or_create_project "$SERVICE_PROJECT_NAME" default
+    get_or_create_project "$SERVICE_PROJECT_NAME" "$SERVICE_DOMAIN_NAME"
 
     # Service role, so service users do not have to be admins
     get_or_create_role service
@@ -489,16 +503,16 @@
     recreate_database keystone
 
     # Initialize keystone database
-    $KEYSTONE_BIN_DIR/keystone-manage db_sync
+    $KEYSTONE_BIN_DIR/keystone-manage --config-file $KEYSTONE_CONF db_sync
 
     if [[ "$KEYSTONE_TOKEN_FORMAT" == "pki" || "$KEYSTONE_TOKEN_FORMAT" == "pkiz" ]]; then
         # Set up certificates
         rm -rf $KEYSTONE_CONF_DIR/ssl
-        $KEYSTONE_BIN_DIR/keystone-manage pki_setup
+        $KEYSTONE_BIN_DIR/keystone-manage --config-file $KEYSTONE_CONF pki_setup
     fi
     if [[ "$KEYSTONE_TOKEN_FORMAT" == "fernet" ]]; then
         rm -rf "$KEYSTONE_CONF_DIR/fernet-keys/"
-        $KEYSTONE_BIN_DIR/keystone-manage fernet_setup
+        $KEYSTONE_BIN_DIR/keystone-manage --config-file $KEYSTONE_CONF fernet_setup
     fi
 }
 
@@ -582,7 +596,14 @@
     # Check that the keystone service is running. Even if the tls tunnel
     # should be enabled, make sure the internal port is checked using
     # unencryted traffic at this point.
-    if ! wait_for_service $SERVICE_TIMEOUT $auth_protocol://$KEYSTONE_SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/; then
+    # If running in Apache, use the path rather than port.
+
+    local service_uri=$auth_protocol://$KEYSTONE_SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/
+    if [ "$KEYSTONE_DEPLOY" == "mod_wsgi" ]; then
+        service_uri=$auth_protocol://$KEYSTONE_SERVICE_HOST/identity/v$IDENTITY_API_VERSION/
+    fi
+
+    if ! wait_for_service $SERVICE_TIMEOUT $service_uri; then
         die $LINENO "keystone did not start"
     fi
 
@@ -625,8 +646,8 @@
         --bootstrap-service-name keystone \
         --bootstrap-region-id "$REGION_NAME" \
         --bootstrap-admin-url "$KEYSTONE_AUTH_URI" \
-        --bootstrap-public-url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT" \
-        --bootstrap-internal-url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT"
+        --bootstrap-public-url "$KEYSTONE_SERVICE_URI" \
+        --bootstrap-internal-url "$KEYSTONE_SERVICE_URI"
 }
 
 # Restore xtrace
diff --git a/lib/neutron b/lib/neutron
new file mode 100644
index 0000000..ba26c5f
--- /dev/null
+++ b/lib/neutron
@@ -0,0 +1,563 @@
+#!/bin/bash
+#
+# lib/neutron
+# Install and start **Neutron** network services
+
+# Dependencies:
+#
+# ``functions`` file
+# ``DEST`` must be defined
+
+# ``stack.sh`` calls the entry points in this order:
+#
+# - is_XXXX_enabled
+# - install_XXXX
+# - configure_XXXX
+# - init_XXXX
+# - start_XXXX
+# - stop_XXXX
+# - cleanup_XXXX
+
+# Save trace setting
+XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+# Defaults
+# --------
+
+# Set up default directories
+GITDIR["python-neutronclient"]=$DEST/python-neutronclient
+
+NEUTRON_AGENT=${NEUTRON_AGENT:-openvswitch}
+NEUTRON_DIR=$DEST/neutron
+NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron}
+
+NEUTRON_BIN_DIR=$(get_python_exec_prefix)
+NEUTRON_DHCP_BINARY="neutron-dhcp-agent"
+
+NEUTRON_CONF_DIR=/etc/neutron
+NEUTRON_CONF=$NEUTRON_CONF_DIR/neutron.conf
+NEUTRON_META_CONF=$NEUTRON_CONF_DIR/metadata_agent.ini
+
+NEUTRON_DHCP_CONF=$NEUTRON_CONF_DIR/dhcp_agent.ini
+NEUTRON_L3_CONF=$NEUTRON_CONF_DIR/l3_agent.ini
+NEUTRON_AGENT_CONF=$NEUTRON_CONF_DIR/
+
+NEUTRON_STATE_PATH=${NEUTRON_STATE_PATH:=$DATA_DIR/neutron}
+NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron}
+
+# By default, use the ML2 plugin
+NEUTRON_PLUGIN=${NEUTRON_PLUGIN:-ml2}
+NEUTRON_PLUGIN_CONF_FILENAME=${NEUTRON_PLUGIN_CONF_FILENAME:-ml2_conf.ini}
+NEUTRON_PLUGIN_CONF_PATH=$NEUTRON_CONF_DIR/plugins/$NEUTRON_PLUGIN
+NEUTRON_PLUGIN_CONF=$NEUTRON_PLUGIN_CONF_PATH/$NEUTRON_PLUGIN_CONF_FILENAME
+
+NEUTRON_AGENT_BINARY=${NEUTRON_AGENT_BINARY:-neutron-$NEUTRON_AGENT-agent}
+NEUTRON_L3_BINARY=${NEUTRON_L3_BINARY:-neutron-l3-agent}
+NEUTRON_META_BINARY=${NEUTRON_META_BINARY:-neutron-metadata-agent}
+
+# Public facing bits
+if is_ssl_enabled_service "neutron" || is_service_enabled tls-proxy; then
+    NEUTRON_SERVICE_PROTOCOL="https"
+fi
+NEUTRON_SERVICE_HOST=${NEUTRON_SERVICE_HOST:-$SERVICE_HOST}
+NEUTRON_SERVICE_PORT=${NEUTRON_SERVICE_PORT:-9696}
+NEUTRON_SERVICE_PORT_INT=${NEUTRON_SERVICE_PORT_INT:-19696}
+NEUTRON_SERVICE_PROTOCOL=${NEUTRON_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
+
+NEUTRON_AUTH_STRATEGY=${NEUTRON_AUTH_STRATEGY:-keystone}
+NEUTRON_ROOTWRAP=$(get_rootwrap_location neutron)
+NEUTRON_ROOTWRAP_CONF_FILE=$NEUTRON_CONF_DIR/rootwrap.conf
+NEUTRON_ROOTWRAP_DAEMON_CMD="sudo $NEUTRON_ROOTWRAP-daemon $NEUTRON_ROOTWRAP_CONF_FILE"
+
+# Add all enabled config files to a single config arg
+NEUTRON_CONFIG_ARG=${NEUTRON_CONFIG_ARG:-""}
+
+# Functions
+# ---------
+
+# Test if any Neutron services are enabled
+# is_neutron_enabled
+function is_neutron_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"neutron-" || ,${ENABLED_SERVICES} =~ ,"q-" ]] && return 0
+    return 1
+}
+
+# Test if any Neutron services are enabled
+# is_neutron_enabled
+function is_neutron_legacy_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"q-" ]] && return 0
+    return 1
+}
+
+# cleanup_neutron() - Remove residual data files, anything left over from previous
+# runs that a clean run would need to clean up
+function cleanup_neutron_new {
+    source $TOP_DIR/lib/neutron_plugins/${NEUTRON_AGENT}_agent
+    if is_neutron_ovs_base_plugin; then
+        neutron_ovs_base_cleanup
+    fi
+
+    if [[ $NEUTRON_AGENT == "linuxbridge" ]]; then
+        neutron_lb_cleanup
+    fi
+    # delete all namespaces created by neutron
+    for ns in $(sudo ip netns list | grep -o -E '(qdhcp|qrouter|qlbaas|fip|snat)-[0-9a-f-]*'); do
+        sudo ip netns delete ${ns}
+    done
+}
+
+# configure_neutron() - Set config files, create data dirs, etc
+function configure_neutron_new {
+    sudo install -d -o $STACK_USER $NEUTRON_CONF_DIR
+
+    (cd $NEUTRON_DIR && exec ./tools/generate_config_file_samples.sh)
+
+    cp $NEUTRON_DIR/etc/neutron.conf.sample $NEUTRON_CONF
+
+    configure_neutron_rootwrap
+
+    mkdir -p $NEUTRON_PLUGIN_CONF_PATH
+
+    cp $NEUTRON_DIR/etc/neutron/plugins/$NEUTRON_PLUGIN/$NEUTRON_PLUGIN_CONF_FILENAME.sample $NEUTRON_PLUGIN_CONF
+
+    iniset $NEUTRON_CONF database connection `database_connection_url neutron`
+    iniset $NEUTRON_CONF DEFAULT state_path $NEUTRON_STATE_PATH
+    iniset $NEUTRON_CONF oslo_concurrency lock_path $NEUTRON_STATE_PATH/lock
+    iniset $NEUTRON_CONF DEFAULT use_syslog $SYSLOG
+
+    iniset $NEUTRON_CONF DEFAULT debug True
+
+    iniset_rpc_backend neutron $NEUTRON_CONF
+
+    # Neutron API server & Neutron plugin
+    if is_service_enabled neutron-api; then
+        local policy_file=$NEUTRON_CONF_DIR/policy.json
+        cp $NEUTRON_DIR/etc/policy.json $policy_file
+        # Allow neutron user to administer neutron to match neutron account
+        sed -i 's/"context_is_admin":  "role:admin"/"context_is_admin":  "role:admin or user_name:neutron"/g' $policy_file
+
+        cp $NEUTRON_DIR/etc/api-paste.ini $NEUTRON_CONF_DIR/api-paste.ini
+
+        iniset $NEUTRON_CONF DEFAULT core_plugin ml2
+
+        iniset $NEUTRON_CONF DEFAULT policy_file $policy_file
+        iniset $NEUTRON_CONF DEFAULT allow_overlapping_ips True
+
+        iniset $NEUTRON_CONF DEFAULT auth_strategy $NEUTRON_AUTH_STRATEGY
+        configure_auth_token_middleware $NEUTRON_CONF neutron $NEUTRON_AUTH_CACHE_DIR keystone_authtoken
+
+        # Configuration for neutron notifations to nova.
+        iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_status_changes $Q_NOTIFY_NOVA_PORT_STATUS_CHANGES
+        iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_data_changes $Q_NOTIFY_NOVA_PORT_DATA_CHANGES
+
+        iniset $NEUTRON_CONF nova auth_type password
+        iniset $NEUTRON_CONF nova auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v3"
+        iniset $NEUTRON_CONF nova username nova
+        iniset $NEUTRON_CONF nova password $SERVICE_PASSWORD
+        iniset $NEUTRON_CONF nova user_domain_id default
+        iniset $NEUTRON_CONF nova project_name $SERVICE_TENANT_NAME
+        iniset $NEUTRON_CONF nova project_domain_id default
+        iniset $NEUTRON_CONF nova region_name $REGION_NAME
+
+        # Configure VXLAN
+        # TODO(sc68cal) not hardcode?
+        iniset $NEUTRON_PLUGIN_CONF ml2 tenant_network_types vxlan
+        iniset $NEUTRON_PLUGIN_CONF ml2 type_drivers vxlan
+        iniset $NEUTRON_PLUGIN_CONF ml2 mechanism_drivers openvswitch,linuxbridge
+        iniset $NEUTRON_PLUGIN_CONF ml2_type_vxlan vni_ranges 1001:2000
+    fi
+
+    # Neutron OVS or LB agent
+    if is_service_enabled neutron-agent; then
+        iniset $NEUTRON_PLUGIN_CONF agent tunnel_types vxlan
+        iniset $NEUTRON_PLUGIN_CONF DEFAULT debug True
+
+        # Configure the neutron agent
+        if [[ $NEUTRON_AGENT == "linuxbridge" ]]; then
+            iniset $NEUTRON_PLUGIN_CONF securitygroup iptables
+            iniset $NEUTRON_PLUGIN_CONF vxlan local_ip $HOST_IP
+        else
+            iniset $NEUTRON_PLUGIN_CONF securitygroup iptables_hybrid
+            iniset $NEUTRON_PLUGIN_CONF ovs local_ip $HOST_IP
+        fi
+    fi
+
+    # DHCP Agent
+    if is_service_enabled neutron-dhcp; then
+        cp $NEUTRON_DIR/etc/dhcp_agent.ini.sample $NEUTRON_DHCP_CONF
+
+        iniset $NEUTRON_DHCP_CONF DEFAULT debug True
+        iniset $NEUTRON_DHCP_CONF agent root_helper_daemon "$NEUTRON_ROOTWRAP_DAEMON_CMD"
+        iniset $NEUTRON_DHCP_CONF DEFAULT interface_driver $NEUTRON_AGENT
+        neutron_plugin_configure_dhcp_agent $NEUTRON_DHCP_CONF
+    fi
+
+    if is_service_enabled neutron-l3; then
+        cp $NEUTRON_DIR/etc/l3_agent.ini.sample $NEUTRON_L3_CONF
+        iniset $NEUTRON_L3_CONF DEFAULT interface_driver $NEUTRON_AGENT
+        iniset $NEUTRON_CONF DEFAULT service_plugins router
+        iniset $NEUTRON_L3_CONF agent root_helper_daemon "$NEUTRON_ROOTWRAP_DAEMON_CMD"
+        iniset $NEUTRON_L3_CONF DEFAULT debug True
+        neutron_plugin_configure_l3_agent $NEUTRON_L3_CONF
+    fi
+
+    # Metadata
+    if is_service_enabled neutron-metadata-agent; then
+        cp $NEUTRON_DIR/etc/metadata_agent.ini.sample $NEUTRON_META_CONF
+
+        iniset $NEUTRON_META_CONF DEFAULT debug True
+        iniset $NEUTRON_META_CONF DEFAULT nova_metadata_ip $SERVICE_HOST
+        iniset $NEUTRON_META_CONF agent root_helper_daemon "$NEUTRON_ROOTWRAP_DAEMON_CMD"
+
+        # TODO(dtroyer): remove the v2.0 hard code below
+        iniset $NEUTRON_META_CONF DEFAULT auth_url $KEYSTONE_SERVICE_URI/v2.0
+        configure_auth_token_middleware $NEUTRON_META_CONF neutron $NEUTRON_AUTH_CACHE_DIR DEFAULT
+    fi
+
+    # Format logging
+    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
+        setup_colorized_logging $NEUTRON_CONF DEFAULT project_id
+    else
+        # Show user_name and project_name by default
+        iniset $NEUTRON_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s"
+    fi
+
+    if is_service_enabled tls-proxy; then
+        # Set the service port for a proxy to take the original
+        iniset $NEUTRON_CONF DEFAULT bind_port "$NEUTRON_SERVICE_PORT_INT"
+    fi
+
+    if is_ssl_enabled_service "nova"; then
+        iniset $NEUTRON_CONF nova cafile $SSL_BUNDLE_FILE
+    fi
+
+    if is_ssl_enabled_service "neutron"; then
+        ensure_certificates NEUTRON
+
+        iniset $NEUTRON_CONF DEFAULT use_ssl True
+        iniset $NEUTRON_CONF DEFAULT ssl_cert_file "$NEUTRON_SSL_CERT"
+        iniset $NEUTRON_CONF DEFAULT ssl_key_file "$NEUTRON_SSL_KEY"
+    fi
+
+    # Metering
+    if is_service_enabled neutron-metering; then
+        source $TOP_DIR/neutron_plugins/services/metering
+        neutron_agent_metering_configure_common
+        neutron_agent_metering_configure_agent
+    fi
+
+}
+
+# configure_neutron_rootwrap() - configure Neutron's rootwrap
+function configure_neutron_rootwrap {
+    # Set the paths of certain binaries
+    neutron_rootwrap=$(get_rootwrap_location neutron)
+
+    # Specify ``rootwrap.conf`` as first parameter to neutron-rootwrap
+    local rootwrap_sudoer_cmd="${neutron_rootwrap} $NEUTRON_CONF_DIR/rootwrap.conf"
+
+    # Deploy new rootwrap filters files (owned by root).
+    # Wipe any existing rootwrap.d files first
+    if [[ -d $NEUTRON_CONF_DIR/rootwrap.d ]]; then
+        sudo rm -rf $NEUTRON_CONF_DIR/rootwrap.d
+    fi
+
+    # Deploy filters to /etc/neutron/rootwrap.d
+    sudo install -d -o root -g root -m 755 $NEUTRON_CONF_DIR/rootwrap.d
+    sudo install -o root -g root -m 644 $NEUTRON_DIR/etc/neutron/rootwrap.d/*.filters $NEUTRON_CONF_DIR/rootwrap.d
+
+    # Set up ``rootwrap.conf``, pointing to ``$NEUTRON_CONF_DIR/rootwrap.d``
+    sudo install -o root -g root -m 644 $NEUTRON_DIR/etc/rootwrap.conf $NEUTRON_CONF_DIR
+    sudo sed -e "s:^filters_path=.*$:filters_path=$NEUTRON_CONF_DIR/rootwrap.d:" -i $NEUTRON_CONF_DIR/rootwrap.conf
+
+    # Set up the rootwrap sudoers for Neutron
+    tempfile=`mktemp`
+    echo "$STACK_USER ALL=(root) NOPASSWD: $rootwrap_sudoer_cmd *" >$tempfile
+    chmod 0440 $tempfile
+    sudo chown root:root $tempfile
+    sudo mv $tempfile /etc/sudoers.d/neutron-rootwrap
+}
+
+# Make Neutron-required changes to nova.conf
+function configure_neutron_nova_new {
+    iniset $NOVA_CONF DEFAULT use_neutron True
+    iniset $NOVA_CONF neutron auth_type "password"
+    iniset $NOVA_CONF neutron auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v3"
+    iniset $NOVA_CONF neutron username neutron
+    iniset $NOVA_CONF neutron password "$SERVICE_PASSWORD"
+    iniset $NOVA_CONF neutron user_domain_name "Default"
+    iniset $NOVA_CONF neutron project_name "$SERVICE_TENANT_NAME"
+    iniset $NOVA_CONF neutron project_domain_name "Default"
+    iniset $NOVA_CONF neutron auth_strategy $NEUTRON_AUTH_STRATEGY
+    iniset $NOVA_CONF neutron region_name "$REGION_NAME"
+    iniset $NOVA_CONF neutron url $NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT
+
+    iniset $NOVA_CONF DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver
+
+    if is_service_enabled neutron-metadata-agent; then
+        iniset $NOVA_CONF neutron service_metadata_proxy "True"
+    fi
+
+}
+
+# Tenant               User       Roles
+# ------------------------------------------------------------------
+# service              neutron    admin        # if enabled
+
+# create_neutron_accounts() - Create required service accounts
+function create_neutron_accounts_new {
+    if [[ "$ENABLED_SERVICES" =~ "neutron-api" ]]; then
+
+        create_service_user "neutron"
+
+        neutron_service=$(get_or_create_service "neutron" \
+            "network" "Neutron Service")
+        get_or_create_endpoint $neutron_service \
+            "$REGION_NAME" \
+            "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/" \
+            "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/" \
+            "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/"
+    fi
+}
+
+# create_neutron_cache_dir() - Part of the init_neutron() process
+function create_neutron_cache_dir {
+    # Create cache dir
+    sudo install -d -o $STACK_USER $NEUTRON_AUTH_CACHE_DIR
+    rm -f $NEUTRON_AUTH_CACHE_DIR/*
+}
+
+# init_neutron() - Initialize databases, etc.
+function init_neutron_new {
+
+    recreate_database neutron
+
+    # Run Neutron db migrations
+    $NEUTRON_BIN_DIR/neutron-db-manage $NEUTRON_CONFIG_ARG upgrade heads
+
+    create_neutron_cache_dir
+}
+
+# install_neutron() - Collect source and prepare
+function install_neutron_new {
+    git_clone $NEUTRON_REPO $NEUTRON_DIR $NEUTRON_BRANCH
+    setup_develop $NEUTRON_DIR
+
+    # Install neutron-lib from git so we make sure we're testing
+    # the latest code.
+    if use_library_from_git "neutron-lib"; then
+        git_clone_by_name "neutron-lib"
+        setup_dev_lib "neutron-lib"
+    fi
+
+    # L3 service requires radvd
+    if is_service_enabled neutron-l3; then
+        install_package radvd
+    fi
+
+    if is_service_enabled neutron-agent neutron-dhcp neutron-l3; then
+        #TODO(sc68cal) - kind of ugly
+        source $TOP_DIR/lib/neutron_plugins/${NEUTRON_AGENT}_agent
+        neutron_plugin_install_agent_packages
+    fi
+
+}
+
+# install_neutronclient() - Collect source and prepare
+function install_neutronclient {
+    if use_library_from_git "python-neutronclient"; then
+        git_clone_by_name "python-neutronclient"
+        setup_dev_lib "python-neutronclient"
+        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-neutronclient"]}/tools/,/etc/bash_completion.d/}neutron.bash_completion
+    fi
+}
+
+# start_neutron_api() - Start the API process ahead of other things
+function start_neutron_api {
+    local service_port=$NEUTRON_SERVICE_PORT
+    local service_protocol=$NEUTRON_SERVICE_PROTOCOL
+    if is_service_enabled tls-proxy; then
+        service_port=$NEUTRON_SERVICE_PORT_INT
+        service_protocol="http"
+    fi
+
+    # Start the Neutron service
+    # TODO(sc68cal) Stop hard coding this
+    run_process neutron-api "$NEUTRON_BIN_DIR/neutron-server --config-file $NEUTRON_CONF --config-file $NEUTRON_PLUGIN_CONF"
+
+    if is_ssl_enabled_service "neutron"; then
+        ssl_ca="--ca-certificate=${SSL_BUNDLE_FILE}"
+        local testcmd="wget ${ssl_ca} --no-proxy -q -O- $service_protocol://$NEUTRON_SERVICE_HOST:$service_port"
+        test_with_retry "$testcmd" "Neutron did not start" $SERVICE_TIMEOUT
+    else
+        if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$NEUTRON_SERVICE_HOST:$service_port; then
+            die $LINENO "neutron-api did not start"
+        fi
+    fi
+
+
+    # Start proxy if enabled
+    if is_service_enabled tls-proxy; then
+        start_tls_proxy '*' $NEUTRON_SERVICE_PORT $NEUTRON_SERVICE_HOST $NEUTRON_SERVICE_PORT_INT &
+    fi
+}
+
+# start_neutron() - Start running processes, including screen
+function start_neutron_new {
+    _set_config_files
+
+    # Start up the neutron agents if enabled
+    # TODO(sc68cal) Make this pluggable so different DevStack plugins for different Neutron plugins
+    # can resolve the $NEUTRON_AGENT_BINARY
+    if is_service_enabled neutron-agent; then
+        run_process neutron-agent "$NEUTRON_BIN_DIR/$NEUTRON_AGENT_BINARY $NEUTRON_CONFIG_ARG"
+    fi
+    if is_service_enabled neutron-dhcp; then
+        neutron_plugin_configure_dhcp_agent $NEUTRON_DHCP_CONF
+        run_process neutron-dhcp "$NEUTRON_BIN_DIR/$NEUTRON_DHCP_BINARY $NEUTRON_CONFIG_ARG"
+    fi
+    if is_service_enabled neutron-l3; then
+        run_process neutron-l3 "$NEUTRON_BIN_DIR/$NEUTRON_L3_BINARY $NEUTRON_CONFIG_ARG"
+        # XXX(sc68cal) - Here's where plugins can wire up their own networks instead
+        # of the code in lib/neutron_plugins/services/l3
+        if type -p neutron_plugin_create_initial_networks > /dev/null; then
+            neutron_plugin_create_initial_networks
+        else
+            # XXX(sc68cal) Load up the built in Neutron networking code and build a topology
+            source $TOP_DIR/lib/neutron_plugins/services/l3
+            # Create the networks using servic
+            create_neutron_initial_network
+        fi
+    fi
+    if is_service_enabled neutron-metadata-agent; then
+        run_process neutron-metadata-agent "$NEUTRON_BIN_DIR/$NEUTRON_META_BINARY $NEUTRON_CONFIG_ARG"
+    fi
+
+    if is_service_enabled neutron-metering; then
+        run_process neutron-metering "$AGENT_METERING_BINARY --config-file $NEUTRON_CONF --config-file $METERING_AGENT_CONF_FILENAME"
+    fi
+}
+
+# stop_neutron() - Stop running processes (non-screen)
+function stop_neutron_new {
+    for serv in neutron-api neutron-agent neutron-l3; do
+        stop_process $serv
+    done
+
+    if is_service_enabled neutron-dhcp; then
+        stop_process neutron-dhcp
+        pid=$(ps aux | awk '/[d]nsmasq.+interface=(tap|ns-)/ { print $2 }')
+        [ ! -z "$pid" ] && sudo kill -9 $pid
+    fi
+
+    if is_service_enabled neutron-metadata-agent; then
+        sudo pkill -9 -f neutron-ns-metadata-proxy || :
+        stop_process neutron-metadata-agent
+    fi
+}
+
+# Compile the lost of enabled config files
+function _set_config_files {
+
+    NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_CONF"
+
+    #TODO(sc68cal) OVS and LB agent uses settings in NEUTRON_PLUGIN_CONF (ml2_conf.ini) but others may not
+    if is_service_enabled neutron-agent; then
+        NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_PLUGIN_CONF"
+    fi
+
+    if is_service_enabled neutron-dhcp; then
+        NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_DHCP_CONF"
+    fi
+
+    if is_service_enabled neutron-l3; then
+        NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_L3_CONF"
+    fi
+
+    if is_service_enabled neutron-metadata-agent; then
+        NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_META_CONF"
+    fi
+
+}
+
+# Dispatch functions
+# These are needed for compatibility between the old and new implementations
+# where there are function name overlaps.  These will be removed when
+# neutron-legacy is removed.
+# TODO(sc68cal) Remove when neutron-legacy is no more.
+function cleanup_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        cleanup_mutnauq "$@"
+    else
+        cleanup_neutron_new "$@"
+    fi
+}
+
+function configure_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        configure_mutnauq "$@"
+    else
+        configure_neutron_new "$@"
+    fi
+}
+
+function configure_neutron_nova {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        create_nova_conf_neutron "$@"
+    else
+        configure_neutron_nova_new "$@"
+    fi
+}
+
+function create_neutron_accounts {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        create_mutnauq_accounts "$@"
+    else
+        create_neutron_accounts_new "$@"
+    fi
+}
+
+function init_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        init_mutnauq "$@"
+    else
+        init_neutron_new "$@"
+    fi
+}
+
+function install_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        install_mutnauq "$@"
+    else
+        install_neutron_new "$@"
+    fi
+}
+
+function start_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        start_mutnauq_l2_agent "$@"
+        start_mutnauq_other_agents "$@"
+    else
+        start_neutron_new "$@"
+    fi
+}
+
+function stop_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        stop_mutnauq "$@"
+    else
+        stop_neutron_new "$@"
+    fi
+}
+
+# Restore xtrace
+$XTRACE
diff --git a/lib/neutron-legacy b/lib/neutron-legacy
index f0592e2..73123ef 100644
--- a/lib/neutron-legacy
+++ b/lib/neutron-legacy
@@ -61,45 +61,12 @@
 # Neutron Network Configuration
 # -----------------------------
 
-# Subnet IP version
-IP_VERSION=${IP_VERSION:-"4+6"}
-# Validate IP_VERSION
-if [[ $IP_VERSION != "4" ]] && [[ $IP_VERSION != "6" ]] && [[ $IP_VERSION != "4+6" ]]; then
-    die $LINENO "IP_VERSION must be either 4, 6, or 4+6"
-fi
-# Gateway and subnet defaults, in case they are not customized in localrc
-NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1}
-PUBLIC_NETWORK_GATEWAY=${PUBLIC_NETWORK_GATEWAY:-172.24.4.1}
-PRIVATE_SUBNET_NAME=${PRIVATE_SUBNET_NAME:-"private-subnet"}
-PUBLIC_SUBNET_NAME=${PUBLIC_SUBNET_NAME:-"public-subnet"}
-
-# Subnetpool defaults
-SUBNETPOOL_NAME=${SUBNETPOOL_NAME:-"shared-default-subnetpool"}
-
-SUBNETPOOL_PREFIX_V4=${SUBNETPOOL_PREFIX_V4:-10.0.0.0/8}
-SUBNETPOOL_PREFIX_V6=${SUBNETPOOL_PREFIX_V6:-2001:db8:8000::/48}
-
-SUBNETPOOL_SIZE_V4=${SUBNETPOOL_SIZE_V4:-24}
-SUBNETPOOL_SIZE_V6=${SUBNETPOOL_SIZE_V6:-64}
-
+deprecated "Using lib/neutron-legacy is deprecated, and it will be removed in the future"
 
 if is_ssl_enabled_service "neutron" || is_service_enabled tls-proxy; then
     Q_PROTOCOL="https"
 fi
 
-# Generate 40-bit IPv6 Global ID to comply with RFC 4193
-IPV6_GLOBAL_ID=`uuidgen | sed s/-//g | cut -c 23- | sed -e "s/\(..\)\(....\)\(....\)/\1:\2:\3/"`
-
-# IPv6 gateway and subnet defaults, in case they are not customized in localrc
-IPV6_RA_MODE=${IPV6_RA_MODE:-slaac}
-IPV6_ADDRESS_MODE=${IPV6_ADDRESS_MODE:-slaac}
-IPV6_PUBLIC_SUBNET_NAME=${IPV6_PUBLIC_SUBNET_NAME:-ipv6-public-subnet}
-IPV6_PRIVATE_SUBNET_NAME=${IPV6_PRIVATE_SUBNET_NAME:-ipv6-private-subnet}
-FIXED_RANGE_V6=${FIXED_RANGE_V6:-fd$IPV6_GLOBAL_ID::/64}
-IPV6_PRIVATE_NETWORK_GATEWAY=${IPV6_PRIVATE_NETWORK_GATEWAY:-fd$IPV6_GLOBAL_ID::1}
-IPV6_PUBLIC_RANGE=${IPV6_PUBLIC_RANGE:-2001:db8::/64}
-IPV6_PUBLIC_NETWORK_GATEWAY=${IPV6_PUBLIC_NETWORK_GATEWAY:-2001:db8::2}
-IPV6_ROUTER_GW_IP=${IPV6_ROUTER_GW_IP:-2001:db8::1}
 
 # Set up default directories
 GITDIR["python-neutronclient"]=$DEST/python-neutronclient
@@ -108,7 +75,6 @@
 NEUTRON_DIR=$DEST/neutron
 NEUTRON_FWAAS_DIR=$DEST/neutron-fwaas
 NEUTRON_LBAAS_DIR=$DEST/neutron-lbaas
-NEUTRON_VPNAAS_DIR=$DEST/neutron-vpnaas
 NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron}
 
 # Support entry points installation of console scripts
@@ -125,9 +91,6 @@
 # Default provider for load balancer service
 DEFAULT_LB_PROVIDER=LOADBALANCER:Haproxy:neutron_lbaas.services.loadbalancer.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default
 
-# Default provider for VPN service
-DEFAULT_VPN_PROVIDER=VPN:openswan:neutron_vpnaas.services.vpn.service_drivers.ipsec.IPsecVPNDriver:default
-
 # Agent binaries.  Note, binary paths for other agents are set in per-service
 # scripts in lib/neutron_plugins/services/
 AGENT_DHCP_BINARY="$NEUTRON_BIN_DIR/neutron-dhcp-agent"
@@ -139,7 +102,6 @@
 Q_DHCP_CONF_FILE=$NEUTRON_CONF_DIR/dhcp_agent.ini
 Q_L3_CONF_FILE=$NEUTRON_CONF_DIR/l3_agent.ini
 Q_FWAAS_CONF_FILE=$NEUTRON_CONF_DIR/fwaas_driver.ini
-Q_VPN_CONF_FILE=$NEUTRON_CONF_DIR/vpn_agent.ini
 Q_META_CONF_FILE=$NEUTRON_CONF_DIR/metadata_agent.ini
 
 # Default name for Neutron database
@@ -168,73 +130,17 @@
 Q_META_DATA_IP=${Q_META_DATA_IP:-$SERVICE_HOST}
 # Allow Overlapping IP among subnets
 Q_ALLOW_OVERLAPPING_IP=${Q_ALLOW_OVERLAPPING_IP:-True}
-# Use neutron-debug command
-Q_USE_DEBUG_COMMAND=${Q_USE_DEBUG_COMMAND:-False}
 # The name of the default q-l3 router
 Q_ROUTER_NAME=${Q_ROUTER_NAME:-router1}
 Q_NOTIFY_NOVA_PORT_STATUS_CHANGES=${Q_NOTIFY_NOVA_PORT_STATUS_CHANGES:-True}
 Q_NOTIFY_NOVA_PORT_DATA_CHANGES=${Q_NOTIFY_NOVA_PORT_DATA_CHANGES:-True}
 VIF_PLUGGING_IS_FATAL=${VIF_PLUGGING_IS_FATAL:-True}
 VIF_PLUGGING_TIMEOUT=${VIF_PLUGGING_TIMEOUT:-300}
-# Specify if the initial private and external networks should be created
-NEUTRON_CREATE_INITIAL_NETWORKS=${NEUTRON_CREATE_INITIAL_NETWORKS:-True}
-
-## Provider Network Information
-PROVIDER_SUBNET_NAME=${PROVIDER_SUBNET_NAME:-"provider_net"}
-IPV6_PROVIDER_SUBNET_NAME=${IPV6_PROVIDER_SUBNET_NAME:-"provider_net_v6"}
-IPV6_PROVIDER_FIXED_RANGE=${IPV6_PROVIDER_FIXED_RANGE:-}
-IPV6_PROVIDER_NETWORK_GATEWAY=${IPV6_PROVIDER_NETWORK_GATEWAY:-}
-
-# Define the public bridge that will transmit traffic from VMs to the
-# physical network - used by both the OVS and Linux Bridge drivers.
-PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
-
-# Use flat providernet for public network
-#
-# If Q_USE_PROVIDERNET_FOR_PUBLIC=True, use a flat provider network
-# for external interface of neutron l3-agent.  In that case,
-# PUBLIC_PHYSICAL_NETWORK specifies provider:physical_network value
-# used for the network.  In case of ofagent, you should add the
-# corresponding entry to your OFAGENT_PHYSICAL_INTERFACE_MAPPINGS.
-# For openvswitch agent, you should add the corresponding entry to
-# your OVS_BRIDGE_MAPPINGS.
-#
-# eg.  (ofagent)
-#    Q_USE_PROVIDERNET_FOR_PUBLIC=True
-#    Q_USE_PUBLIC_VETH=True
-#    PUBLIC_PHYSICAL_NETWORK=public
-#    OFAGENT_PHYSICAL_INTERFACE_MAPPINGS=public:veth-pub-int
-#
-# eg.  (openvswitch agent)
-#    Q_USE_PROVIDERNET_FOR_PUBLIC=True
-#    PUBLIC_PHYSICAL_NETWORK=public
-#    OVS_BRIDGE_MAPPINGS=public:br-ex
-Q_USE_PROVIDERNET_FOR_PUBLIC=${Q_USE_PROVIDERNET_FOR_PUBLIC:-False}
-PUBLIC_PHYSICAL_NETWORK=${PUBLIC_PHYSICAL_NETWORK:-public}
-
-# If Q_USE_PUBLIC_VETH=True, create and use a veth pair instead of
-# PUBLIC_BRIDGE.  This is intended to be used with
-# Q_USE_PROVIDERNET_FOR_PUBLIC=True.
-Q_USE_PUBLIC_VETH=${Q_USE_PUBLIC_VETH:-False}
-Q_PUBLIC_VETH_EX=${Q_PUBLIC_VETH_EX:-veth-pub-ex}
-Q_PUBLIC_VETH_INT=${Q_PUBLIC_VETH_INT:-veth-pub-int}
-
-# The next two variables are configured by plugin
-# e.g.  _configure_neutron_l3_agent or lib/neutron_plugins/*
-#
-# The plugin supports L3.
-Q_L3_ENABLED=${Q_L3_ENABLED:-False}
-# L3 routers exist per tenant
-Q_L3_ROUTER_PER_TENANT=${Q_L3_ROUTER_PER_TENANT:-True}
 
 # List of config file names in addition to the main plugin config file
 # See _configure_neutron_common() for details about setting it up
 declare -a Q_PLUGIN_EXTRA_CONF_FILES
 
-# List of (optional) config files for VPN device drivers to use with
-# the neutron-q-vpn agent
-declare -a Q_VPN_EXTRA_CONF_FILES
-
 
 Q_RR_CONF_FILE=$NEUTRON_CONF_DIR/rootwrap.conf
 if [[ "$Q_USE_ROOTWRAP" == "False" ]]; then
@@ -359,15 +265,13 @@
 # Hardcoding for 1 service plugin for now
 source $TOP_DIR/lib/neutron_plugins/services/metering
 
-# VPN service plugin functions
-# -------------------------------------------
-# Hardcoding for 1 service plugin for now
-source $TOP_DIR/lib/neutron_plugins/services/vpn
-
 # Firewall Service Plugin functions
 # ---------------------------------
 source $TOP_DIR/lib/neutron_plugins/services/firewall
 
+# L3 Service functions
+source $TOP_DIR/lib/neutron_plugins/services/l3
+
 # Use security group or not
 if has_neutron_plugin_security_group; then
     Q_USE_SECGROUP=${Q_USE_SECGROUP:-True}
@@ -392,21 +296,8 @@
     echo "$opts"
 }
 
-function _determine_config_vpn {
-    local cfg_file
-    local opts="--config-file $NEUTRON_CONF --config-file=$Q_L3_CONF_FILE --config-file=$Q_VPN_CONF_FILE"
-    if is_service_enabled q-fwaas; then
-        opts+=" --config-file $Q_FWAAS_CONF_FILE"
-    fi
-    for cfg_file in ${Q_VPN_EXTRA_CONF_FILES[@]}; do
-        opts+=" --config-file $cfg_file"
-    done
-    echo "$opts"
-
-}
-
 function _determine_config_l3 {
-    local opts="--config-file $NEUTRON_CONF --config-file=$Q_L3_CONF_FILE"
+    local opts="--config-file $NEUTRON_CONF --config-file $Q_L3_CONF_FILE"
     if is_service_enabled q-fwaas; then
         opts+=" --config-file $Q_FWAAS_CONF_FILE"
     fi
@@ -419,7 +310,6 @@
     local opts=""
     case "$1" in
         "neutron-server") opts="$(_determine_config_server)" ;;
-        "neutron-vpn-agent") opts="$(_determine_config_vpn)" ;;
         "neutron-l3-agent") opts="$(_determine_config_l3)" ;;
     esac
     if [ -z "$opts" ] ; then
@@ -428,16 +318,9 @@
     echo "$opts"
 }
 
-# Test if any Neutron services are enabled
-# is_neutron_enabled
-function is_neutron_enabled {
-    [[ ,${ENABLED_SERVICES} =~ ,"q-" ]] && return 0
-    return 1
-}
-
-# configure_neutron()
+# configure_mutnauq()
 # Set common config for all neutron server and agents.
-function configure_neutron {
+function configure_mutnauq {
     _configure_neutron_common
     iniset_rpc_backend neutron $NEUTRON_CONF
 
@@ -449,10 +332,6 @@
     if is_service_enabled q-metering; then
         _configure_neutron_metering
     fi
-    if is_service_enabled q-vpn; then
-        deprecated "Configuring q-vpn through devstack is deprecated"
-        _configure_neutron_vpn
-    fi
     if is_service_enabled q-fwaas; then
         deprecated "Configuring q-fwaas through devstack is deprecated"
         _configure_neutron_fwaas
@@ -480,15 +359,13 @@
         _configure_neutron_ceilometer_notifications
     fi
 
-    _configure_neutron_debug_command
-
     iniset $NEUTRON_CONF DEFAULT api_workers "$API_WORKERS"
 }
 
 function create_nova_conf_neutron {
     iniset $NOVA_CONF DEFAULT use_neutron True
     iniset $NOVA_CONF neutron auth_type "password"
-    iniset $NOVA_CONF neutron auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v3"
+    iniset $NOVA_CONF neutron auth_url "$KEYSTONE_AUTH_URI/v3"
     iniset $NOVA_CONF neutron username "$Q_ADMIN_USERNAME"
     iniset $NOVA_CONF neutron password "$SERVICE_PASSWORD"
     iniset $NOVA_CONF neutron user_domain_name "$SERVICE_DOMAIN_NAME"
@@ -514,21 +391,14 @@
     iniset $NOVA_CONF DEFAULT vif_plugging_timeout "$VIF_PLUGGING_TIMEOUT"
 }
 
-# create_neutron_cache_dir() - Part of the _neutron_setup_keystone() process
-function create_neutron_cache_dir {
-    # Create cache dir
-    sudo install -d -o $STACK_USER $NEUTRON_AUTH_CACHE_DIR
-    rm -f $NEUTRON_AUTH_CACHE_DIR/*
-}
-
-# create_neutron_accounts() - Set up common required neutron accounts
+# create_mutnauq_accounts() - Set up common required neutron accounts
 
 # Tenant               User       Roles
 # ------------------------------------------------------------------
 # service              neutron    admin        # if enabled
 
 # Migrated from keystone_data.sh
-function create_neutron_accounts {
+function create_mutnauq_accounts {
     if [[ "$ENABLED_SERVICES" =~ "q-svc" ]]; then
 
         create_service_user "neutron"
@@ -543,107 +413,15 @@
     fi
 }
 
-function create_neutron_initial_network {
-    local project_id
-    project_id=$(openstack project list | grep " demo " | get_field 1)
-    die_if_not_set $LINENO project_id "Failure retrieving project_id for demo"
-
-    # Allow drivers that need to create an initial network to do so here
-    if type -p neutron_plugin_create_initial_network_profile > /dev/null; then
-        neutron_plugin_create_initial_network_profile $PHYSICAL_NETWORK
-    fi
-
-    if is_provider_network; then
-        die_if_not_set $LINENO PHYSICAL_NETWORK "You must specify the PHYSICAL_NETWORK"
-        die_if_not_set $LINENO PROVIDER_NETWORK_TYPE "You must specify the PROVIDER_NETWORK_TYPE"
-        NET_ID=$(neutron net-create $PHYSICAL_NETWORK --tenant_id $project_id --provider:network_type $PROVIDER_NETWORK_TYPE --provider:physical_network "$PHYSICAL_NETWORK" ${SEGMENTATION_ID:+--provider:segmentation_id $SEGMENTATION_ID} --shared | grep ' id ' | get_field 2)
-        die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PHYSICAL_NETWORK $project_id"
-
-        if [[ "$IP_VERSION" =~ 4.* ]]; then
-            SUBNET_ID=$(neutron subnet-create --tenant_id $project_id --ip_version 4 ${ALLOCATION_POOL:+--allocation-pool $ALLOCATION_POOL} --name $PROVIDER_SUBNET_NAME --gateway $NETWORK_GATEWAY $NET_ID $FIXED_RANGE | grep ' id ' | get_field 2)
-            die_if_not_set $LINENO SUBNET_ID "Failure creating SUBNET_ID for $PROVIDER_SUBNET_NAME $project_id"
-        fi
-
-        if [[ "$IP_VERSION" =~ .*6 ]] && [[ -n "$IPV6_PROVIDER_FIXED_RANGE" ]] && [[ -n "$IPV6_PROVIDER_NETWORK_GATEWAY" ]]; then
-            SUBNET_V6_ID=$(neutron subnet-create --tenant_id $project_id --ip_version 6 --ipv6-address-mode $IPV6_ADDRESS_MODE --gateway $IPV6_PROVIDER_NETWORK_GATEWAY --name $IPV6_PROVIDER_SUBNET_NAME $NET_ID $IPV6_PROVIDER_FIXED_RANGE | grep 'id' | get_field 2)
-            die_if_not_set $LINENO SUBNET_V6_ID "Failure creating SUBNET_V6_ID for $IPV6_PROVIDER_SUBNET_NAME $project_id"
-        fi
-
-        if [[ $Q_AGENT == "openvswitch" ]]; then
-            sudo ip link set $OVS_PHYSICAL_BRIDGE up
-            sudo ip link set br-int up
-            sudo ip link set $PUBLIC_INTERFACE up
-        fi
-    else
-        NET_ID=$(neutron net-create --tenant-id $project_id "$PRIVATE_NETWORK_NAME" | grep ' id ' | get_field 2)
-        die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PRIVATE_NETWORK_NAME $project_id"
-
-        if [[ "$IP_VERSION" =~ 4.* ]]; then
-            # Create IPv4 private subnet
-            SUBNET_ID=$(_neutron_create_private_subnet_v4 $project_id)
-        fi
-
-        if [[ "$IP_VERSION" =~ .*6 ]]; then
-            # Create IPv6 private subnet
-            IPV6_SUBNET_ID=$(_neutron_create_private_subnet_v6 $project_id)
-        fi
-    fi
-
-    AUTO_ALLOCATE_EXT=$(neutron ext-list | grep 'auto-allocated-topology' | get_field 1)
-    SUBNETPOOL_EXT=$(neutron ext-list | grep 'subnet_allocation' | get_field 1)
-    if [[ "$Q_L3_ENABLED" == "True" ]]; then
-        # Create a router, and add the private subnet as one of its interfaces
-        if [[ "$Q_L3_ROUTER_PER_TENANT" == "True" ]]; then
-            # create a tenant-owned router.
-            ROUTER_ID=$(neutron router-create --tenant-id $project_id $Q_ROUTER_NAME | grep ' id ' | get_field 2)
-            die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $project_id $Q_ROUTER_NAME"
-        else
-            # Plugin only supports creating a single router, which should be admin owned.
-            ROUTER_ID=$(neutron router-create $Q_ROUTER_NAME | grep ' id ' | get_field 2)
-            die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $Q_ROUTER_NAME"
-        fi
-
-        # if the extension is available, then mark the external
-        # network as default, and provision default subnetpools
-        EXTERNAL_NETWORK_FLAGS="--router:external"
-        if [[ -n $AUTO_ALLOCATE_EXT && -n $SUBNETPOOL_EXT ]]; then
-            EXTERNAL_NETWORK_FLAGS="$EXTERNAL_NETWORK_FLAGS --is-default"
-            if [[ "$IP_VERSION" =~ 4.* ]]; then
-                SUBNETPOOL_V4_ID=$(neutron subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V4 --pool-prefix $SUBNETPOOL_PREFIX_V4 --shared --is-default=True | grep ' id ' | get_field 2)
-            fi
-            if [[ "$IP_VERSION" =~ .*6 ]]; then
-                SUBNETPOOL_V6_ID=$(neutron subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V6 --pool-prefix $SUBNETPOOL_PREFIX_V6 --shared --is-default=True | grep ' id ' | get_field 2)
-            fi
-        fi
-        # Create an external network, and a subnet. Configure the external network as router gw
-        if [ "$Q_USE_PROVIDERNET_FOR_PUBLIC" = "True" ]; then
-            EXT_NET_ID=$(neutron net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS --provider:network_type=flat --provider:physical_network=${PUBLIC_PHYSICAL_NETWORK} | grep ' id ' | get_field 2)
-        else
-            EXT_NET_ID=$(neutron net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS | grep ' id ' | get_field 2)
-        fi
-        die_if_not_set $LINENO EXT_NET_ID "Failure creating EXT_NET_ID for $PUBLIC_NETWORK_NAME"
-
-        if [[ "$IP_VERSION" =~ 4.* ]]; then
-            # Configure router for IPv4 public access
-            _neutron_configure_router_v4
-        fi
-
-        if [[ "$IP_VERSION" =~ .*6 ]]; then
-            # Configure router for IPv6 public access
-            _neutron_configure_router_v6
-        fi
-    fi
-}
-
-# init_neutron() - Initialize databases, etc.
-function init_neutron {
+# init_mutnauq() - Initialize databases, etc.
+function init_mutnauq {
     recreate_database $Q_DB_NAME
     # Run Neutron db migrations
     $NEUTRON_BIN_DIR/neutron-db-manage --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE upgrade head
 }
 
-# install_neutron() - Collect source and prepare
-function install_neutron {
+# install_mutnauq() - Collect source and prepare
+function install_mutnauq {
     # Install neutron-lib from git so we make sure we're testing
     # the latest code.
     if use_library_from_git "neutron-lib"; then
@@ -661,10 +439,6 @@
         git_clone $NEUTRON_LBAAS_REPO $NEUTRON_LBAAS_DIR $NEUTRON_LBAAS_BRANCH
         setup_develop $NEUTRON_LBAAS_DIR
     fi
-    if is_service_enabled q-vpn; then
-        git_clone $NEUTRON_VPNAAS_REPO $NEUTRON_VPNAAS_DIR $NEUTRON_VPNAAS_BRANCH
-        setup_develop $NEUTRON_VPNAAS_DIR
-    fi
 
     if [ "$VIRT_DRIVER" == 'xenserver' ]; then
         local dom0_ip
@@ -685,15 +459,6 @@
     fi
 }
 
-# install_neutronclient() - Collect source and prepare
-function install_neutronclient {
-    if use_library_from_git "python-neutronclient"; then
-        git_clone_by_name "python-neutronclient"
-        setup_dev_lib "python-neutronclient"
-        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-neutronclient"]}/tools/,/etc/bash_completion.d/}neutron.bash_completion
-    fi
-}
-
 # install_neutron_agent_packages() - Collect source and prepare
 function install_neutron_agent_packages {
     # radvd doesn't come with the OS. Install it if the l3 service is enabled.
@@ -740,7 +505,7 @@
 
 # Control of the l2 agent is separated out to make it easier to test partial
 # upgrades (everything upgraded except the L2 agent)
-function start_neutron_l2_agent {
+function start_mutnauq_l2_agent {
     run_process q-agt "$AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE"
 
     if is_provider_network && [[ $Q_AGENT == "openvswitch" ]]; then
@@ -758,19 +523,17 @@
     fi
 }
 
-function start_neutron_other_agents {
-    run_process q-dhcp "$AGENT_DHCP_BINARY --config-file $NEUTRON_CONF --config-file=$Q_DHCP_CONF_FILE"
+function start_mutnauq_other_agents {
+    run_process q-dhcp "$AGENT_DHCP_BINARY --config-file $NEUTRON_CONF --config-file $Q_DHCP_CONF_FILE"
 
     if is_service_enabled neutron-vpnaas; then
         :  # Started by plugin
-    elif is_service_enabled q-vpn; then
-        run_process q-vpn "$AGENT_VPN_BINARY $(determine_config_files neutron-vpn-agent)"
     else
         run_process q-l3 "$AGENT_L3_BINARY $(determine_config_files neutron-l3-agent)"
     fi
 
-    run_process q-meta "$AGENT_META_BINARY --config-file $NEUTRON_CONF --config-file=$Q_META_CONF_FILE"
-    run_process q-lbaas "$AGENT_LBAAS_BINARY --config-file $NEUTRON_CONF --config-file=$LBAAS_AGENT_CONF_FILENAME"
+    run_process q-meta "$AGENT_META_BINARY --config-file $NEUTRON_CONF --config-file $Q_META_CONF_FILE"
+    run_process q-lbaas "$AGENT_LBAAS_BINARY --config-file $NEUTRON_CONF --config-file $LBAAS_AGENT_CONF_FILENAME"
     run_process q-metering "$AGENT_METERING_BINARY --config-file $NEUTRON_CONF --config-file $METERING_AGENT_CONF_FILENAME"
 
     if [ "$VIRT_DRIVER" = 'xenserver' ]; then
@@ -782,15 +545,16 @@
 # Start running processes, including screen
 function start_neutron_agents {
     # Start up the neutron agents if enabled
-    start_neutron_l2_agent
-    start_neutron_other_agents
+    start_mutnauq_l2_agent
+    start_mutnauq_other_agents
 }
 
-function stop_neutron_l2_agent {
+function stop_mutnauq_l2_agent {
     stop_process q-agt
 }
 
-function stop_neutron_other {
+# stop_mutnauq_other() - Stop running processes (non-screen)
+function stop_mutnauq_other {
     if is_service_enabled q-dhcp; then
         stop_process q-dhcp
         pid=$(ps aux | awk '/[d]nsmasq.+interface=(tap|ns-)/ { print $2 }')
@@ -815,9 +579,6 @@
     if is_service_enabled q-fwaas; then
         neutron_fwaas_stop
     fi
-    if is_service_enabled q-vpn; then
-        neutron_vpn_stop
-    fi
     if is_service_enabled q-metering; then
         neutron_metering_stop
     fi
@@ -828,9 +589,9 @@
 }
 
 # stop_neutron() - Stop running processes (non-screen)
-function stop_neutron {
-    stop_neutron_other
-    stop_neutron_l2_agent
+function stop_mutnauq {
+    stop_mutnauq_other
+    stop_mutnauq_l2_agent
 }
 
 # _move_neutron_addresses_route() - Move the primary IP to the OVS bridge
@@ -856,6 +617,7 @@
         DEFAULT_ROUTE_GW=$(ip -f $af r | awk "/default.+$from_intf/ { print \$3; exit }")
         local ADD_OVS_PORT=""
         local DEL_OVS_PORT=""
+        local ARP_CMD=""
 
         IP_BRD=$(ip -f $af a s dev $from_intf scope global primary | grep inet | awk '{ print $2, $3, $4; exit }')
 
@@ -875,17 +637,21 @@
             IP_DEL="sudo ip addr del $IP_BRD dev $from_intf"
             IP_ADD="sudo ip addr add $IP_BRD dev $to_intf"
             IP_UP="sudo ip link set $to_intf up"
+            if [[ "$af" == "inet" ]]; then
+                IP=$(echo $IP_BRD | awk '{ print $1; exit }' | grep -o -E '(.*)/' | cut -d "/" -f1)
+                ARP_CMD="arping -A -c 3 -w 4.5 -I $to_intf $IP "
+            fi
         fi
 
         # The add/del OVS port calls have to happen either before or
         # after the address is moved in order to not leave it orphaned.
-        $DEL_OVS_PORT; $IP_DEL; $IP_ADD; $IP_UP; $ADD_OVS_PORT; $ADD_DEFAULT_ROUTE
+        $DEL_OVS_PORT; $IP_DEL; $IP_ADD; $IP_UP; $ADD_OVS_PORT; $ADD_DEFAULT_ROUTE; $ARP_CMD
     fi
 }
 
-# cleanup_neutron() - Remove residual data files, anything left over from previous
+# cleanup_mutnauq() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
-function cleanup_neutron {
+function cleanup_mutnauq {
 
     if [[ -n "$OVS_PHYSICAL_BRIDGE" ]]; then
         _move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False True "inet"
@@ -974,6 +740,9 @@
     iniset $NEUTRON_CONF DEFAULT bind_host $Q_LISTEN_ADDRESS
     iniset $NEUTRON_CONF oslo_concurrency lock_path $DATA_DIR/neutron/lock
 
+    # NOTE(freerunner): Need to adjust Region Name for nova in multiregion installation
+    iniset $NEUTRON_CONF nova region_name $REGION_NAME
+
     # If addition config files are set, make sure their path name is set as well
     if [[ ${#Q_PLUGIN_EXTRA_CONF_FILES[@]} > 0 && $Q_PLUGIN_EXTRA_CONF_PATH == '' ]]; then
         die $LINENO "Neutron additional plugin config not set.. exiting"
@@ -1025,24 +794,6 @@
     _neutron_setup_rootwrap
 }
 
-function _configure_neutron_debug_command {
-    if [[ "$Q_USE_DEBUG_COMMAND" != "True" ]]; then
-        return
-    fi
-
-    cp $NEUTRON_DIR/etc/l3_agent.ini.sample $NEUTRON_TEST_CONFIG_FILE
-
-    iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT debug False
-    iniset $NEUTRON_TEST_CONFIG_FILE AGENT root_helper "$Q_RR_COMMAND"
-    if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
-        iniset $NEUTRON_TEST_CONFIG_FILE AGENT root_helper_daemon "$Q_RR_DAEMON_COMMAND"
-    fi
-
-    _neutron_setup_interface_driver $NEUTRON_TEST_CONFIG_FILE
-
-    neutron_plugin_configure_debug_command
-}
-
 function _configure_neutron_dhcp_agent {
 
     cp $NEUTRON_DIR/etc/dhcp_agent.ini.sample $Q_DHCP_CONF_FILE
@@ -1069,31 +820,6 @@
     neutron_plugin_configure_dhcp_agent
 }
 
-function _configure_neutron_l3_agent {
-    Q_L3_ENABLED=True
-
-    if is_service_enabled q-vpn; then
-        neutron_vpn_configure_agent
-    fi
-
-    cp $NEUTRON_DIR/etc/l3_agent.ini.sample $Q_L3_CONF_FILE
-
-    iniset $Q_L3_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
-    iniset $Q_L3_CONF_FILE AGENT root_helper "$Q_RR_COMMAND"
-    if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
-        iniset $Q_L3_CONF_FILE AGENT root_helper_daemon "$Q_RR_DAEMON_COMMAND"
-    fi
-
-    _neutron_setup_interface_driver $Q_L3_CONF_FILE
-
-    neutron_plugin_configure_l3_agent
-
-    _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True False "inet"
-
-    if [[ $(ip -f inet6 a s dev "$PUBLIC_INTERFACE" | grep -c 'global') != 0 ]]; then
-        _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" False False "inet6"
-    fi
-}
 
 function _configure_neutron_metadata_agent {
     cp $NEUTRON_DIR/etc/metadata_agent.ini.sample $Q_META_CONF_FILE
@@ -1135,17 +861,6 @@
     neutron_fwaas_configure_driver
 }
 
-function _configure_neutron_vpn {
-    # Uses oslo config generator to generate VPNaaS sample configuration files
-    (cd $NEUTRON_VPNAAS_DIR && exec ./tools/generate_config_file_samples.sh)
-    if [ -f $NEUTRON_VPNAAS_DIR/etc/neutron_vpnaas.conf.sample ]; then
-        cp $NEUTRON_VPNAAS_DIR/etc/neutron_vpnaas.conf.sample $NEUTRON_CONF_DIR/neutron_vpnaas.conf
-        iniset $NEUTRON_CONF_DIR/neutron_vpnaas.conf service_providers service_provider $DEFAULT_VPN_PROVIDER
-    fi
-    neutron_vpn_install_agent_packages
-    neutron_vpn_configure_common
-}
-
 function _configure_dvr {
     iniset $NEUTRON_CONF DEFAULT router_distributed True
     iniset $Q_L3_CONF_FILE DEFAULT agent_mode $Q_DVR_MODE
@@ -1279,164 +994,6 @@
 
     neutron_plugin_setup_interface_driver $1
 }
-
-# Create private IPv4 subnet
-function _neutron_create_private_subnet_v4 {
-    local project_id=$1
-    local subnet_params="--tenant-id $project_id "
-    subnet_params+="--ip_version 4 "
-    subnet_params+="--gateway $NETWORK_GATEWAY "
-    subnet_params+="--name $PRIVATE_SUBNET_NAME "
-    subnet_params+="$NET_ID $FIXED_RANGE"
-    local subnet_id
-    subnet_id=$(neutron subnet-create $subnet_params | grep ' id ' | get_field 2)
-    die_if_not_set $LINENO subnet_id "Failure creating private IPv4 subnet for $project_id"
-    echo $subnet_id
-}
-
-# Create private IPv6 subnet
-function _neutron_create_private_subnet_v6 {
-    local project_id=$1
-    die_if_not_set $LINENO IPV6_RA_MODE "IPV6 RA Mode not set"
-    die_if_not_set $LINENO IPV6_ADDRESS_MODE "IPV6 Address Mode not set"
-    local ipv6_modes="--ipv6-ra-mode $IPV6_RA_MODE --ipv6-address-mode $IPV6_ADDRESS_MODE"
-    local subnet_params="--tenant-id $project_id "
-    subnet_params+="--ip_version 6 "
-    subnet_params+="--gateway $IPV6_PRIVATE_NETWORK_GATEWAY "
-    subnet_params+="--name $IPV6_PRIVATE_SUBNET_NAME "
-    subnet_params+="$NET_ID $FIXED_RANGE_V6 $ipv6_modes"
-    local ipv6_subnet_id
-    ipv6_subnet_id=$(neutron subnet-create $subnet_params | grep ' id ' | get_field 2)
-    die_if_not_set $LINENO ipv6_subnet_id "Failure creating private IPv6 subnet for $project_id"
-    echo $ipv6_subnet_id
-}
-
-# Create public IPv4 subnet
-function _neutron_create_public_subnet_v4 {
-    local subnet_params+="--ip_version 4 "
-    subnet_params+="${Q_FLOATING_ALLOCATION_POOL:+--allocation-pool $Q_FLOATING_ALLOCATION_POOL} "
-    subnet_params+="--gateway $PUBLIC_NETWORK_GATEWAY "
-    subnet_params+="--name $PUBLIC_SUBNET_NAME "
-    subnet_params+="$EXT_NET_ID $FLOATING_RANGE "
-    subnet_params+="-- --enable_dhcp=False"
-    local id_and_ext_gw_ip
-    id_and_ext_gw_ip=$(neutron subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ')
-    die_if_not_set $LINENO id_and_ext_gw_ip "Failure creating public IPv4 subnet"
-    echo $id_and_ext_gw_ip
-}
-
-# Create public IPv6 subnet
-function _neutron_create_public_subnet_v6 {
-    local subnet_params="--ip_version 6 "
-    subnet_params+="--gateway $IPV6_PUBLIC_NETWORK_GATEWAY "
-    subnet_params+="--name $IPV6_PUBLIC_SUBNET_NAME "
-    subnet_params+="$EXT_NET_ID $IPV6_PUBLIC_RANGE "
-    subnet_params+="-- --enable_dhcp=False"
-    local ipv6_id_and_ext_gw_ip
-    ipv6_id_and_ext_gw_ip=$(neutron subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ')
-    die_if_not_set $LINENO ipv6_id_and_ext_gw_ip "Failure creating an IPv6 public subnet"
-    echo $ipv6_id_and_ext_gw_ip
-}
-
-# Configure neutron router for IPv4 public access
-function _neutron_configure_router_v4 {
-    neutron router-interface-add $ROUTER_ID $SUBNET_ID
-    # Create a public subnet on the external network
-    local id_and_ext_gw_ip
-    id_and_ext_gw_ip=$(_neutron_create_public_subnet_v4 $EXT_NET_ID)
-    local ext_gw_ip
-    ext_gw_ip=$(echo $id_and_ext_gw_ip  | get_field 2)
-    PUB_SUBNET_ID=$(echo $id_and_ext_gw_ip | get_field 5)
-    # Configure the external network as the default router gateway
-    neutron router-gateway-set $ROUTER_ID $EXT_NET_ID
-
-    # This logic is specific to using the l3-agent for layer 3
-    if is_service_enabled q-l3; then
-        # Configure and enable public bridge
-        local ext_gw_interface="none"
-        if is_neutron_ovs_base_plugin; then
-            ext_gw_interface=$(_neutron_get_ext_gw_interface)
-        elif [[ "$Q_AGENT" = "linuxbridge" ]]; then
-            # Search for the brq device the neutron router and network for $FIXED_RANGE
-            # will be using.
-            # e.x. brq3592e767-da for NET_ID 3592e767-da66-4bcb-9bec-cdb03cd96102
-            ext_gw_interface=brq${EXT_NET_ID:0:11}
-        fi
-        if [[ "$ext_gw_interface" != "none" ]]; then
-            local cidr_len=${FLOATING_RANGE#*/}
-            local testcmd="ip -o link | grep -q $ext_gw_interface"
-            test_with_retry "$testcmd" "$ext_gw_interface creation failed"
-            if [[ $(ip addr show dev $ext_gw_interface | grep -c $ext_gw_ip) == 0 && ( $Q_USE_PROVIDERNET_FOR_PUBLIC == "False" || $Q_USE_PUBLIC_VETH == "True" ) ]]; then
-                sudo ip addr add $ext_gw_ip/$cidr_len dev $ext_gw_interface
-                sudo ip link set $ext_gw_interface up
-            fi
-            ROUTER_GW_IP=`neutron port-list -c fixed_ips -c device_owner | grep router_gateway | awk -F'ip_address'  '{ print $2 }' | cut -f3 -d\" | tr '\n' ' '`
-            die_if_not_set $LINENO ROUTER_GW_IP "Failure retrieving ROUTER_GW_IP"
-            sudo ip route replace  $FIXED_RANGE via $ROUTER_GW_IP
-        fi
-        _neutron_set_router_id
-    fi
-}
-
-# Configure neutron router for IPv6 public access
-function _neutron_configure_router_v6 {
-    neutron router-interface-add $ROUTER_ID $IPV6_SUBNET_ID
-    # Create a public subnet on the external network
-    local ipv6_id_and_ext_gw_ip
-    ipv6_id_and_ext_gw_ip=$(_neutron_create_public_subnet_v6 $EXT_NET_ID)
-    local ipv6_ext_gw_ip
-    ipv6_ext_gw_ip=$(echo $ipv6_id_and_ext_gw_ip | get_field 2)
-    local ipv6_pub_subnet_id
-    ipv6_pub_subnet_id=$(echo $ipv6_id_and_ext_gw_ip | get_field 5)
-
-    # If the external network has not already been set as the default router
-    # gateway when configuring an IPv4 public subnet, do so now
-    if [[ "$IP_VERSION" == "6" ]]; then
-        neutron router-gateway-set $ROUTER_ID $EXT_NET_ID
-    fi
-
-    # This logic is specific to using the l3-agent for layer 3
-    if is_service_enabled q-l3; then
-        # Ensure IPv6 forwarding is enabled on the host
-        sudo sysctl -w net.ipv6.conf.all.forwarding=1
-        # Configure and enable public bridge
-        # Override global IPV6_ROUTER_GW_IP with the true value from neutron
-        IPV6_ROUTER_GW_IP=`neutron port-list -c fixed_ips | grep $ipv6_pub_subnet_id | awk -F'ip_address' '{ print $2 }' | cut -f3 -d\" | tr '\n' ' '`
-        die_if_not_set $LINENO IPV6_ROUTER_GW_IP "Failure retrieving IPV6_ROUTER_GW_IP"
-
-        if is_neutron_ovs_base_plugin; then
-            local ext_gw_interface
-            ext_gw_interface=$(_neutron_get_ext_gw_interface)
-            local ipv6_cidr_len=${IPV6_PUBLIC_RANGE#*/}
-
-            # Configure interface for public bridge
-            sudo ip -6 addr add $ipv6_ext_gw_ip/$ipv6_cidr_len dev $ext_gw_interface
-            sudo ip -6 route replace $FIXED_RANGE_V6 via $IPV6_ROUTER_GW_IP dev $ext_gw_interface
-        fi
-        _neutron_set_router_id
-    fi
-}
-
-# Explicitly set router id in l3 agent configuration
-function _neutron_set_router_id {
-    if [[ "$Q_L3_ROUTER_PER_TENANT" == "False" ]]; then
-        iniset $Q_L3_CONF_FILE DEFAULT router_id $ROUTER_ID
-    fi
-}
-
-# Get ext_gw_interface depending on value of Q_USE_PUBLIC_VETH
-function _neutron_get_ext_gw_interface {
-    if [[ "$Q_USE_PUBLIC_VETH" == "True" ]]; then
-        echo $Q_PUBLIC_VETH_EX
-    else
-        # Disable in-band as we are going to use local port
-        # to communicate with VMs
-        sudo ovs-vsctl set Bridge $PUBLIC_BRIDGE \
-            other_config:disable-in-band=true
-        echo $PUBLIC_BRIDGE
-    fi
-}
-
 # Functions for Neutron Exercises
 #--------------------------------
 
@@ -1447,26 +1004,8 @@
     neutron-debug --os-tenant-name admin --os-username admin probe-delete $probe_id
 }
 
-function setup_neutron_debug {
-    if [[ "$Q_USE_DEBUG_COMMAND" == "True" ]]; then
-        public_net_id=`_get_net_id $PUBLIC_NETWORK_NAME`
-        if [[ -n $public_net_id ]]; then
-            neutron-debug --os-tenant-name admin --os-username admin --os-password $ADMIN_PASSWORD probe-create --device-owner compute $public_net_id
-        fi
-        private_net_id=`_get_net_id $PRIVATE_NETWORK_NAME`
-        if [[ -n $private_net_id ]]; then
-            neutron-debug --os-tenant-name admin --os-username admin --os-password $ADMIN_PASSWORD probe-create --device-owner compute $private_net_id
-        fi
-    fi
-}
-
-function teardown_neutron_debug {
-    delete_probe $PUBLIC_NETWORK_NAME
-    delete_probe $PRIVATE_NETWORK_NAME
-}
-
 function _get_net_id {
-    neutron --os-tenant-name admin --os-username admin --os-password $ADMIN_PASSWORD net-list | grep $1 | awk '{print $2}'
+    neutron --os-cloud devstack-admin --os-region "$REGION_NAME" --os-tenant-name admin --os-username admin --os-password $ADMIN_PASSWORD net-list | grep $1 | awk '{print $2}'
 }
 
 function _get_probe_cmd_prefix {
@@ -1538,14 +1077,6 @@
     _neutron_third_party_do check
 }
 
-function is_provider_network {
-    if [ "$Q_USE_PROVIDER_NETWORKING" == "True" ] && [ "$Q_L3_ENABLED" == "False" ]; then
-        return 0
-    fi
-    return 1
-}
-
-
 # Restore xtrace
 $_XTRACE_NEUTRON
 
diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent
index 096722b..0a06635 100644
--- a/lib/neutron_plugins/linuxbridge_agent
+++ b/lib/neutron_plugins/linuxbridge_agent
@@ -43,13 +43,15 @@
 }
 
 function neutron_plugin_configure_dhcp_agent {
-    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
+    local conf_file=$1
+    iniset $conf_file DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
 }
 
 function neutron_plugin_configure_l3_agent {
+    local conf_file=$1
     sudo brctl addbr $PUBLIC_BRIDGE
-    iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge
-    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
+    iniset $conf_file DEFAULT external_network_bridge
+    iniset $conf_file DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
 }
 
 function neutron_plugin_configure_plugin_agent {
diff --git a/lib/neutron_plugins/openvswitch_agent b/lib/neutron_plugins/openvswitch_agent
index aba2587..69e38f4 100644
--- a/lib/neutron_plugins/openvswitch_agent
+++ b/lib/neutron_plugins/openvswitch_agent
@@ -28,12 +28,14 @@
 }
 
 function neutron_plugin_configure_dhcp_agent {
-    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
+    local conf_file=$1
+    iniset $conf_file DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
 }
 
 function neutron_plugin_configure_l3_agent {
+    local conf_file=$1
     _neutron_ovs_base_configure_l3_agent
-    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
+    iniset $conf_file DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
 }
 
 function neutron_plugin_configure_plugin_agent {
diff --git a/lib/neutron_plugins/ovs_base b/lib/neutron_plugins/ovs_base
index 59c7737..ecf252f 100644
--- a/lib/neutron_plugins/ovs_base
+++ b/lib/neutron_plugins/ovs_base
@@ -54,7 +54,7 @@
     local kernel_major_minor
     kernel_major_minor=`echo $kernel_version | cut -d. -f1-2`
     # From kernel 3.13 on, openvswitch-datapath-dkms is not needed
-    if [ `vercmp_numbers "$kernel_major_minor" "3.13"` -lt "0" ]; then
+    if vercmp "$kernel_major_minor" "<" "3.13" ; then
         install_package "dkms openvswitch-datapath-dkms linux-headers-$kernel_version"
     fi
 }
diff --git a/lib/neutron_plugins/services/l3 b/lib/neutron_plugins/services/l3
new file mode 100644
index 0000000..350aed8
--- /dev/null
+++ b/lib/neutron_plugins/services/l3
@@ -0,0 +1,370 @@
+#!/bin/bash
+# Subnet IP version
+IP_VERSION=${IP_VERSION:-"4+6"}
+# Validate IP_VERSION
+if [[ $IP_VERSION != "4" ]] && [[ $IP_VERSION != "6" ]] && [[ $IP_VERSION != "4+6" ]]; then
+    die $LINENO "IP_VERSION must be either 4, 6, or 4+6"
+fi
+# Specify if the initial private and external networks should be created
+NEUTRON_CREATE_INITIAL_NETWORKS=${NEUTRON_CREATE_INITIAL_NETWORKS:-True}
+
+## Provider Network Information
+PROVIDER_SUBNET_NAME=${PROVIDER_SUBNET_NAME:-"provider_net"}
+IPV6_PROVIDER_SUBNET_NAME=${IPV6_PROVIDER_SUBNET_NAME:-"provider_net_v6"}
+IPV6_PROVIDER_FIXED_RANGE=${IPV6_PROVIDER_FIXED_RANGE:-}
+IPV6_PROVIDER_NETWORK_GATEWAY=${IPV6_PROVIDER_NETWORK_GATEWAY:-}
+
+PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
+
+# If Q_USE_PUBLIC_VETH=True, create and use a veth pair instead of
+# PUBLIC_BRIDGE.  This is intended to be used with
+# Q_USE_PROVIDERNET_FOR_PUBLIC=True.
+Q_USE_PUBLIC_VETH=${Q_USE_PUBLIC_VETH:-False}
+Q_PUBLIC_VETH_EX=${Q_PUBLIC_VETH_EX:-veth-pub-ex}
+Q_PUBLIC_VETH_INT=${Q_PUBLIC_VETH_INT:-veth-pub-int}
+
+# The next variable is configured by plugin
+# e.g.  _configure_neutron_l3_agent or lib/neutron_plugins/*
+#
+# L3 routers exist per tenant
+Q_L3_ROUTER_PER_TENANT=${Q_L3_ROUTER_PER_TENANT:-True}
+
+
+# Use flat providernet for public network
+#
+# If Q_USE_PROVIDERNET_FOR_PUBLIC=True, use a flat provider network
+# for external interface of neutron l3-agent.  In that case,
+# PUBLIC_PHYSICAL_NETWORK specifies provider:physical_network value
+# used for the network.  In case of ofagent, you should add the
+# corresponding entry to your OFAGENT_PHYSICAL_INTERFACE_MAPPINGS.
+# For openvswitch agent, you should add the corresponding entry to
+# your OVS_BRIDGE_MAPPINGS.
+#
+# eg.  (ofagent)
+#    Q_USE_PROVIDERNET_FOR_PUBLIC=True
+#    Q_USE_PUBLIC_VETH=True
+#    PUBLIC_PHYSICAL_NETWORK=public
+#    OFAGENT_PHYSICAL_INTERFACE_MAPPINGS=public:veth-pub-int
+#
+# eg.  (openvswitch agent)
+#    Q_USE_PROVIDERNET_FOR_PUBLIC=True
+#    PUBLIC_PHYSICAL_NETWORK=public
+#    OVS_BRIDGE_MAPPINGS=public:br-ex
+Q_USE_PROVIDERNET_FOR_PUBLIC=${Q_USE_PROVIDERNET_FOR_PUBLIC:-False}
+PUBLIC_PHYSICAL_NETWORK=${PUBLIC_PHYSICAL_NETWORK:-public}
+
+# Generate 40-bit IPv6 Global ID to comply with RFC 4193
+IPV6_GLOBAL_ID=`uuidgen | sed s/-//g | cut -c 23- | sed -e "s/\(..\)\(....\)\(....\)/\1:\2:\3/"`
+
+# IPv6 gateway and subnet defaults, in case they are not customized in localrc
+IPV6_RA_MODE=${IPV6_RA_MODE:-slaac}
+IPV6_ADDRESS_MODE=${IPV6_ADDRESS_MODE:-slaac}
+IPV6_PUBLIC_SUBNET_NAME=${IPV6_PUBLIC_SUBNET_NAME:-ipv6-public-subnet}
+IPV6_PRIVATE_SUBNET_NAME=${IPV6_PRIVATE_SUBNET_NAME:-ipv6-private-subnet}
+FIXED_RANGE_V6=${FIXED_RANGE_V6:-fd$IPV6_GLOBAL_ID::/64}
+IPV6_PRIVATE_NETWORK_GATEWAY=${IPV6_PRIVATE_NETWORK_GATEWAY:-fd$IPV6_GLOBAL_ID::1}
+IPV6_PUBLIC_RANGE=${IPV6_PUBLIC_RANGE:-2001:db8::/64}
+IPV6_PUBLIC_NETWORK_GATEWAY=${IPV6_PUBLIC_NETWORK_GATEWAY:-2001:db8::2}
+IPV6_ROUTER_GW_IP=${IPV6_ROUTER_GW_IP:-2001:db8::1}
+
+# Gateway and subnet defaults, in case they are not customized in localrc
+NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1}
+PUBLIC_NETWORK_GATEWAY=${PUBLIC_NETWORK_GATEWAY:-172.24.4.1}
+PRIVATE_SUBNET_NAME=${PRIVATE_SUBNET_NAME:-"private-subnet"}
+PUBLIC_SUBNET_NAME=${PUBLIC_SUBNET_NAME:-"public-subnet"}
+
+# Subnetpool defaults
+SUBNETPOOL_NAME=${SUBNETPOOL_NAME:-"shared-default-subnetpool"}
+
+SUBNETPOOL_PREFIX_V4=${SUBNETPOOL_PREFIX_V4:-10.0.0.0/8}
+SUBNETPOOL_PREFIX_V6=${SUBNETPOOL_PREFIX_V6:-2001:db8:8000::/48}
+
+SUBNETPOOL_SIZE_V4=${SUBNETPOOL_SIZE_V4:-24}
+SUBNETPOOL_SIZE_V6=${SUBNETPOOL_SIZE_V6:-64}
+
+function _determine_config_l3 {
+    local opts="--config-file $NEUTRON_CONF --config-file $Q_L3_CONF_FILE"
+    echo "$opts"
+}
+
+function _configure_neutron_l3_agent {
+
+    cp $NEUTRON_DIR/etc/l3_agent.ini.sample $Q_L3_CONF_FILE
+
+    iniset $Q_L3_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
+    iniset $Q_L3_CONF_FILE AGENT root_helper "$Q_RR_COMMAND"
+    if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
+        iniset $Q_L3_CONF_FILE AGENT root_helper_daemon "$Q_RR_DAEMON_COMMAND"
+    fi
+
+    _neutron_setup_interface_driver $Q_L3_CONF_FILE
+
+    neutron_plugin_configure_l3_agent
+
+    _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True False "inet"
+
+    if [[ $(ip -f inet6 a s dev "$PUBLIC_INTERFACE" | grep -c 'global') != 0 ]]; then
+        _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" False False "inet6"
+    fi
+}
+
+# Explicitly set router id in l3 agent configuration
+function _neutron_set_router_id {
+    if [[ "$Q_L3_ROUTER_PER_TENANT" == "False" ]]; then
+        iniset $Q_L3_CONF_FILE DEFAULT router_id $ROUTER_ID
+    fi
+}
+
+# Get ext_gw_interface depending on value of Q_USE_PUBLIC_VETH
+function _neutron_get_ext_gw_interface {
+    if [[ "$Q_USE_PUBLIC_VETH" == "True" ]]; then
+        echo $Q_PUBLIC_VETH_EX
+    else
+        # Disable in-band as we are going to use local port
+        # to communicate with VMs
+        sudo ovs-vsctl set Bridge $PUBLIC_BRIDGE \
+            other_config:disable-in-band=true
+        echo $PUBLIC_BRIDGE
+    fi
+}
+
+function create_neutron_initial_network {
+    local project_id
+    project_id=$(openstack project list | grep " demo " | get_field 1)
+    die_if_not_set $LINENO project_id "Failure retrieving project_id for demo"
+
+    # Allow drivers that need to create an initial network to do so here
+    if type -p neutron_plugin_create_initial_network_profile > /dev/null; then
+        neutron_plugin_create_initial_network_profile $PHYSICAL_NETWORK
+    fi
+
+    if is_provider_network; then
+        die_if_not_set $LINENO PHYSICAL_NETWORK "You must specify the PHYSICAL_NETWORK"
+        die_if_not_set $LINENO PROVIDER_NETWORK_TYPE "You must specify the PROVIDER_NETWORK_TYPE"
+        NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create $PHYSICAL_NETWORK --tenant_id $project_id --provider:network_type $PROVIDER_NETWORK_TYPE --provider:physical_network "$PHYSICAL_NETWORK" ${SEGMENTATION_ID:+--provider:segmentation_id $SEGMENTATION_ID} --shared | grep ' id ' | get_field 2)
+        die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PHYSICAL_NETWORK $project_id"
+
+        if [[ "$IP_VERSION" =~ 4.* ]]; then
+            SUBNET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create --tenant_id $project_id --ip_version 4 ${ALLOCATION_POOL:+--allocation-pool $ALLOCATION_POOL} --name $PROVIDER_SUBNET_NAME --gateway $NETWORK_GATEWAY $NET_ID $FIXED_RANGE | grep ' id ' | get_field 2)
+            die_if_not_set $LINENO SUBNET_ID "Failure creating SUBNET_ID for $PROVIDER_SUBNET_NAME $project_id"
+        fi
+
+        if [[ "$IP_VERSION" =~ .*6 ]]; then
+            die_if_not_set $LINENO IPV6_PROVIDER_FIXED_RANGE "IPV6_PROVIDER_FIXED_RANGE has not been set, but Q_USE_PROVIDERNET_FOR_PUBLIC is true and IP_VERSION includes 6"
+            die_if_not_set $LINENO IPV6_PROVIDER_NETWORK_GATEWAY "IPV6_PROVIDER_NETWORK_GATEWAY has not been set, but Q_USE_PROVIDERNET_FOR_PUBLIC is true and IP_VERSION includes 6"
+            SUBNET_V6_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create --tenant_id $project_id --ip_version 6 --ipv6-address-mode $IPV6_ADDRESS_MODE --gateway $IPV6_PROVIDER_NETWORK_GATEWAY --name $IPV6_PROVIDER_SUBNET_NAME $NET_ID $IPV6_PROVIDER_FIXED_RANGE | grep 'id' | get_field 2)
+            die_if_not_set $LINENO SUBNET_V6_ID "Failure creating SUBNET_V6_ID for $IPV6_PROVIDER_SUBNET_NAME $project_id"
+        fi
+
+        if [[ $Q_AGENT == "openvswitch" ]]; then
+            sudo ip link set $OVS_PHYSICAL_BRIDGE up
+            sudo ip link set br-int up
+            sudo ip link set $PUBLIC_INTERFACE up
+        fi
+    else
+        NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create --tenant-id $project_id "$PRIVATE_NETWORK_NAME" | grep ' id ' | get_field 2)
+        die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PRIVATE_NETWORK_NAME $project_id"
+
+        if [[ "$IP_VERSION" =~ 4.* ]]; then
+            # Create IPv4 private subnet
+            SUBNET_ID=$(_neutron_create_private_subnet_v4 $project_id)
+        fi
+
+        if [[ "$IP_VERSION" =~ .*6 ]]; then
+            # Create IPv6 private subnet
+            IPV6_SUBNET_ID=$(_neutron_create_private_subnet_v6 $project_id)
+        fi
+    fi
+
+    if is_networking_extension_supported "router" && is_networking_extension_supported "external-net"; then
+        # Create a router, and add the private subnet as one of its interfaces
+        if [[ "$Q_L3_ROUTER_PER_TENANT" == "True" ]]; then
+            # create a tenant-owned router.
+            ROUTER_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-create --tenant-id $project_id $Q_ROUTER_NAME | grep ' id ' | get_field 2)
+            die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $project_id $Q_ROUTER_NAME"
+        else
+            # Plugin only supports creating a single router, which should be admin owned.
+            ROUTER_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-create $Q_ROUTER_NAME | grep ' id ' | get_field 2)
+            die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $Q_ROUTER_NAME"
+        fi
+
+        EXTERNAL_NETWORK_FLAGS="--router:external"
+        if is_networking_extension_supported "auto-allocated-topology" && is_networking_extension_supported "subnet_allocation"; then
+            EXTERNAL_NETWORK_FLAGS="$EXTERNAL_NETWORK_FLAGS --is-default"
+            if [[ "$IP_VERSION" =~ 4.* ]]; then
+                SUBNETPOOL_V4_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V4 --pool-prefix $SUBNETPOOL_PREFIX_V4 --shared --is-default=True | grep ' id ' | get_field 2)
+            fi
+            if [[ "$IP_VERSION" =~ .*6 ]]; then
+                SUBNETPOOL_V6_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V6 --pool-prefix $SUBNETPOOL_PREFIX_V6 --shared --is-default=True | grep ' id ' | get_field 2)
+            fi
+        fi
+        # Create an external network, and a subnet. Configure the external network as router gw
+        if [ "$Q_USE_PROVIDERNET_FOR_PUBLIC" = "True" ]; then
+            EXT_NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS --provider:network_type=flat --provider:physical_network=${PUBLIC_PHYSICAL_NETWORK} | grep ' id ' | get_field 2)
+        else
+            EXT_NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS | grep ' id ' | get_field 2)
+        fi
+        die_if_not_set $LINENO EXT_NET_ID "Failure creating EXT_NET_ID for $PUBLIC_NETWORK_NAME"
+
+        if [[ "$IP_VERSION" =~ 4.* ]]; then
+            # Configure router for IPv4 public access
+            _neutron_configure_router_v4
+        fi
+
+        if [[ "$IP_VERSION" =~ .*6 ]]; then
+            # Configure router for IPv6 public access
+            _neutron_configure_router_v6
+        fi
+    fi
+}
+
+# Create private IPv4 subnet
+function _neutron_create_private_subnet_v4 {
+    local project_id=$1
+    local subnet_params="--tenant-id $project_id "
+    subnet_params+="--ip_version 4 "
+    subnet_params+="--gateway $NETWORK_GATEWAY "
+    subnet_params+="--name $PRIVATE_SUBNET_NAME "
+    subnet_params+="$NET_ID $FIXED_RANGE"
+    local subnet_id
+    subnet_id=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep ' id ' | get_field 2)
+    die_if_not_set $LINENO subnet_id "Failure creating private IPv4 subnet for $project_id"
+    echo $subnet_id
+}
+
+# Create private IPv6 subnet
+function _neutron_create_private_subnet_v6 {
+    local project_id=$1
+    die_if_not_set $LINENO IPV6_RA_MODE "IPV6 RA Mode not set"
+    die_if_not_set $LINENO IPV6_ADDRESS_MODE "IPV6 Address Mode not set"
+    local ipv6_modes="--ipv6-ra-mode $IPV6_RA_MODE --ipv6-address-mode $IPV6_ADDRESS_MODE"
+    local subnet_params="--tenant-id $project_id "
+    subnet_params+="--ip_version 6 "
+    subnet_params+="--gateway $IPV6_PRIVATE_NETWORK_GATEWAY "
+    subnet_params+="--name $IPV6_PRIVATE_SUBNET_NAME "
+    subnet_params+="$NET_ID $FIXED_RANGE_V6 $ipv6_modes"
+    local ipv6_subnet_id
+    ipv6_subnet_id=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep ' id ' | get_field 2)
+    die_if_not_set $LINENO ipv6_subnet_id "Failure creating private IPv6 subnet for $project_id"
+    echo $ipv6_subnet_id
+}
+
+# Create public IPv4 subnet
+function _neutron_create_public_subnet_v4 {
+    local subnet_params+="--ip_version 4 "
+    subnet_params+="${Q_FLOATING_ALLOCATION_POOL:+--allocation-pool $Q_FLOATING_ALLOCATION_POOL} "
+    subnet_params+="--gateway $PUBLIC_NETWORK_GATEWAY "
+    subnet_params+="--name $PUBLIC_SUBNET_NAME "
+    subnet_params+="$EXT_NET_ID $FLOATING_RANGE "
+    subnet_params+="-- --enable_dhcp=False"
+    local id_and_ext_gw_ip
+    id_and_ext_gw_ip=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ')
+    die_if_not_set $LINENO id_and_ext_gw_ip "Failure creating public IPv4 subnet"
+    echo $id_and_ext_gw_ip
+}
+
+# Create public IPv6 subnet
+function _neutron_create_public_subnet_v6 {
+    local subnet_params="--ip_version 6 "
+    subnet_params+="--gateway $IPV6_PUBLIC_NETWORK_GATEWAY "
+    subnet_params+="--name $IPV6_PUBLIC_SUBNET_NAME "
+    subnet_params+="$EXT_NET_ID $IPV6_PUBLIC_RANGE "
+    subnet_params+="-- --enable_dhcp=False"
+    local ipv6_id_and_ext_gw_ip
+    ipv6_id_and_ext_gw_ip=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ')
+    die_if_not_set $LINENO ipv6_id_and_ext_gw_ip "Failure creating an IPv6 public subnet"
+    echo $ipv6_id_and_ext_gw_ip
+}
+
+# Configure neutron router for IPv4 public access
+function _neutron_configure_router_v4 {
+    neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-interface-add $ROUTER_ID $SUBNET_ID
+    # Create a public subnet on the external network
+    local id_and_ext_gw_ip
+    id_and_ext_gw_ip=$(_neutron_create_public_subnet_v4 $EXT_NET_ID)
+    local ext_gw_ip
+    ext_gw_ip=$(echo $id_and_ext_gw_ip  | get_field 2)
+    PUB_SUBNET_ID=$(echo $id_and_ext_gw_ip | get_field 5)
+    # Configure the external network as the default router gateway
+    neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-gateway-set $ROUTER_ID $EXT_NET_ID
+
+    # This logic is specific to using the l3-agent for layer 3
+    if is_service_enabled q-l3; then
+        # Configure and enable public bridge
+        local ext_gw_interface="none"
+        if is_neutron_ovs_base_plugin; then
+            ext_gw_interface=$(_neutron_get_ext_gw_interface)
+        elif [[ "$Q_AGENT" = "linuxbridge" ]]; then
+            # Search for the brq device the neutron router and network for $FIXED_RANGE
+            # will be using.
+            # e.x. brq3592e767-da for NET_ID 3592e767-da66-4bcb-9bec-cdb03cd96102
+            ext_gw_interface=brq${EXT_NET_ID:0:11}
+        fi
+        if [[ "$ext_gw_interface" != "none" ]]; then
+            local cidr_len=${FLOATING_RANGE#*/}
+            local testcmd="ip -o link | grep -q $ext_gw_interface"
+            test_with_retry "$testcmd" "$ext_gw_interface creation failed"
+            if [[ $(ip addr show dev $ext_gw_interface | grep -c $ext_gw_ip) == 0 && ( $Q_USE_PROVIDERNET_FOR_PUBLIC == "False" || $Q_USE_PUBLIC_VETH == "True" ) ]]; then
+                sudo ip addr add $ext_gw_ip/$cidr_len dev $ext_gw_interface
+                sudo ip link set $ext_gw_interface up
+            fi
+            ROUTER_GW_IP=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" port-list -c fixed_ips -c device_owner | grep router_gateway | awk -F'ip_address'  '{ print $2 }' | cut -f3 -d\" | tr '\n' ' ')
+            die_if_not_set $LINENO ROUTER_GW_IP "Failure retrieving ROUTER_GW_IP"
+            sudo ip route replace  $FIXED_RANGE via $ROUTER_GW_IP
+        fi
+        _neutron_set_router_id
+    fi
+}
+
+# Configure neutron router for IPv6 public access
+function _neutron_configure_router_v6 {
+    neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-interface-add $ROUTER_ID $IPV6_SUBNET_ID
+    # Create a public subnet on the external network
+    local ipv6_id_and_ext_gw_ip
+    ipv6_id_and_ext_gw_ip=$(_neutron_create_public_subnet_v6 $EXT_NET_ID)
+    local ipv6_ext_gw_ip
+    ipv6_ext_gw_ip=$(echo $ipv6_id_and_ext_gw_ip | get_field 2)
+    local ipv6_pub_subnet_id
+    ipv6_pub_subnet_id=$(echo $ipv6_id_and_ext_gw_ip | get_field 5)
+
+    # If the external network has not already been set as the default router
+    # gateway when configuring an IPv4 public subnet, do so now
+    if [[ "$IP_VERSION" == "6" ]]; then
+        neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-gateway-set $ROUTER_ID $EXT_NET_ID
+    fi
+
+    # This logic is specific to using the l3-agent for layer 3
+    if is_service_enabled q-l3; then
+        # Ensure IPv6 forwarding is enabled on the host
+        sudo sysctl -w net.ipv6.conf.all.forwarding=1
+        # Configure and enable public bridge
+        # Override global IPV6_ROUTER_GW_IP with the true value from neutron
+        IPV6_ROUTER_GW_IP=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" port-list -c fixed_ips | grep $ipv6_pub_subnet_id | awk -F'ip_address' '{ print $2 }' | cut -f3 -d\" | tr '\n' ' ')
+        die_if_not_set $LINENO IPV6_ROUTER_GW_IP "Failure retrieving IPV6_ROUTER_GW_IP"
+
+        if is_neutron_ovs_base_plugin; then
+            local ext_gw_interface
+            ext_gw_interface=$(_neutron_get_ext_gw_interface)
+            local ipv6_cidr_len=${IPV6_PUBLIC_RANGE#*/}
+
+            # Configure interface for public bridge
+            sudo ip -6 addr add $ipv6_ext_gw_ip/$ipv6_cidr_len dev $ext_gw_interface
+            sudo ip -6 route replace $FIXED_RANGE_V6 via $IPV6_ROUTER_GW_IP dev $ext_gw_interface
+        fi
+        _neutron_set_router_id
+    fi
+}
+
+function is_provider_network {
+    if [ "$Q_USE_PROVIDER_NETWORKING" == "True" ]; then
+        return 0
+    fi
+    return 1
+}
+
+function is_networking_extension_supported {
+    local extension=$1
+    # TODO(sc68cal) cache this instead of calling every time
+    EXT_LIST=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" ext-list -c alias -f value)
+    [[ $EXT_LIST =~ $extension ]] && return 0
+}
diff --git a/lib/neutron_plugins/services/vpn b/lib/neutron_plugins/services/vpn
deleted file mode 100644
index e790913..0000000
--- a/lib/neutron_plugins/services/vpn
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/bash
-
-# Neutron VPN plugin
-# ---------------------------
-
-# Save trace setting
-_XTRACE_NEUTRON_VPN=$(set +o | grep xtrace)
-set +o xtrace
-
-
-AGENT_VPN_BINARY="$NEUTRON_BIN_DIR/neutron-vpn-agent"
-VPN_PLUGIN=${VPN_PLUGIN:-"neutron_vpnaas.services.vpn.plugin.VPNDriverPlugin"}
-IPSEC_PACKAGE=${IPSEC_PACKAGE:-"openswan"}
-
-function neutron_vpn_install_agent_packages {
-    install_package $IPSEC_PACKAGE
-    if is_ubuntu && [[ "$IPSEC_PACKAGE" == "strongswan" ]]; then
-        sudo ln -sf /etc/apparmor.d/usr.lib.ipsec.charon /etc/apparmor.d/disable/
-        sudo ln -sf /etc/apparmor.d/usr.lib.ipsec.stroke /etc/apparmor.d/disable/
-        # NOTE: Due to https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1387220
-        # one must use 'sudo start apparmor ACTION=reload' for Ubuntu 14.10
-        restart_service apparmor
-    fi
-}
-
-function neutron_vpn_configure_common {
-    _neutron_service_plugin_class_add $VPN_PLUGIN
-    _neutron_deploy_rootwrap_filters $NEUTRON_VPNAAS_DIR
-}
-
-function neutron_vpn_configure_agent {
-    # Uses oslo config generator to generate LBaaS sample configuration files
-    (cd $NEUTRON_VPNAAS_DIR && exec ./tools/generate_config_file_samples.sh)
-    cp $NEUTRON_VPNAAS_DIR/etc/vpn_agent.ini.sample $Q_VPN_CONF_FILE
-    if [[ "$IPSEC_PACKAGE" == "strongswan" ]]; then
-        iniset_multiline $Q_VPN_CONF_FILE vpnagent vpn_device_driver neutron_vpnaas.services.vpn.device_drivers.strongswan_ipsec.StrongSwanDriver
-        if is_fedora; then
-            iniset $Q_VPN_CONF_FILE strongswan default_config_area /usr/share/strongswan/templates/config/strongswan.d
-        fi
-    else
-        iniset_multiline $Q_VPN_CONF_FILE vpnagent vpn_device_driver neutron_vpnaas.services.vpn.device_drivers.ipsec.OpenSwanDriver
-    fi
-}
-
-function neutron_vpn_stop {
-    local ipsec_data_dir=$DATA_DIR/neutron/ipsec
-    local pids
-    if [ -d $ipsec_data_dir ]; then
-        pids=$(find $ipsec_data_dir -name 'pluto.pid' -exec cat {} \;)
-    fi
-    if [ -n "$pids" ]; then
-        sudo kill $pids
-    fi
-    stop_process q-vpn
-}
-
-# Restore xtrace
-$_XTRACE_NEUTRON_VPN
diff --git a/lib/nova b/lib/nova
index 818ecc4..67a80b9 100644
--- a/lib/nova
+++ b/lib/nova
@@ -59,11 +59,6 @@
 
 NOVA_API_PASTE_INI=${NOVA_API_PASTE_INI:-$NOVA_CONF_DIR/api-paste.ini}
 
-# NOVA_V2_LEGACY defines whether we force the Nova v2.0 enpoint onto
-# the Nova v2.0 legacy code base. Remove this option once the Nova
-# v2.0 legacy codebase is removed.
-NOVA_V2_LEGACY=$(trueorfalse False NOVA_V2_LEGACY)
-
 if is_suse; then
     NOVA_WSGI_DIR=${NOVA_WSGI_DIR:-/srv/www/htdocs/nova}
 else
@@ -311,13 +306,6 @@
     if [[ "$ENABLED_SERVICES" =~ "n-api" ]]; then
         # Get the sample configuration file in place
         cp $NOVA_DIR/etc/nova/api-paste.ini $NOVA_CONF_DIR
-
-        # For setting up an environment where v2.0 is running on the
-        # v2.0 legacy code base.
-        if [[ "$NOVA_V2_LEGACY" == "True" ]]; then
-            sed -i s@"^/v2: openstack_compute_api_v21_legacy_v2_compatible$"@"/v2: openstack_compute_api_legacy_v2"@ \
-                "$NOVA_API_PASTE_INI"
-        fi
     fi
 
     if is_service_enabled n-cpu; then
@@ -495,6 +483,9 @@
 
     iniset $NOVA_CONF privsep_osbrick helper_command "sudo nova-rootwrap \$rootwrap_config privsep-helper --config-file $NOVA_CONF"
 
+    iniset $NOVA_CONF vif_plug_ovs_privileged helper_command "sudo nova-rootwrap \$rootwrap_config privsep-helper --config-file $NOVA_CONF"
+    iniset $NOVA_CONF vif_plug_linux_bridge_privileged helper_command "sudo nova-rootwrap \$rootwrap_config privsep-helper --config-file $NOVA_CONF"
+
     if is_service_enabled n-api; then
         if is_service_enabled n-api-meta; then
             # If running n-api-meta as a separate service
@@ -601,11 +592,6 @@
 
     iniset $NOVA_CONF cinder os_region_name "$REGION_NAME"
 
-    if [[ "$NOVA_BACKEND" == "LVM" ]]; then
-        iniset $NOVA_CONF libvirt images_type "lvm"
-        iniset $NOVA_CONF libvirt images_volume_group $DEFAULT_VOLUME_GROUP_NAME
-    fi
-
     if is_ssl_enabled_service glance || is_service_enabled tls-proxy; then
         iniset $NOVA_CONF DEFAULT glance_protocol https
     fi
@@ -648,7 +634,7 @@
     if is_service_enabled n-cell; then
         cp $NOVA_CONF $NOVA_CELLS_CONF
         iniset $NOVA_CELLS_CONF database connection `database_connection_url $NOVA_CELLS_DB`
-        iniset $NOVA_CELLS_CONF oslo_messaging_rabbit rabbit_virtual_host child_cell
+        iniset_rpc_backend nova $NOVA_CELLS_CONF DEFAULT child_cell
         iniset $NOVA_CELLS_CONF DEFAULT dhcpbridge_flagfile $NOVA_CELLS_CONF
         iniset $NOVA_CELLS_CONF cells enable True
         iniset $NOVA_CELLS_CONF cells cell_type compute
@@ -702,18 +688,18 @@
         recreate_database nova
 
         # Migrate nova database
-        $NOVA_BIN_DIR/nova-manage db sync
+        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF db sync
 
         if is_service_enabled n-cell; then
             recreate_database $NOVA_CELLS_DB
         fi
 
         recreate_database $NOVA_API_DB
-        $NOVA_BIN_DIR/nova-manage api_db sync
+        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF api_db sync
 
         # Run online migrations on the new databases
         # Needed for flavor conversion
-        $NOVA_BIN_DIR/nova-manage db online_data_migrations
+        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF db online_data_migrations
     fi
 
     create_nova_cache_dir
@@ -935,21 +921,21 @@
 # create_instance_types(): Create default flavors
 function create_flavors {
     if is_service_enabled n-api; then
-        if ! openstack flavor list | grep -q ds512M; then
+        if ! openstack --os-region-name="$REGION_NAME" flavor list | grep -q ds512M; then
             # Note that danms hates these flavors and apologizes for sdague
-            openstack flavor create --id c1 --ram 256 --disk 0 --vcpus 1 cirros256
-            openstack flavor create --id d1 --ram 512 --disk 5 --vcpus 1 ds512M
-            openstack flavor create --id d2 --ram 1024 --disk 10 --vcpus 1 ds1G
-            openstack flavor create --id d3 --ram 2048 --disk 10 --vcpus 2 ds2G
-            openstack flavor create --id d4 --ram 4096 --disk 20 --vcpus 4 ds4G
+            openstack --os-region-name="$REGION_NAME" flavor create --id c1 --ram 256 --disk 0 --vcpus 1 cirros256
+            openstack --os-region-name="$REGION_NAME" flavor create --id d1 --ram 512 --disk 5 --vcpus 1 ds512M
+            openstack --os-region-name="$REGION_NAME" flavor create --id d2 --ram 1024 --disk 10 --vcpus 1 ds1G
+            openstack --os-region-name="$REGION_NAME" flavor create --id d3 --ram 2048 --disk 10 --vcpus 2 ds2G
+            openstack --os-region-name="$REGION_NAME" flavor create --id d4 --ram 4096 --disk 20 --vcpus 4 ds4G
         fi
 
-        if ! openstack flavor list | grep -q m1.tiny; then
-            openstack flavor create --id 1 --ram 512 --disk 1 --vcpus 1 m1.tiny
-            openstack flavor create --id 2 --ram 2048 --disk 20 --vcpus 1 m1.small
-            openstack flavor create --id 3 --ram 4096 --disk 40 --vcpus 2 m1.medium
-            openstack flavor create --id 4 --ram 8192 --disk 80 --vcpus 4 m1.large
-            openstack flavor create --id 5 --ram 16384 --disk 160 --vcpus 8 m1.xlarge
+        if ! openstack --os-region-name="$REGION_NAME" flavor list | grep -q m1.tiny; then
+            openstack --os-region-name="$REGION_NAME" flavor create --id 1 --ram 512 --disk 1 --vcpus 1 m1.tiny
+            openstack --os-region-name="$REGION_NAME" flavor create --id 2 --ram 2048 --disk 20 --vcpus 1 m1.small
+            openstack --os-region-name="$REGION_NAME" flavor create --id 3 --ram 4096 --disk 40 --vcpus 2 m1.medium
+            openstack --os-region-name="$REGION_NAME" flavor create --id 4 --ram 8192 --disk 80 --vcpus 4 m1.large
+            openstack --os-region-name="$REGION_NAME" flavor create --id 5 --ram 16384 --disk 160 --vcpus 8 m1.xlarge
         fi
     fi
 }
diff --git a/lib/nova_plugins/functions-libvirt b/lib/nova_plugins/functions-libvirt
index dbb4d4f..4e5a748 100644
--- a/lib/nova_plugins/functions-libvirt
+++ b/lib/nova_plugins/functions-libvirt
@@ -108,9 +108,9 @@
             # source file paths, not relative paths. This screws with the matching
             # of '1:libvirt' making everything turn on. So use libvirt.c for now.
             # This will have to be re-visited when Ubuntu ships libvirt >= 1.2.3
-            local log_filters="1:libvirt.c 1:qemu 1:conf 1:security 3:object 3:event 3:json 3:file 1:util 1:qemu_monitor"
+            local log_filters="1:libvirt.c 1:qemu 1:conf 1:security 3:object 3:event 3:json 3:file 1:util 1:cpu"
         else
-            local log_filters="1:libvirt 1:qemu 1:conf 1:security 3:object 3:event 3:json 3:file 1:util 1:qemu_monitor"
+            local log_filters="1:libvirt 1:qemu 1:conf 1:security 3:object 3:event 3:json 3:file 1:util 1:cpu"
         fi
         local log_outputs="1:file:/var/log/libvirt/libvirtd.log"
         if ! sudo grep -q "^log_filters=\"$log_filters\"" /etc/libvirt/libvirtd.conf; then
@@ -121,18 +121,9 @@
         fi
     fi
 
-    # Update the libvirt cpu map with a gate64 cpu model. This enables nova
-    # live migration for 64bit guest OSes on heterogenous cloud "hardware".
-    if [[ -f /usr/share/libvirt/cpu_map.xml ]] ; then
-        sudo $TOP_DIR/tools/cpu_map_update.py /usr/share/libvirt/cpu_map.xml
-    fi
-
-    # libvirt detects various settings on startup, as we potentially changed
-    # the system configuration (modules, filesystems), we need to restart
-    # libvirt to detect those changes. Use a stop start as otherwise the new
-    # cpu_map is not loaded properly on some systems (Ubuntu).
-    stop_service $LIBVIRT_DAEMON
-    start_service $LIBVIRT_DAEMON
+    # Service needs to be started on redhat/fedora -- do a restart for
+    # sanity after fiddling the config.
+    restart_service $LIBVIRT_DAEMON
 }
 
 
diff --git a/lib/nova_plugins/hypervisor-libvirt b/lib/nova_plugins/hypervisor-libvirt
index 1b4f7ae..d0e364e 100644
--- a/lib/nova_plugins/hypervisor-libvirt
+++ b/lib/nova_plugins/hypervisor-libvirt
@@ -68,6 +68,12 @@
         iniset $NOVA_CONF vnc vncserver_proxyclient_address  $HOST_IP
         iniset $NOVA_CONF vnc vncserver_listen $HOST_IP
         iniset $NOVA_CONF vnc keymap
+    elif [[ "$NOVA_BACKEND" == "LVM" ]]; then
+        iniset $NOVA_CONF libvirt images_type "lvm"
+        iniset $NOVA_CONF libvirt images_volume_group $DEFAULT_VOLUME_GROUP_NAME
+        if isset LVM_VOLUME_CLEAR; then
+            iniset $NOVA_CONF libvirt volume_clear "$LVM_VOLUME_CLEAR"
+        fi
     fi
 }
 
diff --git a/lib/nova_plugins/hypervisor-xenserver b/lib/nova_plugins/hypervisor-xenserver
index 3eb9149..e7f1e87 100644
--- a/lib/nova_plugins/hypervisor-xenserver
+++ b/lib/nova_plugins/hypervisor-xenserver
@@ -29,7 +29,8 @@
 # Allow ``build_domU.sh`` to specify the flat network bridge via kernel args
 FLAT_NETWORK_BRIDGE_DEFAULT=$(sed -e 's/.* flat_network_bridge=\([[:alnum:]]*\).*$/\1/g' /proc/cmdline)
 if is_service_enabled neutron; then
-    XEN_INTEGRATION_BRIDGE=$(sed -e 's/.* xen_integration_bridge=\([[:alnum:]]*\).*$/\1/g' /proc/cmdline)
+    XEN_INTEGRATION_BRIDGE_DEFAULT=$(sed -e 's/.* xen_integration_bridge=\([[:alnum:]]*\).*$/\1/g' /proc/cmdline)
+    XEN_INTEGRATION_BRIDGE=${XEN_INTEGRATION_BRIDGE:-$XEN_INTEGRATION_BRIDGE_DEFAULT}
 fi
 
 VNCSERVER_PROXYCLIENT_ADDRESS=${VNCSERVER_PROXYCLIENT_ADDRESS=169.254.0.1}
diff --git a/lib/rpc_backend b/lib/rpc_backend
index 05e303e..0ee46dc 100644
--- a/lib/rpc_backend
+++ b/lib/rpc_backend
@@ -104,8 +104,9 @@
 
 # builds transport url string
 function get_transport_url {
+    local virtual_host=$1
     if is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
-        echo "rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/"
+        echo "rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/$virtual_host"
     fi
 }
 
@@ -114,11 +115,9 @@
     local package=$1
     local file=$2
     local section=${3:-DEFAULT}
+    local virtual_host=$4
     if is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
-        iniset $file $section rpc_backend "rabbit"
-        iniset $file oslo_messaging_rabbit rabbit_hosts $RABBIT_HOST
-        iniset $file oslo_messaging_rabbit rabbit_password $RABBIT_PASSWORD
-        iniset $file oslo_messaging_rabbit rabbit_userid $RABBIT_USERID
+        iniset $file $section transport_url $(get_transport_url "$virtual_host")
         if [ -n "$RABBIT_HEARTBEAT_TIMEOUT_THRESHOLD" ]; then
             iniset $file oslo_messaging_rabbit heartbeat_timeout_threshold $RABBIT_HEARTBEAT_TIMEOUT_THRESHOLD
         fi
diff --git a/lib/swift b/lib/swift
index 8cb94ef..0c74411 100644
--- a/lib/swift
+++ b/lib/swift
@@ -428,6 +428,7 @@
     sed -i "/^pipeline/ { s/proxy-server/${SWIFT_EXTRAS_MIDDLEWARE_LAST} proxy-server/ ; }" ${SWIFT_CONFIG_PROXY_SERVER}
 
     iniset ${SWIFT_CONFIG_PROXY_SERVER} app:proxy-server account_autocreate true
+    iniset ${SWIFT_CONFIG_PROXY_SERVER} app:proxy-server allow_account_management true
 
     # Configure Crossdomain
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:crossdomain use "egg:swift#crossdomain"
@@ -457,9 +458,7 @@
         cat <<EOF >>${SWIFT_CONFIG_PROXY_SERVER}
 [filter:s3token]
 paste.filter_factory = keystonemiddleware.s3_token:filter_factory
-auth_port = ${KEYSTONE_AUTH_PORT}
-auth_host = ${KEYSTONE_AUTH_HOST}
-auth_protocol = ${KEYSTONE_AUTH_PROTOCOL}
+auth_uri = ${KEYSTONE_AUTH_URI}
 cafile = ${SSL_BUNDLE_FILE}
 admin_user = swift
 admin_tenant_name = ${SERVICE_PROJECT_NAME}
diff --git a/lib/tempest b/lib/tempest
index 46dc1f8..347b2a7 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -16,7 +16,6 @@
 #   - ``BASE_SQL_CONN`` ``lib/database`` declares
 #   - ``PUBLIC_NETWORK_NAME``
 #   - ``Q_ROUTER_NAME``
-#   - ``Q_L3_ENABLED``
 #   - ``VIRT_DRIVER``
 #   - ``LIBVIRT_TYPE``
 #   - ``KEYSTONE_SERVICE_PROTOCOL``, ``KEYSTONE_SERVICE_HOST`` from lib/keystone
@@ -45,8 +44,6 @@
 # --------
 
 # Set up default directories
-GITDIR["tempest-lib"]=$DEST/tempest-lib
-
 TEMPEST_DIR=$DEST/tempest
 TEMPEST_CONFIG_DIR=${TEMPEST_CONFIG_DIR:-$TEMPEST_DIR/etc}
 TEMPEST_CONFIG=$TEMPEST_CONFIG_DIR/tempest.conf
@@ -66,6 +63,10 @@
 # have tempest installed in DevStack by default.
 INSTALL_TEMPEST=${INSTALL_TEMPEST:-"True"}
 
+# This variable is passed directly to pip install inside the common tox venv
+# that is created
+TEMPEST_PLUGINS=${TEMPEST_PLUGINS:-0}
+
 # Cinder/Volume variables
 TEMPEST_VOLUME_DRIVER=${TEMPEST_VOLUME_DRIVER:-default}
 TEMPEST_DEFAULT_VOLUME_VENDOR="Open Source"
@@ -182,8 +183,6 @@
     local admin_username=${ADMIN_USERNAME:-admin}
     local admin_project_name=${ADMIN_TENANT_NAME:-admin}
     local admin_domain_name=${ADMIN_DOMAIN_NAME:-Default}
-    local tempest_username=${TEMPEST_USERNAME:-demo}
-    local tempest_project_name=${TEMPEST_TENANT_NAME:-demo}
     local alt_username=${ALT_USERNAME:-alt_demo}
     local alt_project_name=${ALT_TENANT_NAME:-alt_demo}
     local admin_project_id
@@ -239,7 +238,9 @@
 
     ssh_connect_method=${TEMPEST_SSH_CONNECT_METHOD:-$ssh_connect_method}
 
-    if [ "$Q_L3_ENABLED" = "True" ]; then
+    # the public network (for floating ip access) is only available
+    # if the extension is enabled.
+    if is_networking_extension_supported 'external-net'; then
         public_network_id=$(neutron net-list | grep $PUBLIC_NETWORK_NAME | \
             awk '{print $2}')
     fi
@@ -260,6 +261,8 @@
     # Identity
     iniset $TEMPEST_CONFIG identity uri "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:5000/v2.0/"
     iniset $TEMPEST_CONFIG identity uri_v3 "$KEYSTONE_SERVICE_URI_V3"
+    # Use domain scoped tokens for admin v3 tests, v3 dynamic credentials of v3 account generation
+    iniset $TEMPEST_CONFIG identity admin_domain_scope True
     if [[ "$TEMPEST_HAS_ADMIN" == "True" ]]; then
         iniset $TEMPEST_CONFIG auth admin_username $admin_username
         iniset $TEMPEST_CONFIG auth admin_password "$password"
@@ -288,10 +291,14 @@
     fi
     if [ "$VIRT_DRIVER" = "xenserver" ]; then
         iniset $TEMPEST_CONFIG image disk_formats "ami,ari,aki,vhd,raw,iso"
+        iniset $TEMPEST_CONFIG scenario img_disk_format vhd
     fi
 
     # Image Features
     iniset $TEMPEST_CONFIG image-feature-enabled deactivate_image True
+    if [ "$GLANCE_V1_ENABLED" != "True" ]; then
+        iniset $TEMPEST_CONFIG image-feature-enabled api_v1 False
+    fi
 
     # Compute
     iniset $TEMPEST_CONFIG compute ssh_user ${DEFAULT_INSTANCE_USER:-cirros} # DEPRECATED
@@ -331,14 +338,14 @@
         tempest_compute_max_microversion=None
     fi
     if [ "$tempest_compute_min_microversion" == "None" ]; then
-        inicomment $TEMPEST_CONFIG compute-feature-enabled min_microversion
+        inicomment $TEMPEST_CONFIG compute min_microversion
     else
-        iniset $TEMPEST_CONFIG compute-feature-enabled min_microversion $tempest_compute_min_microversion
+        iniset $TEMPEST_CONFIG compute min_microversion $tempest_compute_min_microversion
     fi
     if [ "$tempest_compute_max_microversion" == "None" ]; then
-        inicomment $TEMPEST_CONFIG compute-feature-enabled max_microversion
+        inicomment $TEMPEST_CONFIG compute max_microversion
     else
-        iniset $TEMPEST_CONFIG compute-feature-enabled max_microversion $tempest_compute_max_microversion
+        iniset $TEMPEST_CONFIG compute max_microversion $tempest_compute_max_microversion
     fi
 
     iniset $TEMPEST_CONFIG compute-feature-enabled resize True
@@ -374,7 +381,7 @@
 
     # Network
     iniset $TEMPEST_CONFIG network api_version 2.0
-    iniset $TEMPEST_CONFIG network tenant_networks_reachable false
+    iniset $TEMPEST_CONFIG network project_networks_reachable false
     iniset $TEMPEST_CONFIG network public_network_id "$public_network_id"
     iniset $TEMPEST_CONFIG network public_router_id "$public_router_id"
     iniset $TEMPEST_CONFIG network default_network "$FIXED_RANGE"
@@ -432,6 +439,19 @@
     iniset $TEMPEST_CONFIG volume-feature-enabled volume_services True
     # TODO(ameade): Remove the api_v3 flag when Mitaka and Liberty are end of life.
     iniset $TEMPEST_CONFIG volume-feature-enabled api_v3 True
+    local tempest_volume_min_microversion=${TEMPEST_VOLUME_MIN_MICROVERSION:-None}
+    local tempest_volume_max_microversion=${TEMPEST_VOLUME_MAX_MICROVERSION:-"latest"}
+    if [ "$tempest_volume_min_microversion" == "None" ]; then
+        inicomment $TEMPEST_CONFIG volume min_microversion
+    else
+        iniset $TEMPEST_CONFIG volume min_microversion $tempest_volume_min_microversion
+    fi
+
+    if [ "$tempest_volume_max_microversion" == "None" ]; then
+        inicomment $TEMPEST_CONFIG volume max_microversion
+    else
+        iniset $TEMPEST_CONFIG volume max_microversion $tempest_volume_max_microversion
+    fi
 
     if ! is_service_enabled c-bak; then
         iniset $TEMPEST_CONFIG volume-feature-enabled backup False
@@ -521,17 +541,17 @@
     tmp_cfg_file=$(mktemp)
     cd $TEMPEST_DIR
     if [[ "$OFFLINE" != "True" ]]; then
-        tox -revenv --notest
+        tox -revenv-tempest --notest
     fi
-    tox -evenv -- pip install -c $REQUIREMENTS_DIR/upper-constraints.txt -r requirements.txt
+    tox -evenv-tempest -- pip install -c $REQUIREMENTS_DIR/upper-constraints.txt -r requirements.txt
 
     # Auth:
     iniset $TEMPEST_CONFIG auth tempest_roles "Member"
     if [[ $TEMPEST_USE_TEST_ACCOUNTS == "True" ]]; then
         if [[ $TEMPEST_HAS_ADMIN == "True" ]]; then
-            tox -evenv -- tempest-account-generator -c $TEMPEST_CONFIG --os-username $admin_username --os-password "$password" --os-tenant-name $admin_project_name -r $TEMPEST_CONCURRENCY --with-admin etc/accounts.yaml
+            tox -evenv-tempest -- tempest-account-generator -c $TEMPEST_CONFIG --os-username $admin_username --os-password "$password" --os-tenant-name $admin_project_name -r $TEMPEST_CONCURRENCY --with-admin etc/accounts.yaml
         else
-            tox -evenv -- tempest-account-generator -c $TEMPEST_CONFIG --os-username $admin_username --os-password "$password" --os-tenant-name $admin_project_name -r $TEMPEST_CONCURRENCY etc/accounts.yaml
+            tox -evenv-tempest -- tempest-account-generator -c $TEMPEST_CONFIG --os-username $admin_username --os-password "$password" --os-tenant-name $admin_project_name -r $TEMPEST_CONCURRENCY etc/accounts.yaml
         fi
         iniset $TEMPEST_CONFIG auth use_dynamic_credentials False
         iniset $TEMPEST_CONFIG auth test_accounts_file "etc/accounts.yaml"
@@ -587,20 +607,6 @@
     IFS=$ifs
 }
 
-
-# install_tempest_lib() - Collect source, prepare, and install ``tempest-lib``
-function install_tempest_lib {
-    if use_library_from_git "tempest-lib"; then
-        git_clone_by_name "tempest-lib"
-        setup_dev_lib "tempest-lib"
-        # NOTE(mtreinish) For testing ``tempest-lib`` from git with Tempest we need to
-        # put the git version of ``tempest-lib`` in the Tempest job's tox venv
-        export PIP_VIRTUAL_ENV=${PROJECT_VENV["tempest"]}
-        setup_dev_lib "tempest-lib"
-        unset PIP_VIRTUAL_ENV
-    fi
-}
-
 # install_tempest() - Collect source and prepare
 function install_tempest {
     git_clone $TEMPEST_REPO $TEMPEST_DIR $TEMPEST_BRANCH
@@ -610,9 +616,19 @@
     # NOTE(mtreinish) Respect constraints in the tempest full venv, things that
     # are using a tox job other than full will not be respecting constraints but
     # running pip install -U on tempest requirements
-    $TEMPEST_DIR/.tox/full/bin/pip install -c $REQUIREMENTS_DIR/upper-constraints.txt -r requirements.txt
-    PROJECT_VENV["tempest"]=${TEMPEST_DIR}/.tox/full
-    install_tempest_lib
+    $TEMPEST_DIR/.tox/tempest/bin/pip install -c $REQUIREMENTS_DIR/upper-constraints.txt -r requirements.txt
+    PROJECT_VENV["tempest"]=${TEMPEST_DIR}/.tox/tempest
+    popd
+}
+
+# install_tempest_plugins() - Install any specified plugins into the tempest venv
+function install_tempest_plugins {
+    pushd $TEMPEST_DIR
+    if [[ $TEMPEST_PLUGINS != 0 ]] ; then
+        tox -evenv-tempest -- pip install $TEMPEST_PLUGINS
+        echo "Checking installed Tempest plugins:"
+        tox -evenv-tempest -- tempest list-plugins
+    fi
     popd
 }
 
diff --git a/lib/template b/lib/template
index 08d10bb..b92fb40 100644
--- a/lib/template
+++ b/lib/template
@@ -35,8 +35,8 @@
 XXX_CONF_DIR=/etc/XXXX
 
 
-# Entry Points
-# ------------
+# Functions
+# ---------
 
 # Test if any XXXX services are enabled
 # is_XXXX_enabled
@@ -62,6 +62,11 @@
     :
 }
 
+# create_XXXX_accounts() - Create required service accounts
+function create_XXXX_accounts {
+    :
+}
+
 # init_XXXX() - Initialize databases, etc.
 function init_XXXX {
     # clean up from previous (possibly aborted) runs
diff --git a/openrc b/openrc
index db2e97d..8d8ae8b 100644
--- a/openrc
+++ b/openrc
@@ -90,6 +90,13 @@
 #
 export OS_AUTH_URL=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:5000/v${OS_IDENTITY_API_VERSION}
 
+# Currently, in order to use openstackclient with Identity API v3,
+# we need to set the domain which the user and project belong to.
+if [ "$OS_IDENTITY_API_VERSION" = "3" ]; then
+    export OS_USER_DOMAIN_ID=${OS_USER_DOMAIN_ID:-"default"}
+    export OS_PROJECT_DOMAIN_ID=${OS_PROJECT_DOMAIN_ID:-"default"}
+fi
+
 # Set OS_CACERT to a default CA certificate chain if it exists.
 if [[ ! -v OS_CACERT ]] ; then
     DEFAULT_OS_CACERT=$INT_CA_DIR/ca-chain.pem
diff --git a/pkg/elasticsearch.sh b/pkg/elasticsearch.sh
index 9c4f6f7..856eaff 100755
--- a/pkg/elasticsearch.sh
+++ b/pkg/elasticsearch.sh
@@ -10,7 +10,7 @@
 
 # Package source and version, all pkg files are expected to have
 # something like this, as well as a way to override them.
-ELASTICSEARCH_VERSION=${ELASTICSEARCH_VERSION:-1.4.2}
+ELASTICSEARCH_VERSION=${ELASTICSEARCH_VERSION:-1.7.5}
 ELASTICSEARCH_BASEURL=${ELASTICSEARCH_BASEURL:-https://download.elasticsearch.org/elasticsearch/elasticsearch}
 
 # Elastic search actual implementation
diff --git a/stack.sh b/stack.sh
index 3de9af2..6fbb0be 100755
--- a/stack.sh
+++ b/stack.sh
@@ -185,7 +185,7 @@
 
 # Warn users who aren't on an explicitly supported distro, but allow them to
 # override check and attempt installation with ``FORCE=yes ./stack``
-if [[ ! ${DISTRO} =~ (trusty|wily|xenial|7.0|wheezy|sid|testing|jessie|f22|f23|rhel7|kvmibm1) ]]; then
+if [[ ! ${DISTRO} =~ (trusty|wily|xenial|7.0|wheezy|sid|testing|jessie|f22|f23|f24|rhel7|kvmibm1) ]]; then
     echo "WARNING: this script has not been tested on $DISTRO"
     if [[ "$FORCE" != "yes" ]]; then
         die $LINENO "If you wish to run this script anyway run with FORCE=yes"
@@ -240,7 +240,6 @@
 # see them by forcing ``PATH``
 echo "Defaults:$STACK_USER secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
 echo "Defaults:$STACK_USER !requiretty" >> $TEMPFILE
-echo "Defaults env_keep += PS4" >> $TEMPFILE
 chmod 0440 $TEMPFILE
 sudo chown root:root $TEMPFILE
 sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh
@@ -336,6 +335,13 @@
 # to speed things up
 SKIP_EPEL_INSTALL=$(trueorfalse False SKIP_EPEL_INSTALL)
 
+# If we have /etc/nodepool/provider assume we're on a OpenStack CI
+# node, where EPEL is already pointing at our internal mirror and RDO
+# is pre-installed.
+if [[ -f /etc/nodepool/provider ]]; then
+    SKIP_EPEL_INSTALL=True
+fi
+
 if is_fedora && [[ $DISTRO == "rhel7" ]] && \
         [[ ${SKIP_EPEL_INSTALL} != True ]]; then
     _install_epel_and_rdo
@@ -559,6 +565,7 @@
 source $TOP_DIR/lib/cinder
 source $TOP_DIR/lib/swift
 source $TOP_DIR/lib/heat
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 source $TOP_DIR/lib/ldap
 source $TOP_DIR/lib/dstat
@@ -1075,7 +1082,7 @@
 
     configure_neutron
     # Run init_neutron only on the node hosting the Neutron API server
-    if is_service_enabled $DATABASE_BACKENDS && is_service_enabled q-svc; then
+    if is_service_enabled $DATABASE_BACKENDS && is_service_enabled neutron; then
         init_neutron
     fi
 fi
@@ -1142,7 +1149,7 @@
 
     # Additional Nova configuration that is dependent on other services
     if is_service_enabled neutron; then
-        create_nova_conf_neutron
+        configure_neutron_nova
     elif is_service_enabled n-net; then
         create_nova_conf_nova_network
     fi
@@ -1208,9 +1215,9 @@
     done
 fi
 
-# Create a randomized default value for the keymgr's fixed_key
+# Create a randomized default value for the key manager's fixed_key
 if is_service_enabled nova; then
-    iniset $NOVA_CONF keymgr fixed_key $(generate_hex_string 32)
+    iniset $NOVA_CONF key_manager fixed_key $(generate_hex_string 32)
 fi
 
 # Launch the nova-api and wait for it to answer before continuing
@@ -1219,7 +1226,11 @@
     start_nova_api
 fi
 
-if is_service_enabled q-svc; then
+if is_service_enabled neutron-api; then
+    echo_summary "Starting Neutron"
+    start_neutron_api
+    # check_neutron_third_party_integration
+elif is_service_enabled q-svc; then
     echo_summary "Starting Neutron"
     start_neutron_service_and_check
     check_neutron_third_party_integration
@@ -1240,14 +1251,14 @@
 fi
 
 if is_service_enabled neutron; then
-    start_neutron_agents
+    start_neutron
 fi
 # Once neutron agents are started setup initial network elements
 if is_service_enabled q-svc && [[ "$NEUTRON_CREATE_INITIAL_NETWORKS" == "True" ]]; then
     echo_summary "Creating initial neutron network elements"
     create_neutron_initial_network
-    setup_neutron_debug
 fi
+
 if is_service_enabled nova; then
     echo_summary "Starting Nova"
     start_nova
@@ -1367,6 +1378,12 @@
     fi
 fi
 
+# Run test-config
+# ---------------
+
+# Phase: test-config
+run_phase stack test-config
+
 
 # Fin
 # ===
diff --git a/stackrc b/stackrc
index 8858788..7a5b821 100644
--- a/stackrc
+++ b/stackrc
@@ -208,6 +208,9 @@
 # ex: LIBS_FROM_GIT=python-keystoneclient,oslo.config
 #
 # Will install those 2 libraries from git, the rest from pypi.
+#
+# Setting the variable to 'ALL' will activate the download for all
+# libraries.
 
 
 ##############
@@ -248,10 +251,6 @@
 NEUTRON_LBAAS_REPO=${NEUTRON_LBAAS_REPO:-${GIT_BASE}/openstack/neutron-lbaas.git}
 NEUTRON_LBAAS_BRANCH=${NEUTRON_LBAAS_BRANCH:-master}
 
-# neutron vpnaas service
-NEUTRON_VPNAAS_REPO=${NEUTRON_VPNAAS_REPO:-${GIT_BASE}/openstack/neutron-vpnaas.git}
-NEUTRON_VPNAAS_BRANCH=${NEUTRON_VPNAAS_BRANCH:-master}
-
 # compute service
 NOVA_REPO=${NOVA_REPO:-${GIT_BASE}/openstack/nova.git}
 NOVA_BRANCH=${NOVA_BRANCH:-master}
@@ -274,10 +273,6 @@
 TEMPEST_REPO=${TEMPEST_REPO:-${GIT_BASE}/openstack/tempest.git}
 TEMPEST_BRANCH=${TEMPEST_BRANCH:-master}
 
-# TODO(sdague): this should end up as a library component like below
-GITREPO["tempest-lib"]=${TEMPEST_LIB_REPO:-${GIT_BASE}/openstack/tempest-lib.git}
-GITBRANCH["tempest-lib"]=${TEMPEST_LIB_BRANCH:-master}
-
 
 ##############
 #
@@ -290,6 +285,10 @@
 GITREPO["python-cinderclient"]=${CINDERCLIENT_REPO:-${GIT_BASE}/openstack/python-cinderclient.git}
 GITBRANCH["python-cinderclient"]=${CINDERCLIENT_BRANCH:-master}
 
+# os-brick client for local volume attachement
+GITREPO["python-brick-cinderclient-ext"]=${BRICK_CINDERCLIENT_REPO:-${GIT_BASE}/openstack/python-brick-cinderclient-ext.git}
+GITBRANCH["python-brick-cinderclient-ext"]=${BRICK_CINDERCLIENT_BRANCH:-master}
+
 # python glance client library
 GITREPO["python-glanceclient"]=${GLANCECLIENT_REPO:-${GIT_BASE}/openstack/python-glanceclient.git}
 GITBRANCH["python-glanceclient"]=${GLANCECLIENT_BRANCH:-master}
diff --git a/tests/test_libs_from_pypi.sh b/tests/test_libs_from_pypi.sh
index f01db6d..bb58088 100755
--- a/tests/test_libs_from_pypi.sh
+++ b/tests/test_libs_from_pypi.sh
@@ -31,7 +31,7 @@
 
 ALL_LIBS="python-novaclient oslo.config pbr oslo.context"
 ALL_LIBS+=" python-keystoneclient taskflow oslo.middleware pycadf"
-ALL_LIBS+=" python-glanceclient python-ironicclient tempest-lib"
+ALL_LIBS+=" python-glanceclient python-ironicclient"
 ALL_LIBS+=" oslo.messaging oslo.log cliff python-heatclient stevedore"
 ALL_LIBS+=" python-cinderclient glance_store oslo.concurrency oslo.db"
 ALL_LIBS+=" oslo.versionedobjects oslo.vmware keystonemiddleware"
@@ -42,7 +42,7 @@
 ALL_LIBS+=" debtcollector os-brick automaton futurist oslo.service"
 ALL_LIBS+=" oslo.cache oslo.reports osprofiler"
 ALL_LIBS+=" keystoneauth ironic-lib neutron-lib oslo.privsep"
-ALL_LIBS+=" diskimage-builder os-vif"
+ALL_LIBS+=" diskimage-builder os-vif python-brick-cinderclient-ext"
 
 # Generate the above list with
 # echo ${!GITREPO[@]}
diff --git a/tools/cpu_map_update.py b/tools/cpu_map_update.py
deleted file mode 100755
index 92b7b8f..0000000
--- a/tools/cpu_map_update.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env python
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-# This small script updates the libvirt CPU map to add a gate64 cpu model
-# that can be used to enable a common 64bit capable feature set across
-# devstack nodes so that features like nova live migration work.
-
-import sys
-import xml.etree.ElementTree as ET
-from xml.dom import minidom
-
-
-def update_cpu_map(tree):
-    root = tree.getroot()
-    cpus = root#.find("cpus")
-    x86 = None
-    for arch in cpus.findall("arch"):
-        if arch.get("name") == "x86":
-            x86 = arch
-            break
-    if x86 is not None:
-        # Create a gate64 cpu model that is core2duo less monitor, pse36,
-        # vme, and ssse3.
-        gate64 = ET.SubElement(x86, "model")
-        gate64.set("name", "gate64")
-        ET.SubElement(gate64, "vendor").set("name", "Intel")
-        ET.SubElement(gate64, "feature").set("name", "fpu")
-        ET.SubElement(gate64, "feature").set("name", "de")
-        ET.SubElement(gate64, "feature").set("name", "pse")
-        ET.SubElement(gate64, "feature").set("name", "tsc")
-        ET.SubElement(gate64, "feature").set("name", "msr")
-        ET.SubElement(gate64, "feature").set("name", "pae")
-        ET.SubElement(gate64, "feature").set("name", "mce")
-        ET.SubElement(gate64, "feature").set("name", "cx8")
-        ET.SubElement(gate64, "feature").set("name", "apic")
-        ET.SubElement(gate64, "feature").set("name", "sep")
-        ET.SubElement(gate64, "feature").set("name", "pge")
-        ET.SubElement(gate64, "feature").set("name", "cmov")
-        ET.SubElement(gate64, "feature").set("name", "pat")
-        ET.SubElement(gate64, "feature").set("name", "mmx")
-        ET.SubElement(gate64, "feature").set("name", "fxsr")
-        ET.SubElement(gate64, "feature").set("name", "sse")
-        ET.SubElement(gate64, "feature").set("name", "sse2")
-        ET.SubElement(gate64, "feature").set("name", "mtrr")
-        ET.SubElement(gate64, "feature").set("name", "mca")
-        ET.SubElement(gate64, "feature").set("name", "clflush")
-        ET.SubElement(gate64, "feature").set("name", "pni")
-        ET.SubElement(gate64, "feature").set("name", "nx")
-        ET.SubElement(gate64, "feature").set("name", "syscall")
-        ET.SubElement(gate64, "feature").set("name", "lm")
-
-
-def format_xml(root):
-    # Adapted from http://pymotw.com/2/xml/etree/ElementTree/create.html
-    # thank you dhellmann
-    rough_string = ET.tostring(root, encoding="UTF-8")
-    dom_parsed = minidom.parseString(rough_string)
-    return dom_parsed.toprettyxml("  ", encoding="UTF-8")
-
-
-def main():
-    if len(sys.argv) != 2:
-        raise Exception("Must pass path to cpu_map.xml to update")
-    cpu_map = sys.argv[1]
-    tree = ET.parse(cpu_map)
-    for model in tree.getroot().iter("model"):
-        if model.get("name") == "gate64":
-            # gate64 model is already present
-            return
-    update_cpu_map(tree)
-    pretty_xml = format_xml(tree.getroot())
-    with open(cpu_map, 'w') as f:
-        f.write(pretty_xml)
-
-
-if __name__ == "__main__":
-    main()
diff --git a/tools/create_userrc.sh b/tools/create_userrc.sh
index a7278e4..b6db5d1 100755
--- a/tools/create_userrc.sh
+++ b/tools/create_userrc.sh
@@ -22,6 +22,9 @@
     file=${file#$RC_DIR/}
     printf "%-40s " "$file:${called[1]}:${called[0]}"
 }
+# PS4 is exported to child shells and uses the 'short_source' function, so
+# export it so child shells have access to the 'short_source' function also.
+export -f short_source
 
 set -o xtrace
 
diff --git a/tools/generate-devstack-plugins-list.py b/tools/generate-devstack-plugins-list.py
index 089a6ef..bbad1bf 100644
--- a/tools/generate-devstack-plugins-list.py
+++ b/tools/generate-devstack-plugins-list.py
@@ -44,16 +44,10 @@
     # stackforge, etc)
     return proj.startswith('openstack/')
 
-# Rather than returning a 404 for a nonexistent file, cgit delivers a
-# 0-byte response to a GET request.  It also does not provide a
-# Content-Length in a HEAD response, so the way we tell if a file exists
-# is to check the length of the entire GET response body.
+# Check if this project has a plugin file
 def has_devstack_plugin(proj):
     r = requests.get("https://git.openstack.org/cgit/%s/plain/devstack/plugin.sh" % proj)
-    if len(r.text) > 0:
-        return True
-    else:
-        return False
+    return r.status_code == 200
 
 logging.debug("Getting project list from %s" % url)
 r = requests.get(url)
diff --git a/tools/install_pip.sh b/tools/install_pip.sh
index dfa4f42..1267699 100755
--- a/tools/install_pip.sh
+++ b/tools/install_pip.sh
@@ -116,7 +116,7 @@
 
 # Eradicate any and all system packages
 
-# Python in f23 and f22 depends on the python-pip package so removing it
+# Python in fedora depends on the python-pip package so removing it
 # results in a nonfunctional system. pip on fedora installs to /usr so pip
 # can safely override the system pip for all versions of fedora
 if ! is_fedora ; then
diff --git a/tools/worlddump.py b/tools/worlddump.py
index 238a23d..e1ef544 100755
--- a/tools/worlddump.py
+++ b/tools/worlddump.py
@@ -88,7 +88,8 @@
 
 
 def _bridge_list():
-    process = subprocess.Popen(['ovs-vsctl', 'list-br'], stdout=subprocess.PIPE)
+    process = subprocess.Popen(['sudo', 'ovs-vsctl', 'list-br'],
+                               stdout=subprocess.PIPE)
     stdout, _ = process.communicate()
     return stdout.split()
 
diff --git a/tools/xen/README.md b/tools/xen/README.md
index 21090e5..7062ecb 100644
--- a/tools/xen/README.md
+++ b/tools/xen/README.md
@@ -170,3 +170,9 @@
     xe vm-import filename="$mountdir/$TEMPLATE_FILENAME"
     umount "$mountdir"
     rm -rf "$mountdir"
+
+### Migrate OpenStack DomU to another host
+
+Given you need to migrate your DomU with OpenStack installed to another host,
+you need to set `XEN_INTEGRATION_BRIDGE` in localrc if neutron network is used.
+It is the bridge for `XEN_INT_BRIDGE_OR_NET_NAME` network created in Dom0
diff --git a/tools/xen/install_os_domU.sh b/tools/xen/install_os_domU.sh
index 46ff0b6..3a61215 100755
--- a/tools/xen/install_os_domU.sh
+++ b/tools/xen/install_os_domU.sh
@@ -183,10 +183,8 @@
         # Copy the tools DEB to the XS web server
         XS_TOOLS_URL="https://github.com/downloads/citrix-openstack/warehouse/xe-guest-utilities_5.6.100-651_amd64.deb"
         ISO_DIR="/opt/xensource/packages/iso"
-        XS_TOOLS_FILE_NAME="xs-tools.deb"
-        XS_TOOLS_PATH="/root/$XS_TOOLS_FILE_NAME"
         if [ -e "$ISO_DIR" ]; then
-            TOOLS_ISO=$(ls -1 $ISO_DIR/xs-tools-*.iso | head -1)
+            TOOLS_ISO=$(ls -1 $ISO_DIR/*-tools-*.iso | head -1)
             TMP_DIR=/tmp/temp.$RANDOM
             mkdir -p $TMP_DIR
             mount -o loop $TOOLS_ISO $TMP_DIR
@@ -299,10 +297,10 @@
 # kernel parameter for DomU
 attach_network "$XEN_INT_BRIDGE_OR_NET_NAME"
 
-XEN_INTEGRATION_BRIDGE=$(bridge_for "$XEN_INT_BRIDGE_OR_NET_NAME")
+XEN_INTEGRATION_BRIDGE_DEFAULT=$(bridge_for "$XEN_INT_BRIDGE_OR_NET_NAME")
 append_kernel_cmdline \
     "$GUEST_NAME" \
-    "xen_integration_bridge=${XEN_INTEGRATION_BRIDGE}"
+    "xen_integration_bridge=${XEN_INTEGRATION_BRIDGE_DEFAULT}"
 
 FLAT_NETWORK_BRIDGE="${FLAT_NETWORK_BRIDGE:-$(bridge_for "$VM_BRIDGE_OR_NET_NAME")}"
 append_kernel_cmdline "$GUEST_NAME" "flat_network_bridge=${FLAT_NETWORK_BRIDGE}"
diff --git a/tox.ini b/tox.ini
index dbd1652..55a06d0 100644
--- a/tox.ini
+++ b/tox.ini
@@ -12,7 +12,7 @@
 # against devstack, just set BASHATE_INSTALL_PATH=/path/... to your
 # modified bashate tree
 deps =
-   {env:BASHATE_INSTALL_PATH:bashate==0.5.0}
+   {env:BASHATE_INSTALL_PATH:bashate==0.5.1}
 whitelist_externals = bash
 commands = bash -c "find {toxinidir}             \
          -not \( -type d -name .?\* -prune \)    \
diff --git a/unstack.sh b/unstack.sh
index 83703ec..a69b218 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -66,6 +66,7 @@
 source $TOP_DIR/lib/cinder
 source $TOP_DIR/lib/swift
 source $TOP_DIR/lib/heat
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 source $TOP_DIR/lib/ldap
 source $TOP_DIR/lib/dstat