Fixes stale fib flows for the g/w and PNF 95/71495/42
authorAswin Suryanarayanan <asuryana@redhat.com>
Fri, 27 Apr 2018 04:28:27 +0000 (09:58 +0530)
committerSridhar Gaddam <sgaddam@redhat.com>
Thu, 28 Jun 2018 05:04:10 +0000 (05:04 +0000)
The mip adjacency in the external interface and LearntVpnVipToPortData
for  external n/w is removed when the last external router is deleted.

This removes the stale flows in table21 and 51 and OLFE in vrfTables
update.

NETVIRT-1157 Stale flows after clearing gateway info from a router.

Change-Id: I3c8db31b64beb123c21fab305cc457154e7d1c57
Signed-off-by: Aswin Suryanarayanan <asuryana@redhat.com>
fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/FibUtil.java
fibmanager/impl/src/main/java/org/opendaylight/netvirt/fibmanager/VrfEntryListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/ha/NatDataUtil.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/AbstractSnatService.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/ConntrackBasedSnatService.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/FlatVlanConntrackBasedSnatService.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/SnatServiceImplFactory.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/VxlanGreConntrackBasedSnatService.java
vpnmanager/impl/src/main/java/org/opendaylight/netvirt/vpnmanager/VpnInterfaceManager.java

index 3d9f75ecf4c8e900feabf438a881adf52c8cde34..4e63fa8f9e0d375dc025a640e5ee643ce5809b6f 100644 (file)
@@ -26,6 +26,8 @@ import javax.inject.Singleton;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.mdsalutil.BucketInfo;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
@@ -100,6 +102,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.id.to.vpn.instance.VpnIdsKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntryKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnList;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.vpn.instance.op.data.entry.VpnToDpnListKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id.VpnInstance;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.to.extraroutes.vpn.extra.routes.Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkAttributes;
@@ -870,4 +874,21 @@ public class FibUtil {
             LOG.error("unlockCluster: Unable to unlock {}", lockName, e);
         }
     }
+
+    public boolean isInterfacePresentInDpn(String vpnName, BigInteger dpnId) {
+        InstanceIdentifier<VpnToDpnList> vpnToDpnListId = InstanceIdentifier.builder(VpnInstanceOpData.class)
+                .child(VpnInstanceOpDataEntry.class, new VpnInstanceOpDataEntryKey(vpnName))
+                .child(VpnToDpnList.class, new VpnToDpnListKey(dpnId)).build();
+        try {
+            VpnToDpnList vpnToDpnList = SingleTransactionDataBroker.syncRead(dataBroker,
+                    LogicalDatastoreType.OPERATIONAL, vpnToDpnListId);
+            if (!(vpnToDpnList == null) && !(vpnToDpnList.getVpnInterfaces() == null)
+                    && !vpnToDpnList.getVpnInterfaces().isEmpty()) {
+                return true;
+            }
+        } catch (ReadFailedException e) {
+            LOG.warn("Failed to read interfaces with error {}", e.getMessage());
+        }
+        return false;
+    }
 }
index 1196915cd2b32021764c59eb8fe467d3db6ce301..7465a861b22ffaac323fd2f08a97bf821bd77c49 100755 (executable)
@@ -1785,10 +1785,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 +1839,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 +1858,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);
+                                    }
                                 }
                             }
                         }));
index f638f7bec8d2cf3e93bc2a8a730da5eb1f8892b9..49a4def03b559f4a60cf07395c387923e06ef949 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.netvirt.natservice.ha;
 
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import javax.inject.Singleton;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
@@ -33,4 +34,8 @@ public class NatDataUtil {
     public Routers getRouter(String routerId) {
         return routerMap.get(routerId);
     }
+
+    public Set<Map.Entry<String,Routers>> getAllRouters() {
+        return routerMap.entrySet();
+    }
 }
index 6e6512eaf7a0024dbd4926920dc4b81f83dd3f78..8803804cdfd0609dc60a665eefc6b2bb3ef6d4e9 100644 (file)
@@ -14,6 +14,10 @@ import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
+import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
 import org.opendaylight.genius.mdsalutil.BucketInfo;
