Traffic drop b/w DC-GW and VM
[netvirt.git] / fibmanager / impl / src / main / java / org / opendaylight / netvirt / fibmanager / VrfEntryListener.java
index 1196915cd2b32021764c59eb8fe467d3db6ce301..a85972866d678d4ec3fd9657a81fe89ee67e4883 100755 (executable)
@@ -326,11 +326,15 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
             //Update the used rds and vpntoextraroute containers only for the deleted nextHops.
             List<String> nextHopsRemoved = FibHelper.getNextHopListFromRoutePaths(original);
             nextHopsRemoved.removeAll(FibHelper.getNextHopListFromRoutePaths(update));
-            ListenableFuture<Void> future =
-                    txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> nextHopsRemoved.parallelStream()
-                            .forEach(nextHopRemoved -> fibUtil.updateUsedRdAndVpnToExtraRoute(
-                                    tx, nextHopRemoved, rd, update.getDestPrefix())));
-            Futures.addCallback(future, new FutureCallback<Void>() {
+            List<ListenableFuture<Void>> futures = new ArrayList<>();
+            ListenableFuture<Void> configFuture =
+                    txRunner.callWithNewWriteOnlyTransactionAndSubmit(configTx ->
+                            futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(operTx ->
+                                    nextHopsRemoved.parallelStream()
+                                            .forEach(nextHopRemoved -> fibUtil.updateUsedRdAndVpnToExtraRoute(
+                                                    configTx, operTx, nextHopRemoved, rd, update.getDestPrefix())))));
+            futures.add(configFuture);
+            Futures.addCallback(configFuture, new FutureCallback<Void>() {
                 @Override
                 public void onSuccess(Void result) {
                     createFibEntries(identifier, update);
@@ -736,6 +740,10 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
             List<String> usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker, vpnId, localNextHopIP);
             List<Routes> vpnExtraRoutes = VpnExtraRouteHelper.getAllVpnExtraRoutes(dataBroker,
                     vpnName, usedRds, localNextHopIP);
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Creating Local fib entry with vpnName {} usedRds {} localNextHopIP {} vpnExtraRoutes {}",
+                        vpnName, usedRds, localNextHopIP, vpnExtraRoutes);
+            }
             boolean localNextHopSeen = false;
             //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn
             for (Routes vpnExtraRoute : vpnExtraRoutes) {
@@ -832,7 +840,6 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                         vpnId, rd, dpnId.toString());
                 return BigInteger.ZERO;
             }
-            String jobKey = FibUtil.getCreateLocalNextHopJobKey(vpnId, dpnId, vrfEntry.getDestPrefix());
             String interfaceName = localNextHopInfo.getVpnInterfaceName();
             String prefix = vrfEntry.getDestPrefix();
             String gwMacAddress = vrfEntry.getGatewayMacAddress();
@@ -845,21 +852,19 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                     localNextHopIP = routes.getNexthopIpList().get(0) + NwConstants.IPV6PREFIX;
                 }
                 if (vpnExtraRoutes.size() > 1) {
-                    groupId = nextHopManager.createNextHopGroups(vpnId, rd, dpnId, vrfEntry, routes,
-                            vpnExtraRoutes);
+                    groupId = nextHopManager.createNextHopGroups(vpnId, rd, dpnId, vrfEntry, routes, vpnExtraRoutes);
                     localGroupId = nextHopManager.getLocalNextHopGroup(vpnId, localNextHopIP);
                 } else if (routes.getNexthopIpList().size() > 1) {
-                    groupId = nextHopManager.createNextHopGroups(vpnId, rd, dpnId, vrfEntry, routes,
-                            vpnExtraRoutes);
+                    groupId = nextHopManager.createNextHopGroups(vpnId, rd, dpnId, vrfEntry, routes, vpnExtraRoutes);
                     localGroupId = groupId;
                 } else {
                     groupId = nextHopManager.createLocalNextHop(vpnId, dpnId, interfaceName, localNextHopIP,
-                            prefix, gwMacAddress, jobKey);
+                            prefix, gwMacAddress);
                     localGroupId = groupId;
                 }
             } else {
                 groupId = nextHopManager.createLocalNextHop(vpnId, dpnId, interfaceName, localNextHopIP, prefix,
-                        gwMacAddress, jobKey);
+                        gwMacAddress);
                 localGroupId = groupId;
             }
             if (groupId == FibConstants.INVALID_GROUP_ID) {
@@ -875,12 +880,12 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                             Arrays.asList(new ActionPopMpls(etherType), new ActionGroup(groupId))));
             java.util.Optional<Long> optLabel = FibUtil.getLabelFromRoutePaths(vrfEntry);
             List<String> nextHopAddressList = FibHelper.getNextHopListFromRoutePaths(vrfEntry);
