BUG:5179 InterfaceStateChange Event handling for Elan
[vpnservice.git] / elanmanager / elanmanager-impl / src / main / java / org / opendaylight / vpnservice / elan / internal / ElanInterfaceManager.java
index b933578d701e89efc5b3454c179252de2c811fed..95460af6a37a1720e16c12cdcfbc099356c4b7e0 100644 (file)
@@ -8,35 +8,23 @@
 package org.opendaylight.vpnservice.elan.internal;
 
 import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataChangeListener;
 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker.DataChangeScope;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.vpnservice.elan.utils.ElanConstants;
-import org.opendaylight.vpnservice.elan.utils.ElanConstants;
 import org.opendaylight.vpnservice.elan.utils.ElanUtils;
 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo;
 import org.opendaylight.vpnservice.interfacemgr.globals.InterfaceInfo.InterfaceType;
 import org.opendaylight.vpnservice.interfacemgr.interfaces.IInterfaceManager;
-import org.opendaylight.vpnservice.itm.api.IITMProvider;
+
+import org.opendaylight.vpnservice.mdsalutil.NwConstants;
 import org.opendaylight.vpnservice.itm.globals.ITMConstants;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PushVlanActionCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.SetFieldCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.ExtensionKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlow;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.GeneralAugMatchNodesNodeTableFlowBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.grouping.ExtensionBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionList;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.general.rev140714.general.extension.list.grouping.ExtensionListBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.*;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.match.rev140714.nxm.nx.reg.grouping.NxmNxRegBuilder;
-
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group.buckets.Bucket;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.groups.Group;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.servicebinding.rev151015.service.bindings.services.info.BoundServices;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
 import org.opendaylight.vpnservice.mdsalutil.*;
@@ -65,13 +53,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.f
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.elan.rev150602.forwarding.entries.MacEntryKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.idmanager.rev150403.IdManagerService;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceInputBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.GetEgressActionsForInterfaceOutput;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.interfacemgr.rpcs.rev151003.OdlInterfaceRpcService;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
-import org.opendaylight.yangtools.yang.common.RpcResult;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -79,8 +63,6 @@ import java.math.BigInteger;
 import java.util.*;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.Future;
 
 
 public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterface> implements AutoCloseable {
@@ -93,7 +75,7 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
     private IMdsalApiManager mdsalManager;
     private IInterfaceManager interfaceManager;
     private IdManagerService idManager;
-    private IITMProvider itmManager;
+
     private ElanForwardingEntriesHandler elanForwardingEntriesHandler;
     private Map<String, ConcurrentLinkedQueue<ElanInterface>> unProcessedElanInterfaces =
             new ConcurrentHashMap<String, ConcurrentLinkedQueue<ElanInterface>> ();
@@ -128,10 +110,6 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         this.broker = broker;
     }
 
-    public void setIITMManager(IITMProvider itmManager) {
-        this.itmManager = itmManager;
-    }
-
     @Override
     public void close() throws Exception {
         if (elanInterfaceListenerRegistration != null) {
@@ -169,12 +147,11 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         removeElanInterface(elanInfo, interfaceName);
     }
 
-    public void removeElanService(ElanInterface del, int vlanId) {
+    public void removeElanService(ElanInterface del, InterfaceInfo interfaceInfo) {
         ElanInstance elanInstance = ElanUtils.getElanInstanceByName(del.getElanInstanceName());
         String interfaceName = del.getName();
-        InterfaceInfo interfaceInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(interfaceName, InterfaceType.VLAN_INTERFACE);
         removeElanInterface(elanInstance, interfaceInfo);
-        unbindService(elanInstance, interfaceName, vlanId);
+        unbindService(elanInstance, interfaceName);
     }
 
     public void removeElanInterface(ElanInstance elanInfo, String interfaceName) {
@@ -225,7 +202,6 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
                 }
             }
         }
-
         /*
          *This condition check is mainly to get DPN-ID in pre-provision deletion scenario after stopping CSS
          */
@@ -246,10 +222,11 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
             removeElanDpnInterfaceFromOperationalDataStore(elanName, dpId, interfaceName);
         }
 
+        removeStaticELanFlows(elanInfo, interfaceInfo);
         ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, elanInterfaceId);
         List<String> elanInterfaces = elanState.getElanInterfaces();
         elanInterfaces.remove(interfaceName);
