Bulk merge of l2gw changes
[netvirt.git] / dhcpservice / impl / src / main / java / org / opendaylight / netvirt / dhcpservice / DhcpExternalTunnelManager.java
index 002999482e800994990e56fcd8739b28d29ba874..f66f4b90a44b4fc4c7a5f8dff52419afb844627e 100644 (file)
@@ -7,9 +7,8 @@
  */
 package org.opendaylight.netvirt.dhcpservice;
 
-import static org.opendaylight.genius.infra.Datastore.CONFIGURATION;
+import static org.opendaylight.mdsal.binding.util.Datastore.CONFIGURATION;
 
-import com.google.common.base.Optional;
 import com.google.common.util.concurrent.ListenableFuture;
 import java.math.BigInteger;
 import java.util.ArrayList;
@@ -19,7 +18,10 @@ import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Locale;
+import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Objects;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -32,15 +34,9 @@ import javax.inject.Named;
 import javax.inject.Singleton;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.genius.infra.Datastore.Configuration;
-import org.opendaylight.genius.infra.ManagedNewTransactionRunner;
-import org.opendaylight.genius.infra.ManagedNewTransactionRunnerImpl;
-import org.opendaylight.genius.infra.TypedReadWriteTransaction;
-import org.opendaylight.genius.infra.TypedWriteTransaction;
+import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.jdt.annotation.Nullable;
+import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.mdsalutil.MDSALUtil;
 import org.opendaylight.genius.mdsalutil.NwConstants;
@@ -50,7 +46,16 @@ import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundConstants;
 import org.opendaylight.genius.utils.hwvtep.HwvtepSouthboundUtils;
 import org.opendaylight.genius.utils.hwvtep.HwvtepUtils;
 import org.opendaylight.infrautils.jobcoordinator.JobCoordinator;
-import org.opendaylight.infrautils.utils.concurrent.ListenableFutures;
+import org.opendaylight.infrautils.utils.concurrent.LoggingFutures;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.binding.api.ReadTransaction;
+import org.opendaylight.mdsal.binding.util.Datastore;
+import org.opendaylight.mdsal.binding.util.Datastore.Configuration;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunner;
+import org.opendaylight.mdsal.binding.util.ManagedNewTransactionRunnerImpl;
+import org.opendaylight.mdsal.binding.util.TypedReadWriteTransaction;
+import org.opendaylight.mdsal.binding.util.TypedWriteTransaction;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipService;
 import org.opendaylight.netvirt.dhcpservice.api.DhcpMConstants;
 import org.opendaylight.netvirt.dhcpservice.api.IDhcpExternalTunnelManager;
@@ -81,6 +86,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.instances.ElanInstanceKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.dhcpservice.api.rev150710.subnet.dhcp.port.data.SubnetToDhcpPort;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.hwvtep.rev150901.HwvtepLogicalSwitchRef;
@@ -96,6 +102,7 @@ import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.
 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.node.TerminationPointKey;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.Uint64;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -116,15 +123,15 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
     private IElanService elanService;
     private final DhcpServiceCounters dhcpServiceCounters;
 
-    private final ConcurrentMap<BigInteger, Set<Pair<IpAddress, String>>> designatedDpnsToTunnelIpElanNameCache =
+    private final ConcurrentMap<Uint64, Set<Pair<IpAddress, String>>> designatedDpnsToTunnelIpElanNameCache =
             new ConcurrentHashMap<>();
     private final ConcurrentMap<Pair<IpAddress, String>, Set<String>> tunnelIpElanNameToVmMacCache =
             new ConcurrentHashMap<>();
     private final ConcurrentMap<Pair<IpAddress, String>, Set<String>> availableVMCache = new ConcurrentHashMap<>();
-    private final ConcurrentMap<Pair<BigInteger, String>, Port> vniMacAddressToPortCache = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Pair<Uint64, String>, Port> vniMacAddressToPortCache = new ConcurrentHashMap<>();
 
     @Override
-    public ConcurrentMap<BigInteger, Set<Pair<IpAddress, String>>> getDesignatedDpnsToTunnelIpElanNameCache() {
+    public ConcurrentMap<Uint64, Set<Pair<IpAddress, String>>> getDesignatedDpnsToTunnelIpElanNameCache() {
         return designatedDpnsToTunnelIpElanNameCache;
     }
 
@@ -139,7 +146,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
     }
 
     @Override
