Datastore txes: natservice, AbstractSnatService 42/73842/3
authorStephen Kitt <skitt@redhat.com>
Mon, 9 Jul 2018 09:32:09 +0000 (11:32 +0200)
committerSam Hague <shague@redhat.com>
Mon, 9 Jul 2018 20:21:02 +0000 (20:21 +0000)
This patch migrates AbstractSnatService and related classes and
methods to datastore-constrained transactions. It also splits a number
of add/remove methods into separate add and remove methods,
simplifying the remove methods as a result.

JIRA: NETVIRT-1342
Change-Id: I75b28b2edea2c576cf2c73f11a38b292e6c8063c
Signed-off-by: Stephen Kitt <skitt@redhat.com>
13 files changed:
natservice/api/pom.xml
natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/SnatServiceListener.java
natservice/api/src/main/java/org/opendaylight/netvirt/natservice/api/SnatServiceManager.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/ha/SnatCentralizedSwitchChangeListener.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/NaptSwitchHA.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatTunnelInterfaceStateListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/NatUtil.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/RouterDpnChangeListener.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/SnatServiceManagerImpl.java
natservice/impl/src/main/java/org/opendaylight/netvirt/natservice/internal/VxlanGreConntrackBasedSnatService.java

index d70c6a49ce69a2f954359ae61ca7124759c3ac42..4664ccd16ae8f9278c3970dfb5ff85f22494807f 100644 (file)
@@ -38,5 +38,10 @@ and is available at http://www.eclipse.org/legal/epl-v10.html
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-common</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.genius</groupId>
+            <artifactId>mdsalutil-api</artifactId>
+            <version>0.5.0-SNAPSHOT</version>
+        </dependency>
     </dependencies>
 </project>
index 33f324e3c31a868bafff7d069ba1e1931e2dfd0a..1fbfc0a2d7266863ff7052f22bc8194c13a2f860 100644 (file)
@@ -9,27 +9,56 @@ package org.opendaylight.netvirt.natservice.api;
 
 import java.math.BigInteger;
 
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
 
 public interface SnatServiceListener {
 
     /**
-     * Adds/removes snat flows for all dpns having ports on the router subnet.
+     * Adds snat flows for all dpns having ports on the router subnet.
+     *
+     * @param confTx The transaction to use.
      * @param routers the router.
      * @param primarySwitchId the primaryswitchId
-     * @param addOrRemove add or remove the flow.
      * @return returns success/failure.
      */
-    boolean handleSnatAllSwitch(Routers routers, BigInteger primarySwitchId,  int addOrRemove);
+    boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId);
 
     /**
-     * Adds/removes snat flows for the dpnId.
+     * Adds snat flows for the dpnId.
+     *
+     * @param confTx The transaction to use.
      * @param routers the router.
      * @param primarySwitchId the primaryswitchId.
      * @param dpnId the dpnId for which the flows needs to be added/removed.
-     * @param addOrRemove add or remove the flow.
      * @return returns success/failure.
      */
-    boolean handleSnat(Routers routers, BigInteger primarySwitchId, BigInteger dpnId,  int addOrRemove);
+    boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers, BigInteger primarySwitchId,
+        BigInteger dpnId);
+
+    /**
+     * Removes snat flows for all dpns having ports on the router subnet.
+     *
+     * @param confTx The transaction to use.
+     * @param routers the router.
+     * @param primarySwitchId the primaryswitchId
+     * @return returns success/failure.
+     */
+    boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId);
+
+    /**
+     * Removes snat flows for the dpnId.
+     *
+     * @param confTx The transaction to use.
+     * @param routers the router.
+     * @param primarySwitchId the primaryswitchId.
+     * @param dpnId the dpnId for which the flows needs to be added/removed.
+     * @return returns success/failure.
+     */
+    boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers, BigInteger primarySwitchId,
+        BigInteger dpnId);
 
 }
index c29d288279a915fe281f615d942e23e7c28f7d8f..abc1aac47dc6836b2b6063ba22f4606489581bd3 100644 (file)
@@ -9,6 +9,8 @@ package org.opendaylight.netvirt.natservice.api;
 
 import java.math.BigInteger;
 
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
 
 public interface SnatServiceManager {
@@ -24,6 +26,7 @@ public interface SnatServiceManager {
 
     void removeNatServiceListener(SnatServiceListener aclServiceListner);
 
-    void notify(Routers router, BigInteger primarySwitchId, BigInteger dpnId, Action action);
+    void notify(TypedReadWriteTransaction<Configuration> confTx,
+        Routers router, BigInteger primarySwitchId, BigInteger dpnId, Action action);
 
 }
index 6ebc81eb90b9db04d909c19bc571cb57f267f6f0..cdf598d4a858c2b4e6f2a20367d48de4eb7a9ef3 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.netvirt.natservice.ha;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
 import java.math.BigInteger;
 
 import java.time.Duration;
@@ -18,6 +20,11 @@ import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.genius.datastoreutils.listeners.DataTreeEventCallbackRegistrar;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.natservice.api.SnatServiceManager;
 import org.opendaylight.netvirt.natservice.internal.NatConstants;
 import org.opendaylight.netvirt.natservice.internal.NatUtil;
@@ -38,6 +45,7 @@ public class SnatCentralizedSwitchChangeListener
 
     private static final Logger LOG = LoggerFactory.getLogger(SnatCentralizedSwitchChangeListener.class);
     private final DataBroker dataBroker;
+    private final ManagedNewTransactionRunner txRunner;
     private final SnatServiceManager snatServiceManger;
     private final NatDataUtil natDataUtil;
     private final DataTreeEventCallbackRegistrar eventCallbacks;
@@ -48,6 +56,7 @@ public class SnatCentralizedSwitchChangeListener
             final DataTreeEventCallbackRegistrar dataTreeEventCallbackRegistrar) {
         super(RouterToNaptSwitch.class, SnatCentralizedSwitchChangeListener.class);
         this.dataBroker = dataBroker;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.snatServiceManger = snatServiceManger;
         this.natDataUtil = natDataUtil;
         this.eventCallbacks = dataTreeEventCallbackRegistrar;
@@ -71,7 +80,10 @@ public class SnatCentralizedSwitchChangeListener
         BigInteger primarySwitchId = routerToNaptSwitch.getPrimarySwitchId();
         Routers router = natDataUtil.getRouter(routerToNaptSwitch.getRouterName());
         if (router != null) {
-            snatServiceManger.notify(router, primarySwitchId, null, SnatServiceManager.Action.SNAT_ALL_SWITCH_DISBL);
+            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                confTx -> snatServiceManger.notify(confTx, router, primarySwitchId, null,
+                    SnatServiceManager.Action.SNAT_ALL_SWITCH_DISBL)), LOG,
+                "error handling SNAT centralized switch removal");
             natDataUtil.removeFromRouterMap(router);
         }
     }
@@ -81,19 +93,21 @@ public class SnatCentralizedSwitchChangeListener
             RouterToNaptSwitch updatedRouterToNaptSwitch) {
         LOG.debug("Updating old {} new {}", origRouterToNaptSwitch, updatedRouterToNaptSwitch);
         BigInteger origPrimarySwitchId = origRouterToNaptSwitch.getPrimarySwitchId();
-        Routers origRouter = NatUtil.getRoutersFromConfigDS(dataBroker, origRouterToNaptSwitch.getRouterName());
-        if (origRouter != null) {
-            snatServiceManger.notify(origRouter, origPrimarySwitchId, null,
+        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
+            Routers origRouter = NatUtil.getRoutersFromConfigDS(confTx, origRouterToNaptSwitch.getRouterName());
+            if (origRouter != null) {
+                snatServiceManger.notify(confTx, origRouter, origPrimarySwitchId, null,
                     SnatServiceManager.Action.SNAT_ALL_SWITCH_DISBL);
-            natDataUtil.removeFromRouterMap(origRouter);
-        }
-        BigInteger updatedPrimarySwitchId = updatedRouterToNaptSwitch.getPrimarySwitchId();
-        Routers updatedRouter = NatUtil.getRoutersFromConfigDS(dataBroker, updatedRouterToNaptSwitch.getRouterName());
-        if (updatedRouter != null) {
-            natDataUtil.updateRouterMap(updatedRouter);
-            snatServiceManger.notify(updatedRouter, updatedPrimarySwitchId, null,
+                natDataUtil.removeFromRouterMap(origRouter);
+            }
+            BigInteger updatedPrimarySwitchId = updatedRouterToNaptSwitch.getPrimarySwitchId();
+            Routers updatedRouter = NatUtil.getRoutersFromConfigDS(confTx, updatedRouterToNaptSwitch.getRouterName());
+            if (updatedRouter != null) {
+                natDataUtil.updateRouterMap(updatedRouter);
+                snatServiceManger.notify(confTx, updatedRouter, updatedPrimarySwitchId, null,
                     SnatServiceManager.Action.SNAT_ALL_SWITCH_ENBL);
-        }
+            }
+        }), LOG, "Error handling SNAT centralized switch update");
     }
 
     @Override
@@ -107,20 +121,26 @@ public class SnatCentralizedSwitchChangeListener
             LOG.warn("VpnId not unavailable for router {} yet", routerName);
             eventCallbacks.onAddOrUpdate(LogicalDatastoreType.CONFIGURATION,
                 NatUtil.getVpnInstanceToVpnIdIdentifier(routerName), (unused, newVpnId) -> {
-                    handleAdd(routerName, router, primarySwitchId);
+                    ListenableFutures.addErrorLogging(
+                        txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                            innerConfTx -> handleAdd(innerConfTx, routerName, router, primarySwitchId)), LOG,
+                        "Error handling router addition");
                     return DataTreeEventCallbackRegistrar.NextAction.UNREGISTER;
-                }, Duration.ofSeconds(5), iid -> {
-                    LOG.error("VpnId not found for router {}", routerName);
-                });
+                }, Duration.ofSeconds(5), iid -> LOG.error("VpnId not found for router {}", routerName));
             return;
         }
-        handleAdd(routerName, router, primarySwitchId);
+        ListenableFutures.addErrorLogging(
+            txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                confTx -> handleAdd(confTx, routerName, router, primarySwitchId)), LOG,
+            "Error handling router addition");
     }
 
-    private void handleAdd(String routerName, Routers router, BigInteger primarySwitchId) {
+    private void handleAdd(TypedReadWriteTransaction<Datastore.Configuration> confTx,
+        String routerName, Routers router, BigInteger primarySwitchId) {
         if (router != null) {
             natDataUtil.addtoRouterMap(router);
-            snatServiceManger.notify(router, primarySwitchId, null, SnatServiceManager.Action.SNAT_ALL_SWITCH_ENBL);
+            snatServiceManger.notify(confTx, router, primarySwitchId, null,
+                SnatServiceManager.Action.SNAT_ALL_SWITCH_ENBL);
         } else {
             LOG.error("Router {} not found for primarySwitch {}", routerName, primarySwitchId);
         }
index 8803804cdfd0609dc60a665eefc6b2bb3ef6d4e9..c405a115fedd65c52afb2848a4600ee88ae99d5a 100644 (file)
@@ -11,6 +11,7 @@ import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Objects;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
@@ -18,6 +19,12 @@ 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.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TransactionAdapter;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
 import org.opendaylight.genius.mdsalutil.BucketInfo;
@@ -86,6 +93,7 @@ public abstract class AbstractSnatService implements SnatServiceListener {
             .METADATA_MASK_SH_FLAG.intValue());
 
     protected final DataBroker dataBroker;
+    protected final ManagedNewTransactionRunner txRunner;
     protected final IMdsalApiManager mdsalManager;
     protected final IdManagerService idManager;
     protected final NAPTSwitchSelector naptSwitchSelector;
@@ -103,6 +111,7 @@ public abstract class AbstractSnatService implements SnatServiceListener {
                                   final IVpnFootprintService vpnFootprintService,
                                   final IFibManager fibManager, final NatDataUtil natDataUtil) {
         this.dataBroker = dataBroker;
+        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
         this.mdsalManager = mdsalManager;
         this.itmManager = itmManager;
         this.interfaceManager = interfaceManager;
@@ -127,7 +136,8 @@ public abstract class AbstractSnatService implements SnatServiceListener {
     }
 
     @Override
-    public boolean handleSnatAllSwitch(Routers routers, BigInteger primarySwitchId,  int addOrRemove) {
+    public boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId) {
         LOG.info("handleSnatAllSwitch : Handle Snat in all switches for router {}", routers.getRouterName());
         String routerName = routers.getRouterName();
         List<BigInteger> switches = naptSwitchSelector.getDpnsForVpn(routerName);
@@ -135,17 +145,33 @@ public abstract class AbstractSnatService implements SnatServiceListener {
          * 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);
+        addSnat(confTx, routers, primarySwitchId, primarySwitchId);
+        for (BigInteger dpnId : switches) {
+            if (!Objects.equals(primarySwitchId, dpnId)) {
+                addSnat(confTx, routers, primarySwitchId, dpnId);
+            }
         }
-        handleSnat(routers, primarySwitchId, primarySwitchId, addOrRemove);
+        return true;
+    }
+
+    @Override
+    public boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId) {
+        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 =
+            NatUtil.isLastExternalRouter(routers.getNetworkId().getValue(), routers.getRouterName(), natDataUtil);
+        LOG.info("handleSnatAllSwitch : action is delete for router {} and isLastRouterDelete is {}",
+            routers.getRouterName(), isLastRouterDelete);
+        removeSnat(confTx, routers, primarySwitchId, primarySwitchId);
         for (BigInteger dpnId : switches) {
-            if (primarySwitchId != dpnId) {
-                handleSnat(routers, primarySwitchId, dpnId, addOrRemove);
+            if (!Objects.equals(primarySwitchId, dpnId)) {
+                removeSnat(confTx, routers, primarySwitchId, dpnId);
             }
         }
         if (isLastRouterDelete) {
@@ -156,26 +182,45 @@ public abstract class AbstractSnatService implements SnatServiceListener {
     }
 
     @Override
-    public boolean handleSnat(Routers routers, BigInteger primarySwitchId, BigInteger dpnId,  int addOrRemove) {
+    public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers, BigInteger primarySwitchId,
+        BigInteger dpnId) {
+
+        // Handle non NAPT switches and NAPT switches separately
+        if (!dpnId.equals(primarySwitchId)) {
+            LOG.info("handleSnat : Handle non NAPT switch {} for router {}", dpnId, routers.getRouterName());
+            addSnatCommonEntriesForNonNaptSwitch(confTx, routers, primarySwitchId, dpnId);
+            addSnatSpecificEntriesForNonNaptSwitch(confTx, routers, dpnId);
+        } else {
+            LOG.info("handleSnat : Handle NAPT switch {} for router {}", dpnId, routers.getRouterName());
+            addSnatCommonEntriesForNaptSwitch(confTx, routers, dpnId);
+            addSnatSpecificEntriesForNaptSwitch(confTx, routers, dpnId);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId, BigInteger dpnId) {
 
         // Handle non NAPT switches and NAPT switches separately
         if (!dpnId.equals(primarySwitchId)) {
             LOG.info("handleSnat : Handle non NAPT switch {} for router {}", dpnId, routers.getRouterName());
-            installSnatCommonEntriesForNonNaptSwitch(routers, primarySwitchId, dpnId, addOrRemove);
-            installSnatSpecificEntriesForNonNaptSwitch(routers, dpnId, addOrRemove);
+            removeSnatCommonEntriesForNonNaptSwitch(confTx, routers, dpnId);
+            removeSnatSpecificEntriesForNonNaptSwitch(confTx, routers, dpnId);
         } else {
             LOG.info("handleSnat : Handle NAPT switch {} for router {}", dpnId, routers.getRouterName());
-            installSnatCommonEntriesForNaptSwitch(routers, dpnId, addOrRemove);
-            installSnatSpecificEntriesForNaptSwitch(routers, dpnId, addOrRemove);
+            removeSnatCommonEntriesForNaptSwitch(confTx, routers, dpnId);
+            removeSnatSpecificEntriesForNaptSwitch(confTx, routers, dpnId);
 
         }
         return true;
     }
 
-    protected void installSnatCommonEntriesForNaptSwitch(Routers routers, BigInteger dpnId,  int addOrRemove) {
+    protected void addSnatCommonEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger dpnId) {
         String routerName = routers.getRouterName();
         Long routerId = NatUtil.getVpnId(dataBroker, routerName);
-        installDefaultFibRouteForSNAT(dpnId, routerId, addOrRemove);
+        addDefaultFibRouteForSNAT(confTx, dpnId, routerId);
         String externalGwMac = routers.getExtGwMacAddress();
         for (ExternalIps externalIp : routers.getExternalIps()) {
             if (!NWUtil.isIpv4Address(externalIp.getIpAddress())) {
@@ -183,43 +228,71 @@ public abstract class AbstractSnatService implements SnatServiceListener {
                 continue;
             }
             //The logic now handle only one external IP per router, others if present will be ignored.
-            long extSubnetId = NatConstants.INVALID_ID;
-            if (addOrRemove == NwConstants.ADD_FLOW) {
-                extSubnetId = NatUtil.getExternalSubnetVpnId(dataBroker, externalIp.getSubnetId());
+            long extSubnetId = NatUtil.getExternalSubnetVpnId(dataBroker, externalIp.getSubnetId());
+            addInboundFibEntry(confTx, dpnId, externalIp.getIpAddress(), routerId, extSubnetId,
+                routers.getNetworkId().getValue(), externalIp.getSubnetId().getValue(), externalGwMac);
+            addInboundTerminatingServiceTblEntry(confTx, dpnId, routerId, extSubnetId);
+            break;
+        }
+    }
+
+    protected void removeSnatCommonEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId) {
+        String routerName = routers.getRouterName();
+        Long routerId = NatUtil.getVpnId(confTx, routerName);
+        removeDefaultFibRouteForSNAT(confTx, dpnId, routerId);
+        for (ExternalIps externalIp : routers.getExternalIps()) {
+            if (!NWUtil.isIpv4Address(externalIp.getIpAddress())) {
+                // In this class we handle only IPv4 use-cases.
+                continue;
             }
-            installInboundFibEntry(dpnId, externalIp.getIpAddress(), routerId, extSubnetId,
-                routers.getNetworkId().getValue(), externalIp.getSubnetId().getValue(), externalGwMac, addOrRemove);
-            installInboundTerminatingServiceTblEntry(dpnId, routerId, extSubnetId, addOrRemove);
+            //The logic now handle only one external IP per router, others if present will be ignored.
+            removeInboundFibEntry(confTx, dpnId, externalIp.getIpAddress(), routerId,
+                externalIp.getSubnetId().getValue());
+            removeInboundTerminatingServiceTblEntry(confTx, dpnId, routerId);
             break;
         }
     }
 
-    protected void installSnatCommonEntriesForNonNaptSwitch(Routers routers, BigInteger primarySwitchId,
-            BigInteger dpnId, int addOrRemove) {
+    protected void addSnatCommonEntriesForNonNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger primarySwitchId, BigInteger dpnId) {
+        String routerName = routers.getRouterName();
+        Long routerId = NatUtil.getVpnId(dataBroker, routerName);
+        addDefaultFibRouteForSNAT(confTx, dpnId, routerId);
+        addSnatMissEntry(confTx, dpnId, routerId, routerName, primarySwitchId);
+    }
+
+    protected void removeSnatCommonEntriesForNonNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId) {
         String routerName = routers.getRouterName();
         Long routerId = NatUtil.getVpnId(dataBroker, routerName);
-        installDefaultFibRouteForSNAT(dpnId, routerId, addOrRemove);
-        installSnatMissEntry(dpnId, routerId, routerName, primarySwitchId, addOrRemove);
+        removeDefaultFibRouteForSNAT(confTx, dpnId, routerId);
+        removeSnatMissEntry(confTx, dpnId, routerId, routerName);
     }
 
-    protected abstract void installSnatSpecificEntriesForNaptSwitch(Routers routers, BigInteger dpnId,
-            int addOrRemove);
+    protected abstract void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId);
+
+    protected abstract void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId);
+
+    protected abstract void addSnatSpecificEntriesForNonNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId);
+
+    protected abstract void removeSnatSpecificEntriesForNonNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId);
 
-    protected abstract void installSnatSpecificEntriesForNonNaptSwitch(Routers routers, BigInteger dpnId,
-            int addOrRemove);
+    protected void addInboundFibEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId, String externalIp,
+        Long routerId, long extSubnetId, String externalNetId, String subNetId, String routerMac) {
 
-    protected void installInboundFibEntry(BigInteger dpnId, String externalIp, Long routerId,
-            long extSubnetId, String externalNetId, String subNetId, String routerMac, int addOrRemove) {
         List<MatchInfo> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            if (extSubnetId == NatConstants.INVALID_ID) {
-                LOG.error("ConntrackBasedSnatService : installInboundFibEntry : external subnet id is invalid.");
-                return;
-            }
-            matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extSubnetId),
-                    MetaDataUtil.METADATA_MASK_VRFID));
+        if (extSubnetId == NatConstants.INVALID_ID) {
+            LOG.error("ConntrackBasedSnatService : installInboundFibEntry : external subnet id is invalid.");
+            return;
         }
