Bug 7939, 7938, 7968, 7997: Potential fix for the four L3VPN bugs 55/53355/6
authorAbhinav Gupta <abhinav.gupta@ericsson.com>
Wed, 15 Mar 2017 14:04:28 +0000 (19:34 +0530)
committerVivekanandan Narasimhan <n.vivekanandan@ericsson.com>
Thu, 16 Mar 2017 16:36:15 +0000 (16:36 +0000)
While creating LocalFibEntry, localDpnId list is being returned empty
leading to local FIB entry not getting installed.
The fix ensures we log an error statement in case it happens and tries
to achieve processing config and inventory transactions for the
vpninterface once operational transaction is processed.

Change-Id: I95589523079f9d990b5e61d96b71b2c6d1c133e1
Signed-off-by: Abhinav Gupta <abhinav.gupta@ericsson.com>
vpnservice/fibmanager/fibmanager-impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java
vpnservice/vpnmanager/vpnmanager-impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java

index c171844e9771f48eab7a0cc15461f5706144605a..ff8ce84c7d33bad28eec9d3077301258a74ea369 100755 (executable)
@@ -368,7 +368,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
         final VpnInstanceOpDataEntry vpnInstance = getVpnInstance(vrfTableKey.getRouteDistinguisher());
         Preconditions.checkNotNull(vpnInstance, "Vpn Instance not available " + vrfTableKey.getRouteDistinguisher());
         Preconditions.checkNotNull(vpnInstance.getVpnId(), "Vpn Instance with rd " + vpnInstance.getVrfId()
-            + " has null vpnId!");
+                + " has null vpnId!");
 
         final Collection<VpnToDpnList> vpnToDpnList = vpnInstance.getVpnToDpnList();
         final Long vpnId = vpnInstance.getVpnId();
@@ -377,21 +377,20 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
         if (subnetRoute != null) {
             final long elanTag = subnetRoute.getElantag();
             LOG.trace("SubnetRoute augmented vrfentry found for rd {} prefix {} with elantag {}",
-                rd, vrfEntry.getDestPrefix(), elanTag);
+                    rd, vrfEntry.getDestPrefix(), elanTag);
             if (vpnToDpnList != null) {
                 DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
-                dataStoreCoordinator.enqueueJob("FIB-" + rd + "-" + vrfEntry.getDestPrefix(),
-                    () -> {
-                        WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
-                        for (final VpnToDpnList curDpn : vpnToDpnList) {
-                            if (curDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
-                                installSubnetRouteInFib(curDpn.getDpnId(), elanTag, rd, vpnId, vrfEntry, tx);
-                            }
+                dataStoreCoordinator.enqueueJob("FIB-" + rd + "-" + vrfEntry.getDestPrefix(), () -> {
+                    WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
+                    for (final VpnToDpnList curDpn : vpnToDpnList) {
+                        if (curDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
+                            installSubnetRouteInFib(curDpn.getDpnId(), elanTag, rd, vpnId, vrfEntry, tx);
                         }
-                        List<ListenableFuture<Void>> futures = new ArrayList<>();
-                        futures.add(tx.submit());
-                        return futures;
-                    });
+                    }
+                    List<ListenableFuture<Void>> futures = new ArrayList<>();
+                    futures.add(tx.submit());
+                    return futures;
+                });
             }
             return;
         }
@@ -402,16 +401,16 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
 
         final List<BigInteger> localDpnIdList = createLocalFibEntry(vpnInstance.getVpnId(), rd, vrfEntry);
 
-        if (vpnToDpnList != null) {
-            DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
-            dataStoreCoordinator.enqueueJob("FIB-" + rd + "-" + vrfEntry.getDestPrefix(),
-                () -> {
+        if (!localDpnIdList.isEmpty()) {
+            if (vpnToDpnList != null) {
+                DataStoreJobCoordinator dataStoreCoordinator = DataStoreJobCoordinator.getInstance();
+                dataStoreCoordinator.enqueueJob("FIB-" + rd + "-" + vrfEntry.getDestPrefix(), () -> {
                     WriteTransaction tx = dataBroker.newWriteOnlyTransaction();
                     for (VpnToDpnList vpnDpn : vpnToDpnList) {
                         if (!localDpnIdList.contains(vpnDpn.getDpnId())) {
                             if (vpnDpn.getDpnState() == VpnToDpnList.DpnState.Active) {
-                                createRemoteFibEntry(vpnDpn.getDpnId(), vpnInstance.getVpnId(),
-                                    vrfTableKey, vrfEntry, tx);
+                                createRemoteFibEntry(vpnDpn.getDpnId(), vpnInstance.getVpnId(), vrfTableKey, vrfEntry,
+                                        tx);
                             }
                         }
                     }
@@ -419,6 +418,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                     futures.add(tx.submit());
                     return futures;
                 });
+            }
         }
 
         Optional<String> optVpnUuid = FibUtil.getVpnNameFromRd(dataBroker, rd);
@@ -834,6 +834,9 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                     }
                 }
             }