-        removeStaticELanFlows(elanInfo, interfaceInfo);
+
         if(elanInterfaces.isEmpty()) {
             ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanInstanceOperationalDataPath(elanName));
             ElanUtils.delete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnOperationDataPath(elanName));
@@ -441,10 +418,10 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         if (isOperational(interfaceInfo)) {
 
             // LocalBroadcast Group creation with elan-Interfaces
-            setupLocalBroadcastGroups(elanInfo, interfaceInfo);
+            setupElanBroadcastGroups(elanInfo, interfaceInfo);
 
-            //Remote-broadcast group & Terminating Service , UnknownDMAC Table.
-            //setupRemoteBroadcastGroups(elanInfo, interfaceInfo);
+            setupLocalBroadcastGroups(elanInfo, interfaceInfo);
+            //Terminating Service , UnknownDMAC Table.
             setupTerminateServiceTable(elanInfo, interfaceInfo);
             setupUnknownDMacTable(elanInfo, interfaceInfo);
             setupFilterEqualsTable(elanInfo, interfaceInfo);
@@ -452,127 +429,129 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
             bindService(elanInfo, interfaceInfo.getInterfaceName());
 
             //update the remote-DPNs remoteBC group entry with Tunnels
-            setRemoteBCGrouponOtherDpns(elanInfo, interfaceInfo);
+            setElanBCGrouponOtherDpns(elanInfo, interfaceInfo);
         }
     }
 
     public void setupFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
-        long elanTag = elanInfo.getElanTag();
-        long ifTag = interfaceInfo.getInterfaceTag();
-        List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
-        MatchBuilder mb = new MatchBuilder();
-        addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, ifTag));
-        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
-                9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsReg1LPortTag(ifTag),
-                getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
+        int ifTag = interfaceInfo.getInterfaceTag();
+        Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
+                9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag), ElanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
 
-        mdsalManager.installFlow(flowEntity);
+        mdsalManager.installFlow(interfaceInfo.getDpId(), flow);
 
-        FlowEntity flowEntity1 = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
+        Flow flowEntry = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
                 10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
                 getInstructionsDrop());
 
-        mdsalManager.installFlow(flowEntity1);
+        mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntry);
     }
 
+    public void removeFilterEqualsTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        int ifTag = interfaceInfo.getInterfaceTag();
+        Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, ifTag),
+                9, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getTunnelIdMatchForFilterEqualsLPortTag(ifTag), ElanUtils.getInstructionsInPortForOutGroup(interfaceInfo.getInterfaceName()));
 
-    protected List<ActionInfo> getEgressActionsForInterface(String ifName) {
-        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
-        try {
-            Future<RpcResult<GetEgressActionsForInterfaceOutput>> result =
-                    interfaceManagerRpcService.getEgressActionsForInterface(
-                            new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName).build());
-            RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
-            System.out.println("Data is populated");
-            if(!rpcResult.isSuccessful()) {
-                logger.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();
-                for (Action action : actions) {
-                    org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
-                    if (actionClass instanceof OutputActionCase) {
-                        System.out.println("Data ");
-                        listActionInfo.add(new ActionInfo(ActionType.output,
-                                new String[] {((OutputActionCase)actionClass).getOutputAction()
-                                        .getOutputNodeConnector().getValue()}));
-                    } else if (actionClass instanceof PushVlanActionCase) {
-                        listActionInfo.add(new ActionInfo(ActionType.push_vlan, new String[] {}));
-                    } else if (actionClass instanceof SetFieldCase) {
-                        if (((SetFieldCase)actionClass).getSetField().getVlanMatch() != null) {
-                            int vlanVid = ((SetFieldCase)actionClass).getSetField().getVlanMatch().getVlanId().getVlanId().getValue();
-                            listActionInfo.add(new ActionInfo(ActionType.set_field_vlan_vid,
-                                    new String[] { Long.toString(vlanVid) }));
-                        }
-                    }
-                }
-            }
-        } catch (InterruptedException | ExecutionException e) {
-            logger.warn("Exception when egress actions for interface {}", ifName, e);
-        }
-        return listActionInfo;
-    }
+        mdsalManager.removeFlow(interfaceInfo.getDpId(), flow);
 
+        Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_FILTER_EQUALS_TABLE, getFlowRef(ElanConstants.ELAN_FILTER_EQUALS_TABLE, 1000+ifTag),
+                10, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_FILTER_EQUALS.add(BigInteger.valueOf(ifTag)), getMatchesForFilterEqualsLPortTag(ifTag),
+                getInstructionsDrop());
 
