update for name change to Neutron

Note: Nova and Horizon are not updated until those projects have
migrated.

Change-Id: I256ef20e7caadd9c96e6dd908c5d8b69ca5c4aeb
diff --git a/lib/neutron_plugins/README.md b/lib/neutron_plugins/README.md
new file mode 100644
index 0000000..be8fd96
--- /dev/null
+++ b/lib/neutron_plugins/README.md
@@ -0,0 +1,38 @@
+Neutron plugin specific files
+=============================
+Neutron plugins require plugin specific behavior.
+The files under the directory, ``lib/neutron_plugins/``, will be used
+when their service is enabled.
+Each plugin has ``lib/neutron_plugins/$Q_PLUGIN`` and define the following
+functions.
+Plugin specific configuration variables should be in this file.
+
+* filename: ``$Q_PLUGIN``
+  * The corresponding file name MUST be the same to plugin name ``$Q_PLUGIN``.
+    Plugin specific configuration variables should be in this file.
+
+functions
+---------
+``lib/neutron`` calls the following functions when the ``$Q_PLUGIN`` is enabled
+
+* ``neutron_plugin_create_nova_conf`` :
+  set ``NOVA_VIF_DRIVER`` and optionally set options in nova_conf
+  e.g.
+  NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtGenericVIFDriver"}
+* ``neutron_plugin_install_agent_packages`` :
+  install packages that is specific to plugin agent
+  e.g.
+  install_package bridge-utils
+* ``neutron_plugin_configure_common`` :
+  set plugin-specific variables, ``Q_PLUGIN_CONF_PATH``, ``Q_PLUGIN_CONF_FILENAME``,
+  ``Q_DB_NAME``, ``Q_PLUGIN_CLASS``
+* ``neutron_plugin_configure_debug_command``
+* ``neutron_plugin_configure_dhcp_agent``
+* ``neutron_plugin_configure_l3_agent``
+* ``neutron_plugin_configure_plugin_agent``
+* ``neutron_plugin_configure_service``
+* ``neutron_plugin_setup_interface_driver``
+* ``has_neutron_plugin_security_group``:
+  return 0 if the plugin support neutron security group otherwise return 1
+* ``neutron_plugin_check_adv_test_requirements``:
+  return 0 if requirements are satisfied otherwise return 1
diff --git a/lib/neutron_plugins/bigswitch_floodlight b/lib/neutron_plugins/bigswitch_floodlight
new file mode 100644
index 0000000..2450731
--- /dev/null
+++ b/lib/neutron_plugins/bigswitch_floodlight
@@ -0,0 +1,74 @@
+# Neuton Big Switch/FloodLight plugin
+# ------------------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+source $TOP_DIR/lib/neutron_plugins/ovs_base
+source $TOP_DIR/lib/neutron_thirdparty/bigswitch_floodlight     # for third party service specific configuration values
+
+function neutron_plugin_create_nova_conf() {
+    NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtGenericVIFDriver"}
+}
+
+function neutron_plugin_install_agent_packages() {
+    _neutron_ovs_base_install_agent_packages
+}
+
+function neutron_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/bigswitch
+    Q_PLUGIN_CONF_FILENAME=restproxy.ini
+    Q_DB_NAME="restproxy_neutron"
+    Q_PLUGIN_CLASS="neutron.plugins.bigswitch.plugin.NeutronRestProxyV2"
+    BS_FL_CONTROLLERS_PORT=${BS_FL_CONTROLLERS_PORT:-localhost:80}
+    BS_FL_CONTROLLER_TIMEOUT=${BS_FL_CONTROLLER_TIMEOUT:-10}
+}
+
+function neutron_plugin_configure_debug_command() {
+    _neutron_ovs_base_configure_debug_command
+}
+
+function neutron_plugin_configure_dhcp_agent() {
+    :
+}
+
+function neutron_plugin_configure_l3_agent() {
+    _neutron_ovs_base_configure_l3_agent
+}
+
+function neutron_plugin_configure_plugin_agent() {
+    :
+}
+
+function neutron_plugin_configure_service() {
+    iniset /$Q_PLUGIN_CONF_FILE restproxy servers $BS_FL_CONTROLLERS_PORT
+    iniset /$Q_PLUGIN_CONF_FILE restproxy servertimeout $BS_FL_CONTROLLER_TIMEOUT
+    if [ "$BS_FL_VIF_DRIVER" = "ivs" ]
+    then
+        iniset /$Q_PLUGIN_CONF_FILE nova vif_type ivs
+    fi
+}
+
+function neutron_plugin_setup_interface_driver() {
+    local conf_file=$1
+    if [ "$BS_FL_VIF_DRIVER" = "ivs" ]
+    then
+        iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.IVSInterfaceDriver
+    else
+        iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
+    fi
+}
+
+
+function has_neutron_plugin_security_group() {
+    # 1 means False here
+    return 1
+}
+
+function neutron_plugin_check_adv_test_requirements() {
+    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/neutron_plugins/brocade b/lib/neutron_plugins/brocade
new file mode 100644
index 0000000..f9275ca
--- /dev/null
+++ b/lib/neutron_plugins/brocade
@@ -0,0 +1,59 @@
+# Brocade Neutron Plugin
+# ----------------------
+
+# Save trace setting
+BRCD_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+function is_neutron_ovs_base_plugin() {
+    return 1
+}
+
+function neutron_plugin_create_nova_conf() {
+    NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtGenericVIFDriver"}
+}
+
+function neutron_plugin_install_agent_packages() {
+    install_package bridge-utils
+}
+
+function neutron_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/brocade
+    Q_PLUGIN_CONF_FILENAME=brocade.ini
+    Q_DB_NAME="brcd_neutron"
+    Q_PLUGIN_CLASS="neutron.plugins.brocade.NeutronPlugin.BrocadePluginV2"
+}
+
+function neutron_plugin_configure_debug_command() {
+    iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT external_network_bridge
+}
+
+function neutron_plugin_configure_dhcp_agent() {
+    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
+}
+
+function neutron_plugin_configure_l3_agent() {
+    iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge
+    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
+}
+
+function neutron_plugin_configure_plugin_agent() {
+    AGENT_BINARY="$NEUTON_BIN_DIR/neutron-linuxbridge-agent"
+}
+
+function neutron_plugin_setup_interface_driver() {
+    local conf_file=$1
+    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.BridgeInterfaceDriver
+}
+
+function has_neutron_plugin_security_group() {
+    # 0 means True here
+    return 0
+}
+
+function neutron_plugin_check_adv_test_requirements() {
+    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
+}
+
+# Restore xtrace
+$BRCD_XTRACE
diff --git a/lib/neutron_plugins/cisco b/lib/neutron_plugins/cisco
new file mode 100644
index 0000000..8948be6
--- /dev/null
+++ b/lib/neutron_plugins/cisco
@@ -0,0 +1,327 @@
+# Neutron Cisco plugin
+# ---------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+# Scecify the VSM parameters
+Q_CISCO_PLUGIN_VSM_IP=${Q_CISCO_PLUGIN_VSM_IP:-}
+# Specify the VSM username
+Q_CISCO_PLUGIN_VSM_USERNAME=${Q_CISCO_PLUGIN_VSM_USERNAME:-admin}
+# Specify the VSM passward for above username
+Q_CISCO_PLUGIN_VSM_PASSWORD=${Q_CISCO_PLUGIN_VSM_PASSWORD:-}
+# Specify the uVEM integration bridge name
+Q_CISCO_PLUGIN_INTEGRATION_BRIDGE=${Q_CISCO_PLUGIN_INTEGRATION_BRIDGE:-br-int}
+# Specify if tunneling is enabled
+Q_CISCO_PLUGIN_ENABLE_TUNNELING=${Q_CISCO_PLUGIN_ENABLE_TUNNELING:-True}
+# Specify the VXLAN range
+Q_CISCO_PLUGIN_VXLAN_ID_RANGES=${Q_CISCO_PLUGIN_VXLAN_ID_RANGES:-5000:10000}
+# Specify the VLAN range
+Q_CISCO_PLUGIN_VLAN_RANGES=${Q_CISCO_PLUGIN_VLAN_RANGES:-vlan:1:4094}
+
+# Specify ncclient package information
+NCCLIENT_DIR=$DEST/ncclient
+NCCLIENT_VERSION=${NCCLIENT_VERSION:-0.3.1}
+NCCLIENT_REPO=${NCCLIENT_REPO:-${GIT_BASE}/CiscoSystems/ncclient.git}
+NCCLIENT_BRANCH=${NCCLIENT_BRANCH:-master}
+
+# This routine put a prefix on an existing function name
+function _prefix_function() {
+    declare -F $1 > /dev/null || die "$1 doesn't exist"
+    eval "$(echo "${2}_${1}()"; declare -f ${1} | tail -n +2)"
+}
+
+function _has_ovs_subplugin() {
+    local subplugin
+    for subplugin in ${Q_CISCO_PLUGIN_SUBPLUGINS[@]}; do
+        if [[ "$subplugin" == "openvswitch" ]]; then
+            return 0
+        fi
+    done
+    return 1
+}
+
+function _has_nexus_subplugin() {
+    local subplugin
+    for subplugin in ${Q_CISCO_PLUGIN_SUBPLUGINS[@]}; do
+        if [[ "$subplugin" == "nexus" ]]; then
+            return 0
+        fi
+    done
+    return 1
+}
+
+function _has_n1kv_subplugin() {
+    local subplugin
+    for subplugin in ${Q_CISCO_PLUGIN_SUBPLUGINS[@]}; do
+        if [[ "$subplugin" == "n1kv" ]]; then
+            return 0
+        fi
+    done
+    return 1
+}
+
+# This routine populates the cisco config file with the information for
+# a particular nexus switch
+function _config_switch() {
+    local cisco_cfg_file=$1
+    local switch_ip=$2
+    local username=$3
+    local password=$4
+    local ssh_port=$5
+    shift 5
+
+    local section="NEXUS_SWITCH:$switch_ip"
+    iniset $cisco_cfg_file $section username $username
+    iniset $cisco_cfg_file $section password $password
+    iniset $cisco_cfg_file $section ssh_port $ssh_port
+
+    while [[ ${#@} != 0 ]]; do
+        iniset  $cisco_cfg_file $section $1 $2
+        shift 2
+    done
+}
+
+# Prefix openvswitch plugin routines with "ovs" in order to differentiate from
+# cisco plugin routines. This means, ovs plugin routines will coexist with cisco
+# plugin routines in this script.
+source $TOP_DIR/lib/neutron_plugins/openvswitch
+_prefix_function neutron_plugin_create_nova_conf ovs
+_prefix_function neutron_plugin_install_agent_packages ovs
+_prefix_function neutron_plugin_configure_common ovs
+_prefix_function neutron_plugin_configure_debug_command ovs
+_prefix_function neutron_plugin_configure_dhcp_agent ovs
+_prefix_function neutron_plugin_configure_l3_agent ovs
+_prefix_function neutron_plugin_configure_plugin_agent ovs
+_prefix_function neutron_plugin_configure_service ovs
+_prefix_function neutron_plugin_setup_interface_driver ovs
+_prefix_function has_neutron_plugin_security_group ovs
+
+# Check the version of the installed ncclient package
+function check_ncclient_version() {
+python << EOF
+version = '$NCCLIENT_VERSION'
+import sys
+try:
+    import pkg_resources
+    import ncclient
+    module_version = pkg_resources.get_distribution('ncclient').version
+    if version != module_version:
+        sys.exit(1)
+except:
+    sys.exit(1)
+EOF
+}
+
+# Install the ncclient package
+function install_ncclient() {
+    git_clone $NCCLIENT_REPO $NCCLIENT_DIR $NCCLIENT_BRANCH
+    (cd $NCCLIENT_DIR; sudo python setup.py install)
+}
+
+# Check if the required version of ncclient has been installed
+function is_ncclient_installed() {
+    # Check if the Cisco ncclient repository exists
+    if [[ -d $NCCLIENT_DIR ]]; then
+        remotes=$(cd $NCCLIENT_DIR; git remote -v | grep fetch | awk '{ print $2}')
+        for remote in $remotes; do
+            if [[ $remote == $NCCLIENT_REPO ]]; then
+                break;
+            fi
+        done
+        if [[ $remote != $NCCLIENT_REPO ]]; then
+            return 1
+        fi
+    else
+        return 1
+    fi
+
+    # Check if the ncclient is installed with the right version
+    if ! check_ncclient_version; then
+        return 1
+    fi
+    return 0
+}
+
+function has_neutron_plugin_security_group() {
+    if _has_ovs_subplugin; then
+        ovs_has_neutron_plugin_security_group
+    else
+        return 1
+    fi
+}
+
+function is_neutron_ovs_base_plugin() {
+    # Cisco uses OVS if openvswitch subplugin is deployed
+    _has_ovs_subplugin
+    return
+}
+
+# populate required nova configuration parameters
+function neutron_plugin_create_nova_conf() {
+    if _has_ovs_subplugin; then
+        ovs_neutron_plugin_create_nova_conf
+    else
+        _neutron_ovs_base_configure_nova_vif_driver
+    fi
+}
+
+function neutron_plugin_install_agent_packages() {
+    # Cisco plugin uses openvswitch to operate in one of its configurations
+    ovs_neutron_plugin_install_agent_packages
+}
+
+# Configure common parameters
+function neutron_plugin_configure_common() {
+    # setup default subplugins
+    if [ ! -v Q_CISCO_PLUGIN_SUBPLUGINS ]; then
+        declare -ga Q_CISCO_PLUGIN_SUBPLUGINS
+        Q_CISCO_PLUGIN_SUBPLUGINS=(openvswitch nexus)
+    fi
+    if _has_ovs_subplugin; then
+        ovs_neutron_plugin_configure_common
+        Q_PLUGIN_EXTRA_CONF_PATH=etc/neutron/plugins/cisco
+        Q_PLUGIN_EXTRA_CONF_FILES=(cisco_plugins.ini)
+    else
+        Q_PLUGIN_CONF_PATH=etc/neutron/plugins/cisco
+        Q_PLUGIN_CONF_FILENAME=cisco_plugins.ini
+    fi
+    Q_PLUGIN_CLASS="neutron.plugins.cisco.network_plugin.PluginV2"
+    Q_DB_NAME=cisco_neutron
+}
+
+function neutron_plugin_configure_debug_command() {
+    if _has_ovs_subplugin; then
+        ovs_neutron_plugin_configure_debug_command
+    fi
+}
+
+function neutron_plugin_configure_dhcp_agent() {
+    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
+}
+
+function neutron_plugin_configure_l3_agent() {
+    if _has_ovs_subplugin; then
+        ovs_neutron_plugin_configure_l3_agent
+    fi
+}
+
+function _configure_nexus_subplugin() {
+    local cisco_cfg_file=$1
+
+    # Install a known compatible ncclient from the Cisco repository if necessary
+    if ! is_ncclient_installed; then
+        # Preserve the two global variables
+        local offline=$OFFLINE
+        local reclone=$RECLONE
+        # Change their values to allow installation
+        OFFLINE=False
+        RECLONE=yes
+        install_ncclient
+        # Restore their values
+        OFFLINE=$offline
+        RECLONE=$reclone
+    fi
+
+    # Setup default nexus switch information
+    if [ ! -v Q_CISCO_PLUGIN_SWITCH_INFO ]; then
+        declare -A Q_CISCO_PLUGIN_SWITCH_INFO
+        HOST_NAME=$(hostname)
+        Q_CISCO_PLUGIN_SWITCH_INFO=([1.1.1.1]=stack:stack:22:${HOST_NAME}:1/10)
+    else
+        iniset $cisco_cfg_file CISCO nexus_driver neutron.plugins.cisco.nexus.cisco_nexus_network_driver_v2.CiscoNEXUSDriver
+    fi
+
+    # Setup the switch configurations
+    local nswitch
+    local sw_info
+    local segment
+    local sw_info_array
+    declare -i count=0
+    for nswitch in ${!Q_CISCO_PLUGIN_SWITCH_INFO[@]}; do
+        sw_info=${Q_CISCO_PLUGIN_SWITCH_INFO[$nswitch]}
+        sw_info_array=${sw_info//:/ }
+        sw_info_array=( $sw_info_array )
+        count=${#sw_info_array[@]}
+        if [[ $count < 5 || $(( ($count-3) % 2 )) != 0 ]]; then
+            die $LINENO "Incorrect switch configuration: ${Q_CISCO_PLUGIN_SWITCH_INFO[$nswitch]}"
+        fi
+        _config_switch $cisco_cfg_file $nswitch ${sw_info_array[@]}
+    done
+}
+
+# Configure n1kv plugin
+function _configure_n1kv_subplugin() {
+    local cisco_cfg_file=$1
+
+    # populate the cisco plugin cfg file with the VSM information
+    echo "Configuring n1kv in $cisco_cfg_file-- $Q_CISCO_PLUGIN_VSM_IP $Q_CISCO_PLUGIN_VSM_USERNAME $Q_CISCO_PLUGIN_VSM_PASSWORD"
+    iniset $cisco_cfg_file N1KV:$Q_CISCO_PLUGIN_VSM_IP username $Q_CISCO_PLUGIN_VSM_USERNAME
+    iniset $cisco_cfg_file N1KV:$Q_CISCO_PLUGIN_VSM_IP password $Q_CISCO_PLUGIN_VSM_PASSWORD
+
+    iniset $cisco_cfg_file CISCO_N1K integration_bridge $Q_CISCO_PLUGIN_INTEGRATION_BRIDGE
+    iniset $cisco_cfg_file CISCO_N1K enable_tunneling $Q_CISCO_PLUGIN_ENABLE_TUNNELING
+    iniset $cisco_cfg_file CISCO_N1K vxlan_id_ranges $Q_CISCO_PLUGIN_VXLAN_ID_RANGES
+    iniset $cisco_cfg_file CISCO_N1K network_vlan_ranges $Q_CISCO_PLUGIN_VLAN_RANGES
+
+    # Setup the integration bridge by calling the ovs_base
+    OVS_BRIDGE=$Q_CISCO_PLUGIN_INTEGRATION_BRIDGE
+    _neutron_ovs_base_setup_bridge $OVS_BRIDGE
+}
+
+function neutron_plugin_configure_plugin_agent() {
+    if _has_ovs_subplugin; then
+        ovs_neutron_plugin_configure_plugin_agent
+    fi
+}
+
+function neutron_plugin_configure_service() {
+    local subplugin
+    local cisco_cfg_file
+
+    if _has_ovs_subplugin; then
+        ovs_neutron_plugin_configure_service
+        cisco_cfg_file=/${Q_PLUGIN_EXTRA_CONF_FILES[0]}
+    else
+        cisco_cfg_file=/$Q_PLUGIN_CONF_FILE
+    fi
+
+    # Setup the [CISCO_PLUGINS] section
+    if [[ ${#Q_CISCO_PLUGIN_SUBPLUGINS[@]} > 2 ]]; then
+        die $LINENO "At most two subplugins are supported."
+    fi
+
+    if _has_ovs_subplugin && _has_n1kv_subplugin; then
+        die $LINENO "OVS subplugin and n1kv subplugin cannot coexist"
+    fi
+
+    # Setup the subplugins
+    inicomment $cisco_cfg_file CISCO_PLUGINS nexus_plugin
+    inicomment $cisco_cfg_file CISCO_PLUGINS vswitch_plugin
+    inicomment $cisco_cfg_file CISCO_TEST host
+    for subplugin in ${Q_CISCO_PLUGIN_SUBPLUGINS[@]}; do
+        case $subplugin in
+            nexus) iniset $cisco_cfg_file CISCO_PLUGINS nexus_plugin neutron.plugins.cisco.nexus.cisco_nexus_plugin_v2.NexusPlugin;;
+            openvswitch) iniset $cisco_cfg_file CISCO_PLUGINS vswitch_plugin neutron.plugins.openvswitch.ovs_neutron_plugin.OVSNeutronPluginV2;;
+            n1kv) iniset $cisco_cfg_file CISCO_PLUGINS vswitch_plugin neutron.plugins.cisco.n1kv.n1kv_neutron_plugin.N1kvNeutronPluginV2;;
+            *) die $LINENO "Unsupported cisco subplugin: $subplugin";;
+        esac
+    done
+
+    if _has_nexus_subplugin; then
+        _configure_nexus_subplugin $cisco_cfg_file
+    fi
+
+    if _has_n1kv_subplugin; then
+        _configure_n1kv_subplugin $cisco_cfg_file
+    fi
+}
+
+function neutron_plugin_setup_interface_driver() {
+    local conf_file=$1
+    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/neutron_plugins/linuxbridge b/lib/neutron_plugins/linuxbridge
new file mode 100644
index 0000000..9aad8f3
--- /dev/null
+++ b/lib/neutron_plugins/linuxbridge
@@ -0,0 +1,54 @@
+# Neutron Linux Bridge plugin
+# ---------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+function neutron_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/linuxbridge
+    Q_PLUGIN_CONF_FILENAME=linuxbridge_conf.ini
+    Q_DB_NAME="neutron_linux_bridge"
+    Q_PLUGIN_CLASS="neutron.plugins.linuxbridge.lb_neutron_plugin.LinuxBridgePluginV2"
+}
+
+function neutron_plugin_configure_service() {
+    if [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE vlans tenant_network_type vlan
+    else
+        echo "WARNING - The linuxbridge plugin is using local tenant networks, with no connectivity between hosts."
+    fi
+
+    # Override ``LB_VLAN_RANGES`` and ``LB_INTERFACE_MAPPINGS`` in ``localrc``
+    # for more complex physical network configurations.
+    if [[ "$LB_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
+        LB_VLAN_RANGES=$PHYSICAL_NETWORK
+        if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
+            LB_VLAN_RANGES=$LB_VLAN_RANGES:$TENANT_VLAN_RANGE
+        fi
+    fi
+    if [[ "$LB_VLAN_RANGES" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE vlans network_vlan_ranges $LB_VLAN_RANGES
+    fi
+    if [[ "$Q_USE_SECGROUP" == "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
+    else
+        iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.firewall.NoopFirewallDriver
+    fi
+
+    # Define extra "LINUX_BRIDGE" configuration options when q-svc is configured by defining
+    # the array ``Q_SRV_EXTRA_OPTS``.
+    # For Example: ``Q_SRV_EXTRA_OPTS=(foo=true bar=2)``
+    for I in "${Q_SRV_EXTRA_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE linux_bridge ${I/=/ }
+    done
+}
+
+function has_neutron_plugin_security_group() {
+    # 0 means True here
+    return 0
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent
new file mode 100644
index 0000000..88c49c5
--- /dev/null
+++ b/lib/neutron_plugins/linuxbridge_agent
@@ -0,0 +1,76 @@
+# Neutron Linux Bridge L2 agent
+# -----------------------------
+
+# Save trace setting
+PLUGIN_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+function is_neutron_ovs_base_plugin() {
+    # linuxbridge doesn't use OVS
+    return 1
+}
+
+function neutron_plugin_create_nova_conf() {
+    NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtGenericVIFDriver"}
+}
+
+function neutron_plugin_install_agent_packages() {
+    install_package bridge-utils
+}
+
+function neutron_plugin_configure_debug_command() {
+    iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT external_network_bridge
+}
+
+function neutron_plugin_configure_dhcp_agent() {
+    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
+}
+
+function neutron_plugin_configure_l3_agent() {
+    iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge
+    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
+}
+
+function neutron_plugin_configure_plugin_agent() {
+    # Setup physical network interface mappings.  Override
+    # ``LB_VLAN_RANGES`` and ``LB_INTERFACE_MAPPINGS`` in ``localrc`` for more
+    # complex physical network configurations.
+    if [[ "$LB_INTERFACE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$LB_PHYSICAL_INTERFACE" != "" ]]; then
+        LB_INTERFACE_MAPPINGS=$PHYSICAL_NETWORK:$LB_PHYSICAL_INTERFACE
+    fi
+    if [[ "$LB_INTERFACE_MAPPINGS" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE linux_bridge physical_interface_mappings $LB_INTERFACE_MAPPINGS
+    fi
+    if [[ "$Q_USE_SECGROUP" == "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.linux.iptables_firewall.IptablesFirewallDriver
+    else
+        iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.firewall.NoopFirewallDriver
+    fi
+    AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-linuxbridge-agent"
+    # Define extra "AGENT" configuration options when q-agt is configured by defining
+    # the array ``Q_AGENT_EXTRA_AGENT_OPTS``.
+    # For Example: ``Q_AGENT_EXTRA_AGENT_OPTS=(foo=true bar=2)``
+    for I in "${Q_AGENT_EXTRA_AGENT_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE agent ${I/=/ }
+    done
+    # Define extra "LINUX_BRIDGE" configuration options when q-agt is configured by defining
+    # the array ``Q_AGENT_EXTRA_SRV_OPTS``.
+    # For Example: ``Q_AGENT_EXTRA_SRV_OPTS=(foo=true bar=2)``
+    for I in "${Q_AGENT_EXTRA_SRV_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE linux_bridge ${I/=/ }
+    done
+}
+
+function neutron_plugin_setup_interface_driver() {
+    local conf_file=$1
+    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.BridgeInterfaceDriver
+}
+
+function neutron_plugin_check_adv_test_requirements() {
+    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
+}
+
+# Restore xtrace
+$PLUGIN_XTRACE
diff --git a/lib/neutron_plugins/ml2 b/lib/neutron_plugins/ml2
new file mode 100644
index 0000000..fcff870
--- /dev/null
+++ b/lib/neutron_plugins/ml2
@@ -0,0 +1,62 @@
+# Neutron Modular Layer 2 plugin
+# ------------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+# Default openvswitch L2 agent
+Q_AGENT=${Q_AGENT:-openvswitch}
+source $TOP_DIR/lib/neutron_plugins/${Q_AGENT}_agent
+
+function neutron_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/ml2
+    Q_PLUGIN_CONF_FILENAME=ml2_conf.ini
+    Q_DB_NAME="neutron_ml2"
+    Q_PLUGIN_CLASS="neutron.plugins.ml2.plugin.Ml2Plugin"
+}
+
+function neutron_plugin_configure_service() {
+    if [[ "$ENABLE_TENANT_TUNNELS" = "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ml2 tenant_network_types gre
+        iniset /$Q_PLUGIN_CONF_FILE ml2_type_gre tunnel_id_ranges $TENANT_TUNNEL_RANGES
+    elif [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ml2 tenant_network_types vlan
+    else
+        echo "WARNING - The ml2 plugin is using local tenant networks, with no connectivity between hosts."
+    fi
+
+    # Override ``ML2_VLAN_RANGES`` and any needed agent configuration
+    # variables in ``localrc`` for more complex physical network
+    # configurations.
+    if [[ "$ML2_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
+        ML2_VLAN_RANGES=$PHYSICAL_NETWORK
+        if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
+            ML2_VLAN_RANGES=$ML2_VLAN_RANGES:$TENANT_VLAN_RANGE
+        fi
+    fi
+    if [[ "$ML2_VLAN_RANGES" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ml2_type_vlan network_vlan_ranges $ML2_VLAN_RANGES
+    fi
+
+    # REVISIT(rkukura): Setting firewall_driver here for
+    # neutron.agent.securitygroups_rpc.is_firewall_enabled() which is
+    # used in the server, in case no L2 agent is configured on the
+    # server's node. If an L2 agent is configured, this will get
+    # overridden with the correct driver. The ml2 plugin should
+    # instead use its own config variable to indicate whether security
+    # groups is enabled, and that will need to be set here instead.
+    if [[ "$Q_USE_SECGROUP" == "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE SECURITYGROUP firewall_driver neutron.agent.not.a.real.FirewallDriver
+    else
+        iniset /$Q_PLUGIN_CONF_FILE SECURITYGROUP firewall_driver neutron.agent.firewall.NoopFirewallDriver
+    fi
+
+}
+
+function has_neutron_plugin_security_group() {
+    return 0
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/neutron_plugins/nec b/lib/neutron_plugins/nec
new file mode 100644
index 0000000..79d41db
--- /dev/null
+++ b/lib/neutron_plugins/nec
@@ -0,0 +1,126 @@
+# Neutron NEC OpenFlow plugin
+# ---------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+# Configuration parameters
+OFC_HOST=${OFC_HOST:-127.0.0.1}
+OFC_PORT=${OFC_PORT:-8888}
+
+OFC_API_HOST=${OFC_API_HOST:-$OFC_HOST}
+OFC_API_PORT=${OFC_API_PORT:-$OFC_PORT}
+OFC_OFP_HOST=${OFC_OFP_HOST:-$OFC_HOST}
+OFC_OFP_PORT=${OFC_OFP_PORT:-6633}
+OFC_DRIVER=${OFC_DRIVER:-trema}
+OFC_RETRY_MAX=${OFC_RETRY_MAX:-0}
+OFC_RETRY_INTERVAL=${OFC_RETRY_INTERVAL:-1}
+
+# Main logic
+# ---------------------------
+
+source $TOP_DIR/lib/neutron_plugins/ovs_base
+
+function neutron_plugin_create_nova_conf() {
+    _neutron_ovs_base_configure_nova_vif_driver
+}
+
+function neutron_plugin_install_agent_packages() {
+    # SKIP_OVS_INSTALL is useful when we want to use Open vSwitch whose
+    # version is different from the version provided by the distribution.
+    if [[ "$SKIP_OVS_INSTALL" = "True" ]]; then
+        echo "You need to install Open vSwitch manually."
+        return
+    fi
+    _neutron_ovs_base_install_agent_packages
+}
+
+function neutron_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/nec
+    Q_PLUGIN_CONF_FILENAME=nec.ini
+    Q_DB_NAME="neutron_nec"
+    Q_PLUGIN_CLASS="neutron.plugins.nec.nec_plugin.NECPluginV2"
+}
+
+function neutron_plugin_configure_debug_command() {
+    _neutron_ovs_base_configure_debug_command
+}
+
+function neutron_plugin_configure_dhcp_agent() {
+    :
+}
+
+function neutron_plugin_configure_l3_agent() {
+    _neutron_ovs_base_configure_l3_agent
+}
+
+function neutron_plugin_configure_plugin_agent() {
+    if [[ "$SKIP_OVS_BRIDGE_SETUP" = "True" ]]; then
+        return
+    fi
+    # Set up integration bridge
+    _neutron_ovs_base_setup_bridge $OVS_BRIDGE
+    sudo ovs-vsctl --no-wait set-controller $OVS_BRIDGE tcp:$OFC_OFP_HOST:$OFC_OFP_PORT
+    # Generate datapath ID from HOST_IP
+    local dpid=$(printf "0x%07d%03d%03d%03d\n" ${HOST_IP//./ })
+    sudo ovs-vsctl --no-wait set Bridge $OVS_BRIDGE other-config:datapath-id=$dpid
+    sudo ovs-vsctl --no-wait set-fail-mode $OVS_BRIDGE secure
+    if [ -n "$OVS_INTERFACE" ]; then
+        sudo ovs-vsctl --no-wait -- --may-exist add-port $OVS_BRIDGE $OVS_INTERFACE
+    fi
+    _neutron_setup_ovs_tunnels $OVS_BRIDGE
+    AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-nec-agent"
+
+    _neutron_ovs_base_configure_firewall_driver
+}
+
+function neutron_plugin_configure_service() {
+    iniset $NEUTRON_CONF DEFAULT api_extensions_path neutron/plugins/nec/extensions/
+    iniset /$Q_PLUGIN_CONF_FILE ofc host $OFC_API_HOST
+    iniset /$Q_PLUGIN_CONF_FILE ofc port $OFC_API_PORT
+    iniset /$Q_PLUGIN_CONF_FILE ofc driver $OFC_DRIVER
+    iniset /$Q_PLUGIN_CONF_FILE ofc api_retry_max OFC_RETRY_MAX
+    iniset /$Q_PLUGIN_CONF_FILE ofc api_retry_interval OFC_RETRY_INTERVAL
+
+    _neutron_ovs_base_configure_firewall_driver
+}
+
+function neutron_plugin_setup_interface_driver() {
+    local conf_file=$1
+    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
+    iniset $conf_file DEFAULT ovs_use_veth True
+}
+
+# Utility functions
+# ---------------------------
+
+# Setup OVS tunnel manually
+function _neutron_setup_ovs_tunnels() {
+    local bridge=$1
+    local id=0
+    GRE_LOCAL_IP=${GRE_LOCAL_IP:-$HOST_IP}
+    if [ -n "$GRE_REMOTE_IPS" ]; then
+         for ip in ${GRE_REMOTE_IPS//:/ }
+         do
+             if [[ "$ip" == "$GRE_LOCAL_IP" ]]; then
+                 continue
+             fi
+             sudo ovs-vsctl --no-wait add-port $bridge gre$id -- \
+                 set Interface gre$id type=gre options:remote_ip=$ip
+             id=`expr $id + 1`
+         done
+    fi
+}
+
+function has_neutron_plugin_security_group() {
+    # 0 means True here
+    return 0
+}
+
+function neutron_plugin_check_adv_test_requirements() {
+    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/neutron_plugins/nicira b/lib/neutron_plugins/nicira
new file mode 100644
index 0000000..7642be6
--- /dev/null
+++ b/lib/neutron_plugins/nicira
@@ -0,0 +1,138 @@
+# Neutron Nicira NVP plugin
+# ---------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+source $TOP_DIR/lib/neutron_plugins/ovs_base
+
+function setup_integration_bridge() {
+    _neutron_ovs_base_setup_bridge $OVS_BRIDGE
+    # Set manager to NVP controller (1st of list)
+    if [[ "$NVP_CONTROLLERS" != "" ]]; then
+        # Get the first controller
+        controllers=(${NVP_CONTROLLERS//,/ })
+        OVS_MGR_IP=${controllers[0]}
+    else
+        die $LINENO "Error - No controller specified. Unable to set a manager for OVS"
+    fi
+    sudo ovs-vsctl set-manager ssl:$OVS_MGR_IP
+}
+
+function is_neutron_ovs_base_plugin() {
+    # NVP uses OVS, but not the l3-agent
+    return 0
+}
+
+function neutron_plugin_create_nova_conf() {
+    NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtOpenVswitchDriver"}
+    # if n-cpu is enabled, then setup integration bridge
+    if is_service_enabled n-cpu; then
+        setup_integration_bridge
+    fi
+}
+
+function neutron_plugin_install_agent_packages() {
+    # Nicira Plugin does not run q-agt, but it currently needs dhcp and metadata agents
+    _neutron_ovs_base_install_agent_packages
+}
+
+function neutron_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/nicira
+    Q_PLUGIN_CONF_FILENAME=nvp.ini
+    Q_DB_NAME="neutron_nvp"
+    Q_PLUGIN_CLASS="neutron.plugins.nicira.nicira_nvp_plugin.NeutronPlugin.NvpPluginV2"
+}
+
+function neutron_plugin_configure_debug_command() {
+    sudo ovs-vsctl --no-wait -- --may-exist add-br $PUBLIC_BRIDGE
+}
+
+function neutron_plugin_configure_dhcp_agent() {
+    setup_integration_bridge
+    iniset $Q_DHCP_CONF_FILE DEFAULT enable_isolated_metadata True
+    iniset $Q_DHCP_CONF_FILE DEFAULT enable_metadata_network True
+    iniset $Q_DHCP_CONF_FILE DEFAULT ovs_use_veth True
+}
+
+function neutron_plugin_configure_l3_agent() {
+   # Nicira plugin does not run L3 agent
+   die $LINENO "q-l3 should must not be executed with Nicira plugin!"
+}
+
+function neutron_plugin_configure_plugin_agent() {
+   # Nicira plugin does not run L2 agent
+   die $LINENO "q-agt must not be executed with Nicira plugin!"
+}
+
+function neutron_plugin_configure_service() {
+    if [[ "$MAX_LP_PER_BRIDGED_LS" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE nvp max_lp_per_bridged_ls $MAX_LP_PER_BRIDGED_LS
+    fi
+    if [[ "$MAX_LP_PER_OVERLAY_LS" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE nvp max_lp_per_overlay_ls $MAX_LP_PER_OVERLAY_LS
+    fi
+    if [[ "$FAILOVER_TIME" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE nvp failover_time $FAILOVER_TIME
+    fi
+    if [[ "$CONCURRENT_CONNECTIONS" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE nvp concurrent_connections $CONCURRENT_CONNECTIONS
+    fi
+
+    if [[ "$DEFAULT_TZ_UUID" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE DEFAULT default_tz_uuid $DEFAULT_TZ_UUID
+    else
+        die $LINENO "The nicira plugin won't work without a default transport zone."
+    fi
+    if [[ "$DEFAULT_L3_GW_SVC_UUID" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE DEFAULT default_l3_gw_service_uuid $DEFAULT_L3_GW_SVC_UUID
+        Q_L3_ENABLED=True
+        Q_L3_ROUTER_PER_TENANT=True
+        iniset /$Q_PLUGIN_CONF_FILE nvp enable_metadata_access_network True
+    fi
+    if [[ "$DEFAULT_L2_GW_SVC_UUID" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE DEFAULT default_l2_gw_service_uuid $DEFAULT_L2_GW_SVC_UUID
+    fi
+    # NVP_CONTROLLERS must be a comma separated string
+    if [[ "$NVP_CONTROLLERS" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE DEFAULT nvp_controllers $NVP_CONTROLLERS
+    else
+        die $LINENO "The nicira plugin needs at least an NVP controller."
+    fi
+    if [[ "$NVP_USER" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE DEFAULT nvp_user $NVP_USER
+    fi
+    if [[ "$NVP_PASSWORD" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE DEFAULT nvp_password $NVP_PASSWORD
+    fi
+    if [[ "$NVP_REQ_TIMEOUT" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE DEFAULT req_timeout $NVP_REQ_TIMEOUT
+    fi
+    if [[ "$NVP_HTTP_TIMEOUT" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE DEFAULT http_timeout $NVP_HTTP_TIMEOUT
+    fi
+    if [[ "$NVP_RETRIES" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE DEFAULT retries $NVP_RETRIES
+    fi
+    if [[ "$NVP_REDIRECTS" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE DEFAULT redirects $NVP_REDIRECTS
+    fi
+}
+
+function neutron_plugin_setup_interface_driver() {
+    local conf_file=$1
+    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
+}
+
+function has_neutron_plugin_security_group() {
+    # 0 means True here
+    return 0
+}
+
+function neutron_plugin_check_adv_test_requirements() {
+    is_service_enabled q-dhcp && return 0
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/neutron_plugins/openvswitch b/lib/neutron_plugins/openvswitch
new file mode 100644
index 0000000..f99eb38
--- /dev/null
+++ b/lib/neutron_plugins/openvswitch
@@ -0,0 +1,60 @@
+# Neutron Open vSwitch plugin
+# ---------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+source $TOP_DIR/lib/neutron_plugins/openvswitch_agent
+
+function neutron_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/openvswitch
+    Q_PLUGIN_CONF_FILENAME=ovs_neutron_plugin.ini
+    Q_DB_NAME="ovs_neutron"
+    Q_PLUGIN_CLASS="neutron.plugins.openvswitch.ovs_neutron_plugin.OVSNeutronPluginV2"
+}
+
+function neutron_plugin_configure_service() {
+    if [[ "$ENABLE_TENANT_TUNNELS" = "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ovs tenant_network_type gre
+        iniset /$Q_PLUGIN_CONF_FILE ovs tunnel_id_ranges $TENANT_TUNNEL_RANGES
+    elif [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ovs tenant_network_type vlan
+    else
+        echo "WARNING - The openvswitch plugin is using local tenant networks, with no connectivity between hosts."
+    fi
+
+    # Override ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc``
+    # for more complex physical network configurations.
+    if [[ "$OVS_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
+        OVS_VLAN_RANGES=$PHYSICAL_NETWORK
+        if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
+            OVS_VLAN_RANGES=$OVS_VLAN_RANGES:$TENANT_VLAN_RANGE
+        fi
+    fi
+    if [[ "$OVS_VLAN_RANGES" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ovs network_vlan_ranges $OVS_VLAN_RANGES
+    fi
+
+    # Enable tunnel networks if selected
+    if [[ $OVS_ENABLE_TUNNELING = "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ovs enable_tunneling True
+    fi
+
+    _neutron_ovs_base_configure_firewall_driver
+
+    # Define extra "OVS" configuration options when q-svc is configured by defining
+    # the array ``Q_SRV_EXTRA_OPTS``.
+    # For Example: ``Q_SRV_EXTRA_OPTS=(foo=true bar=2)``
+    for I in "${Q_SRV_EXTRA_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE ovs ${I/=/ }
+    done
+}
+
+function has_neutron_plugin_security_group() {
+    return 0
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/neutron_plugins/openvswitch_agent b/lib/neutron_plugins/openvswitch_agent
new file mode 100644
index 0000000..46c2a5c
--- /dev/null
+++ b/lib/neutron_plugins/openvswitch_agent
@@ -0,0 +1,131 @@
+# Neutron Open vSwitch L2 agent
+# -----------------------------
+
+# Save trace setting
+PLUGIN_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+source $TOP_DIR/lib/neutron_plugins/ovs_base
+
+function neutron_plugin_create_nova_conf() {
+    _neutron_ovs_base_configure_nova_vif_driver
+    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
+        iniset $NOVA_CONF DEFAULT xenapi_vif_driver nova.virt.xenapi.vif.XenAPIOpenVswitchDriver
+        iniset $NOVA_CONF DEFAULT xenapi_ovs_integration_bridge $XEN_INTEGRATION_BRIDGE
+        # Disable nova's firewall so that it does not conflict with neutron
+        iniset $NOVA_CONF DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver
+    fi
+}
+
+function neutron_plugin_install_agent_packages() {
+    _neutron_ovs_base_install_agent_packages
+}
+
+function neutron_plugin_configure_debug_command() {
+    _neutron_ovs_base_configure_debug_command
+}
+
+function neutron_plugin_configure_dhcp_agent() {
+    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
+}
+
+function neutron_plugin_configure_l3_agent() {
+    _neutron_ovs_base_configure_l3_agent
+    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
+}
+
+function neutron_plugin_configure_plugin_agent() {
+    # Setup integration bridge
+    _neutron_ovs_base_setup_bridge $OVS_BRIDGE
+    _neutron_ovs_base_configure_firewall_driver
+
+    # Setup agent for tunneling
+    if [[ "$OVS_ENABLE_TUNNELING" = "True" ]]; then
+        # Verify tunnels are supported
+        # REVISIT - also check kernel module support for GRE and patch ports
+        OVS_VERSION=`ovs-vsctl --version | head -n 1 | grep -E -o "[0-9]+\.[0-9]+"`
+        if [ `vercmp_numbers "$OVS_VERSION" "1.4"` -lt "0" ] && ! is_service_enabled q-svc ; then
+            die $LINENO "You are running OVS version $OVS_VERSION. OVS 1.4+ is required for tunneling between multiple hosts."
+        fi
+        iniset /$Q_PLUGIN_CONF_FILE ovs enable_tunneling True
+        iniset /$Q_PLUGIN_CONF_FILE ovs local_ip $HOST_IP
+    fi
+
+    # Setup physical network bridge mappings.  Override
+    # ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc`` for more
+    # complex physical network configurations.
+    if [[ "$OVS_BRIDGE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$OVS_PHYSICAL_BRIDGE" != "" ]]; then
+        OVS_BRIDGE_MAPPINGS=$PHYSICAL_NETWORK:$OVS_PHYSICAL_BRIDGE
+
+        # Configure bridge manually with physical interface as port for multi-node
+        sudo ovs-vsctl --no-wait -- --may-exist add-br $OVS_PHYSICAL_BRIDGE
+    fi
+    if [[ "$OVS_BRIDGE_MAPPINGS" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE ovs bridge_mappings $OVS_BRIDGE_MAPPINGS
+    fi
+    AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-openvswitch-agent"
+
+    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
+        # Make a copy of our config for domU
+        sudo cp /$Q_PLUGIN_CONF_FILE "/$Q_PLUGIN_CONF_FILE.domu"
+
+        # Deal with Dom0's L2 Agent:
+        Q_RR_DOM0_COMMAND="$NEUTRON_BIN_DIR/neutron-rootwrap-xen-dom0 $Q_RR_CONF_FILE"
+
+        # For now, duplicate the xen configuration already found in nova.conf
+        iniset $Q_RR_CONF_FILE xenapi xenapi_connection_url "$XENAPI_CONNECTION_URL"
+        iniset $Q_RR_CONF_FILE xenapi xenapi_connection_username "$XENAPI_USER"
+        iniset $Q_RR_CONF_FILE xenapi xenapi_connection_password "$XENAPI_PASSWORD"
+
+        # Under XS/XCP, the ovs agent needs to target the dom0
+        # integration bridge.  This is enabled by using a root wrapper
+        # that executes commands on dom0 via a XenAPI plugin.
+        iniset /$Q_PLUGIN_CONF_FILE agent root_helper "$Q_RR_DOM0_COMMAND"
+
+        # Set "physical" mapping
+        iniset /$Q_PLUGIN_CONF_FILE ovs bridge_mappings "physnet1:$FLAT_NETWORK_BRIDGE"
+
+        # XEN_INTEGRATION_BRIDGE is the integration bridge in dom0
+        iniset /$Q_PLUGIN_CONF_FILE ovs integration_bridge $XEN_INTEGRATION_BRIDGE
+
+        # Set up domU's L2 agent:
+
+        # Create a bridge "br-$GUEST_INTERFACE_DEFAULT"
+        sudo ovs-vsctl --no-wait -- --may-exist add-br "br-$GUEST_INTERFACE_DEFAULT"
+        # Add $GUEST_INTERFACE_DEFAULT to that bridge
+        sudo ovs-vsctl add-port "br-$GUEST_INTERFACE_DEFAULT" $GUEST_INTERFACE_DEFAULT
+
+        # Set bridge mappings to "physnet1:br-$GUEST_INTERFACE_DEFAULT"
+        iniset "/$Q_PLUGIN_CONF_FILE.domU" ovs bridge_mappings "physnet1:br-$GUEST_INTERFACE_DEFAULT"
+        # Set integration bridge to domU's
+        iniset "/$Q_PLUGIN_CONF_FILE.domU" ovs integration_bridge $OVS_BRIDGE
+        # Set root wrap
+        iniset "/$Q_PLUGIN_CONF_FILE.domU" agent root_helper "$Q_RR_COMMAND"
+    fi
+    # Define extra "AGENT" configuration options when q-agt is configured by defining
+    # defining the array ``Q_AGENT_EXTRA_AGENT_OPTS``.
+    # For Example: ``Q_AGENT_EXTRA_AGENT_OPTS=(foo=true bar=2)``
+    for I in "${Q_AGENT_EXTRA_AGENT_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE agent ${I/=/ }
+    done
+    # Define extra "OVS" configuration options when q-agt is configured by defining
+    # defining the array ``Q_AGENT_EXTRA_SRV_OPTS``.
+    # For Example: ``Q_AGENT_EXTRA_SRV_OPTS=(foo=true bar=2)``
+    for I in "${Q_AGENT_EXTRA_SRV_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE ovs ${I/=/ }
+    done
+}
+
+function neutron_plugin_setup_interface_driver() {
+    local conf_file=$1
+    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
+}
+
+function neutron_plugin_check_adv_test_requirements() {
+    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
+}
+
+# Restore xtrace
+$PLUGIN_XTRACE
diff --git a/lib/neutron_plugins/ovs_base b/lib/neutron_plugins/ovs_base
new file mode 100644
index 0000000..0a2765b
--- /dev/null
+++ b/lib/neutron_plugins/ovs_base
@@ -0,0 +1,85 @@
+# common functions for ovs based plugin
+# -------------------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+OVS_BRIDGE=${OVS_BRIDGE:-br-int}
+PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
+
+function is_neutron_ovs_base_plugin() {
+    # Yes, we use OVS.
+    return 0
+}
+
+function _neutron_ovs_base_setup_bridge() {
+    local bridge=$1
+    neutron-ovs-cleanup
+    sudo ovs-vsctl --no-wait -- --may-exist add-br $bridge
+    sudo ovs-vsctl --no-wait br-set-external-id $bridge bridge-id $bridge
+}
+
+function neutron_ovs_base_cleanup() {
+    # remove all OVS ports that look like Neutron created ports
+    for port in $(sudo ovs-vsctl list port | grep -o -e tap[0-9a-f\-]* -e q[rg]-[0-9a-f\-]*); do
+        sudo ovs-vsctl del-port ${port}
+    done
+
+    # remove all OVS bridges created by Neutron
+    for bridge in $(sudo ovs-vsctl list-br | grep -o -e ${OVS_BRIDGE} -e ${PUBLIC_BRIDGE}); do
+        sudo ovs-vsctl del-br ${bridge}
+    done
+}
+
+function _neutron_ovs_base_install_agent_packages() {
+    local kernel_version
+    # Install deps
+    # FIXME add to ``files/apts/neutron``, but don't install if not needed!
+    if is_ubuntu; then
+        kernel_version=`cat /proc/version | cut -d " " -f3`
+        install_package make fakeroot dkms openvswitch-switch openvswitch-datapath-dkms linux-headers-$kernel_version
+    elif is_fedora; then
+        install_package openvswitch
+        # Ensure that the service is started
+        restart_service openvswitch
+    elif is_suse; then
+        ### FIXME: Find out if package can be pushed to Factory
+        echo "OpenVSwitch packages can be installed from Cloud:OpenStack:Master in OBS"
+        restart_service openvswitch
+    fi
+}
+
+function _neutron_ovs_base_configure_debug_command() {
+    iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT external_network_bridge $PUBLIC_BRIDGE
+}
+
+function _neutron_ovs_base_configure_firewall_driver() {
+    if [[ "$Q_USE_SECGROUP" == "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.linux.iptables_firewall.OVSHybridIptablesFirewallDriver
+    else
+        iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.firewall.NoopFirewallDriver
+    fi
+}
+
+function _neutron_ovs_base_configure_l3_agent() {
+    iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge $PUBLIC_BRIDGE
+
+    neutron-ovs-cleanup
+    sudo ovs-vsctl --no-wait -- --may-exist add-br $PUBLIC_BRIDGE
+    # ensure no IP is configured on the public bridge
+    sudo ip addr flush dev $PUBLIC_BRIDGE
+}
+
+function _neutron_ovs_base_configure_nova_vif_driver() {
+    # The hybrid VIF driver needs to be specified when Neutron Security Group
+    # is enabled (until vif_security attributes are supported in VIF extension)
+    if [[ "$Q_USE_SECGROUP" == "True" ]]; then
+        NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtHybridOVSBridgeDriver"}
+    else
+        NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtGenericVIFDriver"}
+    fi
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/neutron_plugins/plumgrid b/lib/neutron_plugins/plumgrid
new file mode 100644
index 0000000..d4cc395
--- /dev/null
+++ b/lib/neutron_plugins/plumgrid
@@ -0,0 +1,42 @@
+# PLUMgrid Neutron Plugin
+# Edgar Magana emagana@plumgrid.com
+# ------------------------------------
+
+# Save trace settings
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+#source $TOP_DIR/lib/neutron_plugins/ovs_base
+
+function neutron_plugin_create_nova_conf() {
+
+    NOVA_VIF_DRIVER=${NOVA_VIF_DRIVER:-"nova.virt.libvirt.vif.LibvirtGenericVIFDriver"}
+}
+
+function neutron_plugin_setup_interface_driver() {
+    :
+}
+
+function neutron_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/plumgrid
+    Q_PLUGIN_CONF_FILENAME=plumgrid.ini
+    Q_DB_NAME="plumgrid_neutron"
+    Q_PLUGIN_CLASS="neutron.plugins.plumgrid.plumgrid_nos_plugin.plumgrid_plugin.NeutronPluginPLUMgridV2"
+}
+
+function neutron_plugin_configure_service() {
+    PLUMGRID_NOS_IP=${PLUMGRID_NOS_IP:-localhost}
+    PLUMGRID_NOS_PORT=${PLUMGRID_NOS_PORT:-7766}
+    iniset /$Q_PLUGIN_CONF_FILE plumgridnos nos_server $PLUMGRID_NOS_IP
+    iniset /$Q_PLUGIN_CONF_FILE plumgridnos nos_server_port $PLUMGRID_NOS_PORT
+}
+
+function neutron_plugin_configure_debug_command() {
+    :
+}
+
+function neutron_plugin_check_adv_test_requirements() {
+    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
+}
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/neutron_plugins/ryu b/lib/neutron_plugins/ryu
new file mode 100644
index 0000000..334c227
--- /dev/null
+++ b/lib/neutron_plugins/ryu
@@ -0,0 +1,80 @@
+# Neutron Ryu plugin
+# ------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+source $TOP_DIR/lib/neutron_plugins/ovs_base
+source $TOP_DIR/lib/neutron_thirdparty/ryu      # for configuration value
+
+function neutron_plugin_create_nova_conf() {
+    _neutron_ovs_base_configure_nova_vif_driver
+    iniset $NOVA_CONF DEFAULT libvirt_ovs_integration_bridge "$OVS_BRIDGE"
+}
+
+function neutron_plugin_install_agent_packages() {
+    _neutron_ovs_base_install_agent_packages
+
+    # neutron_ryu_agent requires ryu module
+    install_package $(get_packages "ryu")
+    install_ryu
+    configure_ryu
+}
+
+function neutron_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/ryu
+    Q_PLUGIN_CONF_FILENAME=ryu.ini
+    Q_DB_NAME="ovs_neutron"
+    Q_PLUGIN_CLASS="neutron.plugins.ryu.ryu_neutron_plugin.RyuNeutronPluginV2"
+}
+
+function neutron_plugin_configure_debug_command() {
+    _neutron_ovs_base_configure_debug_command
+    iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT ryu_api_host $RYU_API_HOST:$RYU_API_PORT
+}
+
+function neutron_plugin_configure_dhcp_agent() {
+    iniset $Q_DHCP_CONF_FILE DEFAULT ryu_api_host $RYU_API_HOST:$RYU_API_PORT
+}
+
+function neutron_plugin_configure_l3_agent() {
+    iniset $Q_L3_CONF_FILE DEFAULT ryu_api_host $RYU_API_HOST:$RYU_API_PORT
+    _neutron_ovs_base_configure_l3_agent
+}
+
+function neutron_plugin_configure_plugin_agent() {
+    # Set up integration bridge
+    _neutron_ovs_base_setup_bridge $OVS_BRIDGE
+    if [ -n "$RYU_INTERNAL_INTERFACE" ]; then
+        sudo ovs-vsctl --no-wait -- --may-exist add-port $OVS_BRIDGE $RYU_INTERNAL_INTERFACE
+    fi
+    iniset /$Q_PLUGIN_CONF_FILE ovs integration_bridge $OVS_BRIDGE
+    AGENT_BINARY="$NEUTRON_DIR/neutron/plugins/ryu/agent/ryu_neutron_agent.py"
+
+    _neutron_ovs_base_configure_firewall_driver
+}
+
+function neutron_plugin_configure_service() {
+    iniset /$Q_PLUGIN_CONF_FILE ovs openflow_rest_api $RYU_API_HOST:$RYU_API_PORT
+
+    _neutron_ovs_base_configure_firewall_driver
+}
+
+function neutron_plugin_setup_interface_driver() {
+    local conf_file=$1
+    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
+    iniset $conf_file DEFAULT ovs_use_veth True
+}
+
+function has_neutron_plugin_security_group() {
+    # 0 means True here
+    return 0
+}
+
+function neutron_plugin_check_adv_test_requirements() {
+    is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
+}
+
+# Restore xtrace
+$MY_XTRACE
diff --git a/lib/neutron_plugins/services/loadbalancer b/lib/neutron_plugins/services/loadbalancer
new file mode 100644
index 0000000..49e286a
--- /dev/null
+++ b/lib/neutron_plugins/services/loadbalancer
@@ -0,0 +1,50 @@
+# Neutron loadbalancer plugin
+# ---------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+AGENT_LBAAS_BINARY="$NEUTRON_BIN_DIR/neutron-lbaas-agent"
+LBAAS_PLUGIN=neutron.services.loadbalancer.plugin.LoadBalancerPlugin
+
+function neutron_agent_lbaas_install_agent_packages() {
+    if is_ubuntu || is_fedora; then
+        install_package haproxy
+    elif is_suse; then
+        ### FIXME: Find out if package can be pushed to Factory
+        echo "HAProxy packages can be installed from server:http project in OBS"
+    fi
+}
+
+function neutron_agent_lbaas_configure_common() {
+    if [[ $Q_SERVICE_PLUGIN_CLASSES == '' ]]; then
+        Q_SERVICE_PLUGIN_CLASSES=$LBAAS_PLUGIN
+    else
+        Q_SERVICE_PLUGIN_CLASSES="$Q_SERVICE_PLUGIN_CLASSES,$LBAAS_PLUGIN"
+    fi
+}
+
+function neutron_agent_lbaas_configure_agent() {
+    LBAAS_AGENT_CONF_PATH=/etc/neutron/services/loadbalancer/haproxy
+    mkdir -p $LBAAS_AGENT_CONF_PATH
+
+    LBAAS_AGENT_CONF_FILENAME="$LBAAS_AGENT_CONF_PATH/lbaas_agent.ini"
+
+    cp $NEUTRON_DIR/etc/lbaas_agent.ini $LBAAS_AGENT_CONF_FILENAME
+
+    iniset $LBAAS_AGENT_CONF_FILENAME DEFAULT use_namespaces $Q_USE_NAMESPACE
+    # ovs_use_veth needs to be set before the plugin configuration
+    # occurs to allow plugins to override the setting.
+    iniset $LBAAS_AGENT_CONF_FILENAME DEFAULT ovs_use_veth $Q_OVS_USE_VETH
+
+    neutron_plugin_setup_interface_driver $LBAAS_AGENT_CONF_FILENAME
+
+    if is_fedora; then
+        iniset $LBAAS_AGENT_CONF_FILENAME DEFAULT user_group "nobody"
+    fi
+}
+
+# Restore xtrace
+$MY_XTRACE