TR: Local routes not appeared on deletion of VPN
[vpnservice.git] / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / vpnservice / VpnInterfaceManager.java
index 2443cb8a772d0f32d68f535e68092a6fff9eeb9b..f128faca1b5ecfa50d64cf3ba78cd0d8f4610562 100644 (file)
@@ -16,6 +16,7 @@ import com.google.common.util.concurrent.JdkFutureAdapters;
 import org.opendaylight.controller.md.sal.binding.api.*;
 import org.opendaylight.vpnservice.mdsalutil.*;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronvpnService;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.PhysAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.PrefixToInterface;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.adjacency.list.AdjacencyKey;
@@ -48,6 +49,7 @@ import java.util.concurrent.*;
 
 import com.google.common.base.Optional;
 
+import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronvpnService;
 import org.opendaylight.bgpmanager.api.IBgpManager;
 import org.opendaylight.fibmanager.api.IFibManager;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
@@ -87,6 +89,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
     private ItmRpcService itmProvider;
     private IdManagerService idManager;
     private OdlArputilService arpManager;
+    private NeutronvpnService neuService;
+    private VpnSubnetRouteHandler vpnSubnetRouteHandler;
     private InterfaceStateChangeListener interfaceListener;
     private VpnInterfaceOpListener vpnInterfaceOpListener;
     private ArpNotificationHandler arpNotificationHandler;
@@ -107,6 +111,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         vpnInterfaceOpListener = new VpnInterfaceOpListener();
         arpNotificationHandler = new ArpNotificationHandler(this, broker);
         notificationService.registerNotificationListener(arpNotificationHandler);
+        vpnSubnetRouteHandler = new VpnSubnetRouteHandler(broker, bgpManager, this);
+        notificationService.registerNotificationListener(vpnSubnetRouteHandler);
         registerListener(db);
     }
 
@@ -129,12 +135,19 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
 
     public void setIdManager(IdManagerService idManager) {
         this.idManager = idManager;
+        vpnSubnetRouteHandler.setIdManager(idManager);
     }
 
     public void setArpManager(OdlArputilService arpManager) {
         this.arpManager = arpManager;
     }
 
+    public void setNeutronvpnManager(NeutronvpnService neuService) { this.neuService = neuService; }
+
+    public VpnSubnetRouteHandler getVpnSubnetRouteHandler() {
+        return this.vpnSubnetRouteHandler;
+    }
+
     @Override
     public void close() throws Exception {
         if (listenerRegistration != null) {
@@ -249,6 +262,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                           InterfaceUtils.buildServiceId(vpnInterfaceName, VpnConstants.L3VPN_SERVICE_IDENTIFIER), serviceInfo);
         makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
                     vpnId, ArpReplyOrRequest.REQUEST, NwConstants.ADD_FLOW);
+        makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
+                vpnId, ArpReplyOrRequest.REPLY, NwConstants.ADD_FLOW);
 
     }
 
@@ -287,6 +302,15 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                                 VpnUtil.getPrefixToInterfaceIdentifier(
                                         VpnUtil.getVpnId(broker, intf.getVpnInstanceName()), prefix),
                                 VpnUtil.getPrefixToInterface(dpnId, intf.getName(), prefix));
+                    } else {
+                        //Extra route adjacency
+                        VpnUtil.syncUpdate(
+                                broker,
+                                LogicalDatastoreType.OPERATIONAL,
+                                VpnUtil.getVpnToExtrarouteIdentifier(
+                                        (rd != null) ? rd : intf.getVpnInstanceName(), nextHop.getIpAddress()),
+                                VpnUtil.getVpnToExtraroute(nextHop.getIpAddress(), nextHop.getNextHopIp()));
+
                     }
                 }
 
@@ -296,14 +320,14 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                 VpnUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, interfaceId, opInterface);
                 for (Adjacency nextHop : aug.getAdjacency()) {
                     long label = nextHop.getLabel();
-                    String adjNextHop = nextHop.getNextHopIp();
+                    //String adjNextHop = nextHop.getNextHopIp();
                     if (rd != null) {
                         addPrefixToBGP(rd, nextHop.getIpAddress(),
-                                            (adjNextHop != null && !adjNextHop.isEmpty()) ? adjNextHop : nextHopIp, label);
+                                            nextHopIp, label);
                     } else {
                         // ### add FIB route directly
                         addFibEntryToDS(intf.getVpnInstanceName(), nextHop.getIpAddress(),
-                                            (adjNextHop != null && !adjNextHop.isEmpty()) ? adjNextHop : nextHopIp, (int) label);
+                                            nextHopIp, (int) label);
                     }
                 }
             }
@@ -475,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) {
                     }
                 }
@@ -490,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();
 
@@ -527,6 +553,8 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         long vpnId = VpnUtil.getVpnId(broker, vpnInstanceName);
         makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
                     vpnId, ArpReplyOrRequest.REQUEST, NwConstants.DEL_FLOW);
+        makeArpFlow(dpId, VpnConstants.L3VPN_SERVICE_IDENTIFIER, lPortTag, vpnInterfaceName,
+                vpnId, ArpReplyOrRequest.REPLY, NwConstants.DEL_FLOW);
     }
 
 
@@ -740,12 +768,11 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                 (rd != null) ? rd : routerID, destination),
             VpnUtil.getVpnToExtraroute(destination, nextHop));
 
-        if(intfName != null && !intfName.isEmpty()) {
+        if (intfName != null && !intfName.isEmpty()) {
             BigInteger dpnId = InterfaceUtils.getDpnForInterface(interfaceManager, intfName);
             String nextHopIp = InterfaceUtils.getEndpointIpAddressForDPN(broker, dpnId);
-            if (nextHopIp == null && !nextHopIp.isEmpty()) {
-                LOG.error("NextHop for interface {} is null. Adding extra route {} without nextHop", intfName,
-                        destination);
+            if (nextHopIp == null || nextHopIp.isEmpty()) {
+                LOG.warn("NextHop for interface {} is null / empty. Failed advertising extra route for prefix {}", intfName, destination);
             }
             nextHop = nextHopIp;
         }
@@ -776,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);
         }