VpnPortIpToPort Listener for ELAN
[netvirt.git] / vpnservice / elanmanager / elanmanager-impl / src / main / java / org / opendaylight / netvirt / elan / utils / ElanUtils.java
index 5eddc87c5a253c8509016c3ca87ffb4b92e77b48..e68fd672620c732dbba7113b50b755dbd141cf6c 100644 (file)
@@ -7,12 +7,6 @@
  */
 package org.opendaylight.netvirt.elan.utils;
 
-import com.google.common.base.Optional;
-import com.google.common.util.concurrent.CheckedFuture;
-import com.google.common.util.concurrent.FutureCallback;
-import com.google.common.util.concurrent.Futures;
-import com.google.common.util.concurrent.ListenableFuture;
-
 import java.math.BigInteger;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -32,6 +26,7 @@ import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceInfo;
 import org.opendaylight.genius.interfacemanager.globals.InterfaceServiceUtil;
+import org.opendaylight.genius.interfacemanager.interfaces.IInterfaceManager;
 import org.opendaylight.genius.itm.globals.ITMConstants;
 import org.opendaylight.genius.mdsalutil.FlowEntity;
 import org.opendaylight.genius.mdsalutil.InstructionInfo;
@@ -77,7 +72,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpc
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceInputBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.GetEgressActionsForInterfaceOutput;
-
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.rpcs.rev160406.OdlInterfaceRpcService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceBindings;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.interfacemanager.servicebinding.rev160406.ServiceModeIngress;
@@ -146,6 +140,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.tag.name.map.ElanTagNameBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.elan.tag.name.map.ElanTagNameKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.elan.rev150602.forwarding.entries.MacEntryKey;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -154,6 +149,12 @@ import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.base.Optional;
+import com.google.common.util.concurrent.CheckedFuture;
+import com.google.common.util.concurrent.FutureCallback;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
+
 public class ElanUtils {
 
     private static final Logger LOG = LoggerFactory.getLogger(ElanUtils.class);
@@ -271,7 +272,7 @@ public class ElanUtils {
 
     public <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
             InstanceIdentifier<T> path) {
-        ReadOnlyTransaction tx = (broker != null) ? broker.newReadOnlyTransaction()
+        ReadOnlyTransaction tx = broker != null ? broker.newReadOnlyTransaction()
                 : this.broker.newReadOnlyTransaction();
         Optional<T> result = Optional.absent();
         try {
@@ -291,18 +292,25 @@ public class ElanUtils {
         Futures.addCallback(tx.submit(), DEFAULT_CALLBACK);
     }
 
+    public static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
+            InstanceIdentifier<T> path, FutureCallback<Void> callback) {
+        WriteTransaction tx = broker.newWriteOnlyTransaction();
+        tx.delete(datastoreType, path);
+        Futures.addCallback(tx.submit(), callback);
+    }
+
     public static InstanceIdentifier<ElanInstance> getElanInstanceIdentifier() {
         return InstanceIdentifier.builder(ElanInstances.class).child(ElanInstance.class).build();
     }
 
     // elan-instances config container
-    public ElanInstance getElanInstanceByName(String elanInstanceName) {
-        ElanInstance elanObj = getElanInstanceFromCache(elanInstanceName);
-         if (elanObj != null) {
-             return elanObj;
-         }
+    public static ElanInstance getElanInstanceByName(DataBroker broker, String elanInstanceName) {
+        ElanInstance elanObj = getElanInstanceFromCache(elanInstanceName);
+        if (elanObj != null) {
+            return elanObj;
+        }
         InstanceIdentifier<ElanInstance> elanIdentifierId = getElanInstanceConfigurationDataPath(elanInstanceName);
-        Optional<ElanInstance> elanInstance = read(broker, LogicalDatastoreType.CONFIGURATION,
+        Optional<ElanInstance> elanInstance = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
                 elanIdentifierId);
         if (elanInstance.isPresent()) {
             return elanInstance.get();
@@ -316,13 +324,13 @@ public class ElanUtils {
     }
 
     // elan-interfaces Config Container
-    public ElanInterface getElanInterfaceByElanInterfaceName(String elanInterfaceName) {
-         ElanInterface elanInterfaceObj = getElanInterfaceFromCache(elanInterfaceName);
-          if (elanInterfaceObj != null) {
-              return elanInterfaceObj;
-          }
+    public static ElanInterface getElanInterfaceByElanInterfaceName(DataBroker broker, String elanInterfaceName) {
+        ElanInterface elanInterfaceObj = getElanInterfaceFromCache(elanInterfaceName);
+        if (elanInterfaceObj != null) {
+            return elanInterfaceObj;
+        }
         InstanceIdentifier<ElanInterface> elanInterfaceId = getElanInterfaceConfigurationDataPathId(elanInterfaceName);
-        Optional<ElanInterface> existingElanInterface = read(broker,
+        Optional<ElanInterface> existingElanInterface = MDSALUtil.read(broker,
                 LogicalDatastoreType.CONFIGURATION, elanInterfaceId);
         if (existingElanInterface.isPresent()) {
             return existingElanInterface.get();
@@ -330,8 +338,8 @@ public class ElanUtils {
         return null;
     }
 
-    public EtreeInterface getEtreeInterfaceByElanInterfaceName(String elanInterfaceName) {
-        ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(elanInterfaceName);
+    public static EtreeInterface getEtreeInterfaceByElanInterfaceName(DataBroker broker, String elanInterfaceName) {
+        ElanInterface elanInterface = getElanInterfaceByElanInterfaceName(broker, elanInterfaceName);
         return elanInterface.getAugmentation(EtreeInterface.class);
     }
 
@@ -341,9 +349,9 @@ public class ElanUtils {
     }
 
     // elan-state Operational container
-    public Elan getElanByName(String elanInstanceName) {
+    public static Elan getElanByName(DataBroker broker, String elanInstanceName) {
         InstanceIdentifier<Elan> elanIdentifier = getElanInstanceOperationalDataPath(elanInstanceName);
-        Optional<Elan> elanInstance = read(broker, LogicalDatastoreType.OPERATIONAL,
+        Optional<Elan> elanInstance = MDSALUtil.read(broker, LogicalDatastoreType.OPERATIONAL,
                 elanIdentifier);
         if (elanInstance.isPresent()) {
             return elanInstance.get();
@@ -435,7 +443,7 @@ public class ElanUtils {
      * @return the elan interface mac addresses
      */
     public List<PhysAddress> getElanInterfaceMacAddresses(String interfaceName) {
-        List<PhysAddress> macAddresses = new ArrayList<PhysAddress>();
+        List<PhysAddress> macAddresses = new ArrayList<>();
         ElanInterfaceMac elanInterfaceMac = getElanInterfaceMacByInterfaceName(interfaceName);
         if (elanInterfaceMac != null && elanInterfaceMac.getMacEntry() != null) {
             List<MacEntry> macEntries = elanInterfaceMac.getMacEntry();
@@ -545,6 +553,17 @@ public class ElanUtils {
         return null;
     }
 
+    public ElanDpnInterfaces getElanDpnInterfacesList() {
+        InstanceIdentifier<ElanDpnInterfaces> elanDpnInterfaceId = InstanceIdentifier.builder(ElanDpnInterfaces.class)
+                .build();
+        Optional<ElanDpnInterfaces> existingElanDpnInterfaces = read(broker,
+                LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
+        if (existingElanDpnInterfaces.isPresent()) {
+            return existingElanDpnInterfaces.get();
+        }
+        return null;
+    }
+
     /**
      * This method is useful get all ELAN participating CSS dpIds to install
      * program remote dmac entries and updating remote bc groups for tor
@@ -555,7 +574,7 @@ public class ElanUtils {
      * @return list of dpIds
      */
     public List<BigInteger> getParticipatingDPNsInElanInstance(String elanInstanceName) {
-        List<BigInteger> dpIds = new ArrayList<BigInteger>();
+        List<BigInteger> dpIds = new ArrayList<>();
         InstanceIdentifier<ElanDpnInterfacesList> elanDpnInterfaceId = getElanDpnOperationDataPath(elanInstanceName);
         Optional<ElanDpnInterfacesList> existingElanDpnInterfaces = read(broker,
                 LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
@@ -598,17 +617,6 @@ public class ElanUtils {
         return isDpIdPresent;
     }
 
-    public ElanDpnInterfaces getElanDpnInterfacesList() {
-        InstanceIdentifier<ElanDpnInterfaces> elanDpnInterfaceId = InstanceIdentifier.builder(ElanDpnInterfaces.class)
-                .build();
-        Optional<ElanDpnInterfaces> existingElanDpnInterfaces = read(broker,
-                LogicalDatastoreType.OPERATIONAL, elanDpnInterfaceId);
-        if (existingElanDpnInterfaces.isPresent()) {
-            return existingElanDpnInterfaces.get();
-        }
-        return null;
-    }
-
     public ElanForwardingTables getElanForwardingList() {
         InstanceIdentifier<ElanForwardingTables> elanForwardingTableId = InstanceIdentifier
                 .builder(ElanForwardingTables.class).build();
@@ -637,29 +645,29 @@ public class ElanUtils {
         return null;
     }
 
-    public static long getElanLocalBCGID(long elanTag) {
-        return ElanConstants.ELAN_GID_MIN + (((elanTag % ElanConstants.ELAN_GID_MIN) * 2) - 1);
+    public static long getElanLocalBCGId(long elanTag) {
+        return ElanConstants.ELAN_GID_MIN + (elanTag % ElanConstants.ELAN_GID_MIN * 2 - 1);
     }
 
-    public static long getElanRemoteBCGID(long elanTag) {
-        return ElanConstants.ELAN_GID_MIN + (((elanTag % ElanConstants.ELAN_GID_MIN) * 2));
+    public static long getElanRemoteBCGId(long elanTag) {
+        return ElanConstants.ELAN_GID_MIN + elanTag % ElanConstants.ELAN_GID_MIN * 2;
     }
 
-    public static long getEtreeLeafLocalBCGID(long etreeLeafTag) {
-        return ElanConstants.ELAN_GID_MIN + (((etreeLeafTag % ElanConstants.ELAN_GID_MIN) * 2) - 1);
+    public static long getEtreeLeafLocalBCGId(long etreeLeafTag) {
+        return ElanConstants.ELAN_GID_MIN + (etreeLeafTag % ElanConstants.ELAN_GID_MIN * 2 - 1);
     }
 
-    public static long getEtreeLeafRemoteBCGID(long etreeLeafTag) {
-        return ElanConstants.ELAN_GID_MIN + (((etreeLeafTag % ElanConstants.ELAN_GID_MIN) * 2));
+    public static long getEtreeLeafRemoteBCGId(long etreeLeafTag) {
+        return ElanConstants.ELAN_GID_MIN + etreeLeafTag % ElanConstants.ELAN_GID_MIN * 2;
     }
 
     public static BigInteger getElanMetadataLabel(long elanTag) {
-        return (BigInteger.valueOf(elanTag)).shiftLeft(24);
+        return BigInteger.valueOf(elanTag).shiftLeft(24);
     }
 
     public static BigInteger getElanMetadataLabel(long elanTag, boolean isSHFlagSet) {
-        int shBit = (isSHFlagSet) ? 1 : 0;
-        return (BigInteger.valueOf(elanTag)).shiftLeft(24).or(BigInteger.valueOf(shBit));
+        int shBit = isSHFlagSet ? 1 : 0;
+        return BigInteger.valueOf(elanTag).shiftLeft(24).or(BigInteger.valueOf(shBit));
     }
 
     public static BigInteger getElanMetadataLabel(long elanTag, int lportTag) {
@@ -688,7 +696,7 @@ public class ElanUtils {
     public void setupMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, long macTimeout,
             String macAddress, WriteTransaction writeFlowGroupTx) {
         synchronized (macAddress) {
-            LOG.info("Acquired lock for mac : " + macAddress + ". Proceeding with install operation.");
+            LOG.debug("Acquired lock for mac : " + macAddress + ". Proceeding with install operation.");
             setupKnownSmacFlow(elanInfo, interfaceInfo, macTimeout, macAddress, mdsalManager,
                     writeFlowGroupTx);
             setupOrigDmacFlows(elanInfo, interfaceInfo, macAddress, mdsalManager,
@@ -699,7 +707,7 @@ public class ElanUtils {
     public void setupDMacFlowonRemoteDpn(ElanInstance elanInfo, InterfaceInfo interfaceInfo, BigInteger dstDpId,
             String macAddress, WriteTransaction writeFlowTx) {
         synchronized (macAddress) {
-            LOG.info("Acquired lock for mac : " + macAddress + "Proceeding with install operation.");
+            LOG.debug("Acquired lock for mac : " + macAddress + ". Proceeding with install operation.");
             setupOrigDmacFlowsonRemoteDpn(elanInfo, interfaceInfo, dstDpId, macAddress, writeFlowTx);
         }
     }
@@ -707,12 +715,6 @@ public class ElanUtils {
     /**
      * Inserts a Flow in SMAC table to state that the MAC has already been
      * learnt.
-     *
-     * @param elanInfo
-     * @param interfaceInfo
-     * @param macTimeout
-     * @param macAddress
-     * @param mdsalApiManager
      */
     private void setupKnownSmacFlow(ElanInstance elanInfo, InterfaceInfo interfaceInfo, long macTimeout,
             String macAddress, IMdsalApiManager mdsalApiManager, WriteTransaction writeFlowGroupTx) {
@@ -726,17 +728,17 @@ public class ElanUtils {
 
     public FlowEntity buildKnownSmacFlow(ElanInstance elanInfo, InterfaceInfo interfaceInfo, long macTimeout,
             String macAddress) {
-        BigInteger dpId = interfaceInfo.getDpId();
         int lportTag = interfaceInfo.getInterfaceTag();
-        long elanTag = getElanTag(elanInfo, interfaceInfo);
         // Matching metadata and eth_src fields
-        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        List<MatchInfo> mkMatches = new ArrayList<>();
         mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
                 getElanMetadataLabel(elanInfo.getElanTag(), lportTag), getElanMetadataMask() }));
         mkMatches.add(new MatchInfo(MatchFieldType.eth_src, new String[] { macAddress }));
-        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
+        List<InstructionInfo> mkInstructions = new ArrayList<>();
         mkInstructions.add(new InstructionInfo(InstructionType.goto_table, new long[] { NwConstants.ELAN_DMAC_TABLE }));
 
+        BigInteger dpId = interfaceInfo.getDpId();
+        long elanTag = getElanTag(broker, elanInfo, interfaceInfo);
         FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, NwConstants.ELAN_SMAC_TABLE,
                 getKnownDynamicmacFlowRef(NwConstants.ELAN_SMAC_TABLE, dpId, lportTag, macAddress, elanTag), 20,
                 elanInfo.getDescription(), (int) macTimeout, 0,
@@ -750,8 +752,8 @@ public class ElanUtils {
         return flowEntity;
     }
 
-    private Long getElanTag(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
-        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(interfaceInfo.getInterfaceName());
+    private static Long getElanTag(DataBroker broker, ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, interfaceInfo.getInterfaceName());
         if (etreeInterface == null || etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
             return elanInfo.getElanTag();
         } else { // Leaf
@@ -769,7 +771,7 @@ public class ElanUtils {
     /**
      * Installs a Flow in INTERNAL_TUNNEL_TABLE of the affected DPN that sends
      * the packet through the specified interface if the tunnel_id matches the
-     * interface's lportTag
+     * interface's lportTag.
      *
      * @param interfaceInfo
      *            the interface info
@@ -811,21 +813,21 @@ public class ElanUtils {
 
     /**
      * Constructs the Matches that checks that the tunnel_id field contains a
-     * specific lportTag
+     * specific lportTag.
      *
      * @param lportTag
      *            lportTag that must be checked against the tunnel_id field
      * @return the list of match Info
      */
     public static List<MatchInfo> getTunnelIdMatchForFilterEqualsLPortTag(int lportTag) {
-        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        List<MatchInfo> mkMatches = new ArrayList<>();
         // Matching metadata
         mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] { BigInteger.valueOf(lportTag) }));
         return mkMatches;
     }
 
     /**
-     * Constructs the Instructions that take the packet over a given interface
+     * Constructs the Instructions that take the packet over a given interface.
      *
      * @param ifName
      *            Name of the interface where the packet must be sent over. It
@@ -834,7 +836,7 @@ public class ElanUtils {
      * @return the Instruction
      */
     public List<Instruction> getInstructionsInPortForOutGroup(String ifName) {
-        List<Instruction> mkInstructions = new ArrayList<Instruction>();
+        List<Instruction> mkInstructions = new ArrayList<>();
         List<Action> actions = getEgressActionsForInterface(ifName, /* tunnelKey */ null);
 
         mkInstructions.add(MDSALUtil.buildApplyActionsInstruction(actions));
@@ -856,7 +858,7 @@ public class ElanUtils {
      * @return the egress actions for interface
      */
     public List<Action> getEgressActionsForInterface(String ifName, Long tunnelKey) {
-        List<Action> listAction = new ArrayList<Action>();
+        List<Action> listAction = new ArrayList<>();
         try {
             GetEgressActionsForInterfaceInput getEgressActionInput = new GetEgressActionsForInterfaceInputBuilder()
                     .setIntfName(ifName).setTunnelKey(tunnelKey).build();
@@ -867,8 +869,7 @@ public class ElanUtils {
                 LOG.warn("RPC Call to Get egress actions for interface {} returned with Errors {}", ifName,
                         rpcResult.getErrors());
             } else {
-                List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actions = rpcResult
-                        .getResult().getAction();
+                List<Action> actions = rpcResult.getResult().getAction();
                 listAction = actions;
             }
         } catch (InterruptedException | ExecutionException e) {
@@ -885,19 +886,15 @@ public class ElanUtils {
         String elanInstanceName = elanInfo.getElanInstanceName();
         List<DpnInterfaces> elanDpns = getInvolvedDpnsInElan(elanInstanceName);
         if (elanDpns != null) {
-            Long elanTag = getElanTag(elanInfo, interfaceInfo); // TODO might be
-                                                                // bug and
-                                                                // should call
-                                                                // here just
-                                                                // elanInfo.getElanTag()
+            // TODO might be bug and should call here just elanInfo.getElanTag()
+            Long elanTag = getElanTag(broker, elanInfo, interfaceInfo);
             for (DpnInterfaces elanDpn : elanDpns) {
                 if (elanDpn.getDpId().equals(dpId)) {
                     // On the local DPN set up a direct output flow
                     setupLocalDmacFlow(elanTag, dpId, ifName, macAddress, elanInstanceName, mdsalApiManager, ifTag,
                             writeFlowGroupTx);
-                    LOG.debug(
-                            "Dmac flow entry created for elan Name:{}, logical port Name:{} and mac address:{} on dpn:{}",
-                            elanInstanceName, interfaceInfo.getPortName(), macAddress, dpId);
+                    LOG.debug("Dmac flow entry created for elan Name:{}, logical port Name:{} mand mac address:{} "
+                            + "on dpn:{}", elanInstanceName, interfaceInfo.getPortName(), macAddress, dpId);
                 } else {
                     // Check for the Remote DPN present in Inventory Manager
                     if (isDpnPresent(elanDpn.getDpId())) {
@@ -916,9 +913,9 @@ public class ElanUtils {
                                 macAddress, // MAC to be programmed in remote
                                             // DPN
                                 elanInstanceName, writeFlowGroupTx, ifName);
-                        LOG.debug(
-                                "Dmac flow entry created for elan Name:{}, logical port Name:{} and mac address:{} on dpn:{}",
-                                elanInstanceName, interfaceInfo.getPortName(), macAddress, elanDpn.getDpId());
+                        LOG.debug("Dmac flow entry created for elan Name:{}, logical port Name:{} and mac address:{} on"
+                                + " dpn:{}", elanInstanceName, interfaceInfo.getPortName(), macAddress,
+                                elanDpn.getDpId());
                     }
                 }
             }
@@ -940,9 +937,8 @@ public class ElanUtils {
                 setupRemoteDmacFlow(dstDpId, dpId, interfaceInfo.getInterfaceTag(), elanTag, macAddress,
                         elanInstanceName, writeFlowTx, interfaceInfo.getInterfaceName());
                 if (LOG.isDebugEnabled()) {
-                    LOG.debug(
-                            "Dmac flow entry created for elan Name:{}, logical port Name:{} and mac address {} on dpn:{}",
-                            elanInstanceName, interfaceInfo.getPortName(), macAddress, remoteFE.getDpId());
+                    LOG.debug("Dmac flow entry created for elan Name:{}, logical port Name:{} and mac address {} on"
+                            + " dpn:{}", elanInstanceName, interfaceInfo.getPortName(), macAddress, remoteFE.getDpId());
                 }
                 break;
             }
@@ -968,7 +964,7 @@ public class ElanUtils {
 
     private void installEtreeLocalDmacFlow(long elanTag, BigInteger dpId, String ifName, String macAddress,
             String displayName, IMdsalApiManager mdsalApiManager, long ifTag, WriteTransaction writeFlowGroupTx) {
-        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(ifName);
+        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, ifName);
         if (etreeInterface != null) {
             if (etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
                 EtreeLeafTagName etreeTagName = getEtreeLeafTagByElanTag(elanTag);
@@ -1006,7 +1002,7 @@ public class ElanUtils {
      * Builds the flow to be programmed in the DMAC table of the local DPN (that
      * is, where the MAC is attached to). This flow consists in:
      *
-     * Match: + elanTag in metadata + packet goes to a MAC locally attached
+     * <p>Match: + elanTag in metadata + packet goes to a MAC locally attached
      * Actions: + optionally, pop-vlan + set-vlan-id + output to ifName's
      * portNumber
      *
@@ -1031,7 +1027,7 @@ public class ElanUtils {
                 new BigInteger[] { getElanMetadataLabel(elanTag), MetaDataUtil.METADATA_MASK_SERVICE }));
         mkMatches.add(new MatchInfo(MatchFieldType.eth_dst, new String[] { macAddress }));
 
-        List<Instruction> mkInstructions = new ArrayList<Instruction>();
+        List<Instruction> mkInstructions = new ArrayList<>();
         List<Action> actions = getEgressActionsForInterface(ifName, /* tunnelKey */ null);
         mkInstructions.add(MDSALUtil.buildApplyActionsInstruction(actions));
         Flow flow = MDSALUtil.buildFlowNew(NwConstants.ELAN_DMAC_TABLE,
@@ -1053,7 +1049,7 @@ public class ElanUtils {
     private void setupEtreeRemoteDmacFlow(BigInteger srcDpId, BigInteger destDpId, int lportTag, long elanTag,
             String macAddress, String displayName, String interfaceName, WriteTransaction writeFlowGroupTx) {
         Flow flowEntity;
-        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(interfaceName);
+        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, interfaceName);
         if (etreeInterface != null) {
             if (etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
                 EtreeLeafTagName etreeTagName = getEtreeLeafTagByElanTag(elanTag);
@@ -1096,7 +1092,7 @@ public class ElanUtils {
                 new BigInteger[] { getElanMetadataLabel(elanTag), MetaDataUtil.METADATA_MASK_SERVICE }));
         mkMatches.add(new MatchInfo(MatchFieldType.eth_dst, new String[] { macAddress }));
 
-        List<Instruction> mkInstructions = new ArrayList<Instruction>();
+        List<Instruction> mkInstructions = new ArrayList<>();
 
         // List of Action for the provided Source and Destination DPIDs
         try {
@@ -1124,7 +1120,7 @@ public class ElanUtils {
         }
         String macAddress = macEntry.getMacAddress().getValue();
         synchronized (macAddress) {
-            LOG.info("Acquired lock for mac : " + macAddress + "Proceeding with remove operation.");
+            LOG.debug("Acquired lock for mac : " + macAddress + ". Proceeding with remove operation.");
             deleteMacFlows(elanInfo, interfaceInfo, macAddress, /* alsoDeleteSMAC */ true, deleteFlowGroupTx);
         }
     }
@@ -1138,20 +1134,20 @@ public class ElanUtils {
         for (DpnInterfaces dpnInterface : remoteFEs) {
             Long elanTag = elanInfo.getElanTag();
             BigInteger dstDpId = dpnInterface.getDpId();
-            if (executeDeleteMacFlows(elanInfo, interfaceInfo, macAddress, deleteSmac, elanInstanceName, srcdpId, elanTag,
-                    dstDpId, deleteFlowGroupTx)) {
+            if (executeDeleteMacFlows(elanInfo, interfaceInfo, macAddress, deleteSmac, elanInstanceName, srcdpId,
+                    elanTag, dstDpId, deleteFlowGroupTx)) {
                 isFlowsRemovedInSrcDpn = true;
             }
-            executeEtreeDeleteMacFlows(elanInfo, interfaceInfo, macAddress, deleteSmac, elanInstanceName, srcdpId, elanTag,
-                    dstDpId, deleteFlowGroupTx);
+            executeEtreeDeleteMacFlows(elanInfo, interfaceInfo, macAddress, deleteSmac, elanInstanceName, srcdpId,
+                    elanTag, dstDpId, deleteFlowGroupTx);
         }
         if (!isFlowsRemovedInSrcDpn) {
             deleteSmacAndDmacFlows(elanInfo, interfaceInfo, macAddress, deleteSmac, deleteFlowGroupTx);
         }
     }
 
-    private void executeEtreeDeleteMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, String macAddress, boolean deleteSmac,
-            String elanInstanceName, BigInteger srcdpId, Long elanTag, BigInteger dstDpId,
+    private void executeEtreeDeleteMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, String macAddress,
+            boolean deleteSmac, String elanInstanceName, BigInteger srcdpId, Long elanTag, BigInteger dstDpId,
             WriteTransaction deleteFlowGroupTx) {
         EtreeLeafTagName etreeLeafTag = getEtreeLeafTagByElanTag(elanTag);
         if (etreeLeafTag != null) {
@@ -1160,8 +1156,8 @@ public class ElanUtils {
         }
     }
 
-    private boolean executeDeleteMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, String macAddress, boolean deleteSmac,
-            String elanInstanceName, BigInteger srcdpId, Long elanTag, BigInteger dstDpId,
+    private boolean executeDeleteMacFlows(ElanInstance elanInfo, InterfaceInfo interfaceInfo, String macAddress,
+            boolean deleteSmac, String elanInstanceName, BigInteger srcdpId, Long elanTag, BigInteger dstDpId,
             WriteTransaction deleteFlowGroupTx) {
         boolean isFlowsRemovedInSrcDpn = false;
         if (dstDpId.equals(srcdpId)) {
@@ -1199,9 +1195,8 @@ public class ElanUtils {
                         getKnownDynamicmacFlowRef(NwConstants.ELAN_DMAC_TABLE, srcdpId, ifTag, macAddress, elanTag)),
                 deleteFlowGroupTx);
         if (LOG.isDebugEnabled()) {
-            LOG.debug(
-                    "All the required flows deleted for elan:{}, logical Interface port:{} and mac address:{} on dpn:{}",
-                    elanInstanceName, interfaceInfo.getPortName(), macAddress, srcdpId);
+            LOG.debug("All the required flows deleted for elan:{}, logical Interface port:{} and MAC address:{} "
+                    + "on dpn:{}", elanInstanceName, interfaceInfo.getPortName(), macAddress, srcdpId);
         }
     }
 
@@ -1292,7 +1287,7 @@ public class ElanUtils {
         InstanceIdentifier<Node> node = InstanceIdentifier.builder(Nodes.class).child(Node.class, new NodeKey(nodeId))
                 .build();
         Optional<Node> nodePresent = read(broker, LogicalDatastoreType.OPERATIONAL, node);
-        return (nodePresent.isPresent());
+        return nodePresent.isPresent();
     }
 
     public static ServicesInfo getServiceInfo(String elanInstanceName, long elanTag, String interfaceName) {
@@ -1310,13 +1305,6 @@ public class ElanUtils {
         return serviceInfo;
     }
 
-    public static <T extends DataObject> void delete(DataBroker broker, LogicalDatastoreType datastoreType,
-            InstanceIdentifier<T> path, FutureCallback<Void> callback) {
-        WriteTransaction tx = broker.newWriteOnlyTransaction();
-        tx.delete(datastoreType, path);
-        Futures.addCallback(tx.submit(), callback);
-    }
-
     public static <T extends DataObject> void syncWrite(DataBroker broker, LogicalDatastoreType datastoreType,
             InstanceIdentifier<T> path, T data) {
         WriteTransaction tx = broker.newWriteOnlyTransaction();
@@ -1423,8 +1411,9 @@ public class ElanUtils {
             if (output.get().isSuccessful()) {
                 GetExternalTunnelInterfaceNameOutput tunnelInterfaceNameOutput = output.get().getResult();
                 String tunnelIfaceName = tunnelInterfaceNameOutput.getInterfaceName();
-                if (LOG.isDebugEnabled())
+                if (LOG.isDebugEnabled()) {
                     LOG.debug("Received tunnelInterfaceName from getTunnelInterfaceName RPC {}", tunnelIfaceName);
+                }
 
                 result = buildTunnelItmEgressActions(tunnelIfaceName, vni);
             }
@@ -1479,7 +1468,7 @@ public class ElanUtils {
 
     /**
      * Build the list of actions to be taken when sending the packet to external
-     * (physical) port
+     * (physical) port.
      *
      * @param interfaceName
      *            Interface name
@@ -1490,7 +1479,7 @@ public class ElanUtils {
     }
 
     public static List<MatchInfo> getTunnelMatchesForServiceId(int elanTag) {
-        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        List<MatchInfo> mkMatches = new ArrayList<>();
         // Matching metadata
         mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] { BigInteger.valueOf(elanTag) }));
 
@@ -1515,7 +1504,7 @@ public class ElanUtils {
     }
 
     public void createTerminatingServiceActions(BigInteger destDpId, int serviceId, List<Action> actions) {
-        List<Instruction> mkInstructions = new ArrayList<Instruction>();
+        List<Instruction> mkInstructions = new ArrayList<>();
         mkInstructions.add(MDSALUtil.buildApplyActionsInstruction(actions));
         CreateTerminatingServiceActionsInput input = new CreateTerminatingServiceActionsInputBuilder()
                 .setDpnId(destDpId).setServiceId(serviceId).setInstruction(mkInstructions).build();
@@ -1523,10 +1512,10 @@ public class ElanUtils {
         itmRpcService.createTerminatingServiceActions(input);
     }
 
-    public TunnelList buildInternalTunnel(DataBroker broker) {
+    public static TunnelList buildInternalTunnel(DataBroker broker) {
         InstanceIdentifier<TunnelList> tunnelListInstanceIdentifier = InstanceIdentifier.builder(TunnelList.class)
                 .build();
-        Optional<TunnelList> tunnelList = read(broker, LogicalDatastoreType.CONFIGURATION,
+        Optional<TunnelList> tunnelList = MDSALUtil.read(broker, LogicalDatastoreType.CONFIGURATION,
                 tunnelListInstanceIdentifier);
         if (tunnelList.isPresent()) {
             return tunnelList.get();
@@ -1685,7 +1674,7 @@ public class ElanUtils {
         if (interfaceName == null) {
             isRoot = true;
         } else {
-            EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(interfaceName);
+            EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, interfaceName);
             if (etreeInterface != null) {
                 if (etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
                     isRoot = true;
@@ -1709,7 +1698,7 @@ public class ElanUtils {
     }
 
     public static List<MatchInfo> buildMatchesForElanTagShFlagAndDstMac(long elanTag, boolean shFlag, String macAddr) {
-        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+        List<MatchInfo> mkMatches = new ArrayList<>();
         mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
                 getElanMetadataLabel(elanTag, shFlag), MetaDataUtil.METADATA_MASK_SERVICE_SH_FLAG }));
         mkMatches.add(new MatchInfo(MatchFieldType.eth_dst, new String[] { macAddr }));
@@ -1772,8 +1761,6 @@ public class ElanUtils {
      *            ElanId to which the MAC is being added to
      * @param dstMacAddress
      *            The mac address to be programmed
-     * @param displayName
-     * @return
      */
     private static Flow buildDmacFlowDropIfPacketComingFromTunnel(BigInteger dpnId, String extDeviceNodeId,
             Long elanTag, String dstMacAddress) {
@@ -1798,7 +1785,7 @@ public class ElanUtils {
      * Builds a Flow to be programmed in a remote DPN's DMAC table. This method
      * must be used when the MAC is located in another CSS.
      *
-     * This flow consists in: Match: + elanTag in packet's metadata + packet
+     * <p>This flow consists in: Match: + elanTag in packet's metadata + packet
      * going to a MAC known to be located in another DPN Actions: +
      * set_tunnel_id(lportTag) + output on ITM internal tunnel interface with
      * the other DPN
@@ -1821,7 +1808,7 @@ public class ElanUtils {
             long elanTag, String macAddress, String displayName) {
         List<MatchInfo> mkMatches = buildMatchesForElanTagShFlagAndDstMac(elanTag, /* shFlag */ false, macAddress);
 
-        List<Instruction> mkInstructions = new ArrayList<Instruction>();
+        List<Instruction> mkInstructions = new ArrayList<>();
 
         try {
             // List of Action for the provided Source and Destination DPIDs
@@ -1969,7 +1956,7 @@ public class ElanUtils {
         if (ifState == null) {
             return false;
         }
-        return ((ifState.getOperStatus() == OperStatus.Up) && (ifState.getAdminStatus() == AdminStatus.Up));
+        return ifState.getOperStatus() == OperStatus.Up && ifState.getAdminStatus() == AdminStatus.Up;
     }
 
     /**
@@ -1981,11 +1968,14 @@ public class ElanUtils {
      *            the data broker
      * @return the interface state from oper ds
      */
-    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(
+    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+        .ietf.interfaces.rev140508.interfaces.state.Interface getInterfaceStateFromOperDS(
             String interfaceName, DataBroker dataBroker) {
-        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = createInterfaceStateInstanceIdentifier(
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+            .ietf.interfaces.rev140508.interfaces.state.Interface> ifStateId = createInterfaceStateInstanceIdentifier(
                 interfaceName);
-        Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional = MDSALUtil
+        Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+            .ietf.interfaces.rev140508.interfaces.state.Interface> ifStateOptional = MDSALUtil
                 .read(dataBroker, LogicalDatastoreType.OPERATIONAL, ifStateId);
         if (ifStateOptional.isPresent()) {
             return ifStateOptional.get();
@@ -2002,11 +1992,13 @@ public class ElanUtils {
      *            the data broker
      * @return the interface from config ds
      */
-    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface getInterfaceFromConfigDS(
+    public static org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+        .ietf.interfaces.rev140508.interfaces.Interface getInterfaceFromConfigDS(
             String interfaceName, DataBroker dataBroker) {
-        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> ifaceId = createInterfaceInstanceIdentifier(
-                interfaceName);
-        Optional<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> iface = MDSALUtil
+        InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+            .ietf.interfaces.rev140508.interfaces.Interface> ifaceId = createInterfaceInstanceIdentifier(interfaceName);
+        Optional<org.opendaylight.yang.gen.v1.urn
+            .ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> iface = MDSALUtil
                 .read(dataBroker, LogicalDatastoreType.CONFIGURATION, ifaceId);
         if (iface.isPresent()) {
             return iface.get();
@@ -2021,12 +2013,16 @@ public class ElanUtils {
      *            the interface name
      * @return the instance identifier
      */
-    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> createInterfaceStateInstanceIdentifier(
+    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+        .ietf.interfaces.rev140508.interfaces.state.Interface> createInterfaceStateInstanceIdentifier(
             String interfaceName) {
-        InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder = InstanceIdentifier
+        InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+            .ietf.interfaces.rev140508.interfaces.state.Interface> idBuilder = InstanceIdentifier
                 .builder(InterfacesState.class)
-                .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.Interface.class,
-                        new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.state.InterfaceKey(
+                .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                        .ietf.interfaces.rev140508.interfaces.state.Interface.class,
+                        new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                            .ietf.interfaces.rev140508.interfaces.state.InterfaceKey(
                                 interfaceName));
         return idBuilder.build();
     }
@@ -2038,17 +2034,22 @@ public class ElanUtils {
      *            the interface name
      * @return the instance identifier
      */
-    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> createInterfaceInstanceIdentifier(
+    public static InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+        .ietf.interfaces.rev140508.interfaces.Interface> createInterfaceInstanceIdentifier(
             String interfaceName) {
-        InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface> idBuilder = InstanceIdentifier
+        InstanceIdentifierBuilder<org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+            .ietf.interfaces.rev140508.interfaces.Interface> idBuilder = InstanceIdentifier
                 .builder(Interfaces.class)
-                .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface.class,
-                        new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey(
+                .child(org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                        .ietf.interfaces.rev140508.interfaces.Interface.class,
+                        new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+                            .ietf.interfaces.rev140508.interfaces.InterfaceKey(
                                 interfaceName));
         return idBuilder.build();
     }
 
-    public static CheckedFuture<Void, TransactionCommitFailedException> waitForTransactionToComplete(WriteTransaction tx) {
+    public static CheckedFuture<Void, TransactionCommitFailedException> waitForTransactionToComplete(
+            WriteTransaction tx) {
         CheckedFuture<Void, TransactionCommitFailedException> futures = tx.submit();
         try {
             futures.get();
@@ -2080,7 +2081,8 @@ public class ElanUtils {
     }
 
     public static boolean isExternal(
-            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface iface) {
+            org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
+            .ietf.interfaces.rev140508.interfaces.Interface iface) {
         if (iface == null) {
             return false;
         }
@@ -2089,11 +2091,47 @@ public class ElanUtils {
         return ifExternal != null && Boolean.TRUE.equals(ifExternal.isExternal());
     }
 
-    public boolean isEtreeRootInterfaceByInterfaceName(String interfaceName) {
-        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(interfaceName);
+    public static boolean isEtreeRootInterfaceByInterfaceName(DataBroker broker, String interfaceName) {
+        EtreeInterface etreeInterface = getEtreeInterfaceByElanInterfaceName(broker, interfaceName);
         if (etreeInterface != null && etreeInterface.getEtreeInterfaceType() == EtreeInterfaceType.Root) {
             return true;
         }
         return false;
     }
+
+    /**
+     * Add Mac Address to ElanInterfaceForwardingEntries and ElanForwardingTables
+     * Install SMAC and DMAC flows
+     */
+    public void addMacEntryToDsAndSetupFlows(IInterfaceManager interfaceManager, String interfaceName, String macAddress, String elanName, WriteTransaction tx, WriteTransaction flowWritetx, int macTimeOut) {
+        LOG.trace("Adding mac address {} and interface name {} to ElanInterfaceForwardingEntries and ElanForwardingTables DS", macAddress, interfaceName);
+        BigInteger timeStamp = new BigInteger(String.valueOf((long)System.currentTimeMillis()));
+        PhysAddress physAddress = new PhysAddress(macAddress);
+        MacEntry macEntry = new MacEntryBuilder().setInterface(interfaceName).setMacAddress(physAddress).setKey(new MacEntryKey(physAddress)).setControllerLearnedForwardingEntryTimestamp(timeStamp).setIsStaticAddress(false).build();
+        InstanceIdentifier<MacEntry> macEntryId = ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+        tx.put(LogicalDatastoreType.OPERATIONAL, macEntryId, macEntry);
+        InstanceIdentifier<MacEntry> elanMacEntryId = ElanUtils.getMacEntryOperationalDataPath(elanName, physAddress);
+        tx.put(LogicalDatastoreType.OPERATIONAL, elanMacEntryId, macEntry);
+        ElanInstance elanInstance = ElanUtils.getElanInstanceByName(broker, elanName);
+        setupMacFlows(elanInstance, interfaceManager.getInterfaceInfo(interfaceName), macTimeOut, macAddress, flowWritetx);
+    }
+
+    /**
+     * Remove Mac Address from ElanInterfaceForwardingEntries and ElanForwardingTables
+     * Remove SMAC and DMAC flows
+     */
+    public void deleteMacEntryFromDsAndRemoveFlows(IInterfaceManager interfaceManager, String interfaceName, String macAddress, String elanName, WriteTransaction tx, WriteTransaction deleteFlowTx) {
+        LOG.trace("Deleting mac address {} and interface name {} from ElanInterfaceForwardingEntries and ElanForwardingTables DS", macAddress, interfaceName);
+        PhysAddress physAddress = new PhysAddress(macAddress);
+        MacEntry macEntry = getInterfaceMacEntriesOperationalDataPath(interfaceName, physAddress);
+        InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfo(interfaceName);
+        if(macEntry != null && interfaceInfo != null) {
+            deleteMacFlows(ElanUtils.getElanInstanceByName(broker, elanName), interfaceInfo, macEntry, deleteFlowTx);
+        }
+        InstanceIdentifier<MacEntry> macEntryIdForElanInterface =  ElanUtils.getInterfaceMacEntriesIdentifierOperationalDataPath(interfaceName, physAddress);
+        InstanceIdentifier<MacEntry> macEntryIdForElanInstance  =  ElanUtils.getMacEntryOperationalDataPath(elanName, physAddress);
+        tx.delete(LogicalDatastoreType.OPERATIONAL, macEntryIdForElanInterface);
+        tx.delete(LogicalDatastoreType.OPERATIONAL, macEntryIdForElanInstance);
+    }
+
 }