-    private List<BucketInfo> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
-            InterfaceInfo interfaceInfo) {
+        mdsalManager.removeFlow(interfaceInfo.getDpId(), flowEntity);
+    }
+
+    private List<Bucket> getRemoteBCGroupBucketInfos(ElanInstance elanInfo,
+                                                     int bucketKeyStart, InterfaceInfo interfaceInfo) {
         BigInteger dpnId = interfaceInfo.getDpId();
         int elanTag = elanInfo.getElanTag().intValue();
-        List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+        int bucketId = bucketKeyStart;
+        List<Bucket> listBuckets = new ArrayList<Bucket>();
         ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
         if(elanDpns != null) {
             List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
             for(DpnInterfaces dpnInterface : dpnInterfaceses) {
                if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
                    try {
-                       //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
-                       //List<ActionInfo> listActionInfo = itmManager.ITMIngressGetActions(dpnId, dpnInterface.getDpId(), (int) elanTag);
-                       //listBucketInfo.add(new BucketInfo(listActionInfo));
+                       List<Action> listAction = ElanUtils.getItmEgressAction(dpnId, dpnInterface.getDpId(), (int) elanTag);
+                       listBuckets.add(MDSALUtil.buildBucket(listAction, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
+                       bucketId++;
                    } catch (Exception ex) {
                        logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
                    }
                }
             }
         }
-        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
-        listActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanInfo.getElanTag()))}));
-        listBucketInfo.add(new BucketInfo(listActionInfo));
-        return listBucketInfo;
+        return listBuckets;
     }
 
-    public ActionInfo getReg1ActionInfo(int interfaceTag) {
-         return new ActionInfo(ActionType.set_field_reg, new String[] {String.valueOf(interfaceTag)});
+    private List<Bucket> getRemoteBCGroupBuckets(ElanInstance elanInfo,
+                                                         InterfaceInfo interfaceInfo, int bucketId) {
+        BigInteger dpnId = interfaceInfo.getDpId();
+        int elanTag = elanInfo.getElanTag().intValue();
+        List<Bucket> listBucketInfo = new ArrayList<Bucket>();
+        ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
+        if(elanDpns != null) {
+            List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
+            for(DpnInterfaces dpnInterface : dpnInterfaceses) {
+                if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && dpnInterface.getDpId() != dpnId && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
+                    try {
+                        List<Action> listActionInfo = ElanUtils.getItmEgressAction(dpnId, dpnInterface.getDpId(), (int) elanTag);
+                        listBucketInfo.add(MDSALUtil.buildBucket(listActionInfo, 0, bucketId, 0xffffffffL, 0xffffffffL));
+                        bucketId++;
+                    } catch (Exception ex) {
+                        logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnId, dpnInterface.getDpId() );
+                    }
+                }
+            }
+        }
+        return listBucketInfo;
     }
 
-    private void setRemoteBCGrouponOtherDpns(ElanInstance elanInfo,
-                                                         InterfaceInfo interfaceInfo) {
+    private void setElanBCGrouponOtherDpns(ElanInstance elanInfo,
+                                           InterfaceInfo interfaceInfo) {
         BigInteger dpnId = interfaceInfo.getDpId();
         int elanTag = elanInfo.getElanTag().intValue();
         long groupId = ElanUtils.getElanRemoteBCGID(elanTag);
+        List<Bucket> listBucket = new ArrayList<Bucket>();
+        int bucketId = 0;
         ElanDpnInterfacesList elanDpns = ElanUtils.getElanDpnInterfacesList(elanInfo.getElanInstanceName());
         if(elanDpns != null) {
             List<DpnInterfaces> dpnInterfaceses = elanDpns.getDpnInterfaces();
             for(DpnInterfaces dpnInterface : dpnInterfaceses) {
-              List<BucketInfo> remoteListBucketInfo = new ArrayList<BucketInfo>();
+              List<Bucket> remoteListBucketInfo = new ArrayList<Bucket>();
                 if(ElanUtils.isDpnPresent(dpnInterface.getDpId()) && !dpnInterface.getDpId().equals(dpnId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
+                    for(String ifName : dpnInterface.getInterfaces()) {
+                        // In case if there is a InterfacePort in the cache which is not in
+                        // operational state, skip processing it
+                        InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
+                        if (!isOperational(ifInfo)) {
+                            continue;
+                        }
+
+                        listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
+                        bucketId++;
+                    }
+                    remoteListBucketInfo.addAll(listBucket);
                     for(DpnInterfaces otherFes : dpnInterfaceses) {
                         if (ElanUtils.isDpnPresent(otherFes.getDpId()) && otherFes.getDpId() != dpnInterface.getDpId()
                                 && otherFes.getInterfaces() != null && ! otherFes.getInterfaces().isEmpty()) {
                             try {
-                                //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
-                                //List<ActionInfo> remoteListActionInfo = itmManager.ITMIngressGetActions(dpnInterface.getDpId(), otherFes.getDpId(), (int) elanTag);
-                                //remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
+                                List<Action> remoteListActionInfo = ElanUtils.getItmEgressAction(dpnInterface.getDpId(), otherFes.getDpId(), (int) elanTag);
+                                remoteListBucketInfo.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT,MDSALUtil.WATCH_GROUP));
+                                bucketId++;
                             } catch (Exception ex) {
                                 logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), otherFes.getDpId() );
                                 return;
                             }
                         }
                     }
-                    List<ActionInfo> remoteListActionInfo = new ArrayList<ActionInfo>();
-                    remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}));
-                    remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
-                    GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnInterface.getDpId(), groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, remoteListBucketInfo);
-                    mdsalManager.installGroup(groupEntity);
+                    if(remoteListBucketInfo.size() == 0) {
+                        logger.debug( "No ITM is present on Dpn - {} " ,dpnInterface.getDpId());
+                        continue;
+                    }
+                    Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucketInfo));
+                    mdsalManager.syncInstallGroup(dpnInterface.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
                 }
             }
         }
