TR: Local routes not appeared on deletion of VPN 59/37859/2
authorSuraj Ranjan <suraj.ranjan@ericsson.com>
Wed, 20 Apr 2016 06:27:15 +0000 (11:57 +0530)
committerSuraj Ranjan <suraj.ranjan@ericsson.com>
Wed, 20 Apr 2016 07:06:32 +0000 (12:36 +0530)
-Datapath broken when router dissociated from VPN

-Enables tentative fixes to ensure clean up of datapath
on removal of an external VPN, when routers are present in it.

-Similarly enables a tentative fix to ensure clean up of datapath
on disassociation of routers from a VPN.

Change-Id: I224d39b33181d52c1332b1548a91eee167814a85
Signed-off-by: Suraj Ranjan <suraj.ranjan@ericsson.com>
Co-Authored-By: Vivekanandan Narasimhan <n.vivekanandan@ericsson.com>
fibmanager/fibmanager-impl/src/main/java/org/opendaylight/vpnservice/fibmanager/FibManager.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnConstants.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnInterfaceManager.java
vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/vpnservice/VpnManager.java

index 57a336e70a820c43d765cf5e01f9c40d18a2b755..28419440cb9806aca1aa91f382b4a056f7ff0e18 100644 (file)
@@ -159,19 +159,19 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
   @Override
   protected void add(final InstanceIdentifier<VrfEntry> identifier,
                      final VrfEntry vrfEntry) {
-    LOG.trace("key: " + identifier + ", value=" + vrfEntry );
+    LOG.trace("Add key: " + identifier + ", value=" + vrfEntry );
     createFibEntries(identifier, vrfEntry);
   }
 
   @Override
   protected void remove(InstanceIdentifier<VrfEntry> identifier, VrfEntry vrfEntry) {
-    LOG.trace("key: " + identifier + ", value=" + vrfEntry);
+    LOG.trace("Remove key: " + identifier + ", value=" + vrfEntry);
     deleteFibEntries(identifier, vrfEntry);
   }
 
   @Override
   protected void update(InstanceIdentifier<VrfEntry> identifier, VrfEntry original, VrfEntry update) {
-    LOG.trace("key: " + identifier + ", original=" + original + ", update=" + update );
+    LOG.trace("Update key: " + identifier + ", original=" + original + ", update=" + update );
     createFibEntries(identifier, update);
   }
 
index 62d6db72e2992a5d59c6c744d6d6a73470e1dfc2..a764d396855feffe0701c9b44afce7b4954f52ef 100644 (file)
@@ -21,7 +21,8 @@ public class VpnConstants {
     public static final BigInteger COOKIE_VM_INGRESS_TABLE = new BigInteger("8000001", 16);
     public static final BigInteger COOKIE_L3_BASE = new BigInteger("8000000", 16);
     public static final String FLOWID_PREFIX = "L3.";
-    public static final long WAIT_TIME_IN_MILLISECONDS = 5000;
+    public static final long MIN_WAIT_TIME_IN_MILLISECONDS = 10000;
+    public static final long MAX_WAIT_TIME_IN_MILLISECONDS = 90000;
     public static final int ELAN_GID_MIN = 200000;
     public static final short ELAN_SMAC_TABLE = 50;
     public static final short FIB_TABLE = 21;
index 2a9a96138aa8c6a3fb5689531fa7fe1f81452fa8..f128faca1b5ecfa50d64cf3ba78cd0d8f4610562 100644 (file)
@@ -499,7 +499,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                 vpnIntfMap.put(interfaceName, notifyTask);
                 synchronized (notifyTask) {
                     try {
-                        notifyTask.wait(VpnConstants.WAIT_TIME_IN_MILLISECONDS);
+                        notifyTask.wait(VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS);
                     } catch (InterruptedException e) {
                     }
                 }
@@ -514,6 +514,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         Optional<Adjacencies> adjacencies = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL, path);
 
         String rd = VpnUtil.getVpnRd(broker, intf.getVpnInstanceName());