+            if (returnLocalDpnId.isEmpty()) {
+                LOG.error("Local DPNID is empty for rd {}, vpnId {}, vrfEntry {}", rd, vpnId, vrfEntry);
+            }
         } else {
             BigInteger dpnId = checkCreateLocalFibEntry(localNextHopInfo, localNextHopIP, vpnId,
                     rd, vrfEntry, vpnId, /*routes*/ null, /*vpnExtraRoutes*/ null);
index a3741f995d0a61281320168c995d493d02fde36e..908209662338e10dbe9b27f1ab428f8537abfe66 100755 (executable)
@@ -26,6 +26,7 @@ import java.util.TimerTask;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
@@ -242,8 +243,15 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                             delAdjFromVpnInterface(identifier, adj, dpnId, writeOperTxn, writeConfigTxn);
                         }
                     }
+                    ListenableFuture<Void> operFuture = writeOperTxn.submit();
+                    try {
+                        operFuture.get();
+                    } catch (ExecutionException e) {
+                        LOG.error("Exception encountered while submitting operational future for addVpnInterface {}: "
+                                + "{}", vpnInterface.getName(), e);
+                        return null;
+                    }
                     List<ListenableFuture<Void>> futures = new ArrayList<>();
-                    futures.add(writeOperTxn.submit());
                     futures.add(writeConfigTxn.submit());
                     futures.add(writeInvTxn.submit());
                     return futures;
@@ -1050,7 +1058,14 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                         processVpnInterfaceDown(dpnId.equals(BigInteger.ZERO) ? vpnOpInterface.getDpnId() : dpnId,
                                 interfaceName, ifIndex, false, true, writeConfigTxn, writeOperTxn,
                                 writeInvTxn, interfaceState);
-                        futures.add(writeOperTxn.submit());
+                        ListenableFuture<Void> operFuture = writeOperTxn.submit();
+                        try {
+                            operFuture.get();
+                        } catch (ExecutionException e) {
+                            LOG.error("Exception encountered while submitting operational future for remove "
+                                    + "VpnInterface {}: {}", vpnInterface.getName(), e);
+                            return null;
+                        }
                         futures.add(writeConfigTxn.submit());
                         futures.add(writeInvTxn.submit());
                     } else {
@@ -1293,9 +1308,10 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
         final VpnInterface update) {
         LOG.trace("Updating VPN Interface : key {},  original value={}, update value={}", identifier, original, update);
         LOG.info("VPN Interface update event - intfName {}", update.getName());
+        final String vpnInterfaceName = update.getName();
         final String oldVpnName = original.getVpnInstanceName();
         final String newVpnName = update.getVpnInstanceName();
-        final BigInteger dpnId = InterfaceUtils.getDpnForInterface(ifaceMgrRpcService, update.getName());
+        final BigInteger dpnId = InterfaceUtils.getDpnForInterface(ifaceMgrRpcService, vpnInterfaceName);
         final UpdateData updateData = new UpdateData(identifier, original, update);
         final Adjacencies origAdjs = original.getAugmentation(Adjacencies.class);
         final List<Adjacency> oldAdjs = (origAdjs != null && origAdjs.getAdjacency()
@@ -1312,11 +1328,10 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
             return;
         }
         final DataStoreJobCoordinator vpnInfAdjUpdateDataStoreCoordinator = DataStoreJobCoordinator.getInstance();
-        vpnInfAdjUpdateDataStoreCoordinator.enqueueJob("VPNINTERFACE-" + update.getName(),
+        vpnInfAdjUpdateDataStoreCoordinator.enqueueJob("VPNINTERFACE-" + vpnInterfaceName,
             () -> {
                 WriteTransaction writeConfigTxn = dataBroker.newWriteOnlyTransaction();
                 WriteTransaction writeOperTxn = dataBroker.newWriteOnlyTransaction();
-                List<ListenableFuture<Void>> futures = new ArrayList<>();
                 //handle both addition and removal of adjacencies
                 //currently, new adjacency may be an extra route
                 if (!oldAdjs.equals(newAdjs)) {
@@ -1332,7 +1347,15 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                         delAdjFromVpnInterface(identifier, adj, dpnId, writeOperTxn, writeConfigTxn);
                     }
                 }
-                futures.add(writeOperTxn.submit());
+                ListenableFuture<Void> operFuture = writeOperTxn.submit();
+                try {
+                    operFuture.get();
+                } catch (ExecutionException e) {
+                    LOG.error("Exception encountered while submitting operational future for update VpnInterface {}: "
+                            + "{}", vpnInterfaceName, e);
+                    return null;
+                }
+                List<ListenableFuture<Void>> futures = new ArrayList<>();
                 futures.add(writeConfigTxn.submit());
                 return futures;
             });