@@ -585,21 +564,22 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         List<DpnInterfaces> elanDpns = ElanUtils.getInvolvedDpnsInElan(elanInfo.getElanInstanceName());
         if(elanDpns != null) {
             for(DpnInterfaces dpnInterface : elanDpns) {
-                List<BucketInfo> remoteListBucketInfo = new ArrayList<BucketInfo>();
+                int bucketId = 0;
+                List<Bucket> remoteListBucket = new ArrayList<Bucket>();
                 if(ElanUtils.isDpnPresent(dstDpId) && dpnInterface.getDpId().equals(dstDpId) && dpnInterface.getInterfaces() != null && !dpnInterface.getInterfaces().isEmpty()) {
                     try {
-                        //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
-                        //List<ActionInfo> remoteListActionInfo = itmManager.ITMIngressGetActions(interfaceInfo.getDpId(), dstDpId, (int) elanTag);
-                        //remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
+                        List<Action> remoteListActionInfo = ElanUtils.getItmEgressAction(interfaceInfo.getDpId(), dstDpId, (int) elanTag);
+                        remoteListBucket.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
+                        bucketId++;
                     } catch (Exception ex) {
                         logger.error( "Logical Group Interface not found between source Dpn - {}, destination Dpn - {} " ,dpnInterface.getDpId(), dstDpId);
                         return;
                     }
-                    List<ActionInfo> remoteListActionInfo = new ArrayList<ActionInfo>();
-                    remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}));
-                    remoteListBucketInfo.add(new BucketInfo(remoteListActionInfo));
-                    GroupEntity groupEntity = MDSALUtil.buildGroupEntity(interfaceInfo.getDpId(), groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, remoteListBucketInfo);
-                    mdsalManager.installGroup(groupEntity);
+                    List<Action> remoteListActionInfo = new ArrayList<Action>();
+                    remoteListActionInfo.add(new ActionInfo(ActionType.group, new String[] {String.valueOf(ElanUtils.getElanLocalBCGID(elanTag))}).buildAction());
+                    remoteListBucket.add(MDSALUtil.buildBucket(remoteListActionInfo, MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
+                    Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(remoteListBucket));
+                    mdsalManager.syncInstallGroup(interfaceInfo.getDpId(), group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
                     break;
                 }
             }
@@ -610,8 +590,8 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
     /**
      * Returns the bucket info with the given interface as the only bucket.
      */
