Stale Floating IP entry in dpn-op-elements 77/84277/11
authorChetan Arakere Gowdru <chetan.arakere@altencalsoftlabs.com>
Mon, 9 Sep 2019 11:44:19 +0000 (17:14 +0530)
committerChetan Arakere Gowdru <chetan.arakere@altencalsoftlabs.com>
Mon, 4 Nov 2019 11:46:26 +0000 (11:46 +0000)
Problem Description:
It's been oberserved that the VM's neutron Port is
deleted first before floating-ip with which it associated. As a result,
when floating-ip-info delete event is triggered, the ifmgr RPC query to
get the DPNID first check for ietf-interface config (which is already
cleared) and return with empty DpnID. As a result, the flow for clear
the DNAT related flows and withdrawal of Floating IP route from
vpn-instance-op-data didn't succeeded.

Solution:
Change are to query the interface-state Oper DS to get the DPNID instead
of ifmmgr RPC call.

Change-Id: Ic12746e73e62d62b8310d391e51e42d376b465e4
Signed-off-by: Chetan Arakere Gowdru <chetan.arakere@altencalsoftlabs.com>
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/FloatingIPListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatVpnMapsChangeListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/VpnFloatingIpHandler.java

index e10e70799cc6a0f0bc95f95ccd84d0e3db32f13e..ff2d32403f69e3a692f7bb2f9e2111856c22b152 100644 (file)
@@ -450,10 +450,14 @@ public class FloatingIPListener extends AsyncDataTreeChangeListenerBase<Internal
             String interfaceName) {
         //Get the DPN on which this interface resides
         if (dpnId == null) {
-            dpnId = NatUtil.getDpnForInterface(interfaceManager, interfaceName);
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces
+                .state.Interface interfaceState = NatUtil.getInterfaceStateFromOperDS(dataBroker, interfaceName);
+            if (interfaceState != null) {
+                dpnId = NatUtil.getDpIdFromInterface(interfaceState);
+            }
         }
         Uint64 updatedDpnId = dpnId;
-        if (updatedDpnId.equals(Uint64.valueOf(BigInteger.ZERO))) {
+        if (updatedDpnId != null && updatedDpnId.equals(Uint64.ZERO)) {
             LOG.debug("getAssociatedDpnWithExternalInterface : The interface {} is not associated with any dpn",
                     interfaceName);
             return updatedDpnId;
index 37da5ad6babf90d60c0f5ec5f475383e95c34cb8..b393cf25d061d9801a9b8c217ade2db4a53a85ff 100644 (file)
@@ -10,8 +10,11 @@ package org.opendaylight.netvirt.natservice.internal;
 import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
 
 import com.google.common.base.Optional;
+import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.ExecutionException;
+import java.util.stream.Collectors;
+import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 import javax.inject.Singleton;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -28,6 +31,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev16011
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.floating.ip.info.router.ports.ports.InternalToExternalPortMap;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.vpnmap.RouterIds;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.common.Uint64;
@@ -56,9 +60,11 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
         this.externalRoutersListener = externalRoutersListener;
     }
 
+    @Override
+    @PostConstruct
     public void init() {
         LOG.info("{} init", getClass().getSimpleName());
-        registerListener(dataBroker);
+        registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
     }
 
     @Override
@@ -66,34 +72,34 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
         return InstanceIdentifier.create(VpnMaps.class).child(VpnMap.class);
     }
 
-    private void registerListener(final DataBroker db) {
-        registerListener(LogicalDatastoreType.CONFIGURATION, db);
-    }
-
     @Override
     protected void add(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
         Uuid vpnUuid = vpnMap.getVpnId();
         String vpnName = vpnUuid.getValue();
-        vpnMap.getRouterIds().stream()
+        if (vpnMap.getRouterIds() != null) {
+            vpnMap.getRouterIds().stream()
                 .filter(router -> !(Objects.equals(router.getRouterId(), vpnUuid)))
                 .forEach(router -> {
                     String routerName = router.getRouterId().getValue();
                     LOG.info("REMOVE: Router {} is disassociated from Vpn {}", routerName, vpnName);
                     onRouterAssociatedToVpn(vpnName, routerName);
                 });
+        }
     }
 
     @Override
     protected void remove(InstanceIdentifier<VpnMap> identifier, VpnMap vpnMap) {
         Uuid vpnUuid = vpnMap.getVpnId();
         String vpnName = vpnUuid.getValue();
-        vpnMap.getRouterIds().stream()
+        if (vpnMap.getRouterIds() != null) {
+            vpnMap.getRouterIds().stream()
                 .filter(router -> !(Objects.equals(router.getRouterId(), vpnUuid)))
                 .forEach(router -> {
                     String routerName = router.getRouterId().getValue();
                     LOG.info("REMOVE: Router {} is disassociated from Vpn {}", routerName, vpnName);
                     onRouterDisassociatedFromVpn(vpnName, routerName);
                 });
+        }
     }
 
     @Override
@@ -101,21 +107,44 @@ public class NatVpnMapsChangeListener extends AsyncDataTreeChangeListenerBase<Vp
         Uuid vpnUuid = updated.getVpnId();
         String vpnName = vpnUuid.getValue();
 
-        updated.getRouterIds().stream()
-                .filter(router -> ! original.getRouterIds().contains(router))
+        List<RouterIds> updatedRouterIdList = updated.getRouterIds();
+        List<RouterIds> originalRouterIdList = original.getRouterIds();
+        List<RouterIds> routersAddedList = null;
+        List<RouterIds> routersRemovedList = null;
+
+        if (originalRouterIdList == null && updatedRouterIdList != null) {
+            routersAddedList = updatedRouterIdList;
+        } else if (originalRouterIdList != null && updatedRouterIdList != null) {
+            routersAddedList = updatedRouterIdList.stream()
+                .filter(routerId -> (!originalRouterIdList.contains(routerId)))
+                .collect(Collectors.toList());
+        }
+
+        if (originalRouterIdList != null && updatedRouterIdList == null) {
+            routersRemovedList = originalRouterIdList;
+        } else if (originalRouterIdList != null && updatedRouterIdList != null) {
+            routersRemovedList = originalRouterIdList.stream()
+                .filter(routerId -> (!updatedRouterIdList.contains(routerId)))
+                .collect(Collectors.toList());
+        }
+
+        if (routersAddedList != null) {
+            routersAddedList.stream()
                 .filter(router -> !(Objects.equals(router.getRouterId(), updated.getVpnId())))
                 .forEach(router -> {
                     String routerName = router.getRouterId().getValue();
                     onRouterAssociatedToVpn(vpnName, routerName);
                 });
+        }
 
-        original.getRouterIds().stream()
-                .filter(router -> ! updated.getRouterIds().contains(router))
+        if (routersRemovedList != null) {
+            routersRemovedList.stream()
                 .filter(router -> !(Objects.equals(router.getRouterId(), original.getVpnId())))
                 .forEach(router -> {
                     String routerName = router.getRouterId().getValue();
                     onRouterDisassociatedFromVpn(vpnName, routerName);
                 });
+        }
     }
 
     @Override
index 12113b409d04e01bced6dcb6ef93da13439781ef..548ee48f52b6b5275a69cb100305cc26bbe8b1a9 100644 (file)
@@ -343,7 +343,7 @@ public class VpnFloatingIpHandler implements FloatingIPHandler {
         String rd = NatUtil.getVpnRd(confTx, vpnName);
         String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp);
         NatUtil.removePrefixFromBGP(bgpManager, fibManager, rd, fibExternalIp, vpnName);
-
+        NatUtil.deletePrefixToInterface(dataBroker, NatUtil.getVpnId(dataBroker, vpnName), fibExternalIp);
         //Remove custom FIB routes
 
         //Future<RpcResult<java.lang.Void>> removeFibEntry(RemoveFibEntryInput input);