+        matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extSubnetId),
+                MetaDataUtil.METADATA_MASK_VRFID));
         matches.add(new MatchIpv4Destination(externalIp, "32"));
 
         ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
@@ -229,26 +302,33 @@ public abstract class AbstractSnatService implements SnatServiceListener {
 
         String flowRef = getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, routerId);
         flowRef = flowRef + "inbound" + externalIp;
-        syncFlow(dpnId, NwConstants.L3_FIB_TABLE, flowRef, NatConstants.SNAT_FIB_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.L3_FIB_TABLE, flowRef, NatConstants.SNAT_FIB_FLOW_PRIORITY, flowRef,
+                NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
         String rd = NatUtil.getVpnRd(dataBroker, subNetId);
         String nextHopIp = NatUtil.getEndpointIpAddressForDPN(dataBroker, dpnId);
         String ipPrefix = externalIp + "/32";
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            NatUtil.addPrefixToInterface(dataBroker, NatUtil.getVpnId(dataBroker, subNetId),
-                    null, ipPrefix, dpnId, new Uuid(subNetId), Prefixes.PrefixCue.Nat);
+        NatUtil.addPrefixToInterface(dataBroker, NatUtil.getVpnId(dataBroker, subNetId),
+                null, ipPrefix, dpnId, new Uuid(subNetId), Prefixes.PrefixCue.Nat);
 
-            fibManager.addOrUpdateFibEntry(rd, routerMac, ipPrefix,
-                    Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, extSubnetId,
-                    0, null, externalNetId, RouteOrigin.STATIC, null);
-        } else {
-            fibManager.removeFibEntry(rd, ipPrefix, null);
-            NatUtil.deletePrefixToInterface(dataBroker, NatUtil.getVpnId(dataBroker, subNetId), ipPrefix);
-        }
+        fibManager.addOrUpdateFibEntry(rd, routerMac, ipPrefix,
+                Collections.singletonList(nextHopIp), VrfEntry.EncapType.Mplsgre, extSubnetId,
+                0, null, externalNetId, RouteOrigin.STATIC, null);
     }
 
-    protected void installSnatMissEntry(BigInteger dpnId, Long routerId, String routerName, BigInteger primarySwitchId,
-            int addOrRemove) {
+    protected void removeInboundFibEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        String externalIp, Long routerId, String subNetId) {
+
+        String flowRef = getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, routerId);
+        flowRef = flowRef + "inbound" + externalIp;
+        removeFlow(confTx, dpnId, NwConstants.L3_FIB_TABLE, flowRef);
+        String rd = NatUtil.getVpnRd(dataBroker, subNetId);
+        String ipPrefix = externalIp + "/32";
+        fibManager.removeFibEntry(rd, ipPrefix, TransactionAdapter.toWriteTransaction(confTx));
+        NatUtil.deletePrefixToInterface(dataBroker, NatUtil.getVpnId(dataBroker, subNetId), ipPrefix);
+    }
+
+    protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long routerId, String routerName, BigInteger primarySwitchId) {
         LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
         List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
         String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
@@ -256,28 +336,23 @@ public abstract class AbstractSnatService implements SnatServiceListener {
         if (ifNamePrimary != null) {
             LOG.debug("installSnatMissEntry : On Non- Napt switch , Primary Tunnel interface is {}", ifNamePrimary);
             listActionInfoPrimary = NatUtil.getEgressActionsForInterface(odlInterfaceRpcService, itmManager,
-                    interfaceManager, ifNamePrimary, routerId, true);
+                interfaceManager, ifNamePrimary, routerId, true);
         }
         BucketInfo bucketPrimary = new BucketInfo(listActionInfoPrimary);
         listBucketInfo.add(0, bucketPrimary);
         LOG.debug("installSnatMissEntry : installSnatMissEntry called for dpnId {} with primaryBucket {} ", dpnId,
-                listBucketInfo.get(0));
+            listBucketInfo.get(0));
         // Install the select group
         long groupId = createGroupId(getGroupIdKey(routerName));
-        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
-                listBucketInfo);
 
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            LOG.debug("installing the PSNAT to NAPTSwitch GroupEntity:{} with GroupId: {}", groupEntity, groupId);
-            mdsalManager.installGroup(groupEntity);
-        } else {
-            LOG.debug("removing the PSNAT to NAPTSwitch GroupEntity:{} with GroupId: {}", groupEntity, groupId);
-            mdsalManager.syncRemoveGroup(groupEntity);
-        }
+        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
+            listBucketInfo);
+        LOG.debug("installing the PSNAT to NAPTSwitch GroupEntity:{} with GroupId: {}", groupEntity, groupId);
+        mdsalManager.addGroup(confTx, groupEntity);
 
         // Install miss entry pointing to group
         LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
-                dpnId, routerName, groupId);
+            dpnId, routerName, groupId);
         List<MatchInfo> matches = new ArrayList<>();
         matches.add(new MatchEthernetType(0x0800L));
         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
@@ -290,51 +365,83 @@ public abstract class AbstractSnatService implements SnatServiceListener {
         List<InstructionInfo> instructions = new ArrayList<>();
         instructions.add(new InstructionApplyActions(actionsInfo));
         String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
-        syncFlow(dpnId, NwConstants.PSNAT_TABLE, flowRef,  NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef,  NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
+            NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
+    }
+
+    protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long routerId, String routerName) {
+        LOG.debug("installSnatMissEntry : Removing SNAT miss entry from switch {}", dpnId);
+        // Install the select group
+        long groupId = createGroupId(getGroupIdKey(routerName));
+
+        LOG.debug("removing the PSNAT to NAPTSwitch on DPN {} with GroupId: {}", dpnId, groupId);
+        mdsalManager.removeGroup(confTx, dpnId, groupId);
+
+        // Install miss entry pointing to group
+        LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
+            dpnId, routerName, groupId);
+
+        String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
+        removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);
     }
 
-    protected void installInboundTerminatingServiceTblEntry(BigInteger dpnId, Long routerId,
-            long extSubnetId, int addOrRemove) {
+    protected void addInboundTerminatingServiceTblEntry(TypedReadWriteTransaction<Configuration> confTx,
+        BigInteger dpnId, Long routerId, long extSubnetId) {
+
         //Install the tunnel table entry in NAPT switch for inbound traffic to SNAP IP from a non a NAPT switch.
         LOG.info("installInboundTerminatingServiceTblEntry : creating entry for Terminating Service Table "
                 + "for switch {}, routerId {}", dpnId, routerId);
         List<MatchInfo> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
         List<ActionInfo> actionsInfos = new ArrayList<>();
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            if (extSubnetId == NatConstants.INVALID_ID) {
-                LOG.error("installInboundTerminatingServiceTblEntry : external subnet id is invalid.");
-                return;
-            }
-            matches.add(new MatchTunnelId(BigInteger.valueOf(extSubnetId)));
-            ActionNxLoadMetadata actionLoadMeta = new ActionNxLoadMetadata(MetaDataUtil
-                    .getVpnIdMetadata(extSubnetId), LOAD_START, LOAD_END);
-            actionsInfos.add(actionLoadMeta);
+        if (extSubnetId == NatConstants.INVALID_ID) {
+            LOG.error("installInboundTerminatingServiceTblEntry : external subnet id is invalid.");
+            return;
         }
+        matches.add(new MatchTunnelId(BigInteger.valueOf(extSubnetId)));
+        ActionNxLoadMetadata actionLoadMeta = new ActionNxLoadMetadata(MetaDataUtil
+                .getVpnIdMetadata(extSubnetId), LOAD_START, LOAD_END);
+        actionsInfos.add(actionLoadMeta);
         actionsInfos.add(new ActionNxResubmit(NwConstants.INBOUND_NAPT_TABLE));
         List<InstructionInfo> instructions = new ArrayList<>();
         instructions.add(new InstructionApplyActions(actionsInfos));
-        String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
-        flowRef = flowRef + "INBOUND";
-        syncFlow(dpnId,  NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.SNAT_FIB_FLOW_PRIORITY, flowRef,
-                 NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue()) + "INBOUND";
+        addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.SNAT_FIB_FLOW_PRIORITY, flowRef,
+                 NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
+    }
 
+    protected void removeInboundTerminatingServiceTblEntry(TypedReadWriteTransaction<Configuration> confTx,
+        BigInteger dpnId, Long routerId) {
+
+        //Install the tunnel table entry in NAPT switch for inbound traffic to SNAP IP from a non a NAPT switch.
+        LOG.info("installInboundTerminatingServiceTblEntry : creating entry for Terminating Service Table "
+            + "for switch {}, routerId {}", dpnId, routerId);
+        String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue()) + "INBOUND";
+        removeFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
     }
 
-    protected void installDefaultFibRouteForSNAT(BigInteger dpnId, Long extNetId, int addOrRemove) {
+    protected void addDefaultFibRouteForSNAT(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long extNetId) {
 
         List<MatchInfo> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetId),
-                MetaDataUtil.METADATA_MASK_VRFID));
+            MetaDataUtil.METADATA_MASK_VRFID));
 
         List<InstructionInfo> instructions = new ArrayList<>();
         instructions.add(new InstructionGotoTable(NwConstants.PSNAT_TABLE));
 
         String flowRef = "DefaultFibRouteForSNAT" + getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, extNetId);
-        syncFlow(dpnId, NwConstants.L3_FIB_TABLE, flowRef, NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.L3_FIB_TABLE, flowRef, NatConstants.DEFAULT_DNAT_FLOW_PRIORITY, flowRef,
+            NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
+    }
+
+    protected void removeDefaultFibRouteForSNAT(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long extNetId) {
+
+        String flowRef = "DefaultFibRouteForSNAT" + getFlowRef(dpnId, NwConstants.L3_FIB_TABLE, extNetId);
+        removeFlow(confTx, dpnId, NwConstants.L3_FIB_TABLE, flowRef);
     }
 
     protected String getFlowRef(BigInteger dpnId, short tableId, long routerID) {
@@ -342,23 +449,32 @@ public abstract class AbstractSnatService implements SnatServiceListener {
                 .FLOWID_SEPARATOR).append(tableId).append(NatConstants.FLOWID_SEPARATOR).append(routerID).toString();
     }
 
-    protected void syncFlow(BigInteger dpId, short tableId, String flowId, int priority, String flowName,
-            BigInteger cookie, List<? extends MatchInfoBase> matches,
-            List<InstructionInfo> instructions, int addOrRemove) {
+    protected void syncFlow(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpId, short tableId,
+        String flowId, int priority, String flowName, BigInteger cookie, List<? extends MatchInfoBase> matches,
+        List<InstructionInfo> instructions, int addOrRemove) {
         if (addOrRemove == NwConstants.DEL_FLOW) {
-            FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
-                    NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches, null);
-            LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
-            mdsalManager.removeFlow(flowEntity);
+            removeFlow(confTx, dpId, tableId, flowId);
         } else {
-            FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
-                    NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
-                    instructions);
-            LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
-            mdsalManager.installFlow(flowEntity);
+            addFlow(confTx, dpId, tableId, flowId, priority, flowName, cookie, matches, instructions);
         }
     }
 