@@ -40,7 +44,12 @@ import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
 import org.opendaylight.netvirt.natservice.api.SnatServiceListener;
+import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfacesBuilder;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
+import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceBuilder;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.AllocateIdInputBuilder;
@@ -55,9 +64,16 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.G
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.rpcs.rev160406.ItmRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.Adjacencies;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.AdjacenciesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortData;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.LearntVpnVipToPortDataBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.adjacency.list.Adjacency;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.learnt.vpn.vip.to.port.data.LearntVpnVipToPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.prefix.to._interface.vpn.ids.Prefixes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.routers.ExternalIps;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -78,13 +94,14 @@ public abstract class AbstractSnatService implements SnatServiceListener {
     protected final IInterfaceManager interfaceManager;
     protected final IVpnFootprintService vpnFootprintService;
     protected final IFibManager fibManager;
+    protected final NatDataUtil natDataUtil;
 
     protected AbstractSnatService(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
                                   final ItmRpcService itmManager, final OdlInterfaceRpcService odlInterfaceRpcService,
                                   final IdManagerService idManager, final NAPTSwitchSelector naptSwitchSelector,
                                   final IInterfaceManager interfaceManager,
                                   final IVpnFootprintService vpnFootprintService,
-                                  final IFibManager fibManager) {
+                                  final IFibManager fibManager, final NatDataUtil natDataUtil) {
         this.dataBroker = dataBroker;
         this.mdsalManager = mdsalManager;
         this.itmManager = itmManager;
@@ -94,6 +111,7 @@ public abstract class AbstractSnatService implements SnatServiceListener {
         this.odlInterfaceRpcService = odlInterfaceRpcService;
         this.vpnFootprintService = vpnFootprintService;
         this.fibManager = fibManager;
+        this.natDataUtil = natDataUtil;
     }
 
     protected DataBroker getDataBroker() {
@@ -110,20 +128,30 @@ public abstract class AbstractSnatService implements SnatServiceListener {
 
     @Override
     public boolean handleSnatAllSwitch(Routers routers, BigInteger primarySwitchId,  int addOrRemove) {
-        LOG.debug("handleSnatAllSwitch : Handle Snat in all switches");
+        LOG.info("handleSnatAllSwitch : Handle Snat in all switches for router {}", routers.getRouterName());
         String routerName = routers.getRouterName();
         List<BigInteger> switches = naptSwitchSelector.getDpnsForVpn(routerName);
         /*
          * Primary switch handled separately since the pseudo port created may
          * not be present in the switch list on delete.
          */
+        boolean isLastRouterDelete = false;
+        if (addOrRemove == NwConstants.DEL_FLOW) {
+            isLastRouterDelete = NatUtil.isLastExternalRouter(routers.getNetworkId()
+                .getValue(), routers.getRouterName(), natDataUtil);
+            LOG.info("handleSnatAllSwitch : action is delete for router {} and isLastRouterDelete is {}",
+                    routers.getRouterName(), isLastRouterDelete);
+        }
         handleSnat(routers, primarySwitchId, primarySwitchId, addOrRemove);
         for (BigInteger dpnId : switches) {
             if (primarySwitchId != dpnId) {
                 handleSnat(routers, primarySwitchId, dpnId, addOrRemove);
             }
         }
-
+        if (isLastRouterDelete) {
+            removeLearntIpPorts(routers);
+            removeMipAdjacencies(routers);
+        }
         return true;
     }
 
@@ -132,11 +160,11 @@ public abstract class AbstractSnatService implements SnatServiceListener {
 
         // Handle non NAPT switches and NAPT switches separately
         if (!dpnId.equals(primarySwitchId)) {
-            LOG.debug("handleSnat : Handle non NAPT switch {}", dpnId);
+            LOG.info("handleSnat : Handle non NAPT switch {} for router {}", dpnId, routers.getRouterName());
             installSnatCommonEntriesForNonNaptSwitch(routers, primarySwitchId, dpnId, addOrRemove);
             installSnatSpecificEntriesForNonNaptSwitch(routers, dpnId, addOrRemove);
         } else {
-            LOG.debug("handleSnat : Handle NAPT switch {}", dpnId);
+            LOG.info("handleSnat : Handle NAPT switch {} for router {}", dpnId, routers.getRouterName());
             installSnatCommonEntriesForNaptSwitch(routers, dpnId, addOrRemove);
             installSnatSpecificEntriesForNaptSwitch(routers, dpnId, addOrRemove);
 
@@ -383,6 +411,99 @@ public abstract class AbstractSnatService implements SnatServiceListener {
         return null;
     }
 
+    protected void removeMipAdjacencies(Routers routers) {
+        LOG.info("removeMipAdjacencies for router {}", routers.getRouterName());
+        String externalSubNetId  = null;
+        for (ExternalIps externalIp : routers.getExternalIps()) {
+            if (!NWUtil.isIpv4Address(externalIp.getIpAddress())) {
+                // In this class we handle only IPv4 use-cases.
+                continue;
+            }
+            externalSubNetId = externalIp.getSubnetId().getValue();
+            break;
+        }
+        if (externalSubNetId == null) {
+            LOG.info("removeMipAdjacencies no external Ipv4 address present on router {}",
+                    routers.getRouterName());
+            return;
+        }
+        InstanceIdentifier<VpnInterfaces> vpnInterfacesId =
+                InstanceIdentifier.builder(VpnInterfaces.class).build();
+        try {
+            VpnInterfaces vpnInterfaces = SingleTransactionDataBroker.syncRead(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, vpnInterfacesId);
+            List<VpnInterface> updatedVpnInterface = new ArrayList<>();
+            for (VpnInterface vpnInterface : vpnInterfaces.getVpnInterface()) {
+                List<Adjacency> updatedAdjacencies = new ArrayList<>();
+                Adjacencies adjacencies = vpnInterface.augmentation(Adjacencies.class);
+                if (null != adjacencies) {
+                    for (Adjacency adjacency : adjacencies.getAdjacency()) {
+                        if (!adjacency.getSubnetId().getValue().equals(externalSubNetId)) {
+                            updatedAdjacencies.add(adjacency);
+                        }
+                    }
+                }
+                AdjacenciesBuilder adjacenciesBuilder = new AdjacenciesBuilder();
+                adjacenciesBuilder.setAdjacency(updatedAdjacencies);
+                VpnInterfaceBuilder vpnInterfaceBuilder = new VpnInterfaceBuilder(vpnInterface);
+                vpnInterfaceBuilder.addAugmentation(Adjacencies.class, adjacenciesBuilder.build());
+                updatedVpnInterface.add(vpnInterfaceBuilder.build());
+            }
+            VpnInterfacesBuilder vpnInterfacesBuilder = new VpnInterfacesBuilder();
+            vpnInterfacesBuilder.setVpnInterface(updatedVpnInterface);
+
+            SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    vpnInterfacesId, vpnInterfacesBuilder.build());
+        } catch (ReadFailedException e) {
+            LOG.warn("Failed to read removeMipAdjacencies with error {}", e.getMessage());
+        } catch (TransactionCommitFailedException e) {
+            LOG.warn("Failed to remove removeMipAdjacencies with error {}", e.getMessage());
+        }
+    }
+
+    private void removeLearntIpPorts(Routers routers) {
+        LOG.info("removeLearntIpPorts for router {} and network {}", routers.getRouterName(), routers.getNetworkId());
+        String networkId = routers.getNetworkId().getValue();
+        LearntVpnVipToPortData learntVpnVipToPortData = NatUtil.getLearntVpnVipToPortData(dataBroker);
+        LearntVpnVipToPortDataBuilder learntVpnVipToPortDataBuilder = new LearntVpnVipToPortDataBuilder();
+        List<LearntVpnVipToPort> learntVpnVipToPortList = new ArrayList<>();
+        for (LearntVpnVipToPort learntVpnVipToPort : learntVpnVipToPortData.getLearntVpnVipToPort()) {
+            if (!learntVpnVipToPort.getVpnName().equals(networkId)) {
+                LOG.info("The learned port belongs to Vpn {} hence not removing", learntVpnVipToPort.getVpnName());
+                learntVpnVipToPortList.add(learntVpnVipToPort);
+            } else {
+                String externalSubNetId = null;
+                for (ExternalIps externalIp : routers.getExternalIps()) {
+                    if (!NWUtil.isIpv4Address(externalIp.getIpAddress())) {
+                        // In this class we handle only IPv4 use-cases.
+                        continue;
+                    }
+                    externalSubNetId = externalIp.getSubnetId().getValue();
+                    break;
+                }
+                if (externalSubNetId == null) {
+                    LOG.info("removeLearntIpPorts no external Ipv4 address present on router {}",
+                            routers.getRouterName());
+                    return;
+                }
+                String prefix = learntVpnVipToPort.getPortFixedip() + "/32";
+                NatUtil.deletePrefixToInterface(dataBroker, NatUtil.getVpnId(dataBroker,
+                        externalSubNetId), prefix);
+            }
+        }
+
+        try {
+            learntVpnVipToPortDataBuilder.setLearntVpnVipToPort(learntVpnVipToPortList);
+            InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = NatUtil
+                    .getLearntVpnVipToPortDataId();
+            SingleTransactionDataBroker.syncWrite(dataBroker, LogicalDatastoreType.OPERATIONAL,
+                    learntVpnVipToPortDataId, learntVpnVipToPortDataBuilder.build());
+
+        } catch (TransactionCommitFailedException e) {
+            LOG.warn("Failed to remove removeLearntIpPorts with error {}", e.getMessage());
+        }
+    }
+
     static int mostSignificantBit(int value) {
         return 31 - Integer.numberOfLeadingZeros(value);
     }
index 4fa177f4c74f291c9ba0e8b1612b44e50d5bf4f1..2461716fdff73006942650af889d34f06a5ff648 100644 (file)
@@ -35,6 +35,7 @@ import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
 import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
+import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
@@ -64,9 +65,9 @@ public abstract class ConntrackBasedSnatService extends AbstractSnatService {
                                      IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
                                      OdlInterfaceRpcService odlInterfaceRpcService,
                                      IInterfaceManager interfaceManager, IVpnFootprintService vpnFootprintService,
-                                     IFibManager fibManager) {
+                                     IFibManager fibManager, NatDataUtil natDataUtil) {
         super(dataBroker, mdsalManager, itmManager, odlInterfaceRpcService, idManager, naptSwitchSelector,
-                interfaceManager, vpnFootprintService, fibManager);
+                interfaceManager, vpnFootprintService, fibManager, natDataUtil);
     }
 
     @Override
index e38d9d106b495ebadd9fbe8a362f25033b226926..3c974f4651d511ccbbf58f6035c88e6b9dc55db6 100644 (file)
@@ -13,6 +13,7 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
+import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
@@ -31,9 +32,10 @@ public class FlatVlanConntrackBasedSnatService extends ConntrackBasedSnatService
                                              IdManagerService idManager, NAPTSwitchSelector naptSwitchSelector,
                                              IInterfaceManager interfaceManager,
                                              IVpnFootprintService vpnFootprintService,
-                                             IFibManager fibManager) {
+                                             IFibManager fibManager, NatDataUtil natDataUtil) {
         super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector,
-                odlInterfaceRpcService, interfaceManager, vpnFootprintService, fibManager);
+                odlInterfaceRpcService, interfaceManager, vpnFootprintService, fibManager ,
+                natDataUtil);
     }
 
     @Override
index cfd3f717702b81eed2294b8565ce600a95f9a812..2ce1b571a615219609dfb4f7db7372c47bf9f633 100644 (file)
@@ -22,12 +22,14 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
 import org.opendaylight.controller.md.sal.binding.api.ReadTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
@@ -60,6 +62,7 @@ import org.opendaylight.netvirt.bgpmanager.api.IBgpManager;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
 import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
+import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
 import org.opendaylight.netvirt.neutronvpn.api.utils.NeutronConstants;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnManager;
 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnAfConfig;
@@ -222,6 +225,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev14
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.group.input.buckets.bucket.action.action.NxActionResubmitRpcAddGroupCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
+import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
@@ -2071,6 +2075,66 @@ public final class NatUtil {
 
     }
 
+    public static DpnInterfaces getElanInterfaceInfoByElanDpn(String elanInstanceName, BigInteger dpId,
+            DataBroker broker) {
+        InstanceIdentifier<DpnInterfaces> elanDpnInterfacesId =
+                getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId);
+        DpnInterfaces dpnInterfaces = null;
+        try {
+            dpnInterfaces = SingleTransactionDataBroker.syncRead(broker, LogicalDatastoreType.OPERATIONAL,
+                    elanDpnInterfacesId);
+        }
+        catch (ReadFailedException e) {
+            LOG.warn("Failed to read ElanDpnInterfacesList with error {}", e.getMessage());
+        }
+        return dpnInterfaces;
+    }
+
+    public static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
+            InstanceIdentifier<T> path) {
+        try (ReadOnlyTransaction tx = broker.newReadOnlyTransaction()) {
+            return tx.read(datastoreType, path).get();
+        } catch (InterruptedException | ExecutionException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static boolean isLastExternalRouter(String networkid, String routerName, NatDataUtil natDataUtil) {
+        Set<Map.Entry<String,Routers>> extRouter = natDataUtil.getAllRouters();
+        for (Map.Entry<String,Routers> router : extRouter) {
+            if (!router.getKey().equals(routerName) && router.getValue().getNetworkId().getValue()
+                    .equals(networkid)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public static InstanceIdentifier<ExtRouters> buildExtRouters() {
+        InstanceIdentifier<ExtRouters> extRouterInstanceIndentifier = InstanceIdentifier.builder(ExtRouters.class)
+                .build();
+        return extRouterInstanceIndentifier;
+    }
+
+    public static LearntVpnVipToPortData getLearntVpnVipToPortData(DataBroker dataBroker) {
+        InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = getLearntVpnVipToPortDataId();
+        LearntVpnVipToPortData learntVpnVipToPortData = null;
+        try {
+            learntVpnVipToPortData = SingleTransactionDataBroker.syncRead(dataBroker,
+                    LogicalDatastoreType.OPERATIONAL, learntVpnVipToPortDataId);
+        }
+        catch (ReadFailedException e) {
+            LOG.warn("Failed to read LearntVpnVipToPortData with error {}", e.getMessage());
+        }
+        return learntVpnVipToPortData;
+    }
+
+    public static InstanceIdentifier<LearntVpnVipToPortData> getLearntVpnVipToPortDataId() {
+        InstanceIdentifier<LearntVpnVipToPortData> learntVpnVipToPortDataId = InstanceIdentifier
+                .builder(LearntVpnVipToPortData.class).build();
+        return learntVpnVipToPortDataId;
+    }
+
     public static InstanceIdentifier<DpnInterfaces> getElanDpnInterfaceOperationalDataPath(String elanInstanceName,
             BigInteger dpId) {
         return InstanceIdentifier.builder(ElanDpnInterfaces.class)
index 2ddb1095d9b3cfeae3aaf6a87349f34c6fde3a69..c9f8d680a4e4d8694d0b17f6c7e0a9ecfe7921c2 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.infrautils.inject.AbstractLifecycle;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
+import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
@@ -42,7 +43,8 @@ public class SnatServiceImplFactory extends AbstractLifecycle {
     private final IElanService elanManager;
     private final IInterfaceManager interfaceManager;
     private final IVpnFootprintService vpnFootprintService;
-    protected final IFibManager fibManager;
+    private final IFibManager fibManager;
+    private final NatDataUtil natDataUtil;
 
     @Inject
     public SnatServiceImplFactory(final DataBroker dataBroker, final IMdsalApiManager mdsalManager,
@@ -56,7 +58,8 @@ public class SnatServiceImplFactory extends AbstractLifecycle {
                                   final IElanService elanManager,
                                   final IInterfaceManager interfaceManager,
                                   final IVpnFootprintService vpnFootprintService,
-                                  final IFibManager fibManager) {
+                                  final IFibManager fibManager,
+                                  final NatDataUtil natDataUtil) {
         this.dataBroker = dataBroker;
         this.mdsalManager = mdsalManager;
         this.itmManager = itmManager;
@@ -74,6 +77,7 @@ public class SnatServiceImplFactory extends AbstractLifecycle {
         this.interfaceManager = interfaceManager;
         this.vpnFootprintService = vpnFootprintService;
         this.fibManager = fibManager;
+        this.natDataUtil = natDataUtil;
     }
 
     @Override
@@ -90,7 +94,7 @@ public class SnatServiceImplFactory extends AbstractLifecycle {
 
         if (natMode == NatMode.Conntrack) {
             return new FlatVlanConntrackBasedSnatService(dataBroker, mdsalManager, itmManager, odlInterfaceRpcService,
-                    idManager, naptSwitchSelector, interfaceManager, vpnFootprintService, fibManager);
+                    idManager, naptSwitchSelector, interfaceManager, vpnFootprintService, fibManager,  natDataUtil);
         }
         return null;
     }
@@ -102,7 +106,7 @@ public class SnatServiceImplFactory extends AbstractLifecycle {
                     NatConstants.ODL_VNI_POOL_NAME);
             return new VxlanGreConntrackBasedSnatService(dataBroker, mdsalManager, itmManager, odlInterfaceRpcService,
                     idManager, naptSwitchSelector, externalRouterListener, elanManager, interfaceManager,
-                    vpnFootprintService, fibManager);
+                    vpnFootprintService, fibManager, natDataUtil);
         }
         return null;
     }
index b936d4c75ba86330fb20d5b3bcd61ef8609cffd5..3e5704289256b5aa128149fe170fd700cb2a4399 100644 (file)
@@ -42,6 +42,7 @@ import org.opendaylight.genius.mdsalutil.nxmatches.NxMatchCtState;
 import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
+import org.opendaylight.netvirt.natservice.ha.NatDataUtil;
 import org.opendaylight.netvirt.vpnmanager.api.IVpnFootprintService;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.idmanager.rev160406.IdManagerService;
@@ -70,9 +71,9 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
                                              ExternalRoutersListener externalRouterListener, IElanService elanManager,
                                              IInterfaceManager interfaceManager,
                                              IVpnFootprintService vpnFootprintService,
-                                             IFibManager fibManager) {
+                                             IFibManager fibManager, NatDataUtil natDataUtil) {
         super(dataBroker, mdsalManager, itmManager, idManager, naptSwitchSelector, odlInterfaceRpcService,
-                interfaceManager, vpnFootprintService, fibManager);
+                interfaceManager, vpnFootprintService, fibManager, natDataUtil);
         this.externalRouterListener = externalRouterListener;
         this.elanManager = elanManager;
         this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
index e748cd62eb795a16b662dac7a0850b31c8fe1e0a..4f0d4260eea6dfbc6ce05694d18138c8076c52cd 100755 (executable)
@@ -1560,10 +1560,15 @@ public class VpnInterfaceManager extends AsyncDataTreeChangeListenerBase<VpnInte
                                                     operTx, confTx);
                                             Optional<VpnInterfaceOpDataEntry> optVpnInterface = operTx.read(
                                                     LogicalDatastoreType.OPERATIONAL, vpnInterfaceOpIdentifier).get();
-                                            VpnInterfaceOpDataEntry vpnInterfaceOpDataEntry = optVpnInterface.get();
-                                            long vpnId = VpnUtil.getVpnId(dataBroker, newVpnName);
-                                            VpnUtil.removePrefixToInterfaceAdj(dataBroker, adj, vpnId,
-                                                    vpnInterfaceOpDataEntry, operTx);
+                                            if (optVpnInterface.isPresent()) {
+                                                VpnInterfaceOpDataEntry vpnInterfaceOpDataEntry = optVpnInterface.get();
+                                                long vpnId = VpnUtil.getVpnId(dataBroker, newVpnName);
+                                                VpnUtil.removePrefixToInterfaceAdj(dataBroker, adj, vpnId,
+                                                        vpnInterfaceOpDataEntry, operTx);
+                                            } else {
+                                                LOG.info("Vpninterface {} not present in Operational",
+                                                        vpnInterfaceName);
+                                            }
                                             //remove FIB entry
                                             String vpnRd = VpnUtil.getVpnRd(dataBroker, newVpnName);
                                             LOG.debug("update: remove prefix {} from the FIB and BGP entry "