Bug 4277 - Deleted Network flow entries retained in br-int, if network associated...
authorravi_sabapathy <ravi_sabapathy@dell.com>
Mon, 28 Sep 2015 07:31:48 +0000 (00:31 -0700)
committerFlavio Fernandes <ffernand@redhat.com>
Thu, 1 Oct 2015 16:12:04 +0000 (16:12 +0000)
        Remove the mac cache after deleting the DHCP neutron port l3 flows

Patch set 2: Move all other caches updated in delete into cleanupRouterCache()

Change-Id: I0c29ba4976ddfd484415d851ad5a2df97d61b19a
Signed-off-by: ravi_sabapathy <ravi_sabapathy@dell.com>
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3Adapter.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3AdapterTest.java

index b679902d379915abf3bdc006b1efc5cee6cd065a..603ecc58315a1fdc04fe25b437c08556ee779690 100644 (file)
@@ -311,6 +311,13 @@ public class NeutronL3Adapter implements ConfigInterface {
             }
             this.updateL3ForNeutronPort(neutronPort, currPortShouldBeDeleted);
         }
+
+        if (isDelete) {
+            /*
+             *  Bug 4277: Remove the router interface cache only after deleting the neutron port l3 flows.
+             */
+            this.cleanupRouterCache(neutronRouterInterface);
+        }
     }
 
     /**
@@ -806,13 +813,7 @@ public class NeutronL3Adapter implements ConfigInterface {
             }
         }
 
-        // Keep cache for finding router's mac from network uuid -- remove
-        //
-        if (isDelete) {
-            networkIdToRouterMacCache.remove(neutronNetwork.getNetworkUUID());
-            networkIdToRouterIpListCache.remove(neutronNetwork.getNetworkUUID());
-            subnetIdToRouterInterfaceCache.remove(subnet.getSubnetUUID());
-        }
+        // Keep cache for finding router's mac from network uuid -- NOTE: remove is done later, via cleanupRouterCache()
     }
 
     private void programFlowForNetworkFromExternal(final Node node,
@@ -1274,6 +1275,21 @@ public class NeutronL3Adapter implements ConfigInterface {
         return null;
     }
 
+     private void cleanupRouterCache(final NeutronRouter_Interface neutronRouterInterface) {
+         /*
+          *  Fix for 4277
+          *  Remove the router cache only after deleting the neutron
+          *  port l3 flows.
+          */
+         final NeutronPort neutronPort = neutronPortCache.getPort(neutronRouterInterface.getPortUUID());
+
+         if (neutronPort != null) {
+             networkIdToRouterMacCache.remove(neutronPort.getNetworkUUID());
+             networkIdToRouterIpListCache.remove(neutronPort.getNetworkUUID());
+             subnetIdToRouterInterfaceCache.remove(neutronRouterInterface.getSubnetUUID());
+         }
+     }
+
     public void triggerGatewayMacResolver(final Node node, final NeutronPort gatewayPort ){
 
         Preconditions.checkNotNull(node);
index 82ccf2571ec00b5d607eb51aa3d1ab0dd583156d..49419a40baee7d330bbdc574ba47c4763e2d6ac1 100644 (file)
@@ -583,6 +583,7 @@ public class NeutronL3AdapterTest {
         NeutronPort neutronPort = mock(NeutronPort.class);
         when(neutronPort.getMacAddress()).thenReturn(MAC_ADDRESS);
         when(neutronPort.getFixedIPs()).thenReturn(ips);
+        when(neutronPort.getNetworkUUID()).thenReturn(UUID);
         NeutronSubnet neutronSubnet = mock(NeutronSubnet.class);
         when(neutronSubnet.getNetworkUUID()).thenReturn(UUID);
         when(neutronSubnet.getGatewayIP()).thenReturn(IP);
@@ -591,6 +592,7 @@ public class NeutronL3AdapterTest {
         when(neutronNetwork.getProviderSegmentationID()).thenReturn(ID);
         when(neutronNetwork.getRouterExternal()).thenReturn(false); //might change that to true
         when(neutronNetwork.getNetworkUUID()).thenReturn(UUID);
+        NeutronRouter neutronRouter = mock(NeutronRouter.class);
 
         Node node = mock(Node.class);
         List<Node> nodes = new ArrayList<Node>();
@@ -605,6 +607,7 @@ public class NeutronL3AdapterTest {
         // init instance variables
         INeutronPortCRUD neutronPortCache = mock(INeutronPortCRUD.class);
         PowerMockito.when(neutronPortCache.getPort(anyString())).thenReturn(neutronPort);
+        PowerMockito.when(neutronPortCache.getAllPorts()).thenReturn(new ArrayList<NeutronPort>());
         INeutronSubnetCRUD neutronSubnetCache = mock(INeutronSubnetCRUD.class);
         PowerMockito.when(neutronSubnetCache.getSubnet(anyString())).thenReturn(neutronSubnet);
         INeutronNetworkCRUD neutronNetworkCache = mock(INeutronNetworkCRUD.class);
@@ -638,14 +641,16 @@ public class NeutronL3AdapterTest {
 
         networkIdToRouterMacCache.put(UUID, MAC_ADDRESS);
         networkIdToRouterIpListCache.put(UUID, ips);
+        subnetIdToRouterInterfaceCache.put(UUID, intf);
         networkIdToRouterMacCacheSize = networkIdToRouterMacCache.size();
         networkIdToRouterIpListCacheSize = networkIdToRouterIpListCache.size();
         subnetIdToRouterInterfaceCacheSize = subnetIdToRouterInterfaceCache.size();
 
-        Whitebox.invokeMethod(neutronL3Adapter, "programFlowsForNeutronRouterInterface", intf, true);
+        Whitebox.invokeMethod(neutronL3Adapter, "handleNeutronRouterInterfaceEvent", neutronRouter, intf, Action.DELETE);
 
+        PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programFlowsForNeutronRouterInterface", intf, true);
         PowerMockito.verifyPrivate(neutronL3Adapter, times(2)).invoke("getDpidForIntegrationBridge", any(Node.class));
-        PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programFlowsForNeutronRouterInterfacePair", any(Node.class), anyLong(), any(NeutronRouter_Interface.class), any(NeutronRouter_Interface.class), any(NeutronNetwork.class), anyString(), anyString(), anyString(), anyInt(), eq(Action.DELETE), anyBoolean());
+        PowerMockito.verifyPrivate(neutronL3Adapter, times(2)).invoke("programFlowsForNeutronRouterInterfacePair", any(Node.class), anyLong(), any(NeutronRouter_Interface.class), any(NeutronRouter_Interface.class), any(NeutronNetwork.class), anyString(), anyString(), anyString(), anyInt(), eq(Action.DELETE), anyBoolean());
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programFlowForNetworkFromExternal", any(Node.class), anyLong(), anyString(), anyString(), anyString(), anyInt(), eq(Action.DELETE));
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programStaticArpStage1", anyLong(), anyString(), anyString(), anyString(), eq(Action.DELETE));
         PowerMockito.verifyPrivate(neutronL3Adapter, times(1)).invoke("programIpRewriteExclusionStage1", any(Node.class), anyLong(), anyString(), anyString(), eq(Action.DELETE));