+    protected void addFlow(TypedWriteTransaction<Configuration> confTx, BigInteger dpId, short tableId,
+        String flowId, int priority, String flowName, BigInteger cookie, List<? extends MatchInfoBase> matches,
+        List<InstructionInfo> instructions) {
+        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, tableId, flowId, priority, flowName,
+                NatConstants.DEFAULT_IDLE_TIMEOUT, NatConstants.DEFAULT_IDLE_TIMEOUT, cookie, matches,
+                instructions);
+        LOG.trace("syncFlow : Installing DpnId {}, flowId {}", dpId, flowId);
+        mdsalManager.addFlow(confTx, flowEntity);
+    }
+
+    protected void removeFlow(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpId, short tableId,
+        String flowId) {
+        LOG.trace("syncFlow : Removing Acl Flow DpnId {}, flowId {}", dpId, flowId);
+        mdsalManager.removeFlow(confTx, dpId, flowId, tableId);
+    }
+
     protected long createGroupId(String groupIdKey) {
         AllocateIdInput getIdInput = new AllocateIdInputBuilder()
             .setPoolName(NatConstants.SNAT_IDPOOL_NAME).setIdKey(groupIdKey)
index 2461716fdff73006942650af889d34f06a5ff648..ded171b366ac342efed6b25fcae58dbc46971515 100644 (file)
@@ -13,6 +13,9 @@ import java.util.ArrayList;
 import java.util.List;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
 import org.opendaylight.genius.mdsalutil.InstructionInfo;
@@ -71,61 +74,109 @@ public abstract class ConntrackBasedSnatService extends AbstractSnatService {
     }
 
     @Override
-    protected void installSnatSpecificEntriesForNaptSwitch(Routers routers, BigInteger dpnId, int addOrRemove) {
+    protected void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId) {
         LOG.info("installSnatSpecificEntriesForNaptSwitch: called for router {}",
-                routers.getRouterName());
+            routers.getRouterName());
         String routerName = routers.getRouterName();
-        Long routerId = NatUtil.getVpnId(getDataBroker(), routerName);
-        int elanId = NatUtil.getElanInstanceByName(routers.getNetworkId().getValue(), getDataBroker())
-                .getElanTag().intValue();
+        Long routerId = NatUtil.getVpnId(confTx, routerName);
+        int elanId = NatUtil.getElanInstanceByName(confTx, routers.getNetworkId().getValue())
+            .getElanTag().intValue();
         if (routerId == NatConstants.INVALID_ID) {
             LOG.error("InvalidRouterId: unable to installSnatSpecificEntriesForNaptSwitch on dpn {}", dpnId);
             return;
         }
         /* Install Outbound NAT entries */
 
-        installSnatMissEntryForPrimrySwch(dpnId, routerId, elanId, addOrRemove);
-        installTerminatingServiceTblEntry(dpnId, routerId, elanId, addOrRemove);
+        addSnatMissEntryForPrimrySwch(confTx, dpnId, routerId, elanId);
+        addTerminatingServiceTblEntry(confTx, dpnId, routerId, elanId);
 
-        String extGwMacAddress = NatUtil.getExtGwMacAddFromRouterName(getDataBroker(), routerName);
-        createOutboundTblTrackEntry(dpnId, routerId, extGwMacAddress, addOrRemove);
+        String extGwMacAddress = NatUtil.getExtGwMacAddFromRouterName(confTx, routerName);
+        addOutboundTblTrackEntry(confTx, dpnId, routerId, extGwMacAddress);
         for (ExternalIps externalIp : routers.getExternalIps()) {
             if (!NWUtil.isIpv4Address(externalIp.getIpAddress())) {
                 // In this class we handle only IPv4 use-cases.
                 continue;
             }
             //The logic now handle only one external IP per router, others if present will be ignored.
-            long extSubnetId = NatConstants.INVALID_ID;
-            if (addOrRemove == NwConstants.ADD_FLOW) {
-                extSubnetId = NatUtil.getExternalSubnetVpnId(getDataBroker(), externalIp.getSubnetId());
+            long extSubnetId = NatUtil.getExternalSubnetVpnId(confTx, externalIp.getSubnetId());
+            addOutboundTblEntry(confTx, dpnId, routerId, externalIp.getIpAddress(), elanId, extGwMacAddress);
+            addNaptPfibFlow(confTx, routers, dpnId, routerId, extSubnetId);
+
+            //Install Inbound NAT entries
+            addInboundEntry(confTx, dpnId, routerId, externalIp.getIpAddress(), elanId, extSubnetId);
+            addNaptPfibEntry(confTx, dpnId, routerId);
+
+            String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp.getIpAddress());
+            Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(confTx, externalIp.getSubnetId());
+            if (externalSubnet.isPresent()) {
+                String externalVpn =  externalIp.getSubnetId().getValue();
+                String vpnRd = NatUtil.getVpnRd(confTx, externalVpn);
+                vpnFootprintService.updateVpnToDpnMapping(dpnId, externalVpn, vpnRd, null /* interfaceName*/,
+                    new ImmutablePair<>(IpAddresses.IpAddressSource.ExternalFixedIP, fibExternalIp),
+                    true);
+            }
+            break;
+        }
+    }
+
+    @Override
+    protected void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId) {
+        LOG.info("installSnatSpecificEntriesForNaptSwitch: called for router {}",
+            routers.getRouterName());
+        String routerName = routers.getRouterName();
+        Long routerId = NatUtil.getVpnId(confTx, routerName);
+        if (routerId == NatConstants.INVALID_ID) {
+            LOG.error("InvalidRouterId: unable to installSnatSpecificEntriesForNaptSwitch on dpn {}", dpnId);
+            return;
+        }
+        /* Remove Outbound NAT entries */
+
+        removeSnatMissEntryForPrimrySwch(confTx, dpnId, routerId);
+        removeTerminatingServiceTblEntry(confTx, dpnId, routerId);
+
+        removeOutboundTblTrackEntry(confTx, dpnId, routerId);
+        for (ExternalIps externalIp : routers.getExternalIps()) {
+            if (!NWUtil.isIpv4Address(externalIp.getIpAddress())) {
+                // In this class we handle only IPv4 use-cases.
+                continue;
             }
-            createOutboundTblEntry(dpnId, routerId, externalIp.getIpAddress(), elanId, extGwMacAddress, addOrRemove);
-            installNaptPfibFlow(routers, dpnId, routerId, extSubnetId, addOrRemove);
+            //The logic now handle only one external IP per router, others if present will be ignored.
+            removeOutboundTblEntry(confTx, dpnId, routerId);
+            removeNaptPfibFlow(confTx, routers, dpnId, routerId);
 
             //Install Inbound NAT entries
-            installInboundEntry(dpnId, routerId, externalIp.getIpAddress(), elanId, extSubnetId, addOrRemove);
-            installNaptPfibEntry(dpnId, routerId, addOrRemove);
+            removeInboundEntry(confTx, dpnId, routerId);
+            removeNaptPfibEntry(confTx, dpnId, routerId);
 
             String fibExternalIp = NatUtil.validateAndAddNetworkMask(externalIp.getIpAddress());
-            Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(dataBroker, externalIp.getSubnetId());
+            Optional<Subnets> externalSubnet = NatUtil.getOptionalExternalSubnets(confTx, externalIp.getSubnetId());
             if (externalSubnet.isPresent()) {
                 String externalVpn =  externalIp.getSubnetId().getValue();
-                String vpnRd = NatUtil.getVpnRd(dataBroker, externalVpn);
+                String vpnRd = NatUtil.getVpnRd(confTx, externalVpn);
                 vpnFootprintService.updateVpnToDpnMapping(dpnId, externalVpn, vpnRd, null /* interfaceName*/,
-                        new ImmutablePair<>(IpAddresses.IpAddressSource.ExternalFixedIP, fibExternalIp),
-                        addOrRemove == NwConstants.ADD_FLOW);
+                    new ImmutablePair<>(IpAddresses.IpAddressSource.ExternalFixedIP, fibExternalIp),
+                    false);
             }
             break;
         }
     }
 
     @Override
-    protected void installSnatSpecificEntriesForNonNaptSwitch(Routers routers, BigInteger dpnId, int addOrRemove) {
-        // Nothing to to do here.
+    protected void addSnatSpecificEntriesForNonNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId) {
+        // Nothing to to do here
+    }
 
+    @Override
+    protected void removeSnatSpecificEntriesForNonNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId) {
+        // Nothing to to do here
     }
 
-    protected void installSnatMissEntryForPrimrySwch(BigInteger dpnId, Long routerId, int elanId, int addOrRemove) {
+    protected void addSnatMissEntryForPrimrySwch(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long routerId, int elanId) {
         LOG.info("installSnatSpecificEntriesForNaptSwitch : called for the primary NAPT switch dpnId {}", dpnId);
         List<MatchInfo> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
@@ -142,18 +193,26 @@ public abstract class ConntrackBasedSnatService extends AbstractSnatService {
         instructions.add(new InstructionApplyActions(actionsInfos));
 
         String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
-        syncFlow(dpnId, NwConstants.PSNAT_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
+                NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
+    }
+
+    protected void removeSnatMissEntryForPrimrySwch(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long routerId) {
+        LOG.info("installSnatSpecificEntriesForNaptSwitch : called for the primary NAPT switch dpnId {}", dpnId);
+
+        String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
+        removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);
     }
 
-    protected void installTerminatingServiceTblEntry(BigInteger dpnId, Long  routerId, int elanId, int addOrRemove) {
+    protected void addTerminatingServiceTblEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long routerId, int elanId) {
         LOG.info("installTerminatingServiceTblEntry : creating entry for Terminating Service Table "
                 + "for switch {}, routerId {}", dpnId, routerId);
         List<MatchInfo> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
         matches.add(new MatchTunnelId(BigInteger.valueOf(routerId)));
 
-
         List<ActionInfo> actionsInfos = new ArrayList<>();
         List<NxCtAction> ctActionsList = new ArrayList<>();
         NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
@@ -161,130 +220,159 @@ public abstract class ConntrackBasedSnatService extends AbstractSnatService {
         ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
                 .OUTBOUND_NAPT_TABLE,ctActionsList);
         ActionNxLoadMetadata actionLoadMeta = new ActionNxLoadMetadata(MetaDataUtil
-                .getVpnIdMetadata(routerId.longValue()), LOAD_START, LOAD_END);
+                .getVpnIdMetadata(routerId), LOAD_START, LOAD_END);
         actionsInfos.add(actionLoadMeta);
         actionsInfos.add(actionNxConntrack);
         List<InstructionInfo> instructions = new ArrayList<>();
         instructions.add(new InstructionApplyActions(actionsInfos));
-        String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
-        syncFlow(dpnId,  NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
-                 NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId);
+        addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY,
+            flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
+    }
 
+    protected void removeTerminatingServiceTblEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long routerId) {
+        LOG.info("installTerminatingServiceTblEntry : creating entry for Terminating Service Table "
+            + "for switch {}, routerId {}", dpnId, routerId);
+
+        String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId);
+        removeFlow(confTx, dpnId,  NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
     }
 
-    protected void createOutboundTblTrackEntry(BigInteger dpnId, Long routerId, String extGwMacAddress,
-            int addOrRemove) {
+    protected void addOutboundTblTrackEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long routerId, String extGwMacAddress) {
         LOG.info("createOutboundTblTrackEntry : called for switch {}, routerId {}", dpnId, routerId);
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
         matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
         ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            listActionInfo.add(new ActionSetFieldEthernetSource(new MacAddress(extGwMacAddress)));
-        }
+        listActionInfo.add(new ActionSetFieldEthernetSource(new MacAddress(extGwMacAddress)));
         ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
         listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
         instructionInfo.add(new InstructionApplyActions(listActionInfo));
 
-        String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
-        flowRef += "trkest";
-        syncFlow(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo, addOrRemove);
+        String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
+        addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
+                NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
+    }
+
+    protected void removeOutboundTblTrackEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long routerId) {
+        LOG.info("createOutboundTblTrackEntry : called for switch {}, routerId {}", dpnId, routerId);
 
+        String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
+        removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
     }
 
-    protected void createOutboundTblEntry(BigInteger dpnId, long routerId, String externalIp,
-            int elanId, String extGwMacAddress,  int addOrRemove) {
+    protected void addOutboundTblEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId, long routerId,
+        String externalIp, int elanId, String extGwMacAddress) {
         LOG.info("createOutboundTblEntry : dpId {} and routerId {}", dpnId, routerId);
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
         matches.add(new NxMatchCtState(TRACKED_NEW_CT_STATE, TRACKED_NEW_CT_MASK));
         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
         List<ActionInfo> actionsInfos = new ArrayList<>();
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            actionsInfos.add(new ActionSetFieldEthernetSource(new MacAddress(extGwMacAddress)));
-        }
+        actionsInfos.add(new ActionSetFieldEthernetSource(new MacAddress(extGwMacAddress)));
         List<NxCtAction> ctActionsListCommit = new ArrayList<>();
         int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
         int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
         NxCtAction nxCtActionCommit = new ActionNxConntrack.NxNat(0, flags, rangePresent,
-                new IpPrefixOrAddress(externalIp.toCharArray()).getIpAddress(),
-                null,0, 0);
+            new IpPrefixOrAddress(externalIp.toCharArray()).getIpAddress(),
+            null,0, 0);
         ctActionsListCommit.add(nxCtActionCommit);
         int ctCommitFlag = 1;
         ActionNxConntrack actionNxConntrackSubmit = new ActionNxConntrack(ctCommitFlag, 0, elanId,
-                NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
+            NwConstants.NAPT_PFIB_TABLE, ctActionsListCommit);
         actionsInfos.add(actionNxConntrackSubmit);
         List<InstructionInfo> instructions = new ArrayList<>();
         instructions.add(new InstructionApplyActions(actionsInfos));
         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
-        syncFlow(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,  NatConstants.SNAT_NEW_FLOW_PRIORITY,
-                flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,  NatConstants.SNAT_NEW_FLOW_PRIORITY,
+            flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
+    }
+
+    protected void removeOutboundTblEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        long routerId) {
+        LOG.info("createOutboundTblEntry : dpId {} and routerId {}", dpnId, routerId);
+        String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
+        removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
     }
 
-    protected void installNaptPfibFlow(Routers routers, BigInteger dpnId, long routerId,
-            long extSubnetId, int addOrRemove) {
-        Long extNetId = NatUtil.getVpnId(getDataBroker(), routers.getNetworkId().getValue());
+    protected void addNaptPfibFlow(TypedReadWriteTransaction<Configuration> confTx, Routers routers, BigInteger dpnId,
+        long routerId, long extSubnetId) {
+        Long extNetId = NatUtil.getVpnId(confTx, routers.getNetworkId().getValue());
         LOG.info("installNaptPfibFlow : dpId {}, extNetId {}", dpnId, extNetId);
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
         matches.add(new NxMatchCtState(SNAT_CT_STATE, SNAT_CT_STATE_MASK));
         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
         List<ActionInfo> listActionInfo = new ArrayList<>();
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            if (extSubnetId == NatConstants.INVALID_ID) {
-                LOG.error("installNaptPfibFlow : external subnet id is invalid.");
-                return;
-            }
-            ActionNxLoadMetadata actionLoadMeta = new ActionNxLoadMetadata(MetaDataUtil
-                    .getVpnIdMetadata(extSubnetId), LOAD_START, LOAD_END);
-            listActionInfo.add(actionLoadMeta);
+        if (extSubnetId == NatConstants.INVALID_ID) {
+            LOG.error("installNaptPfibFlow : external subnet id is invalid.");
+            return;
         }
+        ActionNxLoadMetadata actionLoadMeta = new ActionNxLoadMetadata(MetaDataUtil
+            .getVpnIdMetadata(extSubnetId), LOAD_START, LOAD_END);
+        listActionInfo.add(actionLoadMeta);
         ArrayList<InstructionInfo> instructions = new ArrayList<>();
         listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
         listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
         instructions.add(new InstructionApplyActions(listActionInfo));
         String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId);
         flowRef = flowRef + "OUTBOUND";
-        syncFlow(dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
-                flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
+            flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
+    }
+
+    protected void removeNaptPfibFlow(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger dpnId, long routerId) {
+        Long extNetId = NatUtil.getVpnId(confTx, routers.getNetworkId().getValue());
+        LOG.info("installNaptPfibFlow : dpId {}, extNetId {}", dpnId, extNetId);
+        String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId) + "OUTBOUND";
+        removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
     }
 
-    protected void installInboundEntry(BigInteger dpnId, long routerId, String externalIp, int elanId, long extSubnetId,
-            int addOrRemove) {
+    protected void addInboundEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId, long routerId,
+        String externalIp, int elanId, long extSubnetId) {
         LOG.info("installInboundEntry : dpId {} and routerId {}", dpnId, routerId);
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
         matches.add(new MatchIpv4Destination(externalIp,"32"));
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            if (extSubnetId == NatConstants.INVALID_ID) {
-                LOG.error("installInboundEntry : external subnet id is invalid.");
-                return;
-            }
-            matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extSubnetId),
-                    MetaDataUtil.METADATA_MASK_VRFID));
+        if (extSubnetId == NatConstants.INVALID_ID) {
+            LOG.error("installInboundEntry : external subnet id is invalid.");
+            return;
         }
+        matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extSubnetId),
+            MetaDataUtil.METADATA_MASK_VRFID));
         List<ActionInfo> actionsInfos = new ArrayList<>();
         List<NxCtAction> ctActionsList = new ArrayList<>();
         NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
         ActionNxLoadMetadata actionLoadMeta = new ActionNxLoadMetadata(MetaDataUtil
-                .getVpnIdMetadata(routerId), LOAD_START, LOAD_END);
+            .getVpnIdMetadata(routerId), LOAD_START, LOAD_END);
         actionsInfos.add(actionLoadMeta);
         ctActionsList.add(nxCtAction);
         ActionNxConntrack actionNxConntrack = new ActionNxConntrack(0, 0, elanId, NwConstants
-                .NAPT_PFIB_TABLE,ctActionsList);
+            .NAPT_PFIB_TABLE,ctActionsList);
 
         actionsInfos.add(actionNxConntrack);
         List<InstructionInfo> instructions = new ArrayList<>();
         instructions.add(new InstructionApplyActions(actionsInfos));
         String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
         flowRef = flowRef + "OUTBOUND";
-        syncFlow(dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
+            NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
+    }
+
+    protected void removeInboundEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        long routerId) {
+        LOG.info("installInboundEntry : dpId {} and routerId {}", dpnId, routerId);
+
+        String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId) + "OUTBOUND";
+        removeFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
     }
 