+        LOG.trace("removeAdjacenciesFromVpn: For interface {} RD recovered for vpn {} as rd {}", intf.getName(),
+                intf.getVpnInstanceName(), rd);
         if (adjacencies.isPresent()) {
             List<Adjacency> nextHops = adjacencies.get().getAdjacency();
 
@@ -801,42 +803,57 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         protected void remove(InstanceIdentifier<VpnInterface> identifier, VpnInterface del) {
             final VpnInterfaceKey key = identifier.firstKeyOf(VpnInterface.class, VpnInterfaceKey.class);
             String interfaceName = key.getName();
+            String vpnName = del.getVpnInstanceName();
+
+            LOG.trace("VpnInterfaceOpListener removed: interface name {} vpnName {}", interfaceName, vpnName);
+            //decrement the vpn interface count in Vpn Instance Op Data
+            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
+                    id = VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnName);
+            Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance> vpnInstance
+                    = VpnUtil.read(broker, LogicalDatastoreType.CONFIGURATION, id);
+
+            if (vpnInstance.isPresent()) {
+                String rd = null;
+                rd = vpnInstance.get().getVrfId();
+                //String rd = getRouteDistinguisher(del.getVpnInstanceName());
+
+                VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
+                LOG.trace("VpnInterfaceOpListener removed: interface name {} rd {} vpnName {} in Vpn Op Instance {}",
+                        interfaceName, rd, vpnName, vpnInstOp);
+
+                if (vpnInstOp != null) {
+                    Long ifCnt = 0L;
+                    ifCnt = vpnInstOp.getVpnInterfaceCount();
+                    LOG.trace("VpnInterfaceOpListener removed: interface name {} rd {} vpnName {} Intf count {}",
+                            interfaceName, rd, vpnName, ifCnt);
+                    if ((ifCnt != null) && (ifCnt > 0)) {
+                        VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
+                                VpnUtil.getVpnInstanceOpDataIdentifier(rd),
+                                VpnUtil.updateIntfCntInVpnInstOpData(ifCnt - 1, rd), VpnUtil.DEFAULT_CALLBACK);
+                    }
 
-            //increment the vpn interface count in Vpn Instance Op Data
-            Long ifCnt = 0L;
-            String rd = getRouteDistinguisher(del.getVpnInstanceName());
-            if(rd == null || rd.isEmpty()) rd = del.getVpnInstanceName();
-            VpnInstanceOpDataEntry vpnInstOp = VpnUtil.getVpnInstanceOpData(broker, rd);
-            if(vpnInstOp != null && vpnInstOp.getVpnInterfaceCount() != null) {
-                ifCnt = vpnInstOp.getVpnInterfaceCount();
-            }
-
-            LOG.trace("VpnInterfaceOpListener remove: interface name {} rd {} interface count in Vpn Op Instance {}", interfaceName, rd, ifCnt);
-
-            if(ifCnt != 0) {
-                VpnUtil.asyncUpdate(broker, LogicalDatastoreType.OPERATIONAL,
-                        VpnUtil.getVpnInstanceOpDataIdentifier(rd),
-                        VpnUtil.updateIntfCntInVpnInstOpData(ifCnt - 1, rd), VpnUtil.DEFAULT_CALLBACK);
-            }
-
-            // Vpn Interface removed => No more adjacencies from it.
-            // Hence clean up interface from vpn-dpn-interface list.
-            Adjacency adjacency = del.getAugmentation(Adjacencies.class).getAdjacency().get(0);
-            Optional<Prefixes> prefixToInterface = Optional.absent();
-            prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
-                         VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
-                                                VpnUtil.getIpPrefix(adjacency.getIpAddress())));
-            if (!prefixToInterface.isPresent()) {
-                prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
-                                                 VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
-                                                         VpnUtil.getIpPrefix(adjacency.getNextHopIp())));
-            }
-            if (prefixToInterface.isPresent()) {
-                VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
-                               VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
-                                                 prefixToInterface.get().getIpAddress()),
-                               VpnUtil.DEFAULT_CALLBACK);
-                updateDpnDbs(prefixToInterface.get().getDpnId(), del.getVpnInstanceName(), interfaceName, false);
+                    // Vpn Interface removed => No more adjacencies from it.
+                    // Hence clean up interface from vpn-dpn-interface list.
+                    Adjacency adjacency = del.getAugmentation(Adjacencies.class).getAdjacency().get(0);
+                    Optional<Prefixes> prefixToInterface = Optional.absent();
+                    prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+                            VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+                                    VpnUtil.getIpPrefix(adjacency.getIpAddress())));
+                    if (!prefixToInterface.isPresent()) {
+                        prefixToInterface = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+                                VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+                                        VpnUtil.getIpPrefix(adjacency.getNextHopIp())));
+                    }
+                    if (prefixToInterface.isPresent()) {
+                        VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+                                VpnUtil.getPrefixToInterfaceIdentifier(vpnInstOp.getVpnId(),
+                                        prefixToInterface.get().getIpAddress()),
+                                VpnUtil.DEFAULT_CALLBACK);
+                        updateDpnDbs(prefixToInterface.get().getDpnId(), del.getVpnInstanceName(), interfaceName, false);
+                    }
+                }
+            } else {
+                LOG.error("rd not retrievable as vpninstancetovpnid for vpn {} is absent, trying rd as ", vpnName, vpnName);
             }
             notifyTaskIfRequired(interfaceName);
         }