-    private List<BucketInfo> getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo) {
-        return Lists.newArrayList(new BucketInfo(getInterfacePortActionInfos(interfaceInfo)));
+    private Bucket getLocalBCGroupBucketInfo(InterfaceInfo interfaceInfo, int bucketIdStart) {
+        return MDSALUtil.buildBucket(getInterfacePortActions(interfaceInfo), MDSALUtil.GROUP_WEIGHT, bucketIdStart, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP);
     }
 
     private List<MatchInfo> getMatchesForElanTag(Long elanTag) {
@@ -623,12 +603,12 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         return mkMatches;
     }
 
-    private List<InstructionInfo> getInstructionsForOutGroup(
+    private List<Instruction> getInstructionsForOutGroup(
             long groupId) {
-        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
-        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
-        actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}));
-        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+        List<Instruction> mkInstructions = new ArrayList<Instruction>();
+        List <Action> actions = new ArrayList <Action> ();
+        actions.add(new ActionInfo(ActionType.group, new String[]{Long.toString(groupId)}).buildAction());
+        mkInstructions.add(ElanUtils.getWriteActionInstruction(actions));
         return mkInstructions;
     }
 
@@ -696,10 +676,11 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         }
     }
 
-    public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
-        List<BucketInfo> listBucketInfo = new ArrayList<BucketInfo>();
+    public void setupElanBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        List<Bucket> listBucket = new ArrayList<Bucket>();
+        int bucketId = 0;
         BigInteger dpnId = interfaceInfo.getDpId();
-        long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
+        long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
 
         DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
         for(String ifName : dpnInterfaces.getInterfaces()) {
@@ -710,56 +691,82 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
                 continue;
             }
 
-            listBucketInfo.add(new BucketInfo(getInterfacePortActionInfos(ifInfo)));
+            listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
+            bucketId++;
         }
-        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
-        logger.trace("installing the localBroadCast GroupEntity:{}", groupEntity);
-        mdsalManager.syncInstallGroup(groupEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
+        List<Bucket> listBucketInfoRemote = getRemoteBCGroupBuckets(elanInfo, interfaceInfo, bucketId);
+        listBucket.addAll(listBucketInfoRemote);
+
+        Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
+        logger.trace("installing the localBroadCast Group:{}", group);
+        mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
     }
 
-    public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+    public void setupLocalBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        List<Bucket> listBucket = new ArrayList<Bucket>();
+        int bucketId = 0;
         BigInteger dpnId = interfaceInfo.getDpId();
         long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
 
-        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, getLocalBCGroupBucketInfo(interfaceInfo));
-        logger.trace("deleted the localBroadCast GroupEntity:{}", groupEntity);
-        mdsalManager.syncRemoveGroup(groupEntity);
-    }
+        DpnInterfaces dpnInterfaces = ElanUtils.getElanInterfaceInfoByElanDpn(elanInfo.getElanInstanceName(), dpnId);
+        for(String ifName : dpnInterfaces.getInterfaces()) {
+            // In case if there is a InterfacePort in the cache which is not in
+            // operational state, skip processing it
+            InterfaceInfo ifInfo = interfaceManager.getInterfaceInfoFromOperationalDataStore(ifName, interfaceInfo.getInterfaceType());
+            if (!isOperational(ifInfo)) {
+                continue;
+            }
 
-    public void setupRemoteBroadcastGroups(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
-        List<BucketInfo> listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
-        BigInteger dpnId = interfaceInfo.getDpId();
-        long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
-        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
-        mdsalManager.syncInstallGroup(groupEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
+            listBucket.add(MDSALUtil.buildBucket(getInterfacePortActions(ifInfo), MDSALUtil.GROUP_WEIGHT, bucketId, MDSALUtil.WATCH_PORT, MDSALUtil.WATCH_GROUP));
+            bucketId++;
+        }
+
+        Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBucket));
+        logger.trace("installing the localBroadCast Group:{}", group);
+        mdsalManager.syncInstallGroup(dpnId, group, ElanConstants.DELAY_TIME_IN_MILLISECOND);
     }
 