-    protected void installNaptPfibEntry(BigInteger dpnId, long routerId, int addOrRemove) {
+    protected void addNaptPfibEntry(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId, long routerId) {
         LOG.info("installNaptPfibEntry : called for dpnId {} and routerId {} ", dpnId, routerId);
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
@@ -297,10 +385,15 @@ public abstract class ConntrackBasedSnatService extends AbstractSnatService {
         listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
         instructionInfo.add(new InstructionApplyActions(listActionInfo));
 
+        String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId) + "INBOUND";
+        addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
+            NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
+    }
 
-        String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId);
-        flowRef = flowRef + "INBOUND";
-        syncFlow(dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo, addOrRemove);
+    protected void removeNaptPfibEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        long routerId) {
+        LOG.info("installNaptPfibEntry : called for dpnId {} and routerId {} ", dpnId, routerId);
+        String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, routerId) + "INBOUND";
+        removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
     }
 }
index 3c974f4651d511ccbbf58f6035c88e6b9dc55db6..b141801929792bd6a365369c8e9ec97a546e4750 100644 (file)
@@ -10,6 +10,8 @@ package org.opendaylight.netvirt.natservice.internal;
 import java.math.BigInteger;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.netvirt.fibmanager.api.IFibManager;
@@ -39,22 +41,35 @@ public class FlatVlanConntrackBasedSnatService extends ConntrackBasedSnatService
     }
 
     @Override
-    public boolean handleSnatAllSwitch(Routers routers, BigInteger primarySwitchId,  int addOrRemove) {
-        ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
-        LOG.debug("FlatVlanConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
-        if (extNwProviderType == ProviderTypes.VXLAN || extNwProviderType == ProviderTypes.GRE) {
+    public boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId) {
+        if (checkProviderType(confTx, routers)) {
             return false;
         }
-        return super.handleSnatAllSwitch(routers, primarySwitchId, addOrRemove);
+        return super.addSnatAllSwitch(confTx, routers, primarySwitchId);
     }
 
     @Override
-    public boolean handleSnat(Routers routers, BigInteger primarySwitchId, BigInteger dpnId,  int addOrRemove) {
-        ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
-        LOG.debug("FlatVlanConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
-        if (extNwProviderType == ProviderTypes.VXLAN || extNwProviderType == ProviderTypes.GRE) {
-            return false;
-        }
-        return super.handleSnat(routers, primarySwitchId, dpnId, addOrRemove);
+    public boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId) {
+        return !checkProviderType(confTx, routers) && super.removeSnatAllSwitch(confTx, routers, primarySwitchId);
+    }
+
+    @Override
+    public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId, BigInteger dpnId) {
+        return !checkProviderType(confTx, routers) && super.addSnat(confTx, routers, primarySwitchId, dpnId);
+    }
+
+    @Override
+    public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId, BigInteger dpnId) {
+        return !checkProviderType(confTx, routers) && super.removeSnat(confTx, routers, primarySwitchId, dpnId);
+    }
+
+    private boolean checkProviderType(TypedReadWriteTransaction<Configuration> confTx, Routers routers) {
+        ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
+        LOG.debug("FlatVlanConntrackBasedSnatService: ProviderTypes {}", extNwProviderType);
+        return extNwProviderType == ProviderTypes.VXLAN || extNwProviderType == ProviderTypes.GRE;
     }
 }
index a5d3e2b64dec52ee6d4f3971da14dbf4a7e73e0c..dca3fc2ab02ebe0d1f11360c7b6104ab5983e7cd 100644 (file)
@@ -11,7 +11,6 @@ import com.google.common.base.Optional;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -26,6 +25,9 @@ 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.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.TransactionAdapter;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
 import org.opendaylight.genius.mdsalutil.BucketInfo;
@@ -177,7 +179,10 @@ public class NaptSwitchHA {
     }*/
 
     protected void removeSnatFlowsInOldNaptSwitch(String routerName, Long routerId, BigInteger naptSwitch,
-                                                  Map<String, Long> externalIpmap, WriteTransaction removeFlowInvTx) {
+                                                  Map<String, Long> externalIpmap,
+                                                  TypedReadWriteTransaction<Configuration> confTx) {
+        WriteTransaction removeFlowInvTx = TransactionAdapter.toWriteTransaction(confTx);
+
         //remove SNAT flows in old NAPT SWITCH
         Uuid networkId = NatUtil.getNetworkIdFromRouterName(dataBroker, routerName);
         String vpnName = getExtNetworkVpnName(routerName, networkId);
@@ -206,7 +211,7 @@ public class NaptSwitchHA {
 
             LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for the old napt switch "
                     + "with the DPN ID {} and router ID {}", NwConstants.INTERNAL_TUNNEL_TABLE, naptSwitch, routerId);
-            mdsalManager.removeFlowToTx(tsNatFlowEntity, removeFlowInvTx);
+            mdsalManager.removeFlow(confTx, tsNatFlowEntity);
         }
         if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanManager, extNwProvType)) {
             //Remove the flow table 25->44 If there is no FIP Match on table 25 (PDNAT_TABLE)
@@ -220,19 +225,19 @@ public class NaptSwitchHA {
             NwConstants.OUTBOUND_NAPT_TABLE, routerId, NwConstants.IP_PROT_TCP);
         FlowEntity outboundTcpNatFlowEntity = NatUtil.buildFlowEntity(naptSwitch,
             NwConstants.OUTBOUND_NAPT_TABLE, outboundTcpNatFlowRef);
-        mdsalManager.removeFlowToTx(outboundTcpNatFlowEntity, removeFlowInvTx);
+        mdsalManager.removeFlow(confTx, outboundTcpNatFlowEntity);
 
         String outboundUdpNatFlowRef = externalRouterListener.getFlowRefOutbound(naptSwitch,
                 NwConstants.OUTBOUND_NAPT_TABLE, routerId, NwConstants.IP_PROT_UDP);
         FlowEntity outboundUdpNatFlowEntity = NatUtil.buildFlowEntity(naptSwitch,
                 NwConstants.OUTBOUND_NAPT_TABLE, outboundUdpNatFlowRef);
-        mdsalManager.removeFlowToTx(outboundUdpNatFlowEntity, removeFlowInvTx);
+        mdsalManager.removeFlow(confTx, outboundUdpNatFlowEntity);
 
         String icmpDropFlowRef = externalRouterListener.getFlowRefOutbound(naptSwitch,
                 NwConstants.OUTBOUND_NAPT_TABLE, routerId, NwConstants.IP_PROT_ICMP);
         FlowEntity icmpDropFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.OUTBOUND_NAPT_TABLE,
                 icmpDropFlowRef);
-        mdsalManager.removeFlowToTx(icmpDropFlowEntity, removeFlowInvTx);
+        mdsalManager.removeFlow(confTx, icmpDropFlowEntity);
 
         //Remove the NAPT PFIB TABLE (47->21) which forwards the incoming packet to FIB Table matching on the
         // External Subnet Vpn Id.
@@ -245,7 +250,7 @@ public class NaptSwitchHA {
                         NwConstants.NAPT_PFIB_TABLE, subnetVpnId);
                 FlowEntity natPfibFlowEntity = NatUtil.buildFlowEntity(naptSwitch, NwConstants.NAPT_PFIB_TABLE,
                         natPfibSubnetFlowRef);
-                mdsalManager.removeFlowToTx(natPfibFlowEntity, removeFlowInvTx);
+                mdsalManager.removeFlow(confTx, natPfibFlowEntity);
                 LOG.debug("removeSnatFlowsInOldNaptSwitch : Removed the flow in table {} with external subnet "
                                 + "Vpn Id {} as metadata on Napt Switch {}", NwConstants.NAPT_PFIB_TABLE,
                         subnetVpnId, naptSwitch);
@@ -259,7 +264,7 @@ public class NaptSwitchHA {
             NatUtil.buildFlowEntity(naptSwitch, NwConstants.NAPT_PFIB_TABLE, naptPFibflowRef);
         LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for the old napt switch "
                 + "with the DPN ID {} and router ID {}", NwConstants.NAPT_PFIB_TABLE, naptSwitch, routerId);
-        mdsalManager.removeFlowToTx(naptPFibFlowEntity, removeFlowInvTx);
+        mdsalManager.removeFlow(confTx, naptPFibFlowEntity);
 
         // Remove the NAPT_PFIB_TABLE(47) flow entry forwards the packet to Fib Table for outbound traffic
         // matching on the vpn ID.
@@ -288,7 +293,7 @@ public class NaptSwitchHA {
                             NatUtil.buildFlowEntity(naptSwitch, NwConstants.NAPT_PFIB_TABLE, naptFibflowRef);
                     LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for the old napt switch"
                             + " with the DPN ID {} and vpnId {}", NwConstants.NAPT_PFIB_TABLE, naptSwitch, vpnId);
-                    mdsalManager.removeFlowToTx(naptFibFlowEntity, removeFlowInvTx);
+                    mdsalManager.removeFlow(confTx, naptFibFlowEntity);
                 } else {
                     LOG.error("removeSnatFlowsInOldNaptSwitch : Invalid vpnId retrieved for routerId {}",
                             routerId);
@@ -360,7 +365,7 @@ public class NaptSwitchHA {
 
                 LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for old napt switch "
                         + "with the DPN ID {} and router ID {}", NwConstants.OUTBOUND_NAPT_TABLE, naptSwitch, routerId);
-                mdsalManager.removeFlowToTx(outboundNaptFlowEntity, removeFlowInvTx);
+                mdsalManager.removeFlow(confTx, outboundNaptFlowEntity);
 
                 IpPortExternal ipPortExternal = ipPortMap.getIpPortExternal();
                 if (ipPortExternal == null) {
@@ -380,7 +385,7 @@ public class NaptSwitchHA {
 
                 LOG.info("removeSnatFlowsInOldNaptSwitch : Remove the flow in table {} for old napt switch with the "
                         + "DPN ID {} and router ID {}", NwConstants.INBOUND_NAPT_TABLE, naptSwitch, routerId);
-                mdsalManager.removeFlowToTx(inboundNaptFlowEntity, removeFlowInvTx);
+                mdsalManager.removeFlow(confTx, inboundNaptFlowEntity);
             }
         }
     }
@@ -406,16 +411,16 @@ public class NaptSwitchHA {
 
     public boolean isNaptSwitchDown(String routerName, Long routerId, BigInteger dpnId, BigInteger naptSwitch,
                                     Long routerVpnId, Collection<String> externalIpCache,
-                                    WriteTransaction writeFlowInvTx) {
+                                    TypedReadWriteTransaction<Configuration> confTx) {
         return isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch, routerVpnId, externalIpCache, true,
-                writeFlowInvTx);
+                confTx);
     }
 
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
     public boolean isNaptSwitchDown(String routerName, Long routerId, BigInteger dpnId, BigInteger naptSwitch,
                                     Long routerVpnId, Collection<String> externalIpCache, boolean isClearBgpRts,
-                                    WriteTransaction writeFlowInvTx) {
+                                    TypedReadWriteTransaction<Configuration> confTx) {
         externalIpsCache = externalIpCache;
         if (!naptSwitch.equals(dpnId)) {
             LOG.debug("isNaptSwitchDown : DpnId {} is not a naptSwitch {} for Router {}",
@@ -433,8 +438,8 @@ public class NaptSwitchHA {
         naptSwitch = naptSwitchSelector.selectNewNAPTSwitch(routerName);
         if (natMode == NatMode.Conntrack) {
             Routers extRouters = NatUtil.getRoutersFromConfigDS(dataBroker, routerName);
-            natServiceManager.notify(extRouters, dpnId, dpnId, SnatServiceManager.Action.SNAT_ALL_SWITCH_DISBL);
-            natServiceManager.notify(extRouters, naptSwitch, naptSwitch,
+            natServiceManager.notify(confTx, extRouters, dpnId, dpnId, SnatServiceManager.Action.SNAT_ALL_SWITCH_DISBL);
+            natServiceManager.notify(confTx, extRouters, naptSwitch, naptSwitch,
                     SnatServiceManager.Action.SNAT_ALL_SWITCH_ENBL);
         } else {
             if (naptSwitch.equals(BigInteger.ZERO)) {
@@ -499,10 +504,10 @@ public class NaptSwitchHA {
             } else {
                 LOG.debug("isNaptSwitchDown : Successfully installed flow in naptSwitch {} for router {}",
                         naptSwitch, routerName);
-                mdsalManager.addFlowToTx(flowEntity, writeFlowInvTx);
+                mdsalManager.addFlow(confTx, flowEntity);
             }
 
-            installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, writeFlowInvTx);
+            installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, confTx);
 
             boolean flowInstalledStatus = handleNatFlowsInNewNaptSwitch(routerName, routerId, dpnId, naptSwitch,
                     routerVpnId, networkId);
@@ -516,14 +521,11 @@ public class NaptSwitchHA {
 
             //remove group in new naptswitch, coz this switch acted previously as ordinary switch
             long groupId = NatUtil.createGroupId(NatUtil.getGroupIdKey(routerName), idManager);
-            GroupEntity groupEntity = null;
             try {
-                groupEntity = MDSALUtil.buildGroupEntity(naptSwitch, groupId, routerName,
-                        GroupTypes.GroupAll, Collections.emptyList() /*listBucketInfo*/);
                 LOG.info("isNaptSwitchDown : Removing NAPT Group in new naptSwitch {}", naptSwitch);
-                mdsalManager.removeGroup(groupEntity);
+                mdsalManager.removeGroup(confTx, naptSwitch, groupId);
             } catch (Exception ex) {
-                LOG.error("isNaptSwitchDown : Failed to remove group in new naptSwitch {}", groupEntity, ex);
+                LOG.error("isNaptSwitchDown : Failed to remove group in new naptSwitch {}", naptSwitch, ex);
             }
         }
         return true;
@@ -889,7 +891,8 @@ public class NaptSwitchHA {
     }
 
     protected void installSnatFlows(String routerName, Long routerId, BigInteger naptSwitch, Long routerVpnId,
-                                    WriteTransaction writeFlowInvTx) {
+                                    TypedReadWriteTransaction<Configuration> confTx) {
+        WriteTransaction writeFlowInvTx = TransactionAdapter.toWriteTransaction(confTx);
 
         if (routerId.equals(routerVpnId)) {
             LOG.debug("installSnatFlows : Installing flows for router with internalvpnId");
@@ -990,7 +993,7 @@ public class NaptSwitchHA {
     }
 
     protected void bestEffortDeletion(long routerId, String routerName, Map<String, Long> externalIpLabel,
-                                      WriteTransaction removeFlowInvTx) {
+                                      TypedReadWriteTransaction<Configuration> confTx) {
         Collection<String> newExternalIps = NatUtil.getExternalIpsForRouter(dataBroker, routerId);
         if (externalIpsCache != null) {
             Set<String> removedExternalIps = new HashSet<>(externalIpsCache);
@@ -1028,7 +1031,8 @@ public class NaptSwitchHA {
                 for (String externalIp : removedExternalIps) {
                     externalRouterListener.clearBgpRoutes(externalIp, vpnName);
                     externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName,
-                            networkId, NatConstants.DEFAULT_LABEL_VALUE, gwMacAddress, true, removeFlowInvTx);
+                        networkId, NatConstants.DEFAULT_LABEL_VALUE, gwMacAddress, true,
+                        TransactionAdapter.toWriteTransaction(confTx));
                     LOG.debug("bestEffortDeletion : Successfully removed fib entry for externalIp {} for routerId {} "
                                     + "on NAPT switch {} ", externalIp, routerId, naptSwitch);
                 }
@@ -1050,7 +1054,7 @@ public class NaptSwitchHA {
                     }
                     externalRouterListener.clearBgpRoutes(externalIp, vpnName);
                     externalRouterListener.delFibTsAndReverseTraffic(naptSwitch, routerId, externalIp, vpnName,
-                            networkId, label, gwMacAddress, true, removeFlowInvTx);
+                        networkId, label, gwMacAddress, true, TransactionAdapter.toWriteTransaction(confTx));
                     LOG.debug("bestEffortDeletion : Successfully removed fib entries in switch {} for router {} "
                             + "and externalIps {}", naptSwitch, routerId, externalIp);
                 }
index 67a267a480fdc329e164c604325762bed1dcda85..ecba39adac9b2f00c55743a6309e05ae58aa6df2 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.netvirt.natservice.internal;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
 import com.google.common.base.Optional;
 import com.google.common.base.Strings;
 import com.google.common.util.concurrent.FutureCallback;
@@ -17,7 +19,6 @@ import com.google.common.util.concurrent.MoreExecutors;
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
@@ -26,16 +27,18 @@ import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 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.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore.Configuration;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TransactionAdapter;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.BucketInfo;
 import org.opendaylight.genius.mdsalutil.FlowEntity;
-import org.opendaylight.genius.mdsalutil.GroupEntity;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.MetaDataUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
@@ -60,7 +63,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.Tep
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TepTypeInternal;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.TunnelsState;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.itm.op.rev160406.tunnels_state.StateTunnelList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.GroupTypes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.CreateFibEntryInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.CreateFibEntryInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fib.rpc.rev160121.CreateFibEntryOutput;
@@ -223,7 +225,7 @@ public class NatTunnelInterfaceStateListener
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
     void removeSNATFromDPN(BigInteger dpnId, String routerName, long routerId, long routerVpnId,
-            Uuid networkId, ProviderTypes extNwProvType, WriteTransaction writeFlowInvTx) {
+            Uuid networkId, ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> confTx) {
         //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
         //remove miss entry to NAPT switch
         //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
@@ -253,7 +255,7 @@ public class NatTunnelInterfaceStateListener
             BigInteger naptSwitch = dpnId;
             boolean naptStatus =
                 naptSwitchHA.isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch,
-                        routerVpnId, externalIpCache, false, writeFlowInvTx);
+                        routerVpnId, externalIpCache, false, confTx);
             if (!naptStatus) {
                 LOG.debug("removeSNATFromDPN:SNAT->NaptSwitchDown:Switch with DpnId {} is not naptSwitch for router {}",
                     dpnId, routerName);
@@ -268,7 +270,7 @@ public class NatTunnelInterfaceStateListener
                         return;
                     }
                     LOG.debug("removeSNATFromDPN : SNAT->Removing default SNAT miss entry flow entity {}", flowEntity);
-                    mdsalManager.removeFlowToTx(flowEntity, writeFlowInvTx);
+                    mdsalManager.removeFlow(confTx, flowEntity);
 
                 } catch (Exception ex) {
                     LOG.error("removeSNATFromDPN : SNAT->Failed to remove default SNAT miss entry flow entity {}",
@@ -279,21 +281,17 @@ public class NatTunnelInterfaceStateListener
                     dpnId, routerName);
 
                 //remove group
-                GroupEntity groupEntity = null;
                 try {
-                    groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName,
-                        GroupTypes.GroupAll, Collections.emptyList() /*listBucketInfo*/);
-                    LOG.info("removeSNATFromDPN : SNAT->Removing NAPT GroupEntity:{} on Dpn {}", groupEntity, dpnId);
-                    mdsalManager.removeGroup(groupEntity);
+                    LOG.info("removeSNATFromDPN : SNAT->Removing NAPT Group :{} on Dpn {}", groupId, dpnId);
+                    mdsalManager.removeGroup(confTx, dpnId, groupId);
                 } catch (Exception ex) {
-                    LOG.error("removeSNATFromDPN : SNAT->Failed to remove group entity {}", groupEntity, ex);
+                    LOG.error("removeSNATFromDPN : SNAT->Failed to remove group {}", groupId, ex);
                     return;
                 }
                 LOG.debug("removeSNATFromDPN : SNAT->Removed default SNAT miss entry flow for dpnID {}, routerName {}",
                     dpnId, routerName);
             } else {
-                naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, dpnId,
-                        externalIpLabel, writeFlowInvTx);
+                naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, dpnId, externalIpLabel, confTx);
                 //remove table 26 flow ppointing to table46
                 FlowEntity flowEntity = null;
                 try {
@@ -306,7 +304,7 @@ public class NatTunnelInterfaceStateListener
                     }
                     LOG.debug("removeSNATFromDPN : SNAT->Removing default SNAT miss entry flow entity for "
                         + "router {} with dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
-                    mdsalManager.removeFlowToTx(flowEntity, writeFlowInvTx);
+                    mdsalManager.removeFlow(confTx, flowEntity);
 
                 } catch (Exception ex) {
                     LOG.error("removeSNATFromDPN : SNAT->Failed to remove default SNAT miss entry flow entity {}",
@@ -317,7 +315,7 @@ public class NatTunnelInterfaceStateListener
                         + "with routername {}", dpnId, routerName);
 
                 //best effort to check IntExt model
-                naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, writeFlowInvTx);
+                naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
             }
         } catch (Exception ex) {
             LOG.error("removeSNATFromDPN : SNAT->Exception while handling naptSwitch down for router {}",
@@ -325,8 +323,6 @@ public class NatTunnelInterfaceStateListener
         }
     }
 
