Browse code

Delete OVS port on unstack to retain system connectivity

If you configure devstack with the following three values,
for example:

PHYSICAL_NETWORK=eth0
PUBLIC_INTERFACE=eth0
OVS_PHYSICAL_BRIDGE=br-eth0

This will cause devstack to create an OVS bridge, create a port for
eth0, and add it to the bridge (along with it's IP address).

The problem is that on unstack the port is never deleted from OVS,
so eth0 gets "trapped", not showing up in any of the OVS commands,
but not usable by the system. The only workaround is to unload the
OVS kernel module.

There needs to be an 'ovs-vsctl del-port ...' call at the end of
_move_neutron_addresses_route() on unstack - the antidote to the
'ovs-vsctl add-port ...', that happened on stack.

Closes-Bug: #1516801

Change-Id: Id2ff60f1f8e8fffff1eaffd68d9de4f6aa772943

Brian Haley authored on 2015/11/17 07:30:48
Showing 1 changed files
... ...
@@ -802,7 +802,8 @@ function _move_neutron_addresses_route {
802 802
     local from_intf=$1
803 803
     local to_intf=$2
804 804
     local add_ovs_port=$3
805
-    local af=$4
805
+    local del_ovs_port=$4
806
+    local af=$5
806 807
 
807 808
     if [[ -n "$from_intf" && -n "$to_intf" ]]; then
808 809
         # Remove the primary IP address from $from_intf and add it to $to_intf,
... ...
@@ -816,6 +817,7 @@ function _move_neutron_addresses_route {
816 816
         local DEFAULT_ROUTE_GW
817 817
         DEFAULT_ROUTE_GW=$(ip -f $af r | awk "/default.+$from_intf/ { print \$3; exit }")
818 818
         local ADD_OVS_PORT=""
819
+        local DEL_OVS_PORT=""
819 820
 
820 821
         IP_BRD=$(ip -f $af a s dev $from_intf scope global primary | grep inet | awk '{ print $2, $3, $4; exit }')
821 822
 
... ...
@@ -827,13 +829,19 @@ function _move_neutron_addresses_route {
827 827
             ADD_OVS_PORT="sudo ovs-vsctl --may-exist add-port $to_intf $from_intf"
828 828
         fi
829 829
 
830
+        if [[ "$del_ovs_port" == "True" ]]; then
831
+            DEL_OVS_PORT="sudo ovs-vsctl --if-exists del-port $from_intf $to_intf"
832
+        fi
833
+
830 834
         if [[ "$IP_BRD" != "" ]]; then
831 835
             IP_DEL="sudo ip addr del $IP_BRD dev $from_intf"
832 836
             IP_ADD="sudo ip addr add $IP_BRD dev $to_intf"
833 837
             IP_UP="sudo ip link set $to_intf up"
834 838
         fi
835 839
 
836
-        $IP_DEL; $IP_ADD; $IP_UP; $ADD_OVS_PORT; $ADD_DEFAULT_ROUTE
840
+        # The add/del OVS port calls have to happen either before or
841
+        # after the address is moved in order to not leave it orphaned.
842
+        $DEL_OVS_PORT; $IP_DEL; $IP_ADD; $IP_UP; $ADD_OVS_PORT; $ADD_DEFAULT_ROUTE
837 843
     fi
838 844
 }
839 845
 
... ...
@@ -842,14 +850,14 @@ function _move_neutron_addresses_route {
842 842
 function cleanup_neutron {
843 843
 
844 844
     if [[ -n "$OVS_PHYSICAL_BRIDGE" ]]; then
845
-        _move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False "inet"
845
+        _move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False True "inet"
846 846
 
847 847
         if [[ $(ip -f inet6 a s dev "$OVS_PHYSICAL_BRIDGE" | grep -c 'global') != 0 ]]; then
848 848
             # ip(8) wants the prefix length when deleting
849 849
             local v6_gateway
850 850
             v6_gateway=$(ip -6 a s dev $OVS_PHYSICAL_BRIDGE | grep $IPV6_PUBLIC_NETWORK_GATEWAY | awk '{ print $2 }')
851 851
             sudo ip -6 addr del $v6_gateway dev $OVS_PHYSICAL_BRIDGE
852
-            _move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False "inet6"
852
+            _move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False False "inet6"
853 853
         fi
854 854
 
855 855
         if is_provider_network && is_ironic_hardware; then
... ...
@@ -1044,10 +1052,10 @@ function _configure_neutron_l3_agent {
1044 1044
 
1045 1045
     neutron_plugin_configure_l3_agent
1046 1046
 
1047
-    _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True "inet"
1047
+    _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True False "inet"
1048 1048
 
1049 1049
     if [[ $(ip -f inet6 a s dev "$PUBLIC_INTERFACE" | grep -c 'global') != 0 ]]; then
1050
-        _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" False "inet6"
1050
+        _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" False False "inet6"
1051 1051
     fi
1052 1052
 }
1053 1053