-    public void removeRemoteBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
-        List<BucketInfo> listBucketInfo = getRemoteBCGroupBucketInfos(elanInfo, interfaceInfo);
+    public void removeLocalBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        BigInteger dpnId = interfaceInfo.getDpId();
+        long groupId = ElanUtils.getElanLocalBCGID(elanInfo.getElanTag());
+        List<Bucket> listBuckets = new ArrayList<>();
+        int bucketId = 0;
+        listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
+        //listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, 1, interfaceInfo));
+        Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
+        logger.trace("deleted the localBroadCast Group:{}", group);
+        mdsalManager.syncRemoveGroup(dpnId, group);
+    }
+
+    public void removeElanBroadcastGroup(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
+        int bucketId = 0;
+        List<Bucket> listBuckets = new ArrayList<>();
+        listBuckets.add(getLocalBCGroupBucketInfo(interfaceInfo, bucketId));
+        bucketId++;
+        listBuckets.addAll(getRemoteBCGroupBucketInfos(elanInfo, bucketId, interfaceInfo));
         BigInteger dpnId = interfaceInfo.getDpId();
         long groupId = ElanUtils.getElanRemoteBCGID(elanInfo.getElanTag());
-        GroupEntity groupEntity = MDSALUtil.buildGroupEntity(dpnId, groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, listBucketInfo);
-        logger.trace("deleting the remoteBroadCast GroupEntity:{}", groupEntity);
-        mdsalManager.syncRemoveGroup(groupEntity);
+        Group group = MDSALUtil.buildGroup(groupId, elanInfo.getElanInstanceName(), GroupTypes.GroupAll, MDSALUtil.buildBucketLists(listBuckets));
+        logger.trace("deleting the remoteBroadCast group:{}", group);
+        mdsalManager.syncRemoveGroup(dpnId, group);
     }
 
     public void setupTerminateServiceTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
         long elanTag = elanInfo.getElanTag();
-        //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
-//        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ITMConstants.TERMINATING_SERVICE_TABLE, getFlowRef(ITMConstants.TERMINATING_SERVICE_TABLE, elanTag),
-//                5, elanInfo.getElanInstanceName(), 0,  0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), itmManager.getTunnelMatchesForServiceId(elanTag),
-//                getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
-//
-//        mdsalManager.installFlow(flowEntity);
+        Flow flowEntity = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE, getFlowRef(NwConstants.INTERNAL_TUNNEL_TABLE, elanTag),
+                5, String.format("%s:%d","ITM Flow Entry ",elanTag), 0,  0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(elanTag)), ElanUtils.getTunnelMatchesForServiceId((int)elanTag),
+                getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGID(elanTag)));
+
+        mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
     }
 
     public void setupUnknownDMacTable(ElanInstance elanInfo, InterfaceInfo interfaceInfo) {
         long elanTag = elanInfo.getElanTag();
-        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(interfaceInfo.getDpId(), ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
+        Flow flowEntity = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
                 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)), getMatchesForElanTag(elanTag),
-                getInstructionsForOutGroup(ElanUtils.getElanLocalBCGID(elanTag)));
+                getInstructionsForOutGroup(ElanUtils.getElanRemoteBCGID(elanTag)));
 
-        mdsalManager.installFlow(flowEntity);
+        mdsalManager.installFlow(interfaceInfo.getDpId(), flowEntity);
     }
 
     private void removeStaticELanFlows(final ElanInstance elanInfo, final InterfaceInfo interfaceInfo) {
@@ -779,21 +786,23 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
             logger.debug("deleting the elan: {} present on dpId: {}", elanInfo.getElanInstanceName(), dpId);
             removeDefaultTermFlow(dpId, elanInfo.getElanTag());
             removeUnknownDmacFlow(dpId, elanInfo);
-            removeRemoteBroadcastGroup(elanInfo, interfaceInfo);
+            removeElanBroadcastGroup(elanInfo, interfaceInfo);
             removeLocalBroadcastGroup(elanInfo, interfaceInfo);
+            removeFilterEqualsTable(elanInfo, interfaceInfo);
         } else {
+            setupElanBroadcastGroups(elanInfo, interfaceInfo);
             setupLocalBroadcastGroups(elanInfo, interfaceInfo);
+            removeFilterEqualsTable(elanInfo, interfaceInfo);
         }
     }
 
     private void removeUnknownDmacFlow(BigInteger dpId, ElanInstance elanInfo) {
-        FlowEntity flowEntity = getUnknownDmacFlowEntity(dpId, elanInfo);
-        mdsalManager.syncRemoveFlow(flowEntity, ElanConstants.DELAY_TIME_IN_MILLISECOND);
+        Flow flow = getUnknownDmacFlowEntity(dpId, elanInfo);
+        mdsalManager.removeFlow(dpId, flow);
     }
 
     private void removeDefaultTermFlow(BigInteger dpId, long elanTag) {
-        //FIXME [ELANBE] Removing ITM API for now, will need this for multi dpn.
-        //itmManager.removeTerminatingServiceAction(dpId, (int) elanTag);
+        ElanUtils.removeTerminatingServiceAction(dpId, (int) elanTag);
     }
 
     private void bindService(ElanInstance elanInfo, String interfaceName) {
@@ -825,7 +834,7 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
                 ElanUtils.DEFAULT_CALLBACK);
     }
 