-    // TODO Clean up the exception handling
-    @SuppressWarnings("checkstyle:IllegalCatch")
     private void hndlTepEvntsForDpn(StateTunnelList stateTunnelList, TunnelAction tunnelAction) {
         final BigInteger srcDpnId = new BigInteger(stateTunnelList.getSrcInfo().getTepDeviceId());
         final String srcTepIp = String.valueOf(stateTunnelList.getSrcInfo().getTepIp().getValue());
@@ -335,56 +331,52 @@ public class NatTunnelInterfaceStateListener
                 srcDpnId, srcTepIp, destTepIp);
         int tunTypeVal = getTunnelType(stateTunnelList);
         LOG.trace("hndlTepEvntsForDpn : tunTypeVal is {}", tunTypeVal);
-        try {
-            String srcTepId = stateTunnelList.getSrcInfo().getTepDeviceId();
-            String tunnelType = stateTunnelList.getTransportType().toString();
-            String tunnelName = stateTunnelList.getTunnelInterfaceName();
-
-            if (tunTypeVal == NatConstants.ITMTunnelLocType.Invalid.getValue()) {
-                LOG.warn("hndlTepEvntsForDpn : Ignoring TEP event {} for the DPN {} "
-                        + "since its a INVALID TUNNEL TYPE {} b/w SRC IP {} and DST IP {} and " + "TUNNEL NAME {} ",
-                    tunnelAction, srcTepId, tunnelType, srcTepIp, destTepIp, tunnelName);
-                return;
-            }
+        String srcTepId = stateTunnelList.getSrcInfo().getTepDeviceId();
+        String tunnelType = stateTunnelList.getTransportType().toString();
+        String tunnelName = stateTunnelList.getTunnelInterfaceName();
+
+        if (tunTypeVal == NatConstants.ITMTunnelLocType.Invalid.getValue()) {
+            LOG.warn("hndlTepEvntsForDpn : Ignoring TEP event {} for the DPN {} "
+                    + "since its a INVALID TUNNEL TYPE {} b/w SRC IP {} and DST IP {} and " + "TUNNEL NAME {} ",
+                tunnelAction, srcTepId, tunnelType, srcTepIp, destTepIp, tunnelName);
+            return;
+        }
 
-            switch (tunnelAction) {
-                case TUNNEL_EP_ADD:
-                    try {
-                        txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
-                            if (isTunnelInLogicalGroup(stateTunnelList)
-                                    || !hndlTepAddForAllRtrs(srcDpnId, tunnelType, tunnelName, srcTepIp, destTepIp,
-                                    tx)) {
-                                LOG.debug("hndlTepEvntsForDpn : Unable to process TEP ADD");
-                            }
-                        }).get();
-                    } catch (InterruptedException | ExecutionException e) {
-                        LOG.error("Error processing tunnel endpoint addition", e);
-                    }
-                    break;
-                case TUNNEL_EP_DELETE:
-                    try {
-                        txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
-                            if (!handleTepDelForAllRtrs(srcDpnId, tunnelType, tunnelName, srcTepIp, destTepIp, tx)) {
-                                LOG.debug("hndlTepEvntsForDpn : Unable to process TEP DEL");
-                            }
-                        }).get();
-                    } catch (InterruptedException | ExecutionException e) {
-                        LOG.error("Error processing tunnel endpoint removal", e);
-                    }
-                    break;
-                case TUNNEL_EP_UPDATE:
-                    break;
-                default:
-                    LOG.warn("hndlTepEvntsForDpn: unknown tunnelAction: {}", tunnelAction);
-                    break;
-            }
-        } catch (Exception e) {
-            LOG.error("hndlTepEvntsForDpn : Unable to handle the TEP event.", e);
+        switch (tunnelAction) {
+            case TUNNEL_EP_ADD:
+                try {
+                    txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+                        if (isTunnelInLogicalGroup(stateTunnelList)
+                                || !hndlTepAddForAllRtrs(srcDpnId, tunnelType, tunnelName, srcTepIp, destTepIp,
+                                tx)) {
+                            LOG.debug("hndlTepEvntsForDpn : Unable to process TEP ADD");
+                        }
+                    }).get();
+                } catch (InterruptedException | ExecutionException e) {
+                    LOG.error("Error processing tunnel endpoint addition", e);
+                }
+                break;
+            case TUNNEL_EP_DELETE:
+                try {
+                    txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+                        if (!handleTepDelForAllRtrs(srcDpnId, tunnelType, tunnelName, srcTepIp, destTepIp, tx)) {
+                            LOG.debug("hndlTepEvntsForDpn : Unable to process TEP DEL");
+                        }
+                    }).get();
+                } catch (InterruptedException | ExecutionException e) {
+                    LOG.error("Error processing tunnel endpoint removal", e);
+                }
+                break;
+            case TUNNEL_EP_UPDATE:
+                break;
+            default:
+                LOG.warn("hndlTepEvntsForDpn: unknown tunnelAction: {}", tunnelAction);
+                break;
         }
     }
 
     private boolean hndlTepAddForAllRtrs(BigInteger srcDpnId, String tunnelType, String tunnelName, String srcTepIp,
-                                         String destTepIp, WriteTransaction writeFlowInvTx) {
+                                         String destTepIp, TypedReadWriteTransaction<Configuration> writeFlowInvTx) {
         LOG.trace("hndlTepAddForAllRtrs: TEP ADD ----- for EXTERNAL/HWVTEP ITM Tunnel, TYPE {} ,State is UP b/w SRC IP"
             + " : {} and DEST IP: {}", fibManager.getTransportTypeStr(tunnelType), srcTepIp, destTepIp);
 
@@ -435,7 +427,7 @@ public class NatTunnelInterfaceStateListener
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
     private boolean handleTepDelForAllRtrs(BigInteger srcDpnId, String tunnelType, String tunnelName, String srcTepIp,
-                                           String destTepIp, WriteTransaction writeFlowInvTx) {
+                                           String destTepIp, TypedReadWriteTransaction<Configuration> writeFlowInvTx) {
 
         LOG.trace("handleTepDelForAllRtrs : TEP DEL ----- for EXTERNAL/HWVTEP ITM Tunnel,TYPE {},State is UP b/w SRC IP"
             + " : {} and DEST IP: {}", fibManager.getTransportTypeStr(tunnelType), srcTepIp, destTepIp);
@@ -504,7 +496,7 @@ public class NatTunnelInterfaceStateListener
 
     private void hndlTepAddForSnatInEachRtr(RoutersList router, long routerId, final BigInteger srcDpnId,
             String tunnelType, String srcTepIp, String destTepIp, String tunnelName, String nextHopIp,
-            ProviderTypes extNwProvType, WriteTransaction writeFlowInvTx) {
+            ProviderTypes extNwProvType, TypedReadWriteTransaction<Configuration> writeFlowInvTx) {
 
         /*SNAT : Remove the old routes to the external IP having the old TEP IP as the next hop IP
                  Advertise to the BGP about the new route to the external IP having the new TEP IP
@@ -514,9 +506,13 @@ public class NatTunnelInterfaceStateListener
 
         // Check if this is externalRouter else ignore
         InstanceIdentifier<Routers> extRoutersId = NatUtil.buildRouterIdentifier(routerName);
-        Optional<Routers> routerData =
-                SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
-                        LogicalDatastoreType.CONFIGURATION, extRoutersId);
+        Optional<Routers> routerData;
+        try {
+            routerData = writeFlowInvTx.read(extRoutersId).get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error reading router data for {}", extRoutersId, e);
+            routerData = Optional.absent();
+        }
         if (!routerData.isPresent()) {
             LOG.warn("hndlTepAddForSnatInEachRtr : SNAT->Ignoring TEP add for router {} since its not External Router",
                     routerName);
@@ -531,7 +527,7 @@ public class NatTunnelInterfaceStateListener
             return;
         }
         if (natMode == NatMode.Conntrack) {
-            natServiceManager.notify(routerData.get(), naptId, srcDpnId,
+            natServiceManager.notify(writeFlowInvTx, routerData.get(), naptId, srcDpnId,
                     SnatServiceManager.Action.SNAT_ROUTER_ENBL);
         } else {
             Uuid bgpVpnUuId = NatUtil.getVpnForRouter(dataBroker, routerName);
@@ -561,8 +557,8 @@ public class NatTunnelInterfaceStateListener
     }
 
     private boolean hndlTepAddOnNonNaptSwitch(BigInteger srcDpnId, BigInteger primaryDpnId, String tunnelType,
-                                              String srcTepIp, String destTepIp, String tunnelName, String routerName,
-                                              long routerId, Uuid vpnName, WriteTransaction writeFlowInvTx) {
+        String srcTepIp, String destTepIp, String tunnelName, String routerName, long routerId, Uuid vpnName,
+        TypedWriteTransaction<Configuration> confTx) {
 
         /*
         1) Install default NAT rule from table 21 to 26
@@ -587,7 +583,8 @@ public class NatTunnelInterfaceStateListener
             //Install default entry in FIB to SNAT table
             LOG.debug("hndlTepAddOnNonNaptSwitch : Installing default route in FIB on DPN {} for router {} with"
                 + " vpn {}...", srcDpnId, routerName, vpnId);
-            defaultRouteProgrammer.installDefNATRouteInDPN(srcDpnId, vpnId, writeFlowInvTx);
+            defaultRouteProgrammer.installDefNATRouteInDPN(srcDpnId, vpnId,
+                TransactionAdapter.toWriteTransaction(confTx));
 
             LOG.debug("hndlTepAddOnNonNaptSwitch : SNAT -> Install the group which forward packet to the tunnel port "
                 + "for the NAPT switch {} and the flow 26 which forwards to group", primaryDpnId);
@@ -609,7 +606,8 @@ public class NatTunnelInterfaceStateListener
             //Install default entry in FIB to SNAT table
             LOG.debug("hndlTepAddOnNonNaptSwitch : Installing default route in FIB on dpn {} for routerId {} "
                 + "with vpnId {}...", srcDpnId, routerId, vpnId);
-            defaultRouteProgrammer.installDefNATRouteInDPN(srcDpnId, vpnId, routerId, writeFlowInvTx);
+            defaultRouteProgrammer.installDefNATRouteInDPN(srcDpnId, vpnId, routerId,
+                TransactionAdapter.toWriteTransaction(confTx));
 
             LOG.debug("hndlTepAddOnNonNaptSwitch : Install group in non NAPT switch {} for router {}",
                     srcDpnId, routerName);
@@ -621,7 +619,7 @@ public class NatTunnelInterfaceStateListener
                     + "in the non NAPT switch {}", groupId, srcDpnId);
             FlowEntity flowEntity =
                 externalRouterListner.buildSnatFlowEntityWithUpdatedVpnId(srcDpnId, routerName, groupId, vpnId);
-            mdsalManager.addFlowToTx(flowEntity, writeFlowInvTx);
+            mdsalManager.addFlow(confTx, flowEntity);
         }
         return true;
     }
@@ -629,7 +627,7 @@ public class NatTunnelInterfaceStateListener
     private boolean hndlTepAddOnNaptSwitch(BigInteger srcDpnId, String tunnelType, String srcTepIp,
                                            String destTepIp, String tunnelName, long routerId,
                                            Optional<Routers> routerData, String nextHopIp, Uuid vpnName,
-                                           ProviderTypes extNwProvType, WriteTransaction writeFlowInvTx) {
+                                           ProviderTypes extNwProvType, TypedWriteTransaction<Configuration> confTx) {
         if (!routerData.isPresent()) {
             LOG.warn("hndlTepAddOnNaptSwitch: routerData is not present");
             return false;
@@ -731,8 +729,8 @@ public class NatTunnelInterfaceStateListener
                 LOG.debug("hndlTepAddOnNaptSwitch : SNAT -> Advertise the route to the externalIp {} "
                         + "having nextHopIp {}", externalIp, nextHopIp);
                 NatEvpnUtil.addRoutesForVxLanProvType(dataBroker, bgpManager, fibManager, externalVpnName, rd,
-                        externalIp, nextHopIp, l3Vni, tunnelName, gwMacAddress, writeFlowInvTx, RouteOrigin.STATIC,
-                        srcDpnId);
+                        externalIp, nextHopIp, l3Vni, tunnelName, gwMacAddress,
+                        TransactionAdapter.toWriteTransaction(confTx), RouteOrigin.STATIC, srcDpnId);
                 serviceId = l3Vni;
             } else {
 
@@ -804,7 +802,7 @@ public class NatTunnelInterfaceStateListener
     }
 
     private void hndlTepAddForDnatInEachRtr(RoutersList router, long routerId, String nextHopIp,
-            BigInteger tepAddedDpnId, ProviderTypes extNwProvType, WriteTransaction writeFlowInvTx) {
+            BigInteger tepAddedDpnId, ProviderTypes extNwProvType, TypedWriteTransaction<Configuration> confTx) {
         //DNAT : Advertise the new route to the floating IP having the new TEP IP as the next hop IP
         final String routerName = router.getRouter();
 
@@ -880,8 +878,8 @@ public class NatTunnelInterfaceStateListener
                     LOG.debug("hndlTepAddForDnatInEachRtr : DNAT -> Advertise the route to the externalIp {} "
                             + "having nextHopIp {}", externalIp, nextHopIp);
                     NatEvpnUtil.addRoutesForVxLanProvType(dataBroker, bgpManager, fibManager, vpnName, rd,
-                            externalIp, nextHopIp, l3Vni, interfaceName, gwMacAddress, writeFlowInvTx,
-                            RouteOrigin.STATIC, fipCfgdDpnId);
+                            externalIp, nextHopIp, l3Vni, interfaceName, gwMacAddress,
+                            TransactionAdapter.toWriteTransaction(confTx), RouteOrigin.STATIC, fipCfgdDpnId);
                     serviceId = l3Vni;
                 } else {
                     long label = floatingIPListener.getOperationalIpMapping(routerName, interfaceName, internalIp);
@@ -937,8 +935,8 @@ public class NatTunnelInterfaceStateListener
     }
 
     private void hndlTepDelForSnatInEachRtr(RoutersList router, long routerId, BigInteger dpnId, String tunnelType,
-                                            String srcTepIp, String destTepIp, String tunnelName,
-                                            ProviderTypes extNwProvType, WriteTransaction writeFlowInvTx) {
+        String srcTepIp, String destTepIp, String tunnelName, ProviderTypes extNwProvType,
+        TypedReadWriteTransaction<Configuration> confTx) {
        /*SNAT :
             1) Elect a new switch as the primary NAPT
             2) Advertise the new routes to BGP for the newly elected TEP IP as the DPN IP
@@ -951,9 +949,13 @@ public class NatTunnelInterfaceStateListener
 
         // Check if this is externalRouter else ignore
         InstanceIdentifier<Routers> extRoutersId = NatUtil.buildRouterIdentifier(routerName);
-        Optional<Routers> routerData =
-                SingleTransactionDataBroker.syncReadOptionalAndTreatReadFailedExceptionAsAbsentOptional(dataBroker,
-                        LogicalDatastoreType.CONFIGURATION, extRoutersId);
+        Optional<Routers> routerData;
+        try {
+            routerData = confTx.read(extRoutersId).get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error retrieving routers {}", extRoutersId, e);
+            routerData = Optional.absent();
+        }
         if (!routerData.isPresent()) {
             LOG.debug("hndlTepDelForSnatInEachRtr : SNAT->Ignoring TEP del for router {} since its not External Router",
                     routerName);
@@ -969,7 +971,8 @@ public class NatTunnelInterfaceStateListener
             return;
         }
         if (natMode == NatMode.Conntrack) {
-            natServiceManager.notify(routerData.get(), naptId, dpnId, SnatServiceManager.Action.SNAT_ROUTER_DISBL);
+            natServiceManager.notify(confTx, routerData.get(), naptId, dpnId,
+                SnatServiceManager.Action.SNAT_ROUTER_DISBL);
         } else {
 
 
@@ -993,7 +996,8 @@ public class NatTunnelInterfaceStateListener
                 //Install default entry in FIB to SNAT table
                 LOG.debug("hndlTepDelForSnatInEachRtr : Installing default route in FIB on DPN {} for router {} with"
                         + " vpn {}...", dpnId, routerName, bgpVpnId);
-                defaultRouteProgrammer.installDefNATRouteInDPN(dpnId, bgpVpnId, writeFlowInvTx);
+                defaultRouteProgrammer.installDefNATRouteInDPN(dpnId, bgpVpnId,
+                    TransactionAdapter.toWriteTransaction(confTx));
             } else {
                 bgpVpnId = NatUtil.getVpnId(dataBroker, bgpVpnUuid.getValue());
                 if (bgpVpnId == NatConstants.INVALID_ID) {
@@ -1006,7 +1010,8 @@ public class NatTunnelInterfaceStateListener
                 //Install default entry in FIB to SNAT table
                 LOG.debug("hndlTepDelForSnatInEachRtr : Installing default route in FIB on dpn {} for routerId {} "
                         + "with vpnId {}...", dpnId, routerId, bgpVpnId);
-                defaultRouteProgrammer.installDefNATRouteInDPN(dpnId, bgpVpnId, routerId, writeFlowInvTx);
+                defaultRouteProgrammer.installDefNATRouteInDPN(dpnId, bgpVpnId, routerId,
+                    TransactionAdapter.toWriteTransaction(confTx));
             }
 
             if (routerData.get().isEnableSnat()) {
@@ -1022,7 +1027,7 @@ public class NatTunnelInterfaceStateListener
                             + "associated to the router {}", routerVpnId, routerName);
                 }
                 //Re-elect the other available switch as the NAPT switch and program the NAT flows.
-                removeSNATFromDPN(dpnId, routerName, routerId, routerVpnId, networkId, extNwProvType, writeFlowInvTx);
+                removeSNATFromDPN(dpnId, routerName, routerId, routerVpnId, networkId, extNwProvType, confTx);
             } else {
                 LOG.info("hndlTepDelForSnatInEachRtr : SNAT is not enabled for router {} to handle addDPN event {}",
                         routerId, dpnId);
index f142b79f729ec090d8fe6acc50d144531dbbc197..72e55047f763db9ebe1a3e67d3b48896a9e0b32b 100644 (file)
@@ -37,7 +37,9 @@ 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.infra.Datastore.Configuration;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
+import org.opendaylight.genius.infra.TypedReadTransaction;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
 import org.opendaylight.genius.mdsalutil.FlowEntity;
@@ -285,6 +287,22 @@ public final class NatUtil {
         return vpnId;
     }
 
+    public static long getVpnId(TypedReadTransaction<Configuration> confTx, String vpnName) {
+        if (vpnName == null) {
+            return NatConstants.INVALID_ID;
+        }
+
+        try {
+            return confTx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
+                    .VpnInstance::getVpnId).orElse(NatConstants.INVALID_ID);
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error retrieving VPN id for {}", vpnName, e);
+        }
+
+        return NatConstants.INVALID_ID;
+    }
+
     public static Long getNetworkVpnIdFromRouterId(DataBroker broker, long routerId) {
         //Get the external network ID from the ExternalRouter model
         Uuid networkId = NatUtil.getNetworkIdFromRouterId(broker, routerId);
@@ -416,6 +434,17 @@ public final class NatUtil {
                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
     }
 
+    @Nullable
+    public static ProviderTypes getProviderTypefromNetworkId(TypedReadTransaction<Configuration> tx, Uuid networkId) {
+        InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
+        try {
+            return tx.read(id).get().toJavaUtil().map(Networks::getProviderNetworkType).orElse(null);
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error retrieving provider type for {}", networkId, e);
+            return null;
+        }
+    }
+
     @Nonnull
     public static List<Uuid> getRouterIdsfromNetworkId(DataBroker broker, Uuid networkId) {
         InstanceIdentifier<Networks> id = buildNetworkIdentifier(networkId);
@@ -531,6 +560,17 @@ public final class NatUtil {
                         .VpnInstance::getVrfId).orElse(null);
     }
 
+    public static String getVpnRd(TypedReadTransaction<Configuration> tx, String vpnName) {
+        try {
+            return tx.read(getVpnInstanceToVpnIdIdentifier(vpnName)).get().toJavaUtil().map(
+                org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.to.vpn.id
+                    .VpnInstance::getVrfId).orElse(null);
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error reading the VPN VRF id for {}", vpnName, e);
+            return null;
+        }
+    }
+
     public static IpPortExternal getExternalIpPortMap(DataBroker broker, Long routerId, String internalIpAddress,
                                                       String internalPort, NAPTEntryEvent.Protocol protocol) {
         ProtocolTypes protocolType = NatUtil.getProtocolType(protocol);
@@ -1589,6 +1629,16 @@ public final class NatUtil {
                 LogicalDatastoreType.CONFIGURATION, routerIdentifier).orNull();
     }
 
+    @Nullable
+    public static Routers getRoutersFromConfigDS(TypedReadTransaction<Configuration> confTx, String routerName) {
+        try {
+            return confTx.read(NatUtil.buildRouterIdentifier(routerName)).get().orNull();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error reading router {}", routerName, e);
+            return null;
+        }
+    }
+
     static void createRouterIdsConfigDS(DataBroker dataBroker, long routerId, String routerName) {
         if (routerId == NatConstants.INVALID_ID) {
             LOG.error("createRouterIdsConfigDS : invalid routerId for routerName {}", routerName);
@@ -1642,6 +1692,16 @@ public final class NatUtil {
                 LogicalDatastoreType.CONFIGURATION, id).toJavaUtil().map(Routers::getExtGwMacAddress).orElse(null);
     }
 
+    @Nullable
+    static String getExtGwMacAddFromRouterName(TypedReadTransaction<Configuration> tx, String routerName) {
+        try {
+            return tx.read(buildRouterIdentifier(routerName)).get().toJavaUtil().map(
+                Routers::getExtGwMacAddress).orElse(null);
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error retrieving external gateway MAC address for router {}", routerName, e);
+            return null;
+        }
+    }
 
     static InstanceIdentifier<Router> buildNeutronRouterIdentifier(Uuid routerUuid) {
         InstanceIdentifier<Router> routerInstanceIdentifier = InstanceIdentifier.create(Neutron.class)
@@ -1739,6 +1799,27 @@ public final class NatUtil {
                 LogicalDatastoreType.CONFIGURATION, subnetsIdentifier);
     }
 
+    @Nonnull
+    protected static Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
+        .subnets.Subnets> getOptionalExternalSubnets(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
+        if (subnetId == null) {
+            LOG.warn("getOptionalExternalSubnets : subnetId is null");
+            return Optional.absent();
+        }
+
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
+            .rev160111.external.subnets.Subnets> subnetsIdentifier =
+            InstanceIdentifier.builder(ExternalSubnets.class)
+                .child(org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice
+                    .rev160111.external.subnets.Subnets.class, new SubnetsKey(subnetId)).build();
+        try {
+            return tx.read(subnetsIdentifier).get();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error retrieving external subnets on {}", subnetId, e);
+            return Optional.absent();
+        }
+    }
+
     protected static long getExternalSubnetVpnId(DataBroker dataBroker, Uuid subnetId) {
         Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
             .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(dataBroker,
@@ -1750,6 +1831,17 @@ public final class NatUtil {
         return NatConstants.INVALID_ID;
     }
 
+    protected static long getExternalSubnetVpnId(TypedReadTransaction<Configuration> tx, Uuid subnetId) {
+        Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.external
+            .subnets.Subnets> optionalExternalSubnets = NatUtil.getOptionalExternalSubnets(tx,
+            subnetId);
+        if (optionalExternalSubnets.isPresent()) {
+            return NatUtil.getVpnId(tx, subnetId.getValue());
+        }
+
+        return NatConstants.INVALID_ID;
+    }
+
     protected static long getExternalSubnetVpnIdForRouterExternalIp(DataBroker dataBroker, String externalIpAddress,
             Routers router) {
         Uuid externalSubnetId = NatUtil.getExternalSubnetForRouterExternalIp(externalIpAddress, router);
@@ -1799,6 +1891,16 @@ public final class NatUtil {
                 LogicalDatastoreType.CONFIGURATION, elanIdentifierId).orNull();
     }
 
+    @Nullable
+    public static ElanInstance getElanInstanceByName(TypedReadTransaction<Configuration> tx, String elanInstanceName) {
+        try {
+            return tx.read(getElanInstanceConfigurationDataPath(elanInstanceName)).get().orNull();
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.error("Error retrieving ELAN instance by name {}", elanInstanceName, e);
+            return null;
+        }
+    }
+
     public static InstanceIdentifier<ElanInstance> getElanInstanceConfigurationDataPath(String elanInstanceName) {
         return InstanceIdentifier.builder(ElanInstances.class)
                 .child(ElanInstance.class, new ElanInstanceKey(elanInstanceName)).build();
index 5c10978936e63590122b95ccecacb9d2936ac4dd..6d1c8aa00624bd09375ed6934885098ffc3c3a75 100644 (file)
@@ -7,10 +7,10 @@
  */
 package org.opendaylight.netvirt.natservice.internal;
 
+import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+
 import com.google.common.base.Optional;
-import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -19,18 +19,21 @@ import javax.annotation.PostConstruct;
 import javax.inject.Inject;
 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.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
+import org.opendaylight.genius.infra.Datastore.Configuration;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
 import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.TransactionAdapter;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.genius.mdsalutil.BucketInfo;
 import org.opendaylight.genius.mdsalutil.FlowEntity;
 import org.opendaylight.genius.mdsalutil.GroupEntity;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.interfaces.IMdsalApiManager;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
+import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
 import org.opendaylight.netvirt.elanmanager.api.IElanService;
 import org.opendaylight.netvirt.natservice.api.SnatServiceManager;
 import org.opendaylight.netvirt.neutronvpn.interfaces.INeutronVpnManager;
@@ -135,8 +138,9 @@ public class RouterDpnChangeListener
                         LOG.debug("Skipping the notification recived for NAPT switch {}", routerUuid);
                         return;
                     }
-                    natServiceManager.notify(router, naptSwitch, dpnId,
-                            SnatServiceManager.Action.SNAT_ROUTER_ENBL);
+                    ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                        confTx -> natServiceManager.notify(confTx, router, naptSwitch, dpnId,
+                            SnatServiceManager.Action.SNAT_ROUTER_ENBL)), LOG, "Error notifying NAT service manager");
                 } else {
                     Long routerId = NatUtil.getVpnId(dataBroker, routerUuid);
                     if (routerId == NatConstants.INVALID_ID) {
@@ -154,53 +158,51 @@ public class RouterDpnChangeListener
                         });
                     }
                     coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + router.getRouterName(), () -> {
-                        List<ListenableFuture<Void>> futures = new ArrayList<>(2);
                         LOG.debug("add : Router {} is associated with ext nw {}", routerUuid, networkId);
                         Uuid vpnName = NatUtil.getVpnForRouter(dataBroker, routerUuid);
-                        futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(writeFlowInvTx -> {
-                            Long vpnId;
-                            if (vpnName == null) {
-                                LOG.debug("add : Internal vpn associated to router {}", routerUuid);
-                                vpnId = routerId;
-                                if (vpnId == NatConstants.INVALID_ID) {
-                                    LOG.error("add : Invalid vpnId returned for routerName {}", routerUuid);
-                                    return;
-                                }
-                                LOG.debug("add : Retrieved vpnId {} for router {}", vpnId, routerUuid);
-                                //Install default entry in FIB to SNAT table
-                                LOG.info("add : Installing default route in FIB on dpn {} for router {} with vpn {}",
+                        return Collections.singletonList(
+                            txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
+                                Long vpnId;
+                                if (vpnName == null) {
+                                    LOG.debug("add : Internal vpn associated to router {}", routerUuid);
+                                    vpnId = routerId;
+                                    if (vpnId == NatConstants.INVALID_ID) {
+                                        LOG.error("add : Invalid vpnId returned for routerName {}", routerUuid);
+                                        return;
+                                    }
+                                    LOG.debug("add : Retrieved vpnId {} for router {}", vpnId, routerUuid);
+                                    //Install default entry in FIB to SNAT table
+                                    LOG.info(
+                                        "add : Installing default route in FIB on dpn {} for router {} with vpn {}",
                                         dpnId, routerUuid, vpnId);
-                                snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnId, writeFlowInvTx);
-                            } else {
-                                LOG.debug("add : External BGP vpn associated to router {}", routerUuid);
-                                vpnId = NatUtil.getVpnId(dataBroker, vpnName.getValue());
-                                if (vpnId == NatConstants.INVALID_ID) {
-                                    LOG.error("add : Invalid vpnId returned for routerName {}", routerUuid);
-                                    return;
-                                }
-                                LOG.debug("add : Retrieved vpnId {} for router {}", vpnId, routerUuid);
-                                //Install default entry in FIB to SNAT table
-                                LOG.debug("add : Installing default route in FIB on dpn {} for routerId {} with "
+                                    snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnId,
+                                        TransactionAdapter.toWriteTransaction(confTx));
+                                } else {
+                                    LOG.debug("add : External BGP vpn associated to router {}", routerUuid);
+                                    vpnId = NatUtil.getVpnId(dataBroker, vpnName.getValue());
+                                    if (vpnId == NatConstants.INVALID_ID) {
+                                        LOG.error("add : Invalid vpnId returned for routerName {}", routerUuid);
+                                        return;
+                                    }
+                                    LOG.debug("add : Retrieved vpnId {} for router {}", vpnId, routerUuid);
+                                    //Install default entry in FIB to SNAT table
+                                    LOG.debug("add : Installing default route in FIB on dpn {} for routerId {} with "
                                         + "vpnId {}...", dpnId, routerUuid, vpnId);
-                                snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnId, routerId,
-                                        writeFlowInvTx);
-                            }
-                            if (router.isEnableSnat()) {
-                                LOG.info("add : SNAT enabled for router {}", routerUuid);
-                                if (extNwProvType == null) {
-                                    LOG.error("add : External Network Provider Type missing");
-                                    return;
+                                    snatDefaultRouteProgrammer.installDefNATRouteInDPN(dpnId, vpnId, routerId,
+                                        TransactionAdapter.toWriteTransaction(confTx));
                                 }
-                                futures.add(txRunner.callWithNewWriteOnlyTransactionAndSubmit(removeFlowInvTx -> {
-                                    handleSNATForDPN(dpnId, routerUuid, routerId, vpnId, writeFlowInvTx,
-                                            removeFlowInvTx, extNwProvType);
-                                }));
-                            } else {
-                                LOG.info("add : SNAT is not enabled for router {} to handle addDPN event {}",
+                                if (router.isEnableSnat()) {
+                                    LOG.info("add : SNAT enabled for router {}", routerUuid);
+                                    if (extNwProvType == null) {
+                                        LOG.error("add : External Network Provider Type missing");
+                                        return;
+                                    }
+                                    handleSNATForDPN(dpnId, routerUuid, routerId, vpnId, confTx, extNwProvType);
+                                } else {
+                                    LOG.info("add : SNAT is not enabled for router {} to handle addDPN event {}",
                                         routerUuid, dpnId);
-                            }
-                        }));
-                        return futures;
+                                }
+                            }));
                     }, NatConstants.NAT_DJC_MAX_RETRIES);
                 } // end of controller based SNAT
             }
