Merge "Bug 5054:"
[vpnservice.git] / fibmanager / fibmanager-impl / src / main / java / org / opendaylight / vpnservice / fibmanager / FibManager.java
index 80500315315a38b9a18cd35d8a9d87daeb78c56e..493076af544cae7f6561f4de08980348302e584e 100644 (file)
@@ -41,6 +41,7 @@ import org.opendaylight.vpnservice.mdsalutil.MatchInfo;
 import org.opendaylight.vpnservice.mdsalutil.MetaDataUtil;
 import org.opendaylight.vpnservice.mdsalutil.NwConstants;
 import org.opendaylight.vpnservice.mdsalutil.interfaces.IMdsalApiManager;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.OpState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnInstanceOpData;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.VpnToExtraroute;
@@ -275,6 +276,7 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
 
   public BigInteger deleteLocalFibEntry(Long vpnId, String rd, VrfEntry vrfEntry) {
     BigInteger localDpnId = BigInteger.ZERO;
+    boolean isExtraRoute = false;
     VpnNexthop localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getDestPrefix());
     String localNextHopIP = vrfEntry.getDestPrefix();
 
@@ -284,13 +286,17 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
         if (extra_route != null) {
             localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, extra_route.getNexthopIp());
             localNextHopIP = extra_route.getNexthopIp() + "/32";
+            isExtraRoute = true;
         }
     }
 
 
     if(localNextHopInfo != null) {
       localDpnId = localNextHopInfo.getDpnId();
-      //if (getPrefixToInterface(vpnId, (staticRoute == true) ? extra_route.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix()) == null)
+      Prefixes prefix = getPrefixToInterface(vpnId, isExtraRoute ? localNextHopIP : vrfEntry.getDestPrefix());
+      Optional<OpState> opStateData = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+                                                            FibUtil.getVpnInterfaceOpStateIdentifier(prefix.getVpnInterfaceName()));
+      if(opStateData.isPresent() && !opStateData.get().isStateUp())
       {
         makeConnectedRoute(localDpnId, vpnId, vrfEntry, rd, null /* invalid */,
                            NwConstants.DEL_FLOW);
@@ -423,8 +429,10 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
             if (vpnInterfaces.remove(currVpnInterface)) {
                 if (vpnInterfaces.isEmpty()) {
                     //FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id);
+                  LOG.trace("cleanUpOpDataForFib: cleanUpDpnForVpn: {}, {}", dpnId, vpnId);
                     cleanUpDpnForVpn(dpnId, vpnId, rd);
                 } else {
+                  LOG.trace("cleanUpOpDataForFib: delete interface: {} on {}", intfName, dpnId);
                     FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, id.child(
                             org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data
                                     .vpn.instance.op.data.entry.vpn.to.dpn.list.VpnInterfaces.class,
@@ -452,23 +460,34 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
       if (prefixInfo == null)
           return; //Don't have any info for this prefix (shouldn't happen); need to return
       String ifName = prefixInfo.getVpnInterfaceName();
-      Optional<Adjacencies> optAdjacencies = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getAdjListPath(ifName));
-      int numAdj = 0;
-      if (optAdjacencies.isPresent()) {
+      Optional<OpState> opStateData = FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
+                                                   FibUtil.getVpnInterfaceOpStateIdentifier(ifName));
+      if(opStateData.isPresent() && !opStateData.get().isStateUp()) {
+        Optional<Adjacencies>
+            optAdjacencies =
+            FibUtil.read(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getAdjListPath(ifName));
+        int numAdj = 0;
+        if (optAdjacencies.isPresent()) {
           numAdj = optAdjacencies.get().getAdjacency().size();
-      }
-      //remove adjacency corr to prefix
-      FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL, FibUtil.getAdjacencyIdentifier(ifName, vrfEntry.getDestPrefix()));
-
-      if((numAdj - 1) == 0) { //there are no adjacencies left for this vpn interface, clean up
-        //clean up the vpn interface from DpnToVpn list
+        }
+        LOG.trace("cleanUpOpDataForFib: remove adjacency for prefix: {} {}", vpnId,
+                  vrfEntry.getDestPrefix());
+        //remove adjacency corr to prefix
+        FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+                       FibUtil.getAdjacencyIdentifier(ifName, vrfEntry.getDestPrefix()));
+
+        if ((numAdj - 1) == 0) { //there are no adjacencies left for this vpn interface, clean up
+          //clean up the vpn interface from DpnToVpn list
           delIntfFromDpnToVpnList(vpnId, prefixInfo.getDpnId(), ifName, rd);
+          LOG.trace("cleanUpOpDataForFib: Delete prefix to interface and vpnInterface ");
           FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
-                  FibUtil.getPrefixToInterfaceIdentifier(
-                          vpnId,
-                          (extra_route) ? vrfEntry.getNextHopAddress() + "/32" : vrfEntry.getDestPrefix()));
+                         FibUtil.getPrefixToInterfaceIdentifier(
+                             vpnId,
+                             (extra_route) ? vrfEntry.getNextHopAddress() + "/32"
+                                           : vrfEntry.getDestPrefix()));
           FibUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
-                  FibUtil.getVpnInterfaceIdentifier(ifName));
+                         FibUtil.getVpnInterfaceIdentifier(ifName));
+        }
       }
   }
 
@@ -500,17 +519,25 @@ public class FibManager extends AbstractDataChangeListener<VrfEntry> implements
                                 final VrfEntry vrfEntry) {
     LOG.debug("deleting route "+ vrfEntry.getDestPrefix() + " "+vpnId);
     String rd = vrfTableKey.getRouteDistinguisher();
-    String egressInterface = resolveAdjacency(localDpnId, remoteDpnId, vpnId, vrfEntry, rd);
-    if(egressInterface == null) {
-      LOG.error("Could not get nexthop group id for nexthop: {} in vpn {}",
-                vrfEntry.getNextHopAddress(), rd);
-      LOG.warn("Failed to delete Route: {} in vpn: {}",
-               vrfEntry.getDestPrefix(), rd);
-      return;
+    boolean isRemoteRoute = true;
+    if (localDpnId == null) {
+      // localDpnId is not known when clean up happens for last vm for a vpn on a dpn
+      VpnNexthop localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, vrfEntry.getDestPrefix());
+      if(localNextHopInfo == null) {
+        //Is this fib route an extra route? If yes, get the nexthop which would be an adjacency in the vpn
+        Extraroute extra_route = getVpnToExtraroute(rd, vrfEntry.getDestPrefix());
+        if (extra_route != null) {
+          localNextHopInfo = nextHopManager.getVpnNexthop(vpnId, extra_route.getNexthopIp());
+        }
+      }
+      isRemoteRoute = ((localNextHopInfo != null) && (!remoteDpnId.equals(localNextHopInfo.getDpnId())));
+    }
+    if (isRemoteRoute) {
+      makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, null, NwConstants.DEL_FLOW);
+      LOG.debug("Successfully delete fib entry for "+ vrfEntry.getDestPrefix() + " vpnId "+vpnId);
+    } else{
+      LOG.debug("Did not delete fib entry rd: {} =, prefix: {} as it is local to dpn {}", rd, vrfEntry.getDestPrefix(), remoteDpnId);
     }
-
-    makeConnectedRoute(remoteDpnId, vpnId, vrfEntry, rd, null, NwConstants.DEL_FLOW);
-    LOG.debug("Successfully delete fib entry for "+ vrfEntry.getDestPrefix() + " vpnId "+vpnId);
   }
 
   private long getIpAddress(byte[] rawIpAddress) {