index 88c73c2de8b7d68a6522dd2517175a62e712b8b7..b41225ceef323f25f7f08a9f68169de9dcbec31a 100644 (file)
@@ -98,7 +98,7 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
                     getWildCardPath(), VpnManager.this, DataChangeScope.SUBTREE);
             fibListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
                     getFibEntryListenerPath(), fibListener, DataChangeScope.BASE);
-            opListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION,
+            opListenerRegistration = db.registerDataChangeListener(LogicalDatastoreType.OPERATIONAL,
                     getVpnInstanceOpListenerPath(), vpnInstOpListener, DataChangeScope.SUBTREE);
 
         } catch (final Exception e) {
@@ -115,14 +115,14 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
         this.vpnInterfaceManager = vpnInterfaceManager;
     }
 
-    private void waitForOpDataRemoval(String id) {
+    private void waitForOpDataRemoval(String id, long timeout) {
         //wait till DCN for update on VPN Instance Op Data signals that vpn interfaces linked to this vpn instance is zero
         Runnable notifyTask = new VpnNotifyTask();
         synchronized (id.intern()) {
             vpnOpMap.put(id, notifyTask);
             synchronized (notifyTask) {
                 try {
-                    notifyTask.wait(VpnConstants.WAIT_TIME_IN_MILLISECONDS);
+                    notifyTask.wait(timeout);
                 } catch (InterruptedException e) {
                 }
             }
@@ -132,30 +132,69 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
 
     @Override
     protected void remove(InstanceIdentifier<VpnInstance> identifier, VpnInstance del) {
-        LOG.trace("Remove VPN event - Key: {}, value: {}", identifier, del);
+        LOG.trace("Remove VPN event key: {}, value: {}", identifier, del);
         String vpnName = del.getVpnInstanceName();
 
-        //Clean up vpn Interface
-        InstanceIdentifier<VpnInterfaces> vpnInterfacesId = InstanceIdentifier.builder(VpnInterfaces.class).build();
-        Optional<VpnInterfaces> optionalVpnInterfaces = read(LogicalDatastoreType.OPERATIONAL, vpnInterfacesId);
+        String rd = del.getIpv4Family().getRouteDistinguisher();
 
-        if(optionalVpnInterfaces.isPresent()) {
-            List<VpnInterface> vpnInterfaces = optionalVpnInterfaces.get().getVpnInterface();
-            for(VpnInterface vpnInterface : vpnInterfaces) {
-                if(vpnInterface.getVpnInstanceName().equals(vpnName)) {
-                    LOG.debug("VpnInterface {} will be removed from VPN {}", vpnInterface.getName(), vpnName);
-                    vpnInterfaceManager.remove(
-                            VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
+//        //Clean up vpn Interface
+//        InstanceIdentifier<VpnInterfaces> vpnInterfacesId = InstanceIdentifier.builder(VpnInterfaces.class).build();
+//        Optional<VpnInterfaces> optionalVpnInterfaces = read(LogicalDatastoreType.OPERATIONAL, vpnInterfacesId);
+//
+//        if(optionalVpnInterfaces.isPresent()) {
+//            List<VpnInterface> vpnInterfaces = optionalVpnInterfaces.get().getVpnInterface();
+//            for(VpnInterface vpnInterface : vpnInterfaces) {
+//                if(vpnInterface.getVpnInstanceName().equals(vpnName)) {
+//                    LOG.debug("VpnInterface {} will be removed from VPN {}", vpnInterface.getName(), vpnName);
+//                    vpnInterfaceManager.remove(
+//                            VpnUtil.getVpnInterfaceIdentifier(vpnInterface.getName()), vpnInterface);
+//                }
+//            }
+//        }
+
+        //TODO(vpnteam): Entire code would need refactoring to listen only on the parent object - VPNInstance
+        Optional<VpnInstanceOpDataEntry> vpnOpValue = null;
+        if ((rd != null) && (!rd.isEmpty())) {
+            vpnOpValue = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+                    VpnUtil.getVpnInstanceOpDataIdentifier(rd));
+        } else {
+            vpnOpValue = VpnUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+                    VpnUtil.getVpnInstanceOpDataIdentifier(vpnName));
+        }
+
+        if ((vpnOpValue != null) && (vpnOpValue.isPresent())) {
+            VpnInstanceOpDataEntry vpnOpEntry = null;
+            long timeout = VpnConstants.MIN_WAIT_TIME_IN_MILLISECONDS;
+            Long intfCount = 0L;
+
+            vpnOpEntry = vpnOpValue.get();
+            intfCount = vpnOpEntry.getVpnInterfaceCount();
+            if (intfCount != null && intfCount > 0) {
+                // Minimum wait time of 10 seconds for one VPN Interface clearance (inclusive of full trace on)
+                timeout = intfCount * 10000;
+                // Maximum wait time of 90 seconds for all VPN Interfaces clearance (inclusive of full trace on)
+                if (timeout > VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS) {
+                    timeout = VpnConstants.MAX_WAIT_TIME_IN_MILLISECONDS;
                 }
+                LOG.trace("VPNInstance removal interface count at {} for for rd {}, vpnname {}",
+                        intfCount, rd, vpnName);
+            }
+            LOG.trace("VPNInstance removal thread waiting for {} seconds for rd {}, vpnname {}",
+                    (timeout/1000), rd, vpnName);
+
+            if ((rd != null)  && (!rd.isEmpty())) {
+                waitForOpDataRemoval(rd, timeout);
+            } else {
+                waitForOpDataRemoval(vpnName, timeout);
             }
+
+            LOG.trace("Returned out of waiting for  Op Data removal for rd {}, vpnname {}", rd, vpnName);
         }
+
         InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance>
-            vpnIdentifier = VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnName);
+                vpnIdentifier = VpnUtil.getVpnInstanceToVpnIdIdentifier(vpnName);
         delete(LogicalDatastoreType.CONFIGURATION, vpnIdentifier);
-
-        VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME, vpnName);
-        String rd = del.getIpv4Family().getRouteDistinguisher();
-
+        LOG.trace("Removed vpnIdentifier for  rd{} vpnname {}", rd, vpnName);
         if (rd !=null) {
 
             try {
@@ -163,24 +202,26 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
             } catch (Exception e) {
                 LOG.error("Exception when removing VRF from BGP", e);
             }
-            waitForOpDataRemoval(rd);
+
             delete(LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(rd));
         } else {
-            waitForOpDataRemoval(vpnName);
+
             delete(LogicalDatastoreType.OPERATIONAL, VpnUtil.getVpnInstanceOpDataIdentifier(vpnName));
         }
+
+        VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME, vpnName);
     }
 
     @Override
     protected void update(InstanceIdentifier<VpnInstance> identifier,
             VpnInstance original, VpnInstance update) {
-        LOG.trace("Update event - Key: {}, value: {}", identifier, update);
+        LOG.trace("Update VPN event key: {}, value: {}", identifier, update);
     }
 
     @Override
     protected void add(InstanceIdentifier<VpnInstance> identifier,
             VpnInstance value) {
-        LOG.trace("VPN Instance key: {}, value: {}", identifier, value);
+        LOG.trace("Add VPN event key: {}, value: {}", identifier, value);
         VpnAfConfig config = value.getIpv4Family();
         String rd = config.getRouteDistinguisher();
 
@@ -230,7 +271,6 @@ public class VpnManager extends AbstractDataChangeListener<VpnInstance> implemen
             }
         }
         //Try to add up vpn Interfaces if already in Operational Datastore
-        LOG.trace("Trying to add the vpn interfaces  -1.");
         InstanceIdentifier<VpnInterfaces> vpnInterfacesId = InstanceIdentifier.builder(VpnInterfaces.class).build();
         Optional<VpnInterfaces> optionalVpnInterfaces = read(LogicalDatastoreType.CONFIGURATION, vpnInterfacesId);