@@ -239,48 +241,52 @@ public class RouterDpnChangeListener
                         LOG.debug("Skipping the notification recived for NAPT switch {}", routerUuid);
                         return;
                     }
-                    natServiceManager.notify(router, naptSwitch, dpnId,
-                            SnatServiceManager.Action.SNAT_ROUTER_DISBL);
+                    ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION,
+                        confTx -> natServiceManager.notify(confTx, router, naptSwitch, dpnId,
+                            SnatServiceManager.Action.SNAT_ROUTER_DISBL)), LOG, "Error notifying NAT service manager");
                 } else {
                     coordinator.enqueueJob(NatConstants.NAT_DJC_PREFIX + routerUuid, () -> {
                         LOG.debug("remove : Router {} is associated with ext nw {}", routerUuid, networkId);
                         Uuid vpnName = NatUtil.getVpnForRouter(dataBroker, routerUuid);
-                        return Collections.singletonList(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
-                            Long vpnId;
-                            if (vpnName == null) {
-                                LOG.debug("remove : Internal vpn associated to router {}", routerUuid);
-                                vpnId = routerId;
-                                if (vpnId == NatConstants.INVALID_ID) {
-                                    LOG.error("remove : Invalid vpnId returned for routerName {}", routerUuid);
-                                    return;
-                                }
-                                LOG.debug("remove : Retrieved vpnId {} for router {}", vpnId, routerUuid);
-                                //Remove default entry in FIB
-                                LOG.debug("remove : Removing default route in FIB on dpn {} for vpn {} ...", dpnId,
+                        return Collections.singletonList(
+                            txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, confTx -> {
+                                Long vpnId;
+                                if (vpnName == null) {
+                                    LOG.debug("remove : Internal vpn associated to router {}", routerUuid);
+                                    vpnId = routerId;
+                                    if (vpnId == NatConstants.INVALID_ID) {
+                                        LOG.error("remove : Invalid vpnId returned for routerName {}", routerUuid);
+                                        return;
+                                    }
+                                    LOG.debug("remove : Retrieved vpnId {} for router {}", vpnId, routerUuid);
+                                    //Remove default entry in FIB
+                                    LOG.debug("remove : Removing default route in FIB on dpn {} for vpn {} ...", dpnId,
                                         vpnName);
-                                snatDefaultRouteProgrammer.removeDefNATRouteInDPN(dpnId, vpnId, tx);
-                            } else {
-                                LOG.debug("remove : External vpn associated to router {}", routerUuid);
-                                vpnId = NatUtil.getVpnId(dataBroker, vpnName.getValue());
-                                if (vpnId == NatConstants.INVALID_ID) {
-                                    LOG.error("remove : Invalid vpnId returned for routerName {}", routerUuid);
-                                    return;
-                                }
-                                LOG.debug("remove : Retrieved vpnId {} for router {}", vpnId, routerUuid);
-                                //Remove default entry in FIB
-                                LOG.debug("remove : Removing default route in FIB on dpn {} for vpn {} ...", dpnId,
+                                    snatDefaultRouteProgrammer.removeDefNATRouteInDPN(dpnId, vpnId,
+                                        TransactionAdapter.toWriteTransaction(confTx));
+                                } else {
+                                    LOG.debug("remove : External vpn associated to router {}", routerUuid);
+                                    vpnId = NatUtil.getVpnId(dataBroker, vpnName.getValue());
+                                    if (vpnId == NatConstants.INVALID_ID) {
+                                        LOG.error("remove : Invalid vpnId returned for routerName {}", routerUuid);
+                                        return;
+                                    }
+                                    LOG.debug("remove : Retrieved vpnId {} for router {}", vpnId, routerUuid);
+                                    //Remove default entry in FIB
+                                    LOG.debug("remove : Removing default route in FIB on dpn {} for vpn {} ...", dpnId,
                                         vpnName);
-                                snatDefaultRouteProgrammer.removeDefNATRouteInDPN(dpnId, vpnId, routerId, tx);
-                            }
+                                    snatDefaultRouteProgrammer.removeDefNATRouteInDPN(dpnId, vpnId, routerId,
+                                        TransactionAdapter.toWriteTransaction(confTx));
+                                }
 
-                            if (router.isEnableSnat()) {
-                                LOG.info("remove : SNAT enabled for router {}", routerUuid);
-                                removeSNATFromDPN(dpnId, routerUuid, routerId, vpnId, networkId, tx);
-                            } else {
-                                LOG.info("remove : SNAT is not enabled for router {} to handle removeDPN event {}",
+                                if (router.isEnableSnat()) {
+                                    LOG.info("remove : SNAT enabled for router {}", routerUuid);
+                                    removeSNATFromDPN(dpnId, routerUuid, routerId, vpnId, networkId, confTx);
+                                } else {
+                                    LOG.info("remove : SNAT is not enabled for router {} to handle removeDPN event {}",
                                         routerUuid, dpnId);
-                            }
-                        }));
+                                }
+                            }));
                     }, NatConstants.NAT_DJC_MAX_RETRIES);
                 } // end of controller based SNAT
             }