-    private FlowEntity getUnknownDmacFlowEntity(BigInteger dpId, ElanInstance elanInfo) {
+    private Flow getUnknownDmacFlowEntity(BigInteger dpId, ElanInstance elanInfo) {
         long elanTag = elanInfo.getElanTag();
         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
         // Matching metadata
@@ -833,38 +842,35 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
                 ElanUtils.getElanMetadataLabel(elanTag),
                 MetaDataUtil.METADATA_MASK_SERVICE }));
 
-        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
-        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
-        actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(ElanUtils.getElanRemoteBCGID(elanTag))}));
-        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+        List<Instruction> mkInstructions = new ArrayList<Instruction>();
+        List <Action> actionsInfos = new ArrayList <Action> ();
+        actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(ElanUtils.getElanRemoteBCGID(elanTag))}, 0).buildAction());
+        mkInstructions.add(ElanUtils.getWriteActionInstruction(actionsInfos));
 
-        FlowEntity flowEntity = MDSALUtil.buildFlowEntity(dpId, ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
+        Flow flow = MDSALUtil.buildFlowNew(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, getFlowRef(ElanConstants.ELAN_UNKNOWN_DMAC_TABLE, elanTag),
                 5, elanInfo.getElanInstanceName(), 0, 0, ElanConstants.COOKIE_ELAN_UNKNOWN_DMAC.add(BigInteger.valueOf(elanTag)),
                 mkMatches, mkInstructions);
-        return flowEntity;
+        return flow;
     }
 
     private String getFlowRef(long tableId, long elanTag) {
         return new StringBuffer().append(tableId).append(elanTag).toString();
     }
 
-    private List<ActionInfo> getInterfacePortActionInfos(InterfaceInfo interfaceInfo) {
-        List<ActionInfo> listActionInfo = new ArrayList<ActionInfo>();
-        listActionInfo.add(getReg1ActionInfo(interfaceInfo.getInterfaceTag()));
-        listActionInfo.add(new ActionInfo(ActionType.nx_resubmit, new String[]{}));
-        return listActionInfo;
+    private List<Action> getInterfacePortActions(InterfaceInfo interfaceInfo) {
+        List<Action> listAction = new ArrayList<Action>();
+        int actionKey = 0;
+        listAction.add((new ActionInfo(ActionType.set_field_tunnel_id, new BigInteger[] {BigInteger.valueOf(interfaceInfo.getInterfaceTag())}, actionKey)).buildAction());
+        actionKey++;
+        listAction.add((new ActionInfo(ActionType.nx_resubmit, new BigInteger[] {BigInteger.valueOf(55)}, actionKey)).buildAction());
+        return listAction;
     }
 
     private void updateElanDpnInterfacesList(String elanInstanceName, BigInteger dpId, List<String> interfaceNames) {
-        if(!interfaceNames.isEmpty()) {
-            DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
-                    .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
-            MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
-                    dpnInterface);
-        } else {
-            MDSALUtil.syncDelete(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId));
-        }
-        
+        DpnInterfaces dpnInterface = new DpnInterfacesBuilder().setDpId(dpId)
+                .setInterfaces(interfaceNames).setKey(new DpnInterfacesKey(dpId)).build();
+        MDSALUtil.syncWrite(broker, LogicalDatastoreType.OPERATIONAL, ElanUtils.getElanDpnInterfaceOperationalDataPath(elanInstanceName, dpId),
+                dpnInterface);
     }
 
     private List<String> createElanInterfacesList(String elanInstanceName, String interfaceName, BigInteger dpId) {
@@ -1028,105 +1034,32 @@ public class ElanInterfaceManager extends AbstractDataChangeListener<ElanInterfa
         }
     }
 
-    private List<MatchInfo> getMatchesForFilterEqualsLPortTag(Long LportTag) {
+    private List<MatchInfo> getMatchesForFilterEqualsLPortTag(int LportTag) {
         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
         // Matching metadata
         mkMatches.add(new MatchInfo(MatchFieldType.metadata, new BigInteger[] {
-                ElanUtils.getElanMetadataLabel(LportTag),
-                MetaDataUtil.METADATA_MASK_SERVICE }));
-        mkMatches.add(new MatchInfo(MatchFieldType.reg1, new long[] {LportTag.longValue()}));
+                MetaDataUtil.getLportTagMetaData(LportTag),
+                MetaDataUtil.METADATA_MASK_LPORT_TAG }));
+        mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {BigInteger.valueOf(LportTag)}));
         return mkMatches;
     }
 
 
