Merge "Natservice module bug fixes"
[vpnservice.git] / vpnmanager / vpnmanager-impl / src / main / java / org / opendaylight / vpnservice / VpnInterfaceManager.java
index 2a9a96138aa8c6a3fb5689531fa7fe1f81452fa8..469b0e33a6c6c9f84d035cc78ba647acd77c359e 100644 (file)
@@ -16,11 +16,21 @@ 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.l3vpn.rev130911.NeutronRouterDpns;
 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;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.RouterDpnList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.RouterDpnListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.RouterDpnListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.DpnVpninterfacesListKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfaces;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.neutron.router.dpns.router.dpn.list.dpn.vpninterfaces.list.RouterInterfacesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListBuilder;
@@ -352,7 +362,7 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         List<InstructionInfo> instructions = new ArrayList<InstructionInfo>();
         List<ActionInfo> actionsInfos = new ArrayList<ActionInfo>();
         actionsInfos.add(new ActionInfo(ActionType.punt_to_controller, new String[] {}));
-        instructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+        instructions.add(new InstructionInfo(InstructionType.apply_actions, actionsInfos));
 
         // Install the flow entry in L3_INTERFACE_TABLE
         String flowRef = VpnUtil.getFlowRef(dpId, NwConstants.L3_INTERFACE_TABLE,
@@ -499,7 +509,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,15 +524,18 @@ 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();
 
             if (!nextHops.isEmpty()) {
                 LOG.trace("NextHops are " + nextHops);
                 for (Adjacency nextHop : nextHops) {
-                    VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME,
+                    // Commenting the release of ID here as it will be released by FIB
+                   /* VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME,
                                       VpnUtil.getNextHopLabelKey(rd, nextHop.getIpAddress()));
-                    /*VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
+                    VpnUtil.delete(broker, LogicalDatastoreType.OPERATIONAL,
                                    VpnUtil.getPrefixToInterfaceIdentifier(
                                        VpnUtil.getVpnId(broker, intf.getVpnInstanceName()),
                                        nextHop.getIpAddress()),
@@ -734,8 +747,9 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
                     while (adjIt.hasNext()) {
                         Adjacency adjElem = adjIt.next();
                         if (adjElem.getIpAddress().equals(adj.getIpAddress())) {
-                            VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME,
-                                    VpnUtil.getNextHopLabelKey(rd, adj.getIpAddress()));
+                            // Commenting the release of ID here as it will be released by FIB
+                           /* VpnUtil.releaseId(idManager, VpnConstants.VPN_IDPOOL_NAME,
+                                    VpnUtil.getNextHopLabelKey(rd, adj.getIpAddress()));*/
                             adjIt.remove();
 
                             Adjacencies aug = VpnUtil.getVpnInterfaceAugmentation(adjacencies);
@@ -801,42 +815,56 @@ 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();
-
-            //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);
+            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) {
+                    // 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);
+                    }
+                    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);
+                    }
+                }
+            } else {
+                LOG.error("rd not retrievable as vpninstancetovpnid for vpn {} is absent, trying rd as ", vpnName, vpnName);
             }
             notifyTaskIfRequired(interfaceName);
         }
@@ -948,4 +976,91 @@ public class VpnInterfaceManager extends AbstractDataChangeListener<VpnInterface
         }
     }
 