@@ -296,7 +302,7 @@ public class RouterDpnChangeListener
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
     void handleSNATForDPN(BigInteger dpnId, String routerName, long routerId, Long routerVpnId,
-            WriteTransaction writeFlowInvTx, WriteTransaction removeFlowInvTx, ProviderTypes extNwProvType) {
+        TypedReadWriteTransaction<Configuration> confTx, ProviderTypes extNwProvType) {
        //Check if primary and secondary switch are selected, If not select the role
         //Install select group to NAPT switch
         //Install default miss entry to NAPT switch
@@ -326,7 +332,7 @@ public class RouterDpnChangeListener
                     naptSwitchHA.subnetRegisterMapping(extRouters, routerId);
                 }
 
-                naptSwitchHA.installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, writeFlowInvTx);
+                naptSwitchHA.installSnatFlows(routerName, routerId, naptSwitch, routerVpnId, confTx);
 
                 // Install miss entry (table 26) pointing to table 46
                 FlowEntity flowEntity = naptSwitchHA.buildSnatFlowEntityForNaptSwitch(dpnId, routerName,
@@ -337,12 +343,12 @@ public class RouterDpnChangeListener
                     return;
                 }
                 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {}", dpnId, routerName);
-                mdsalManager.addFlowToTx(flowEntity, writeFlowInvTx);
+                mdsalManager.addFlow(confTx, flowEntity);
                 //Removing primary flows from old napt switch
                 if (naptId != null && !naptId.equals(BigInteger.ZERO)) {
                     LOG.debug("handleSNATForDPN : Removing primary flows from old napt switch {} for router {}",
                             naptId, routerName);
-                    naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptId, null, removeFlowInvTx);
+                    naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptId, null, confTx);
                 }
             } else if (naptId.equals(dpnId)) {
                 LOG.debug("handleSNATForDPN : NaptSwitch {} gone down during cluster reboot came alive", naptId);
@@ -368,7 +374,7 @@ public class RouterDpnChangeListener
                 }
                 LOG.debug("handleSNATForDPN : Successfully installed flow for dpnId {} router {} group {}",
                         dpnId, routerName, groupId);
-                mdsalManager.addFlowToTx(flowEntity, writeFlowInvTx);
+                mdsalManager.addFlow(confTx, flowEntity);
             }
 
         } catch (Exception ex) {
@@ -379,7 +385,7 @@ public class RouterDpnChangeListener
     // TODO Clean up the exception handling
     @SuppressWarnings("checkstyle:IllegalCatch")
     void removeSNATFromDPN(BigInteger dpnId, String routerName, long routerId, long routerVpnId,
-            Uuid extNetworkId, WriteTransaction removeFlowInvTx) {
+            Uuid extNetworkId, TypedReadWriteTransaction<Configuration> confTx) {
         //irrespective of naptswitch or non-naptswitch, SNAT default miss entry need to be removed
         //remove miss entry to NAPT switch
         //if naptswitch elect new switch and install Snat flows and remove those flows in oldnaptswitch
@@ -404,7 +410,7 @@ public class RouterDpnChangeListener
         try {
             boolean naptStatus =
                 naptSwitchHA.isNaptSwitchDown(routerName, routerId, dpnId, naptSwitch, routerVpnId,
-                        externalIpCache, removeFlowInvTx);
+                        externalIpCache, confTx);
             if (!naptStatus) {
                 LOG.debug("removeSNATFromDPN: Switch with DpnId {} is not naptSwitch for router {}",
                     dpnId, routerName);
@@ -419,7 +425,7 @@ public class RouterDpnChangeListener
                         return;
                     }
                     LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity {}", flowEntity);
-                    mdsalManager.removeFlowToTx(flowEntity, removeFlowInvTx);
+                    mdsalManager.removeFlow(confTx, flowEntity);
 
                 } catch (Exception ex) {
                     LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
@@ -444,7 +450,7 @@ public class RouterDpnChangeListener
                     dpnId, routerName);
             } else {
                 naptSwitchHA.removeSnatFlowsInOldNaptSwitch(routerName, routerId, naptSwitch,
-                        externalIpLabel, removeFlowInvTx);
+                        externalIpLabel, confTx);
                 //remove table 26 flow ppointing to table46
                 FlowEntity flowEntity = null;
                 try {
@@ -457,7 +463,7 @@ public class RouterDpnChangeListener
                     }
                     LOG.debug("removeSNATFromDPN : Removing default SNAT miss entry flow entity for router {} with "
                         + "dpnId {} in napt switch {}", routerName, dpnId, naptSwitch);
-                    mdsalManager.removeFlowToTx(flowEntity, removeFlowInvTx);
+                    mdsalManager.removeFlow(confTx, flowEntity);
 
                 } catch (Exception ex) {
                     LOG.error("removeSNATFromDPN : Failed to remove default SNAT miss entry flow entity {}",
@@ -468,7 +474,7 @@ public class RouterDpnChangeListener
                     dpnId, routerName);
 
                 //best effort to check IntExt model
-                naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, removeFlowInvTx);
+                naptSwitchHA.bestEffortDeletion(routerId, routerName, externalIpLabel, confTx);
             }
         } catch (Exception ex) {
             LOG.error("removeSNATFromDPN : Exception while handling naptSwitch down for router {}", routerName, ex);
index 41cb68cdb8c7ef9225539fd03330705d825d496f..2e90cb1d34095df3fe30352f600aba0c7485d5df 100644 (file)
@@ -12,7 +12,8 @@ import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import org.opendaylight.genius.mdsalutil.NwConstants;
+import org.opendaylight.genius.infra.Datastore;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
 import org.opendaylight.netvirt.natservice.api.SnatServiceListener;
 import org.opendaylight.netvirt.natservice.api.SnatServiceManager;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.natservice.rev160111.ext.routers.Routers;
@@ -49,24 +50,25 @@ public class SnatServiceManagerImpl implements SnatServiceManager {
     }
 
     @Override
-    public void notify(Routers router, BigInteger primarySwitchId, BigInteger dpnId, Action action) {
+    public void notify(TypedReadWriteTransaction<Datastore.Configuration> confTx,
+        Routers router, BigInteger primarySwitchId, BigInteger dpnId, Action action) {
         for (SnatServiceListener snatServiceListener : snatServiceListeners) {
             boolean result = false;
             switch (action) {
                 case SNAT_ALL_SWITCH_ENBL:
-                    result = snatServiceListener.handleSnatAllSwitch(router, primarySwitchId, NwConstants.ADD_FLOW);
+                    result = snatServiceListener.addSnatAllSwitch(confTx, router, primarySwitchId);
                     break;
 
                 case SNAT_ALL_SWITCH_DISBL:
-                    result = snatServiceListener.handleSnatAllSwitch(router, primarySwitchId, NwConstants.DEL_FLOW);
+                    result = snatServiceListener.removeSnatAllSwitch(confTx, router, primarySwitchId);
                     break;
 
                 case SNAT_ROUTER_ENBL:
-                    result = snatServiceListener.handleSnat(router, primarySwitchId, dpnId,  NwConstants.ADD_FLOW);
+                    result = snatServiceListener.addSnat(confTx, router, primarySwitchId, dpnId);
                     break;
 
                 case SNAT_ROUTER_DISBL:
-                    result = snatServiceListener.handleSnat(router, primarySwitchId, dpnId, NwConstants.DEL_FLOW);
+                    result = snatServiceListener.removeSnat(confTx, router, primarySwitchId, dpnId);
                     break;
 
                 default:
index 3e5704289256b5aa128149fe170fd700cb2a4399..253490f610119d5ecc4f917905621be0078fadb3 100644 (file)
@@ -13,8 +13,10 @@ import java.util.Collections;
 import java.util.List;
 
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
-import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.genius.infra.Datastore.Configuration;
+import org.opendaylight.genius.infra.TransactionAdapter;
+import org.opendaylight.genius.infra.TypedReadWriteTransaction;
+import org.opendaylight.genius.infra.TypedWriteTransaction;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.ActionInfo;
 import org.opendaylight.genius.mdsalutil.BucketInfo;
@@ -39,7 +41,6 @@ import org.opendaylight.genius.mdsalutil.matches.MatchIpv4Destination;
 import org.opendaylight.genius.mdsalutil.matches.MatchMetadata;
 import org.opendaylight.genius.mdsalutil.matches.MatchTunnelId;
 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;
@@ -63,7 +64,6 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
     private static final Logger LOG = LoggerFactory.getLogger(VxlanGreConntrackBasedSnatService.class);
     private final ExternalRoutersListener externalRouterListener;
     private final IElanService elanManager;
-    private final ManagedNewTransactionRunner txRunner;
 
     public VxlanGreConntrackBasedSnatService(DataBroker dataBroker, IMdsalApiManager mdsalManager,
                                              ItmRpcService itmManager, OdlInterfaceRpcService odlInterfaceRpcService,
@@ -76,86 +76,143 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
                 interfaceManager, vpnFootprintService, fibManager, natDataUtil);
         this.externalRouterListener = externalRouterListener;
         this.elanManager = elanManager;
-        this.txRunner = new ManagedNewTransactionRunnerImpl(dataBroker);
     }
 
     @Override
-    public boolean handleSnatAllSwitch(Routers routers, BigInteger primarySwitchId,  int addOrRemove) {
-        ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
+    public boolean addSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId) {
+        ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
         LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
         if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
             LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
             return true;
         }
-        return super.handleSnatAllSwitch(routers, primarySwitchId, addOrRemove);
+        return super.addSnatAllSwitch(confTx, routers, primarySwitchId);
     }
 
     @Override
-    public boolean handleSnat(Routers routers, BigInteger primarySwitchId, BigInteger dpnId,  int addOrRemove) {
-        ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(dataBroker, routers.getNetworkId());
+    public boolean removeSnatAllSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId) {
+        ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
+        LOG.debug("VxlanGreConntrackBasedSnatService: handleSnatAllSwitch ProviderTypes {}", extNwProviderType);
+        if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
+            LOG.debug("handleSnatAllSwitch : Skip FLAT/VLAN provider networks.");
+            return true;
+        }
+        return super.removeSnatAllSwitch(confTx, routers, primarySwitchId);
+    }
+
+    @Override
+    public boolean addSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId, BigInteger dpnId) {
+        ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
+        LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
+        if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
+            LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
+            return true;
+        }
+        return super.addSnat(confTx, routers, primarySwitchId, dpnId);
+    }
+
+    @Override
+    public boolean removeSnat(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger primarySwitchId, BigInteger dpnId) {
+        ProviderTypes extNwProviderType = NatUtil.getProviderTypefromNetworkId(confTx, routers.getNetworkId());
         LOG.debug("VxlanGreConntrackBasedSnatService: handleSnat ProviderTypes {}", extNwProviderType);
         if (extNwProviderType == ProviderTypes.FLAT || extNwProviderType == ProviderTypes.VLAN) {
             LOG.debug("handleSnat : Skip FLAT/VLAN provider networks.");
             return true;
         }
-        return super.handleSnat(routers, primarySwitchId, dpnId, addOrRemove);
+        return super.removeSnat(confTx, routers, primarySwitchId, dpnId);
     }
 
     @Override
