Fixes for linux bridge and Q_USE_PROVIDER_NET

===Set bridge_mappings for linux bridge===
The external network physnet needs a bridge_mapping to the public
bridge when the L2 agent is responsible for wiring.

===Add PUBLIC_PHYSICAL_NETWORK to flat_networks===
This network must be present in the ML2 flat_networks config if
flat_networks is specified.

===Set ext_gw_interface to PUBLIC_BRIDGE in provider net case===
ext_gw_interface must be a bridge in a bridge_mapping when
Q_USE_PROVIDERNET_FOR_PUBLIC is used.

Closes-Bug: #1605423
Change-Id: I95d63f8dfd21499c599d425678bf5327b599efcc
diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent
index e5a7b76..437aaeb 100644
--- a/lib/neutron_plugins/linuxbridge_agent
+++ b/lib/neutron_plugins/linuxbridge_agent
@@ -62,6 +62,9 @@
     if [[ "$LB_INTERFACE_MAPPINGS" == "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$LB_PHYSICAL_INTERFACE" != "" ]]; then
         LB_INTERFACE_MAPPINGS=$PHYSICAL_NETWORK:$LB_PHYSICAL_INTERFACE
     fi
+    if [[ "$PUBLIC_BRIDGE" != "" ]] && [[ "$PUBLIC_PHYSICAL_NETWORK" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE linux_bridge bridge_mappings "$PUBLIC_PHYSICAL_NETWORK:$PUBLIC_BRIDGE"
+    fi
     if [[ "$LB_INTERFACE_MAPPINGS" != "" ]]; then
         iniset /$Q_PLUGIN_CONF_FILE linux_bridge physical_interface_mappings $LB_INTERFACE_MAPPINGS
     fi
diff --git a/lib/neutron_plugins/ml2 b/lib/neutron_plugins/ml2
index 2ece210..7e80209 100644
--- a/lib/neutron_plugins/ml2
+++ b/lib/neutron_plugins/ml2
@@ -95,8 +95,16 @@
 
 
     # Allow for setup the flat type network
-    if [[ -z "$Q_ML2_PLUGIN_FLAT_TYPE_OPTIONS" && -n "$PHYSICAL_NETWORK" ]]; then
-            Q_ML2_PLUGIN_FLAT_TYPE_OPTIONS="flat_networks=$PHYSICAL_NETWORK"
+    if [[ -z "$Q_ML2_PLUGIN_FLAT_TYPE_OPTIONS" ]]; then
+        if [[ -n "$PHYSICAL_NETWORK" || -n "$PUBLIC_PHYSICAL_NETWORK" ]]; then
+            Q_ML2_PLUGIN_FLAT_TYPE_OPTIONS="flat_networks="
+            if [[ -n "$PHYSICAL_NETWORK" ]]; then
+                Q_ML2_PLUGIN_FLAT_TYPE_OPTIONS+="${PHYSICAL_NETWORK},"
+            fi
+            if [[ -n "$PUBLIC_PHYSICAL_NETWORK" ]]; then
+                Q_ML2_PLUGIN_FLAT_TYPE_OPTIONS+="${PUBLIC_PHYSICAL_NETWORK},"
+            fi
+        fi
     fi
     # REVISIT(rkukura): Setting firewall_driver here for
     # neutron.agent.securitygroups_rpc.is_firewall_enabled() which is
diff --git a/lib/neutron_plugins/services/l3 b/lib/neutron_plugins/services/l3
index 61b8402..a4e7248 100644
--- a/lib/neutron_plugins/services/l3
+++ b/lib/neutron_plugins/services/l3
@@ -306,10 +306,15 @@
         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
+            # Get the 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}
+            if [ "$Q_USE_PROVIDERNET_FOR_PUBLIC" = "True" ]; then
+                # in provider nets a bridge mapping uses the public bridge directly
+                ext_gw_interface=$PUBLIC_BRIDGE
+            else
+                # e.x. brq3592e767-da for NET_ID 3592e767-da66-4bcb-9bec-cdb03cd96102
+                ext_gw_interface=brq${EXT_NET_ID:0:11}
+            fi
         fi
         if [[ "$ext_gw_interface" != "none" ]]; then
             local cidr_len=${FLOATING_RANGE#*/}