-    private List<MatchInfo> getMatchesForFilterEqualsReg1LPortTag(Long LportTag) {
+    private List<MatchInfo> getTunnelIdMatchForFilterEqualsLPortTag(int LportTag) {
         List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
         // Matching metadata
-        mkMatches.add(new MatchInfo(MatchFieldType.reg1, new long[] {
-                (LportTag.longValue())}));
+        mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
+                BigInteger.valueOf(LportTag)}));
         return mkMatches;
 
 
     }
 
-    public static class RegMatch {
-
-        final Class<? extends NxmNxReg> reg;
-        final Long value;
-
-        public RegMatch(Class<? extends NxmNxReg> reg, Long value) {
-            super();
-            this.reg = reg;
-            this.value = value;
-        }
-
-        public static RegMatch of(Class<? extends NxmNxReg> reg, Long value) {
-            return new RegMatch(reg, value);
-        }
-    }
-
-    public static void addNxRegMatch(MatchBuilder match, RegMatch... matches) {
-        ArrayList<ExtensionList> extensions = new ArrayList<>();
-        for (RegMatch rm : matches) {
-            Class<? extends ExtensionKey> key;
-            if (NxmNxReg0.class.equals(rm.reg)) {
-                key = NxmNxReg0Key.class;
-            } else if (NxmNxReg1.class.equals(rm.reg)) {
-                key = NxmNxReg1Key.class;
-            } else if (NxmNxReg2.class.equals(rm.reg)) {
-                key = NxmNxReg2Key.class;
-            } else if (NxmNxReg3.class.equals(rm.reg)) {
-                key = NxmNxReg3Key.class;
-            } else if (NxmNxReg4.class.equals(rm.reg)) {
-                key = NxmNxReg4Key.class;
-            } else if (NxmNxReg5.class.equals(rm.reg)) {
-                key = NxmNxReg5Key.class;
-            } else if (NxmNxReg6.class.equals(rm.reg)) {
-                key = NxmNxReg6Key.class;
-            } else {
-                key = NxmNxReg7Key.class;
-            }
-            NxAugMatchNodesNodeTableFlow am = new NxAugMatchNodesNodeTableFlowBuilder().setNxmNxReg(
-                    new NxmNxRegBuilder().setReg(rm.reg).setValue(rm.value).build()).build();
-            extensions.add(new ExtensionListBuilder().setExtensionKey(key)
-                    .setExtension(new ExtensionBuilder().addAugmentation(NxAugMatchNodesNodeTableFlow.class, am).build())
-                    .build());
-        }
-        GeneralAugMatchNodesNodeTableFlow m = new GeneralAugMatchNodesNodeTableFlowBuilder().setExtensionList(
-                extensions).build();
-        match.addAugmentation(GeneralAugMatchNodesNodeTableFlow.class, m);
-
-    }
-
-
-    private List<InstructionInfo> getInstructionsInPortForOutGroup(
-            long GroupId) {
-        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
-        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
-        actionsInfos.add(new ActionInfo(ActionType.nx_resubmit, new String[]{ "123"}));
-        actionsInfos.add(new ActionInfo(ActionType.group, new String[]{Long.toString(GroupId)}));
-        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
-        return mkInstructions;
-    }
-
-    private List<InstructionInfo> getInstructionsInPortForOutGroup(
-            String ifName) {
-        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
-        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
-        //TODO: modify in-port action
-        //actionsInfos.add(new ActionInfo(ActionType.set_source_port_field, new String[]{ "255"}));
-        actionsInfos.addAll(getEgressActionsForInterface(ifName));
-        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
-        return mkInstructions;
-    }
-
-
-
-    private List<InstructionInfo> getInstructionsDrop() {
-        List<InstructionInfo> mkInstructions = new ArrayList<InstructionInfo>();
-        List <ActionInfo> actionsInfos = new ArrayList <ActionInfo> ();
-        actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}));
-        mkInstructions.add(new InstructionInfo(InstructionType.write_actions, actionsInfos));
+    private List<Instruction> getInstructionsDrop() {
+        List<Instruction> mkInstructions = new ArrayList<Instruction>();
+        List <Action> actionsInfos = new ArrayList <Action> ();
+        actionsInfos.add(new ActionInfo(ActionType.drop_action, new String[]{}).buildAction());
+        mkInstructions.add(ElanUtils.getWriteActionInstruction(actionsInfos));
         return mkInstructions;
     }