+       InstanceIdentifier<DpnVpninterfacesList> getRouterDpnId(String routerName, BigInteger dpnId) {
+        return InstanceIdentifier.builder(NeutronRouterDpns.class)
+            .child(RouterDpnList.class, new RouterDpnListKey(routerName))
+            .child(DpnVpninterfacesList.class, new DpnVpninterfacesListKey(dpnId)).build();
+    }
+
+    InstanceIdentifier<RouterDpnList> getRouterId(String routerName) {
+        return InstanceIdentifier.builder(NeutronRouterDpns.class)
+            .child(RouterDpnList.class, new RouterDpnListKey(routerName)).build();
+    }
+
+    protected void addToNeutronRouterDpnsMap(String routerName, String vpnInterfaceName) {
+        BigInteger dpId = InterfaceUtils.getDpnForInterface(interfaceManager, vpnInterfaceName);
+        if(dpId.equals(BigInteger.ZERO)) {
+            LOG.warn("Could not retrieve dp id for interface {} to handle router {} association model", vpnInterfaceName, routerName);
+            return;
+        }
+        InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
+
+        Optional<DpnVpninterfacesList> optionalRouterDpnList = VpnUtil.read(broker, LogicalDatastoreType
+                .CONFIGURATION, routerDpnListIdentifier);
+        RouterInterfaces routerInterface = new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName)).setInterface(vpnInterfaceName).build();
+        if (optionalRouterDpnList.isPresent()) {
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, routerDpnListIdentifier.child(
+                    RouterInterfaces.class,  new RouterInterfacesKey(vpnInterfaceName)), routerInterface);
+        } else {
+            MDSALUtil.syncUpdate(broker, LogicalDatastoreType.CONFIGURATION,
+                    getRouterId(routerName),
+                    new RouterDpnListBuilder().setRouterId(routerName).build());
+            //VpnToDpnListBuilder vpnToDpnList = new VpnToDpnListBuilder().setDpnId(dpnId);
+            DpnVpninterfacesListBuilder dpnVpnList = new DpnVpninterfacesListBuilder().setDpnId(dpId);
+            List<RouterInterfaces> routerInterfaces =  new ArrayList<>();
+            routerInterfaces.add(routerInterface);
+            MDSALUtil.syncWrite(broker, LogicalDatastoreType.CONFIGURATION, routerDpnListIdentifier,
+                    dpnVpnList.setRouterInterfaces(routerInterfaces).build());
+        }
+    }
+
+    protected void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName) {
+        BigInteger dpId = InterfaceUtils.getDpnForInterface(interfaceManager, vpnInterfaceName);
+        if(dpId.equals(BigInteger.ZERO)) {
+            LOG.warn("Could not retrieve dp id for interface {} to handle router {} dissociation model", vpnInterfaceName, routerName);
+            return;
+        }
+        InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
+        Optional<DpnVpninterfacesList> optionalRouterDpnList = VpnUtil.read(broker, LogicalDatastoreType
+                .CONFIGURATION, routerDpnListIdentifier);
+        if (optionalRouterDpnList.isPresent()) {
+            List<RouterInterfaces> routerInterfaces = optionalRouterDpnList.get().getRouterInterfaces();
+            RouterInterfaces routerInterface = new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName)).setInterface(vpnInterfaceName).build();
+
+            if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
+                if (routerInterfaces.isEmpty()) {
+                    MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, routerDpnListIdentifier);
+                } else {
+                    MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, routerDpnListIdentifier.child(
+                            RouterInterfaces.class,
+                            new RouterInterfacesKey(vpnInterfaceName)));
+                }
+            }
+        }
+    }
+       
+       protected void removeFromNeutronRouterDpnsMap(String routerName, String vpnInterfaceName,BigInteger dpId) {
+        if(dpId.equals(BigInteger.ZERO)) {
+            LOG.warn("Could not retrieve dp id for interface {} to handle router {} dissociation model", vpnInterfaceName, routerName);
+            return;
+        }
+        InstanceIdentifier<DpnVpninterfacesList> routerDpnListIdentifier = getRouterDpnId(routerName, dpId);
+        Optional<DpnVpninterfacesList> optionalRouterDpnList = VpnUtil.read(broker, LogicalDatastoreType
+                .CONFIGURATION, routerDpnListIdentifier);
+        if (optionalRouterDpnList.isPresent()) {
+            List<RouterInterfaces> routerInterfaces = optionalRouterDpnList.get().getRouterInterfaces();
+            RouterInterfaces routerInterface = new RouterInterfacesBuilder().setKey(new RouterInterfacesKey(vpnInterfaceName)).setInterface(vpnInterfaceName).build();
+
+            if (routerInterfaces != null && routerInterfaces.remove(routerInterface)) {
+                if (routerInterfaces.isEmpty()) {
+                    MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, routerDpnListIdentifier);
+                } else {
+                    MDSALUtil.syncDelete(broker, LogicalDatastoreType.CONFIGURATION, routerDpnListIdentifier.child(
+                            RouterInterfaces.class,
+                            new RouterInterfacesKey(vpnInterfaceName)));
+                }
+            }
+        }
+    }
+
 }