+            String jobKey = FibUtil.getCreateLocalNextHopJobKey(vpnId, dpnId, vrfEntry.getDestPrefix());
             jobCoordinator.enqueueJob(jobKey, () -> {
                 return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
                     baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, instructions,
                             NwConstants.ADD_FLOW, tx, null);
-                    if (!fibUtil.enforceVxlanDatapathSemanticsforInternalRouterVpn(localNextHopInfo.getSubnetId(),
-                            vpnName, rd)) {
+                    if (FibUtil.isBgpVpn(vpnName, rd)) {
                         optLabel.ifPresent(label -> {
                             if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.SELF_IMPORTED) {
                                 LOG.debug(
@@ -1060,8 +1065,8 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                 localNextHopInfo = fibUtil.getPrefixToInterface(vpnId, ipPrefix);
                 if (localNextHopInfo != null) {
                     String localNextHopIP = localNextHopInfo.getIpAddress();
-                    BigInteger dpnId = checkDeleteLocalFibEntry(localNextHopInfo, localNextHopIP,
-                            vpnId, rd, vrfEntry, shouldUpdateNonEcmpLocalNextHop);
+                    BigInteger dpnId = checkDeleteLocalFibEntry(localNextHopInfo, localNextHopIP, vpnName, vpnId, rd,
+                            vrfEntry, shouldUpdateNonEcmpLocalNextHop);
                     if (!dpnId.equals(BigInteger.ZERO)) {
                         LOG.trace("Deleting ECMP group for prefix {}, dpn {}", vrfEntry.getDestPrefix(), dpnId);
                         nextHopManager.setupLoadBalancingNextHop(vpnId, dpnId,
@@ -1086,7 +1091,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                         PrefixesBuilder prefixBuilder = new PrefixesBuilder();
                         prefixBuilder.setDpnId(lri.getDpnId());
                         BigInteger dpnId = checkDeleteLocalFibEntry(prefixBuilder.build(), nextHopAddressList.get(0),
-                                vpnId, rd, vrfEntry, shouldUpdateNonEcmpLocalNextHop);
+                                vpnName, vpnId, rd, vrfEntry, shouldUpdateNonEcmpLocalNextHop);
                         if (!dpnId.equals(BigInteger.ZERO)) {
                             returnLocalDpnId.add(dpnId);
                         }
@@ -1097,8 +1102,8 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
         } else {
             LOG.debug("Obtained prefix to interface for rd {} prefix {}", rd, vrfEntry.getDestPrefix());
             String localNextHopIP = localNextHopInfo.getIpAddress();
-            BigInteger dpnId = checkDeleteLocalFibEntry(localNextHopInfo, localNextHopIP,
-                vpnId, rd, vrfEntry, shouldUpdateNonEcmpLocalNextHop);
+            BigInteger dpnId = checkDeleteLocalFibEntry(localNextHopInfo, localNextHopIP, vpnName, vpnId, rd, vrfEntry,
+                    shouldUpdateNonEcmpLocalNextHop);
             if (!dpnId.equals(BigInteger.ZERO)) {
                 returnLocalDpnId.add(dpnId);
             }
@@ -1108,8 +1113,8 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
     }
 
     private BigInteger checkDeleteLocalFibEntry(Prefixes localNextHopInfo, final String localNextHopIP,
-                                                final Long vpnId, final String rd, final VrfEntry vrfEntry,
-                                                boolean shouldUpdateNonEcmpLocalNextHop) {
+            final String vpnName, final Long vpnId, final String rd, final VrfEntry vrfEntry,
+            boolean shouldUpdateNonEcmpLocalNextHop) {
         if (localNextHopInfo != null) {
             final BigInteger dpnId = localNextHopInfo.getDpnId();
             if (Prefixes.PrefixCue.Nat.equals(localNextHopInfo.getPrefixCue())) {
@@ -1127,8 +1132,7 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                 () -> Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
                     baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, null,
                             NwConstants.DEL_FLOW, tx, null);
-                    if (!fibUtil.enforceVxlanDatapathSemanticsforInternalRouterVpn(localNextHopInfo.getSubnetId(),
-                            vpnId, rd)) {
+                    if (FibUtil.isBgpVpn(vpnName, rd)) {
                         if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.SELF_IMPORTED) {
                             FibUtil.getLabelFromRoutePaths(vrfEntry).ifPresent(label -> {
                                 makeLFibTableEntry(dpnId, label, null /* instructions */, DEFAULT_FIB_FLOW_PRIORITY,
@@ -1785,10 +1789,12 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                 if (vrfTable.isPresent()) {
                     synchronized (vpnInstance.getVpnInstanceName().intern()) {
                         futures.add(retryingTxRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
+                            String vpnName = fibUtil.getVpnNameFromId(vpnInstance.getVpnId());
                             for (final VrfEntry vrfEntry : vrfTable.get().getVrfEntry()) {
                                 /* Handle subnet routes here */
                                 SubnetRoute subnetRoute = vrfEntry.augmentation(SubnetRoute.class);
-                                if (subnetRoute != null) {
+                                if (subnetRoute != null && !fibUtil
+                                        .isInterfacePresentInDpn(vrfEntry.getParentVpnRd(), dpnId)) {
                                     LOG.trace("SUBNETROUTE: cleanUpDpnForVpn: Cleaning subnetroute {} on dpn {}"
                                             + " for vpn {}", vrfEntry.getDestPrefix(), dpnId, rd);
                                     baseVrfEntryHandler.makeConnectedRoute(dpnId, vpnId, vrfEntry, rd, null,
@@ -1837,7 +1843,6 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                                 // to which prefix is attached at this point
                                 List<String> usedRds = VpnExtraRouteHelper.getUsedRds(dataBroker,
                                         vpnInstance.getVpnId(), vrfEntry.getDestPrefix());
-                                String vpnName = fibUtil.getVpnNameFromId(vpnInstance.getVpnId());
                                 Optional<Routes> extraRouteOptional;
                                 //Is this fib route an extra route? If yes, get the nexthop which would be
                                 //an adjacency in the vpn
@@ -1857,8 +1862,11 @@ public class VrfEntryListener extends AsyncDataTreeChangeListenerBase<VrfEntry,
                                     bgpRouteVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId,
                                             vrfTable.get().key(), vrfEntry, extraRouteOptional, tx, txnObjects);
                                 } else {
-                                    baseVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId, vrfTable.get().key(),
-                                            vrfEntry, extraRouteOptional, tx);
+                                    if (subnetRoute == null || !fibUtil
+                                            .isInterfacePresentInDpn(vrfEntry.getParentVpnRd(), dpnId)) {
+                                        baseVrfEntryHandler.deleteRemoteRoute(null, dpnId, vpnId,
+                                                vrfTable.get().key(), vrfEntry, extraRouteOptional, tx);
+                                    }
                                 }
                             }
                         }));