-    public ConcurrentMap<Pair<BigInteger, String>, Port> getVniMacAddressToPortCache() {
+    public ConcurrentMap<Pair<Uint64, String>, Port> getVniMacAddressToPortCache() {
         return vniMacAddressToPortCache;
     }
 
@@ -170,15 +177,21 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         LOG.trace("Loading designatedDpnsToTunnelIpElanNameCache");
         InstanceIdentifier<DesignatedSwitchesForExternalTunnels> instanceIdentifier =
                 InstanceIdentifier.builder(DesignatedSwitchesForExternalTunnels.class).build();
-        Optional<DesignatedSwitchesForExternalTunnels> designatedSwitchForTunnelOptional =
-                MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, instanceIdentifier);
+        Optional<DesignatedSwitchesForExternalTunnels> designatedSwitchForTunnelOptional;
+        try {
+            designatedSwitchForTunnelOptional = SingleTransactionDataBroker.syncReadOptional(broker,
+                    LogicalDatastoreType.CONFIGURATION, instanceIdentifier);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("initilizeCaches: Exception while reading the DesignatedSwitchesForExternalTunnels DS", e);
+            return;
+        }
         if (designatedSwitchForTunnelOptional.isPresent()) {
-            List<DesignatedSwitchForTunnel> list =
-                    designatedSwitchForTunnelOptional.get().getDesignatedSwitchForTunnel();
-            for (DesignatedSwitchForTunnel designatedSwitchForTunnel : list) {
+            Map<DesignatedSwitchForTunnelKey, DesignatedSwitchForTunnel> keyDesignatedSwitchForTunnelMap =
+                designatedSwitchForTunnelOptional.get().nonnullDesignatedSwitchForTunnel();
+            for (DesignatedSwitchForTunnel designatedSwitchForTunnel : keyDesignatedSwitchForTunnelMap.values()) {
                 Set<Pair<IpAddress, String>> setOfTunnelIpElanNamePair =
                         designatedDpnsToTunnelIpElanNameCache
-                                .get(BigInteger.valueOf(designatedSwitchForTunnel.getDpId()));
+                                .get(Uint64.valueOf(designatedSwitchForTunnel.getDpId()));
                 if (setOfTunnelIpElanNamePair == null) {
                     setOfTunnelIpElanNamePair = new CopyOnWriteArraySet<>();
                 }
@@ -186,16 +199,23 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
                         new ImmutablePair<>(designatedSwitchForTunnel.getTunnelRemoteIpAddress(),
                                 designatedSwitchForTunnel.getElanInstanceName());
                 setOfTunnelIpElanNamePair.add(tunnelIpElanNamePair);
-                designatedDpnsToTunnelIpElanNameCache.put(BigInteger.valueOf(designatedSwitchForTunnel.getDpId()),
+                designatedDpnsToTunnelIpElanNameCache.put(Uint64.valueOf(designatedSwitchForTunnel.getDpId()),
                         setOfTunnelIpElanNamePair);
             }
         }
         LOG.trace("Loading vniMacAddressToPortCache");
         InstanceIdentifier<Ports> inst = InstanceIdentifier.builder(Neutron.class).child(Ports.class).build();
-        Optional<Ports> optionalPorts = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, inst);
+        Optional<Ports> optionalPorts;
+        try {
+            optionalPorts = SingleTransactionDataBroker.syncReadOptional(broker, LogicalDatastoreType.CONFIGURATION,
+                    inst);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("initilizeCaches: Exception while reading the Ports DS", e);
+            return;
+        }
         if (optionalPorts.isPresent()) {
-            List<Port> list = optionalPorts.get().getPort();
-            for (Port port : list) {
+            Map<PortKey, Port> portKeyPortMap = optionalPorts.get().nonnullPort();
+            for (Port port : portKeyPortMap.values()) {
                 if (NeutronUtils.isPortVnicTypeNormal(port)) {
                     continue;
                 }
@@ -205,13 +225,13 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
                 if (segmentationId == null) {
                     return;
                 }
-                updateVniMacToPortCache(new BigInteger(segmentationId), macAddress, port);
+                updateVniMacToPortCache(Uint64.valueOf(new BigInteger(segmentationId)), macAddress, port);
             }
         }
     }
 
-    public BigInteger designateDpnId(IpAddress tunnelIp, String elanInstanceName, List<BigInteger> dpns) {
-        BigInteger designatedDpnId = readDesignatedSwitchesForExternalTunnel(tunnelIp, elanInstanceName);
+    public Uint64 designateDpnId(IpAddress tunnelIp, String elanInstanceName, List<Uint64> dpns) {
+        Uint64 designatedDpnId = readDesignatedSwitchesForExternalTunnel(tunnelIp, elanInstanceName);
         if (designatedDpnId != null && !designatedDpnId.equals(DhcpMConstants.INVALID_DPID)) {
             LOG.trace("Dpn {} already designated for tunnelIp - elan : {} - {}", designatedDpnId, tunnelIp,
                     elanInstanceName);
@@ -220,8 +240,8 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         return chooseDpn(tunnelIp, elanInstanceName, dpns);
     }
 
-    public void installDhcpFlowsForVms(final IpAddress tunnelIp, String elanInstanceName, final List<BigInteger> dpns,
-            final BigInteger designatedDpnId, final String vmMacAddress) {
+    public void installDhcpFlowsForVms(final IpAddress tunnelIp, String elanInstanceName, final List<Uint64> dpns,
+            final Uint64 designatedDpnId, final String vmMacAddress) {
         LOG.trace("In installDhcpFlowsForVms ipAddress {}, elanInstanceName {}, dpn {}, vmMacAddress {}", tunnelIp,
                 elanInstanceName, designatedDpnId, vmMacAddress);
 
@@ -232,7 +252,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
                 return Collections.singletonList(
                     txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
                         dpns.remove(designatedDpnId);
-                        for (BigInteger dpn : dpns) {
+                        for (Uint64 dpn : dpns) {
                             installDhcpDropAction(dpn, vmMacAddress, tx);
                         }
                         installDhcpEntries(designatedDpnId, vmMacAddress, tx);
@@ -247,19 +267,19 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         updateLocalCache(tunnelIp, elanInstanceName, vmMacAddress);
     }
 
-    public void installDhcpFlowsForVms(BigInteger designatedDpnId, Set<String> listVmMacAddress,
-        TypedReadWriteTransaction<Configuration> tx) {
+    public void installDhcpFlowsForVms(Uint64 designatedDpnId, Set<String> listVmMacAddress,
+            TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
         for (String vmMacAddress : listVmMacAddress) {
             installDhcpEntries(designatedDpnId, vmMacAddress, tx);
         }
     }
 
-    public void unInstallDhcpFlowsForVms(String elanInstanceName, List<BigInteger> dpns, String vmMacAddress) {
+    public void unInstallDhcpFlowsForVms(String elanInstanceName, List<Uint64> dpns, String vmMacAddress) {
         unInstallDhcpEntriesOnDpns(dpns, vmMacAddress);
         removeFromLocalCache(elanInstanceName, vmMacAddress);
     }
 
-    public void unInstallDhcpFlowsForVms(String elanInstanceName, IpAddress tunnelIp, List<BigInteger> dpns) {
+    public void unInstallDhcpFlowsForVms(String elanInstanceName, IpAddress tunnelIp, List<Uint64> dpns) {
         Pair<IpAddress, String> tunnelIpElanNamePair = new ImmutablePair<>(tunnelIp, elanInstanceName);
         Set<String> vmMacs = tunnelIpElanNameToVmMacCache.get(tunnelIpElanNamePair);
         LOG.trace("In unInstallFlowsForVms elanInstanceName {}, tunnelIp {}, dpns {}, vmMacs {}",
@@ -273,23 +293,31 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         tunnelIpElanNameToVmMacCache.remove(tunnelIpElanNamePair);
     }
 
-    public BigInteger readDesignatedSwitchesForExternalTunnel(IpAddress tunnelIp, String elanInstanceName) {
+    @NonNull
+    public Uint64 readDesignatedSwitchesForExternalTunnel(IpAddress tunnelIp, String elanInstanceName) {
         if (tunnelIp == null || elanInstanceName == null || elanInstanceName.isEmpty()) {
-            return null;
+            return Uint64.ZERO;
         }
         InstanceIdentifier<DesignatedSwitchForTunnel> instanceIdentifier =
                 InstanceIdentifier.builder(DesignatedSwitchesForExternalTunnels.class)
                         .child(DesignatedSwitchForTunnel.class,
                                 new DesignatedSwitchForTunnelKey(elanInstanceName, tunnelIp)).build();
-        Optional<DesignatedSwitchForTunnel> designatedSwitchForTunnelOptional =
-                MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, instanceIdentifier);
+        Optional<DesignatedSwitchForTunnel> designatedSwitchForTunnelOptional;
+        try {
+            designatedSwitchForTunnelOptional = SingleTransactionDataBroker.syncReadOptional(broker,
+                    LogicalDatastoreType.CONFIGURATION, instanceIdentifier);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("readDesignatedSwitchesForExternalTunnel: Exception while reading the DesignatedSwitchForTunnel "
+                    + "DS for the elan-instance {} tunnelIp {}", elanInstanceName, tunnelIp, e);
+            return Uint64.ZERO;
+        }
         if (designatedSwitchForTunnelOptional.isPresent()) {
-            return BigInteger.valueOf(designatedSwitchForTunnelOptional.get().getDpId());
+            return Uint64.valueOf(designatedSwitchForTunnelOptional.get().getDpId());
         }
-        return null;
+        return Uint64.ZERO;
     }
 
-    public void writeDesignatedSwitchForExternalTunnel(BigInteger dpnId, IpAddress tunnelIp,
+    public void writeDesignatedSwitchForExternalTunnel(Uint64 dpnId, IpAddress tunnelIp,
                                                        String elanInstanceName) {
         DesignatedSwitchForTunnelKey designatedSwitchForTunnelKey =
                 new DesignatedSwitchForTunnelKey(elanInstanceName, tunnelIp);
@@ -306,7 +334,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         updateLocalCache(dpnId, tunnelIp, elanInstanceName);
     }
 
-    public void removeDesignatedSwitchForExternalTunnel(BigInteger dpnId, IpAddress tunnelIp,
+    public void removeDesignatedSwitchForExternalTunnel(Uint64 dpnId, IpAddress tunnelIp,
                                                         String elanInstanceName) {
         DesignatedSwitchForTunnelKey designatedSwitchForTunnelKey =
                 new DesignatedSwitchForTunnelKey(elanInstanceName, tunnelIp);
@@ -320,37 +348,44 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
     }
 
     // This method is called whenever new OVS Switch is added.
-    public void installDhcpDropActionOnDpn(BigInteger dpId) {
+    public void installDhcpDropActionOnDpn(Uint64 dpId) {
         // During controller restart we'll get add for designatedDpns as well and we
         // need not install drop flows for those dpns
         if (designatedDpnsToTunnelIpElanNameCache.get(dpId) != null) {
-            LOG.trace("The dpn {} is designated DPN need not install drop flows");
+            LOG.trace("The dpn {} is designated DPN need not install drop flows", dpId);
             return;
         }
         // Read from DS since the cache may not get loaded completely in restart scenario
         if (isDpnDesignatedDpn(dpId)) {
-            LOG.trace("The dpn {} is designated DPN need not install drop flows");
+            LOG.trace("The dpn {} is designated DPN need not install drop flows", dpId);
             return;
         }
         List<String> vmMacs = getAllVmMacs();
         LOG.trace("Installing drop actions to this new DPN {} VMs {}", dpId, vmMacs);
-        ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+        LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
             for (String vmMacAddress : vmMacs) {
                 installDhcpDropAction(dpId, vmMacAddress, tx);
             }
         }), LOG, "Error writing to the datastore");
     }
 
-    private boolean isDpnDesignatedDpn(BigInteger dpId) {
+    private boolean isDpnDesignatedDpn(Uint64 dpId) {
         InstanceIdentifier<DesignatedSwitchesForExternalTunnels> instanceIdentifier =
                 InstanceIdentifier.builder(DesignatedSwitchesForExternalTunnels.class).build();
-        Optional<DesignatedSwitchesForExternalTunnels> designatedSwitchForTunnelOptional =
-                MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION, instanceIdentifier);
+        Optional<DesignatedSwitchesForExternalTunnels> designatedSwitchForTunnelOptional;
+        try {
+            designatedSwitchForTunnelOptional = SingleTransactionDataBroker.syncReadOptional(broker,
+                    LogicalDatastoreType.CONFIGURATION, instanceIdentifier);
+        } catch (ExecutionException | InterruptedException e) {
+            LOG.error("isDpnDesignatedDpn: Exception while reading the DesignatedSwitchesForExternalTunnels "
+                    + "DS for the dpId {}", dpId, e);
+            return false;
+        }
         if (designatedSwitchForTunnelOptional.isPresent()) {
-            List<DesignatedSwitchForTunnel> list =
-                    designatedSwitchForTunnelOptional.get().getDesignatedSwitchForTunnel();
-            for (DesignatedSwitchForTunnel designatedSwitchForTunnel : list) {
-                if (dpId.equals(BigInteger.valueOf(designatedSwitchForTunnel.getDpId()))) {
+            Map<DesignatedSwitchForTunnelKey, DesignatedSwitchForTunnel> keyDesignatedSwitchForTunnelMap =
+                    designatedSwitchForTunnelOptional.get().nonnullDesignatedSwitchForTunnel();
+            for (DesignatedSwitchForTunnel designatedSwitchForTunnel : keyDesignatedSwitchForTunnelMap.values()) {
+                if (dpId.equals(Uint64.valueOf(designatedSwitchForTunnel.getDpId()))) {
                     return true;
                 }
             }
@@ -367,7 +402,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         return vmMacs;
     }
 
-    public void updateLocalCache(BigInteger designatedDpnId, IpAddress tunnelIp, String elanInstanceName) {
+    public void updateLocalCache(Uint64 designatedDpnId, IpAddress tunnelIp, String elanInstanceName) {
         Pair<IpAddress, String> tunnelIpElanName = new ImmutablePair<>(tunnelIp, elanInstanceName);
         Set<Pair<IpAddress, String>> tunnelIpElanNameSet;
         tunnelIpElanNameSet = designatedDpnsToTunnelIpElanNameCache.get(designatedDpnId);
@@ -407,13 +442,13 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         availableVMCache.put(tunnelIpElanName, listExistingVmMacAddress);
     }
 
-    public void handleDesignatedDpnDown(BigInteger dpnId, List<BigInteger> listOfDpns) {
+    public void handleDesignatedDpnDown(Uint64 dpnId, List<Uint64> listOfDpns) {
         LOG.trace("In handleDesignatedDpnDown dpnId {}, listOfDpns {}", dpnId, listOfDpns);
         Set<Pair<IpAddress, String>> setOfTunnelIpElanNamePairs = designatedDpnsToTunnelIpElanNameCache.get(dpnId);
         if (setOfTunnelIpElanNamePairs == null || setOfTunnelIpElanNamePairs.isEmpty()) {
             LOG.trace("No tunnelIpElanName to handle for dpn {}. Returning", dpnId);
         } else {
-            ListenableFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
+            LoggingFutures.addErrorLogging(txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
                 if (!dpnId.equals(DhcpMConstants.INVALID_DPID)) {
                     List<String> listOfVms = getAllVmMacs();
                     for (String vmMacAddress : listOfVms) {
@@ -427,9 +462,9 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         }
     }
 
-    public void updateCacheAndInstallNewFlows(List<BigInteger> listOfDpns, Pair<IpAddress, String> pair,
-            TypedReadWriteTransaction<Configuration> tx) {
-        BigInteger newDesignatedDpn = chooseDpn(pair.getLeft(), pair.getRight(), listOfDpns);
+    public void updateCacheAndInstallNewFlows(List<Uint64> listOfDpns, Pair<IpAddress, String> pair,
+            TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
+        Uint64 newDesignatedDpn = chooseDpn(pair.getLeft(), pair.getRight(), listOfDpns);
         if (newDesignatedDpn.equals(DhcpMConstants.INVALID_DPID)) {
             return;
         }
@@ -445,8 +480,9 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         }
     }
 
-    private void changeExistingFlowToDrop(Pair<IpAddress, String> tunnelIpElanNamePair, BigInteger dpnId,
-                                          TypedReadWriteTransaction<Configuration> tx) {
+    private void changeExistingFlowToDrop(Pair<IpAddress, String> tunnelIpElanNamePair, Uint64 dpnId,
+                                          TypedReadWriteTransaction<Configuration> tx)
+            throws ExecutionException, InterruptedException {
         Set<String> setOfVmMacAddress = tunnelIpElanNameToVmMacCache.get(tunnelIpElanNamePair);
         if (setOfVmMacAddress == null || setOfVmMacAddress.isEmpty()) {
             return;
@@ -463,11 +499,11 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
      * @param dpns The data path nodes
      * @return The designated dpn
      */
-    private BigInteger chooseDpn(IpAddress tunnelIp, String elanInstanceName,
-            List<BigInteger> dpns) {
-        BigInteger designatedDpnId = DhcpMConstants.INVALID_DPID;
+    private Uint64 chooseDpn(IpAddress tunnelIp, String elanInstanceName,
+            List<Uint64> dpns) {
+        Uint64 designatedDpnId = DhcpMConstants.INVALID_DPID;
         if (dpns != null && dpns.size() != 0) {
-            List<BigInteger> candidateDpns = DhcpServiceUtils.getDpnsForElan(elanInstanceName, broker);
+            List<Uint64> candidateDpns = DhcpServiceUtils.getDpnsForElan(elanInstanceName, broker);
             candidateDpns.retainAll(dpns);
             LOG.trace("Choosing new dpn for tunnelIp {}, elanInstanceName {}, among elanDpns {}",
                     tunnelIp, elanInstanceName, candidateDpns);
@@ -484,7 +520,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
                 handleUnableToDesignateDpn(tunnelIp, elanInstanceName);
                 return designatedDpnId;
             }
-            for (BigInteger dpn : candidateDpns) {
+            for (Uint64 dpn : candidateDpns) {
                 String hwvtepNodeId = device.getHwvtepNodeId();
                 if (!elanDpnAvailableFlag) {
                     if (!isTunnelConfigured(dpn, hwvtepNodeId)) {
@@ -516,8 +552,8 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         writeDesignatedSwitchForExternalTunnel(DhcpMConstants.INVALID_DPID, tunnelIp, elanInstanceName);
     }
 
-    private void installDhcpEntries(BigInteger dpnId, String vmMacAddress,
-        TypedReadWriteTransaction<Configuration> tx) {
+    private void installDhcpEntries(Uint64 dpnId, String vmMacAddress,
+            TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
         DhcpServiceUtils.setupDhcpFlowEntry(dpnId, NwConstants.DHCP_TABLE_EXTERNAL_TUNNEL,
                 vmMacAddress, NwConstants.ADD_FLOW, mdsalUtil, dhcpServiceCounters, tx);
     }
@@ -525,8 +561,8 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
     public void addOrRemoveDhcpArpFlowforElan(String elanInstanceName, boolean addFlow, String dhcpIpAddress,
                                               String dhcpMacAddress) {
         LOG.trace("Configure DHCP SR-IOV Arp flows for Elan {} dpns .", elanInstanceName);
-        for (Entry<BigInteger, Set<Pair<IpAddress,String>>> entry : designatedDpnsToTunnelIpElanNameCache.entrySet()) {
-            BigInteger dpn = entry.getKey();
+        for (Entry<Uint64, Set<Pair<IpAddress,String>>> entry : designatedDpnsToTunnelIpElanNameCache.entrySet()) {
+            Uint64 dpn = entry.getKey();
             Set<Pair<IpAddress,String>> tunnelIpElanNameSet = entry.getValue();
             for (Pair<IpAddress, String> pair : tunnelIpElanNameSet) {
                 if (pair.getRight().equalsIgnoreCase(elanInstanceName)) {
@@ -547,7 +583,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
     }
 
 
-    public void configureDhcpArpRequestResponseFlow(BigInteger dpnId, String elanInstanceName, boolean addFlow,
+    public void configureDhcpArpRequestResponseFlow(Uint64 dpnId, String elanInstanceName, boolean addFlow,
                                             IpAddress tunnelIp, String dhcpIpAddress, String dhcpMacAddress) {
         L2GatewayDevice device = getDeviceFromTunnelIp(tunnelIp);
         if (device == null) {
@@ -557,7 +593,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         jobCoordinator.enqueueJob(getJobKey(elanInstanceName), () -> {
             if (entityOwnershipUtils.isEntityOwner(HwvtepSouthboundConstants.ELAN_ENTITY_TYPE,
                     HwvtepSouthboundConstants.ELAN_ENTITY_NAME)) {
-                String tunnelInterfaceName = getExternalTunnelInterfaceName(String.valueOf(dpnId),
+                String tunnelInterfaceName = getExternalTunnelInterfaceName(dpnId.toString(),
                         device.getHwvtepNodeId());
                 int lportTag = interfaceManager.getInterfaceInfo(tunnelInterfaceName).getInterfaceTag();
                 InstanceIdentifier<ElanInstance> elanIdentifier = InstanceIdentifier.builder(ElanInstances.class)
@@ -569,25 +605,28 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
                             lportTag, optElan.get().getElanTag());
                     Uuid nwUuid = new Uuid(elanInstanceName);
                     String strVni = DhcpServiceUtils.getSegmentationId(nwUuid, broker);
-                    BigInteger vni = strVni != null ? new BigInteger(strVni) : BigInteger.ZERO;
-                    if (!vni.equals(BigInteger.ZERO)) {
-                        if (addFlow) {
-                            LOG.trace("Installing the SR-IOV DHCP Arp flow for DPN {} Port Ip {}, Lport {}.",
-                                    dpnId, dhcpIpAddress, lportTag);
-                            installDhcpArpRequestFlows(dpnId, vni, dhcpIpAddress, lportTag,
-                                    optElan.get().getElanTag());
-                            installDhcpArpResponderFlows(dpnId, tunnelInterfaceName, lportTag, elanInstanceName,
-                                    dhcpIpAddress, dhcpMacAddress);
-                        } else {
-                            LOG.trace("Uninstalling the SR-IOV DHCP Arp flows for DPN {} Port Ip {}, Lport {}.",
-                                    dpnId, dhcpIpAddress, lportTag);
-                            uninstallDhcpArpRequestFlows(dpnId, vni, dhcpIpAddress, lportTag);
-                            uninstallDhcpArpResponderFlows(dpnId, tunnelInterfaceName, lportTag, dhcpIpAddress);
-                        }
+                    Uint64 vni = strVni != null ? Uint64.valueOf(strVni) : Uint64.valueOf(0);
+                    if (!vni.equals(Uint64.ZERO)) {
+                        return Collections.singletonList(txRunner.callWithNewReadWriteTransactionAndSubmit(
+                            Datastore.CONFIGURATION, tx -> {
+                                if (addFlow) {
+                                    LOG.trace("Installing the SR-IOV DHCP Arp flow for DPN {} Port Ip {}, Lport {}.",
+                                        dpnId, dhcpIpAddress, lportTag);
+                                    installDhcpArpRequestFlows(tx, dpnId, vni, dhcpIpAddress, lportTag,
+                                        optElan.get().getElanTag().toJava());
+                                    installDhcpArpResponderFlows(dpnId, tunnelInterfaceName, lportTag, elanInstanceName,
+                                        dhcpIpAddress, dhcpMacAddress);
+                                } else {
+                                    LOG.trace("Uninstalling the SR-IOV DHCP Arp flows for DPN {} Port Ip {}, Lport {}.",
+                                        dpnId, dhcpIpAddress, lportTag);
+                                    uninstallDhcpArpRequestFlows(tx, dpnId, vni, dhcpIpAddress, lportTag);
+                                    uninstallDhcpArpResponderFlows(dpnId, tunnelInterfaceName, lportTag, dhcpIpAddress);
+                                }
+                            }));
                     }
                 }
             }
-            return null;
+            return Collections.emptyList();
         });
     }
 
@@ -604,53 +643,55 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         return optSubnetDhcp;
     }
 
-    private void installDhcpArpRequestFlows(BigInteger dpnId, BigInteger vni, String dhcpIpAddress,
-                                            int lportTag, Long elanTag) {
+    private void installDhcpArpRequestFlows(TypedReadWriteTransaction<Configuration> tx, Uint64 dpnId,
+                                            Uint64 vni, String dhcpIpAddress, int lportTag, Long elanTag)
+            throws ExecutionException, InterruptedException {
         DhcpServiceUtils.setupDhcpArpRequest(dpnId, NwConstants.EXTERNAL_TUNNEL_TABLE, vni, dhcpIpAddress,
-                lportTag, elanTag, true, mdsalUtil);
+                lportTag, elanTag, true, mdsalUtil, tx);
     }
 
-    private void installDhcpArpResponderFlows(BigInteger dpnId, String interfaceName, int lportTag,
+    private void installDhcpArpResponderFlows(Uint64 dpnId, String interfaceName, int lportTag,
                                               String elanInstanceName, String dhcpIpAddress, String dhcpMacAddress) {
         LOG.trace("Adding SR-IOV DHCP ArpResponder for elan {} Lport {} Port Ip {}.",
                 elanInstanceName, lportTag, dhcpIpAddress);
         ArpResponderInput.ArpReponderInputBuilder builder = new ArpResponderInput.ArpReponderInputBuilder();
-        builder.setDpId(dpnId).setInterfaceName(interfaceName).setSpa(dhcpIpAddress).setSha(dhcpMacAddress)
+        builder.setDpId(dpnId.toJava()).setInterfaceName(interfaceName).setSpa(dhcpIpAddress).setSha(dhcpMacAddress)
                 .setLportTag(lportTag);
         builder.setInstructions(ArpResponderUtil.getInterfaceInstructions(interfaceManager, interfaceName,
                 dhcpIpAddress, dhcpMacAddress, itmRpcService));
         elanService.addExternalTunnelArpResponderFlow(builder.buildForInstallFlow(), elanInstanceName);
     }
 
-    private void uninstallDhcpArpResponderFlows(BigInteger dpnId, String interfaceName, int lportTag,
+    private void uninstallDhcpArpResponderFlows(Uint64 dpnId, String interfaceName, int lportTag,
                                                 String dhcpIpAddress) {
         LOG.trace("Removing SR-IOV DHCP ArpResponder flow for interface {} on DPN {}", interfaceName, dpnId);
-        ArpResponderInput arpInput = new ArpResponderInput.ArpReponderInputBuilder().setDpId(dpnId)
+        ArpResponderInput arpInput = new ArpResponderInput.ArpReponderInputBuilder().setDpId(dpnId.toJava())
                 .setInterfaceName(interfaceName).setSpa(dhcpIpAddress)
                 .setLportTag(lportTag).buildForRemoveFlow();
         elanService.removeArpResponderFlow(arpInput);
     }
 
-    private void uninstallDhcpArpRequestFlows(BigInteger dpnId, BigInteger vni, String dhcpIpAddress,
-                                              int lportTag) {
+    private void uninstallDhcpArpRequestFlows(TypedReadWriteTransaction<Configuration> tx, Uint64 dpnId,
+                                              Uint64 vni, String dhcpIpAddress, int lportTag)
+            throws ExecutionException, InterruptedException {
         DhcpServiceUtils.setupDhcpArpRequest(dpnId, NwConstants.EXTERNAL_TUNNEL_TABLE, vni, dhcpIpAddress,
-                lportTag, null, false, mdsalUtil);
+                lportTag, null, false, mdsalUtil, tx);
     }
 
 
-    public void unInstallDhcpEntries(BigInteger dpnId, String vmMacAddress,
-        TypedReadWriteTransaction<Configuration> tx) {
+    public void unInstallDhcpEntries(Uint64 dpnId, String vmMacAddress,
+            TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
         DhcpServiceUtils.setupDhcpFlowEntry(dpnId, NwConstants.DHCP_TABLE_EXTERNAL_TUNNEL,
                 vmMacAddress, NwConstants.DEL_FLOW, mdsalUtil, dhcpServiceCounters, tx);
     }
 
-    private void installDhcpDropAction(BigInteger dpn, String vmMacAddress,
-        TypedReadWriteTransaction<Configuration> tx) {
+    private void installDhcpDropAction(Uint64 dpn, String vmMacAddress,
+            TypedReadWriteTransaction<Configuration> tx) throws ExecutionException, InterruptedException {
         DhcpServiceUtils.setupDhcpDropAction(dpn, NwConstants.DHCP_TABLE_EXTERNAL_TUNNEL,
                 vmMacAddress, NwConstants.ADD_FLOW, mdsalUtil, dhcpServiceCounters, tx);
     }
 
-    public List<ListenableFuture<Void>> handleTunnelStateDown(IpAddress tunnelIp, BigInteger interfaceDpn) {
+    public List<ListenableFuture<?>> handleTunnelStateDown(IpAddress tunnelIp, Uint64 interfaceDpn) {
         LOG.trace("In handleTunnelStateDown tunnelIp {}, interfaceDpn {}", tunnelIp, interfaceDpn);
         if (interfaceDpn == null) {
             return Collections.emptyList();
@@ -680,7 +721,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
                             LOG.trace("Couldn't find device for given tunnelIpElanPair {} in L2GwConnCache",
                                     tunnelElanPair);
                         }
-                        List<BigInteger> dpns = DhcpServiceUtils.getListOfDpns(broker);
+                        List<Uint64> dpns = DhcpServiceUtils.getListOfDpns(broker);
                         dpns.remove(interfaceDpn);
                         changeExistingFlowToDrop(tunnelElanPair, interfaceDpn, tx);
                         java.util.Optional<SubnetToDhcpPort> subnetDhcpData = getSubnetDhcpPortData(elanInstanceName);
@@ -697,17 +738,15 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
     }
 
     private boolean checkL2GatewayConnection(Pair<IpAddress, String> tunnelElanPair) {
-        ConcurrentMap<String, L2GatewayDevice> l2GwDevices =
-                ElanL2GwCacheUtils.getInvolvedL2GwDevices(tunnelElanPair.getRight());
-        for (L2GatewayDevice device : l2GwDevices.values()) {
-            if (device.getTunnelIp().equals(tunnelElanPair.getLeft())) {
+        for (L2GatewayDevice device : ElanL2GwCacheUtils.getInvolvedL2GwDevices(tunnelElanPair.getRight()).values()) {
+            if (Objects.equals(device.getTunnelIp(), tunnelElanPair.getLeft())) {
                 return true;
             }
         }
         return false;
     }
 
-    private String getTunnelIpDpnKey(IpAddress tunnelIp, BigInteger interfaceDpn) {
+    private String getTunnelIpDpnKey(IpAddress tunnelIp, Uint64 interfaceDpn) {
         return tunnelIp.toString() + interfaceDpn;
     }
 
@@ -731,7 +770,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         }
     }
 
-    public void removeFromLocalCache(BigInteger designatedDpnId, IpAddress tunnelIp, String elanInstanceName) {
+    public void removeFromLocalCache(Uint64 designatedDpnId, IpAddress tunnelIp, String elanInstanceName) {
         Pair<IpAddress, String> tunnelIpElanName = new ImmutablePair<>(tunnelIp, elanInstanceName);
         Set<Pair<IpAddress, String>> tunnelIpElanNameSet;
         tunnelIpElanNameSet = designatedDpnsToTunnelIpElanNameCache.get(designatedDpnId);
@@ -748,31 +787,32 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         }
     }
 
-    public void updateVniMacToPortCache(BigInteger vni, String macAddress, Port port) {
+    public void updateVniMacToPortCache(Uint64 vni, String macAddress, Port port) {
         if (macAddress == null) {
             return;
         }
-        Pair<BigInteger, String> vniMacAddressPair = new ImmutablePair<>(
+        Pair<Uint64, String> vniMacAddressPair = new ImmutablePair<>(
                 vni, macAddress.toUpperCase(Locale.getDefault()));
         LOG.trace("Updating vniMacAddressToPortCache with vni {} , mac {} , pair {} and port {}", vni,
                 macAddress.toUpperCase(Locale.getDefault()), vniMacAddressPair, port);
         vniMacAddressToPortCache.put(vniMacAddressPair, port);
     }
 
-    public void removeVniMacToPortCache(BigInteger vni, String macAddress) {
+    public void removeVniMacToPortCache(Uint64 vni, String macAddress) {
         if (macAddress == null) {
             return;
         }
-        Pair<BigInteger, String> vniMacAddressPair = new ImmutablePair<>(
+        Pair<Uint64, String> vniMacAddressPair = new ImmutablePair<>(
                 vni, macAddress.toUpperCase(Locale.getDefault()));
         vniMacAddressToPortCache.remove(vniMacAddressPair);
     }
 
-    public Port readVniMacToPortCache(BigInteger vni, String macAddress) {
+    @Nullable
+    public Port readVniMacToPortCache(Uint64 vni, String macAddress) {
         if (macAddress == null) {
             return null;
         }
-        Pair<BigInteger, String> vniMacAddressPair = new ImmutablePair<>(
+        Pair<Uint64, String> vniMacAddressPair = new ImmutablePair<>(
                 vni, macAddress.toUpperCase(Locale.getDefault()));
         LOG.trace("Reading vniMacAddressToPortCache with vni {} , mac {} , pair {} and port {}",
                 vni, macAddress.toUpperCase(Locale.getDefault()), vniMacAddressPair,
@@ -808,6 +848,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         return MDSALUtil.read(LogicalDatastoreType.CONFIGURATION, psNodeId, dataBroker);
     }
 
+    @Nullable
     public RemoteMcastMacs createRemoteMcastMac(Node dstDevice, String logicalSwitchName, IpAddress internalTunnelIp) {
         Set<LocatorSet> locators = new HashSet<>();
         TerminationPointKey terminationPointKey = HwvtepSouthboundUtils.getTerminationPointKey(
@@ -825,14 +866,16 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
                 .setLogicalSwitchRef(lsRef).build();
         InstanceIdentifier<RemoteMcastMacs> iid = HwvtepSouthboundUtils.createRemoteMcastMacsInstanceIdentifier(
                 dstDevice.getNodeId(), remoteMcastMacs.key());
-        ReadOnlyTransaction transaction = broker.newReadOnlyTransaction();
+        ReadTransaction transaction = broker.newReadOnlyTransaction();
         try {
             //TODO do async mdsal read
-            remoteMcastMacs = transaction.read(LogicalDatastoreType.CONFIGURATION, iid).checkedGet().get();
+            remoteMcastMacs = transaction.read(LogicalDatastoreType.CONFIGURATION, iid).get().get();
             locators.addAll(remoteMcastMacs.getLocatorSet());
             return new RemoteMcastMacsBuilder(remoteMcastMacs).setLocatorSet(new ArrayList<>(locators)).build();
-        } catch (ReadFailedException e) {
+        } catch (InterruptedException | ExecutionException e) {
             LOG.error("Failed to read the macs {}", iid);
+        } finally {
+            transaction.close();
         }
         return null;
     }
@@ -840,16 +883,16 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
     private void putRemoteMcastMac(TypedWriteTransaction<Configuration> transaction, String elanName,
                                    L2GatewayDevice device, IpAddress internalTunnelIp) {
         Optional<Node> optionalNode = getNode(broker, device.getHwvtepNodeId());
-        Node dstNode = optionalNode.get();
-        if (dstNode == null) {
+        if (!optionalNode.isPresent()) {
             LOG.trace("could not get device node {} ", device.getHwvtepNodeId());
             return;
         }
+        Node dstNode = optionalNode.get();
         RemoteMcastMacs macs = createRemoteMcastMac(dstNode, elanName, internalTunnelIp);
         HwvtepUtils.addRemoteMcastMac(transaction, dstNode.getNodeId(), macs);
     }
 
-    public void installRemoteMcastMac(final BigInteger designatedDpnId, final IpAddress tunnelIp,
+    public void installRemoteMcastMac(final Uint64 designatedDpnId, final IpAddress tunnelIp,
                                       final String elanInstanceName) {
         if (designatedDpnId.equals(DhcpMConstants.INVALID_DPID)) {
             return;
@@ -886,6 +929,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         });
     }
 
+    @Nullable
     private L2GatewayDevice getDeviceFromTunnelIp(IpAddress tunnelIp) {
         Collection<L2GatewayDevice> devices = l2GatewayCache.getAll();
         LOG.trace("In getDeviceFromTunnelIp devices {}", devices);
@@ -897,7 +941,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         return null;
     }
 
-    private boolean isTunnelUp(String nodeName, BigInteger dpn) {
+    private boolean isTunnelUp(String nodeName, Uint64 dpn) {
         String tunnelInterfaceName = getExternalTunnelInterfaceName(String.valueOf(dpn), nodeName);
         if (tunnelInterfaceName == null) {
             LOG.trace("Tunnel Interface is not present on node {} with dpn {}", nodeName, dpn);
@@ -913,12 +957,12 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         return tunnelInterface.getOperStatus() == OperStatus.Up;
     }
 
-    public List<ListenableFuture<Void>> handleTunnelStateUp(IpAddress tunnelIp, BigInteger interfaceDpn) {
+    public List<ListenableFuture<?>> handleTunnelStateUp(IpAddress tunnelIp, Uint64 interfaceDpn) {
         LOG.trace("In handleTunnelStateUp tunnelIp {}, interfaceDpn {}", tunnelIp, interfaceDpn);
         synchronized (getTunnelIpDpnKey(tunnelIp, interfaceDpn)) {
             Set<Pair<IpAddress, String>> tunnelIpElanPair =
                     designatedDpnsToTunnelIpElanNameCache.get(DhcpMConstants.INVALID_DPID);
-            List<BigInteger> dpns = DhcpServiceUtils.getListOfDpns(broker);
+            List<Uint64> dpns = DhcpServiceUtils.getListOfDpns(broker);
             if (tunnelIpElanPair == null || tunnelIpElanPair.isEmpty()) {
                 LOG.trace("There are no undesignated DPNs");
                 return Collections.emptyList();
@@ -927,7 +971,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
                 for (Pair<IpAddress, String> pair : tunnelIpElanPair) {
                     if (tunnelIp.equals(pair.getLeft())) {
                         String elanInstanceName = pair.getRight();
-                        BigInteger newDesignatedDpn = designateDpnId(tunnelIp, elanInstanceName, dpns);
+                        Uint64 newDesignatedDpn = designateDpnId(tunnelIp, elanInstanceName, dpns);
                         if (newDesignatedDpn != null && !newDesignatedDpn.equals(DhcpMConstants.INVALID_DPID)) {
                             Set<String> vmMacAddress = tunnelIpElanNameToVmMacCache.get(pair);
                             if (vmMacAddress != null && !vmMacAddress.isEmpty()) {
@@ -948,7 +992,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         }
     }
 
-    private boolean isTunnelConfigured(BigInteger dpn, String hwVtepNodeId) {
+    private boolean isTunnelConfigured(Uint64 dpn, String hwVtepNodeId) {
         String tunnelInterfaceName = getExternalTunnelInterfaceName(String.valueOf(dpn), hwVtepNodeId);
         if (tunnelInterfaceName == null) {
             return false;
@@ -965,13 +1009,13 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         availableVMCache.remove(tunnelIpElanName);
     }
 
-    private void unInstallDhcpEntriesOnDpns(final List<BigInteger> dpns, final String vmMacAddress) {
+    private void unInstallDhcpEntriesOnDpns(final List<Uint64> dpns, final String vmMacAddress) {
         jobCoordinator.enqueueJob(getJobKey(vmMacAddress), () -> {
             if (entityOwnershipUtils.isEntityOwner(HwvtepSouthboundConstants.ELAN_ENTITY_TYPE,
                     HwvtepSouthboundConstants.ELAN_ENTITY_NAME)) {
                 return Collections.singletonList(
                     txRunner.callWithNewReadWriteTransactionAndSubmit(CONFIGURATION, tx -> {
-                        for (final BigInteger dpn : dpns) {
+                        for (final Uint64 dpn : dpns) {
                             unInstallDhcpEntries(dpn, vmMacAddress, tx);
                         }
                     }));
@@ -983,6 +1027,7 @@ public class DhcpExternalTunnelManager implements IDhcpExternalTunnelManager {
         });
     }
 
+    @Nullable
     public IpAddress getTunnelIpBasedOnElan(String elanInstanceName, String vmMacAddress) {
         LOG.trace("DhcpExternalTunnelManager getTunnelIpBasedOnElan elanInstanceName {}", elanInstanceName);
         IpAddress tunnelIp = null;