-    protected void installSnatSpecificEntriesForNaptSwitch(Routers routers, BigInteger dpnId, int addOrRemove) {
+    protected void addSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger dpnId) {
+
         LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
-                routers.getRouterName());
+            routers.getRouterName());
         String routerName = routers.getRouterName();
         Long routerId = NatUtil.getVpnId(dataBroker, routerName);
         int elanId = NatUtil.getElanInstanceByName(routers.getNetworkId().getValue(), dataBroker)
-                .getElanTag().intValue();
+            .getElanTag().intValue();
         /* Install Outbound NAT entries */
 
-        installSnatMissEntryForPrimrySwch(dpnId, routerId, elanId, addOrRemove);
-        installTerminatingServiceTblEntryForVxlanGre(dpnId, routerName, routerId, elanId, addOrRemove);
+        addSnatMissEntryForPrimrySwch(confTx, dpnId, routerId, elanId);
+        addTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerName, routerId, elanId);
         //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
         Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
         if (vpnUuid == null) {
             LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
-                    + "external network {} with routerId {}", routers.getNetworkId(), routerId);
+                + "external network {} with routerId {}", routers.getNetworkId(), routerId);
             return;
         }
         Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
-        /*//Long extNetVpnId = NatUtil.getAssociatedVPN(dataBroker, routers.getNetworkId(), LOG);
-        if (extNetVpnId == NatConstants.INVALID_ID && addOrRemove == NwConstants.ADD_FLOW) {
+        LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
+            extNetVpnId, routers.getRouterName());
+        List<ExternalIps> externalIps = routers.getExternalIps();
+        addOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId);
+        addOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
+        addNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
+        addNaptPfibEntry(confTx, dpnId, routerId);
+
+        //Install Inbound NAT entries
+        addInboundEntryForVxlanGre(confTx, dpnId, routerId, extNetVpnId, externalIps, elanId);
+        if (externalIps.isEmpty()) {
+            LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
+                routerName);
+            return;
+        }
+        //The logic now handle only one external IP per router, others if present will be ignored.
+        String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
+        externalRouterListener.handleSnatReverseTraffic(dpnId, routers, routerId, routerName, externalIp,
+            TransactionAdapter.toWriteTransaction(confTx));
+    }
+
+    @Override
+    protected void removeSnatSpecificEntriesForNaptSwitch(TypedReadWriteTransaction<Configuration> confTx,
+        Routers routers, BigInteger dpnId) {
+
+        LOG.info("installSnatSpecificEntriesForNaptSwitch for router {}",
+            routers.getRouterName());
+        String routerName = routers.getRouterName();
+        Long routerId = NatUtil.getVpnId(dataBroker, routerName);
+
+        /* Remove Outbound NAT entries */
+        removeSnatMissEntryForPrimrySwch(confTx, dpnId, routerId);
+        removeTerminatingServiceTblEntryForVxlanGre(confTx, dpnId, routerId);
+        //Long extNetVpnId = NatUtil.getNetworkVpnIdFromRouterId(dataBroker, routerId);
+        Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, routers.getNetworkId());
+        if (vpnUuid == null) {
             LOG.error("installSnatSpecificEntriesForNaptSwitch: Unable to retrieve external vpn_id for "
-                    + "external network {} with routerId {}", routers.getNetworkId(), routerId);
+                + "external network {} with routerId {}", routers.getNetworkId(), routerId);
             return;
-        }*/
+        }
+        Long extNetVpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
         LOG.info("installSnatSpecificEntriesForNaptSwitch: external network vpn_id {} for router {}",
-                extNetVpnId, routers.getRouterName());
+            extNetVpnId, routers.getRouterName());
         List<ExternalIps> externalIps = routers.getExternalIps();
-        createOutboundTblTrackEntryForVxlanGre(dpnId, routerId, extNetVpnId, addOrRemove);
-        createOutboundTblEntryForVxlanGre(dpnId, routerId, extNetVpnId, externalIps, elanId, addOrRemove);
-        installNaptPfibFlowForVxlanGre(routers, dpnId, extNetVpnId, addOrRemove);
-        installNaptPfibEntry(dpnId, routerId, addOrRemove);
+        removeOutboundTblTrackEntryForVxlanGre(confTx, dpnId, routerId);
+        removeOutboundTblEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
+        removeNaptPfibFlowForVxlanGre(confTx, routers, dpnId, extNetVpnId);
+        removeNaptPfibEntry(confTx, dpnId, routerId);
 
         //Install Inbound NAT entries
-        installInboundEntryForVxlanGre(dpnId, routerId, extNetVpnId, externalIps, elanId, addOrRemove);
+        removeInboundEntryForVxlanGre(confTx, dpnId, routerId, externalIps);
         if (externalIps.isEmpty()) {
             LOG.error("installSnatSpecificEntriesForNaptSwitch: No externalIP present for router {}",
-                    routerName);
+                routerName);
             return;
         }
         //The logic now handle only one external IP per router, others if present will be ignored.
         String externalIp = NatUtil.validateAndAddNetworkMask(externalIps.get(0).getIpAddress());
-        ListenableFutures.addErrorLogging(txRunner.callWithNewWriteOnlyTransactionAndSubmit(tx -> {
-            if (addOrRemove == NwConstants.ADD_FLOW) {
-                externalRouterListener.handleSnatReverseTraffic(dpnId, routers, routerId, routerName, externalIp, tx);
-            } else {
-                externalRouterListener.clearFibTsAndReverseTraffic(dpnId, routerId, routers.getNetworkId(),
-                        Collections.singletonList(externalIp), null, routers.getExtGwMacAddress(), tx);
-            }
-        }), LOG, "Error installing SNAT-specific entries for NAPT switch");
+        externalRouterListener.clearFibTsAndReverseTraffic(dpnId, routerId, routers.getNetworkId(),
+            Collections.singletonList(externalIp), null, routers.getExtGwMacAddress(),
+            TransactionAdapter.toWriteTransaction(confTx));
     }
 
-    protected void createOutboundTblTrackEntryForVxlanGre(BigInteger dpnId, Long routerId, Long extNetVpnId,
-                                               int addOrRemove) {
+    protected void addOutboundTblTrackEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long routerId, Long extNetVpnId) {
         LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
                 + "routerId {}", dpnId, routerId);
         List<MatchInfoBase> matches = new ArrayList<>();
@@ -164,24 +221,30 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
         matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(routerId), MetaDataUtil.METADATA_MASK_VRFID));
 
         ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
-                    .getVpnIdMetadata(extNetVpnId));
-            listActionInfo.add(actionSetFieldMeta);
-        }
+        ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil.getVpnIdMetadata(extNetVpnId));
+        listActionInfo.add(actionSetFieldMeta);
         ArrayList<InstructionInfo> instructionInfo = new ArrayList<>();
         listActionInfo.add(new ActionNxResubmit(NwConstants.NAPT_PFIB_TABLE));
         instructionInfo.add(new InstructionApplyActions(listActionInfo));
 
-        String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
-        flowRef += "trkest";
-        syncFlow(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo, addOrRemove);
+        String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
+        addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY, flowRef,
+                NwConstants.COOKIE_SNAT_TABLE, matches, instructionInfo);
 
     }
 
-    protected void createOutboundTblEntryForVxlanGre(BigInteger dpnId, long routerId, Long extNetVpnId,
-                                                     List<ExternalIps> externalIps, int elanId, int addOrRemove) {
+    protected void removeOutboundTblTrackEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
+        BigInteger dpnId, Long routerId) {
+        LOG.info("createOutboundTblTrackEntryForVxlanGre: Install Outbound tracking table flow on dpId {} for "
+            + "routerId {}", dpnId, routerId);
+
+        String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId) + "trkest";
+        removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
+
+    }
+
+    protected void addOutboundTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        long routerId, Long extNetVpnId, List<ExternalIps> externalIps, int elanId) {
         LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
                 routerId);
         List<MatchInfoBase> matches = new ArrayList<>();
@@ -196,11 +259,9 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
         //The logic now handle only one external IP per router, others if present will be ignored.
         String externalIp = externalIps.get(0).getIpAddress();
         List<ActionInfo> actionsInfos = new ArrayList<>();
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
-                    .getVpnIdMetadata(extNetVpnId));
-            actionsInfos.add(actionSetFieldMeta);
-        }
+        ActionSetFieldMeta actionSetFieldMeta = new ActionSetFieldMeta(MetaDataUtil
+                .getVpnIdMetadata(extNetVpnId));
+        actionsInfos.add(actionSetFieldMeta);
         List<ActionNxConntrack.NxCtAction> ctActionsListCommit = new ArrayList<>();
         int rangePresent = NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue();
         int flags = NxActionNatFlags.NXNATFSRC.getIntValue();
@@ -215,32 +276,52 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
         List<InstructionInfo> instructions = new ArrayList<>();
         instructions.add(new InstructionApplyActions(actionsInfos));
         String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
-        syncFlow(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,  NatConstants.SNAT_NEW_FLOW_PRIORITY,
-                flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef,  NatConstants.SNAT_NEW_FLOW_PRIORITY,
+                flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
     }
 
-    protected void installNaptPfibFlowForVxlanGre(Routers routers, BigInteger dpnId, Long extNetVpnId,
-                                                  int addOrRemove) {
+    protected void removeOutboundTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        long routerId, List<ExternalIps> externalIps) {
+        LOG.info("createOutboundTblEntryForVxlanGre: Install Outbound table flow on dpId {} for routerId {}", dpnId,
+            routerId);
+        if (externalIps.isEmpty()) {
+            LOG.error("createOutboundTblEntryForVxlanGre: No externalIP present for routerId {}",
+                routerId);
+            return;
+        }
+        //The logic now handle only one external IP per router, others if present will be ignored.
+        String flowRef = getFlowRef(dpnId, NwConstants.OUTBOUND_NAPT_TABLE, routerId);
+        removeFlow(confTx, dpnId, NwConstants.OUTBOUND_NAPT_TABLE, flowRef);
+    }
+
+    protected void addNaptPfibFlowForVxlanGre(TypedWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger dpnId, Long extNetVpnId) {
         LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
                 + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
         List<MatchInfoBase> matches = new ArrayList<>();
         matches.add(MatchEthernetType.IPV4);
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId),
-                    MetaDataUtil.METADATA_MASK_VRFID));
-        }
+        matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNetVpnId),
+                MetaDataUtil.METADATA_MASK_VRFID));
         ArrayList<ActionInfo> listActionInfo = new ArrayList<>();
         ArrayList<InstructionInfo> instructions = new ArrayList<>();
         listActionInfo.add(new ActionNxLoadInPort(BigInteger.ZERO));
         listActionInfo.add(new ActionNxResubmit(NwConstants.L3_FIB_TABLE));
         instructions.add(new InstructionApplyActions(listActionInfo));
         String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
-        syncFlow(dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
-                flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef, NatConstants.SNAT_TRK_FLOW_PRIORITY,
+                flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
+    }
+
+    protected void removeNaptPfibFlowForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, Routers routers,
+        BigInteger dpnId, Long extNetVpnId) {
+        LOG.info("installNaptPfibFlowForVxlanGre: Install Napt preFibFlow on dpId {} with matching extNetVpnId {} "
+            + "for router {}", dpnId, extNetVpnId, routers.getRouterName());
+        String flowRef = getFlowRef(dpnId, NwConstants.NAPT_PFIB_TABLE, extNetVpnId);
+        removeFlow(confTx, dpnId, NwConstants.NAPT_PFIB_TABLE, flowRef);
     }
 
-    protected void installInboundEntryForVxlanGre(BigInteger dpnId, long routerId, Long extNeVpnId,
-                                                  List<ExternalIps> externalIps, int elanId, int addOrRemove) {
+    protected void addInboundEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        long routerId, Long extNeVpnId, List<ExternalIps> externalIps, int elanId) {
         LOG.info("installInboundEntryForVxlanGre:  Install Inbound table entry on dpId {} for routerId {}",
                 dpnId, routerId);
         List<MatchInfoBase> matches = new ArrayList<>();
@@ -252,10 +333,7 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
         }
         String externalIp = externalIps.get(0).getIpAddress();
         matches.add(new MatchIpv4Destination(externalIp,"32"));
-        if (addOrRemove == NwConstants.ADD_FLOW) {
-            matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId),
-                    MetaDataUtil.METADATA_MASK_VRFID));
-        }
+        matches.add(new MatchMetadata(MetaDataUtil.getVpnIdMetadata(extNeVpnId), MetaDataUtil.METADATA_MASK_VRFID));
         List<ActionInfo> actionsInfos = new ArrayList<>();
         List<ActionNxConntrack.NxCtAction> ctActionsList = new ArrayList<>();
         ActionNxConntrack.NxCtAction nxCtAction = new ActionNxConntrack.NxNat(0, 0, 0,null, null,0, 0);
@@ -270,12 +348,26 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
         List<InstructionInfo> instructions = new ArrayList<>();
         instructions.add(new InstructionApplyActions(actionsInfos));
         String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
-        syncFlow(dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
+                NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
     }
 
-    protected void installTerminatingServiceTblEntryForVxlanGre(BigInteger dpnId, String routerName,
-            Long  routerId, int elanId, int addOrRemove) {
+    protected void removeInboundEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        long routerId, List<ExternalIps> externalIps) {
+        LOG.info("removeInboundEntryForVxlanGre: remove Inbound table entry on dpId {} for routerId {}",
+            dpnId, routerId);
+        if (externalIps.isEmpty()) {
+            LOG.error("removeInboundEntryForVxlanGre : createInboundTblEntry no externalIP present for routerId {}",
+                routerId);
+            return;
+        }
+
+        String flowRef = getFlowRef(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId);
+        removeFlow(confTx, dpnId, NwConstants.INBOUND_NAPT_TABLE, flowRef);
+    }
+
+    protected void addTerminatingServiceTblEntryForVxlanGre(TypedWriteTransaction<Configuration> confTx,
+        BigInteger dpnId, String routerName, Long routerId, int elanId) {
         LOG.info("installTerminatingServiceTblEntryForVxlanGre : creating entry for"
                 + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
         List<MatchInfo> matches = new ArrayList<>();
@@ -300,13 +392,24 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
         List<InstructionInfo> instructions = new ArrayList<>();
         instructions.add(new InstructionApplyActions(actionsInfos));
         String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
-        syncFlow(dpnId,  NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY, flowRef,
-                 NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, flowRef, NatConstants.DEFAULT_TS_FLOW_PRIORITY,
+            flowRef, NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
 
     }
 
-    protected void installSnatMissEntry(BigInteger dpnId, Long routerId, String routerName, BigInteger primarySwitchId,
-            int addOrRemove) {
+    protected void removeTerminatingServiceTblEntryForVxlanGre(TypedReadWriteTransaction<Configuration> confTx,
+        BigInteger dpnId, Long routerId) {
+        LOG.info("removeTerminatingServiceTblEntryForVxlanGre : removing entry for"
+            + "Terminating Service Table for switch {}, routerId {}", dpnId, routerId);
+
+        String flowRef = getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, routerId.longValue());
+        removeFlow(confTx, dpnId,  NwConstants.INTERNAL_TUNNEL_TABLE, flowRef);
+
+    }
+
+    @Override
+    protected void addSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId, Long routerId,
+        String routerName, BigInteger primarySwitchId) {
         LOG.debug("installSnatMissEntry : Installing SNAT miss entry in switch {}", dpnId);
         List<ActionInfo> listActionInfoPrimary = new ArrayList<>();
         String ifNamePrimary = getTunnelInterfaceName(dpnId, primarySwitchId);
@@ -325,7 +428,7 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
         GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, routerName, GroupTypes.GroupAll,
                 listBucketInfo);
         LOG.debug("installSnatMissEntry : installing the SNAT to NAPT GroupEntity:{}", groupEntity);
-        mdsalManager.installGroup(groupEntity);
+        mdsalManager.addGroup(confTx, groupEntity);
         // Install miss entry pointing to group
         LOG.debug("installSnatMissEntry : buildSnatFlowEntity is called for dpId {}, routerName {} and groupId {}",
                 dpnId, routerName, groupId);
@@ -346,8 +449,17 @@ public class VxlanGreConntrackBasedSnatService extends ConntrackBasedSnatService
         List<InstructionInfo> instructions = new ArrayList<>();
         instructions.add(new InstructionApplyActions(actionsInfo));
         String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
-        syncFlow(dpnId, NwConstants.PSNAT_TABLE, flowRef,  NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
-                NwConstants.COOKIE_SNAT_TABLE, matches, instructions, addOrRemove);
+        addFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef,  NatConstants.DEFAULT_PSNAT_FLOW_PRIORITY, flowRef,
+                NwConstants.COOKIE_SNAT_TABLE, matches, instructions);
+    }
+
+    @Override
+    protected void removeSnatMissEntry(TypedReadWriteTransaction<Configuration> confTx, BigInteger dpnId,
+        Long routerId, String routerName) {
+        LOG.debug("installSnatMissEntry : Removing SNAT miss entry in switch {}", dpnId);
+
+        String flowRef = getFlowRef(dpnId, NwConstants.PSNAT_TABLE, routerId);
+        removeFlow(confTx, dpnId, NwConstants.PSNAT_TABLE, flowRef);
     }
 
 }