diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
index 70aafd4..a020a64 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
@@ -251,6 +251,18 @@
     }
 
     /**
+     * Determines whether this pipeline requires second VLAN entry in VLAN table.
+     * OF-DPA hardware requires one VLAN filtering rule and one VLAN assignment
+     * flow in the VLAN table in the case of untagged packets. Software emulations
+     * just use one flow.
+     *
+     * @return true if required
+     */
+    public boolean requireSecondVlanTableEntry() {
+        return true;
+    }
+
+    /**
      * Determines whether in-port should be matched on in TMAC table rules.
      *
      * @return true if match on in-port should be programmed
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java
index afab73f..93967cb 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaGroupHandlerUtility.java
@@ -68,16 +68,16 @@
      * L2 Flood Groups have <4bits-4><12bits-vlanId><16bits-index>
      * L3 VPN Groups have <4bits-9><4bits-2><24bits-index>
      */
-    static final int L2_INTERFACE_TYPE = 0x00000000;
+    public static final int L2_INTERFACE_TYPE = 0x00000000;
     static final int L2_UNFILTERED_TYPE = 0xb0000000;
     static final int L3_INTERFACE_TYPE = 0x50000000;
     static final int L3_UNICAST_TYPE = 0x20000000;
-    static final int L3_MULTICAST_TYPE = 0x60000000;
+    public static final int L3_MULTICAST_TYPE = 0x60000000;
     static final int MPLS_INTERFACE_TYPE = 0x90000000;
     static final int MPLS_L3VPN_SUBTYPE = 0x92000000;
     static final int L3_ECMP_TYPE = 0x70000000;
-    static final int L2_FLOOD_TYPE = 0x40000000;
-    static final int L2_MULTICAST_TYPE = 0x30000000;
+    public static final int L2_FLOOD_TYPE = 0x40000000;
+    public static final int L2_MULTICAST_TYPE = 0x30000000;
     static final int L2_LB_TYPE = 0xc0000000;
 
     static final int TYPE_MASK = 0x0fffffff;
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaPipelineUtility.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaPipelineUtility.java
index 242ab47..020629d 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaPipelineUtility.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OfdpaPipelineUtility.java
@@ -54,19 +54,19 @@
     }
 
     // Ofdpa specific tables number
-    static final int PORT_TABLE = 0;
-    static final int VLAN_TABLE = 10;
+    public static final int PORT_TABLE = 0;
+    public static final int VLAN_TABLE = 10;
     static final int VLAN_1_TABLE = 11;
     static final int MPLS_L2_PORT_FLOW_TABLE = 13;
     static final int MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE = 16;
-    static final int TMAC_TABLE = 20;
-    static final int UNICAST_ROUTING_TABLE = 30;
-    static final int MULTICAST_ROUTING_TABLE = 40;
-    static final int MPLS_TABLE_0 = 23;
-    static final int MPLS_TABLE_1 = 24;
-    static final int MPLS_L3_TYPE_TABLE = 27;
-    static final int MPLS_TYPE_TABLE = 29;
-    static final int BRIDGING_TABLE = 50;
+    public static final int TMAC_TABLE = 20;
+    public static final int UNICAST_ROUTING_TABLE = 30;
+    public static final int MULTICAST_ROUTING_TABLE = 40;
+    public static final int MPLS_TABLE_0 = 23;
+    public static final int MPLS_TABLE_1 = 24;
+    public static final int MPLS_L3_TYPE_TABLE = 27;
+    public static final int MPLS_TYPE_TABLE = 29;
+    public static final int BRIDGING_TABLE = 50;
     public static final int ACL_TABLE = 60;
     static final int EGRESS_VLAN_FLOW_TABLE = 210;
     static final int EGRESS_DSCP_PCP_REMARK_FLOW_TABLE = 230;
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaPipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaPipeline.java
index 7e43cab..0d79dcd 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaPipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/OvsOfdpaPipeline.java
@@ -109,7 +109,7 @@
      * This is a non-OFDPA table to emulate OFDPA packet in behavior.
      * VLAN will be popped before punting if the VLAN is internally assigned.
      */
-    private static final int PUNT_TABLE = 63;
+    public static final int PUNT_TABLE = 63;
 
     /**
      * A static indirect group that pop vlan and punt to controller.
@@ -117,7 +117,7 @@
      * The purpose of using a group instead of immediate action is that this
      * won't affect another copy on the data plane when write action exists.
      */
-    private static final int POP_VLAN_PUNT_GROUP_ID = 0xd0000000;
+    public static final int POP_VLAN_PUNT_GROUP_ID = 0xd0000000;
 
     /**
      * Executor for group checker thread that checks pop vlan punt group.
@@ -145,6 +145,11 @@
     }
 
     @Override
+    public boolean requireSecondVlanTableEntry() {
+        return false;
+    }
+
+    @Override
     protected void initDriverId() {
         driverId = coreService.registerApplication(
                 "org.onosproject.driver.OvsOfdpaPipeline");
diff --git a/drivers/default/src/main/java/org/onosproject/driver/traceable/OfdpaPipelineTraceable.java b/drivers/default/src/main/java/org/onosproject/driver/traceable/OfdpaPipelineTraceable.java
new file mode 100644
index 0000000..c269022
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/traceable/OfdpaPipelineTraceable.java
@@ -0,0 +1,785 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.driver.traceable;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.GroupId;
+import org.onosproject.driver.pipeline.ofdpa.Ofdpa2Pipeline;
+import org.onosproject.driver.pipeline.ofdpa.OvsOfdpaPipeline;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PipelineTraceableHitChain;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DataPlaneEntity;
+import org.onosproject.net.PipelineTraceableInput;
+import org.onosproject.net.PipelineTraceableOutput;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.PipelineTraceable;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.driver.AbstractHandlerBehaviour;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.IndexTableId;
+import org.onosproject.net.flow.TableId;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.criteria.Criteria;
+import org.onosproject.net.flow.criteria.Criterion;
+import org.onosproject.net.flow.criteria.EthCriterion;
+import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.IPCriterion;
+import org.onosproject.net.flow.criteria.MetadataCriterion;
+import org.onosproject.net.flow.criteria.VlanIdCriterion;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.slf4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.L2_FLOOD_TYPE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.L2_INTERFACE_TYPE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.L2_MULTICAST_TYPE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaGroupHandlerUtility.L3_MULTICAST_TYPE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.ACL_TABLE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.BRIDGING_TABLE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.MPLS_L3_TYPE_TABLE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.MULTICAST_ROUTING_TABLE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.TMAC_TABLE;
+import static org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility.VLAN_TABLE;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Implements a driver behavior that enables a logical probe packet to traverse the device pipeline
+ * and to return dataplane entities that matched against the logical probe packet.
+ */
+public class OfdpaPipelineTraceable extends AbstractHandlerBehaviour implements PipelineTraceable {
+
+    private static final Logger log = getLogger(OfdpaPipelineTraceable.class);
+    // Behavior context
+    private DeviceId deviceId;
+    private String driverName;
+    // Utility
+    private final Comparator<FlowEntry> comparatorById = Comparator.comparing(
+            (FlowEntry f) -> ((IndexTableId) f.table()).id());
+    private final Comparator<FlowEntry> comparatorByPriority = Comparator.comparing(
+            FlowRule::priority);
+
+    @Override
+    public void init() {
+        this.deviceId = this.data().deviceId();
+        this.driverName = this.data().driver().name();
+    }
+
+    @Override
+    public PipelineTraceableOutput apply(PipelineTraceableInput input) {
+        PipelineTraceableOutput.Builder outputBuilder = PipelineTraceableOutput.builder();
+        log.debug("Current packet {} - applying flow tables", input.ingressPacket());
+        List<FlowEntry> outputFlows = new ArrayList<>();
+        List<Instruction> deferredInstructions = new ArrayList<>();
+        PipelineTraceableHitChain currentHitChain = PipelineTraceableHitChain.emptyHitChain();
+        TrafficSelector currentPacket = DefaultTrafficSelector.builder(input.ingressPacket()).build();
+
+        // Init step - find out the first table
+        int initialTableId = -1;
+        FlowEntry nextTableIdEntry = findNextTableIdEntry(initialTableId, input.flows());
+        if (nextTableIdEntry == null) {
+            currentHitChain.setEgressPacket(currentPacket);
+            currentHitChain.dropped();
+            return outputBuilder.appendToLog("No flow rules for device " + deviceId + ". Aborting")
+                    .noFlows()
+                    .addHitChain(currentHitChain)
+                    .build();
+        }
+
+        // Iterates over the flow tables until the end of the pipeline
+        TableId tableId = nextTableIdEntry.table();
+        FlowEntry flowEntry;
+        boolean lastTable = false;
+        while (!lastTable) {
+            log.debug("Searching a Flow Entry on table {} for packet {}", tableId, currentPacket);
+
+            // Gets the rule that matches the incoming packet
+            flowEntry = matchHighestPriority(currentPacket, tableId, input.flows());
+            log.debug("Found Flow Entry {}", flowEntry);
+
+            // If the flow entry on a table is null and we are on hardware we treat as table miss, with few exceptions
+            if (flowEntry == null && isHardwareSwitch()) {
+                log.debug("Ofdpa Hw setup, no flow rule means table miss");
+
+                if (((IndexTableId) tableId).id() == MPLS_L3_TYPE_TABLE) {
+                    // Apparently a miss but Table 27 on OFDPA is a fixed table
+                    currentPacket = handleOfdpa27FixedTable(input.ingressPacket(), currentPacket);
+                    // The nextTable should be ACL
+                    tableId = IndexTableId.of(ACL_TABLE - 1);
+                }
+
+                // Finding next table to go In case of miss
+                nextTableIdEntry = findNextTableIdEntry(((IndexTableId) tableId).id(), input.flows());
+                log.debug("Next table id entry {}", nextTableIdEntry);
+                // FIXME Find better solution that enable granularity greater than 0 or all rules
+                // (another possibility is max tableId)
+                if (nextTableIdEntry == null && currentHitChain.getHitChain().size() == 0) {
+                    currentHitChain.setEgressPacket(currentPacket);
+                    currentHitChain.dropped();
+                    return outputBuilder.appendToLog("No flow rules for device " + deviceId + ". Aborting")
+                            .noFlows()
+                            .addHitChain(currentHitChain)
+                            .build();
+
+                } else if (nextTableIdEntry == null) {
+                    // Means that no more flow rules are present
+                    lastTable = true;
+
+                } else if (((IndexTableId) tableId).id() == TMAC_TABLE) {
+                    // If the table is 20 OFDPA skips to table 50
+                    log.debug("A miss on Table 20 on OFDPA means that we skip directly to table 50");
+                    tableId = IndexTableId.of(BRIDGING_TABLE);
+
+                } else if (((IndexTableId) tableId).id() == MULTICAST_ROUTING_TABLE) {
+                    // If the table is 40 OFDPA skips to table 60
+                    log.debug("A miss on Table 40 on OFDPA means that we skip directly to table 60");
+                    tableId = IndexTableId.of(ACL_TABLE);
+                } else {
+                    tableId = nextTableIdEntry.table();
+                }
+
+            } else if (flowEntry == null) {
+                currentHitChain.setEgressPacket(currentPacket);
+                currentHitChain.dropped();
+                return outputBuilder.appendToLog("Packet has no match on table " + tableId
+                        + " in device " + deviceId + ". Dropping")
+                        .noFlows()
+                        .addHitChain(currentHitChain)
+                        .build();
+            } else {
+
+                // If the table has a transition
+                if (flowEntry.treatment().tableTransition() != null) {
+                    // Updates the next table we transitions to
+                    tableId = IndexTableId.of(flowEntry.treatment().tableTransition().tableId());
+                    log.debug("Flow Entry has transition to table Id {}", tableId);
+                    currentHitChain.addDataPlaneEntity(new DataPlaneEntity(flowEntry));
+                } else {
+                    // Table has no transition so it means that it's an output rule if on the last table
+                    log.debug("Flow Entry has no transition to table, treating as last rule {}", flowEntry);
+                    currentHitChain.addDataPlaneEntity(new DataPlaneEntity(flowEntry));
+                    outputFlows.add(flowEntry);
+                    lastTable = true;
+                }
+
+                // Updates the packet according to the immediate actions of this flow rule.
+                currentPacket = updatePacket(currentPacket, flowEntry.treatment().immediate()).build();
+
+                // Saves the deferred rules for later maintaining the order
+                deferredInstructions.addAll(flowEntry.treatment().deferred());
+
+                // If the flow requires to clear deferred actions we do so for all the ones we encountered.
+                if (flowEntry.treatment().clearedDeferred()) {
+                    deferredInstructions.clear();
+                }
+
+                // On table 10 OFDPA needs two rules to apply the vlan if none and then to transition to the next table.
+                if (shouldMatchSecondVlanFlow(flowEntry)) {
+
+                    // Let's get the packet vlanId instruction
+                    VlanIdCriterion packetVlanIdCriterion =
+                            (VlanIdCriterion) currentPacket.getCriterion(Criterion.Type.VLAN_VID);
+
+                    // Let's get the flow entry vlan mod instructions
+                    ModVlanIdInstruction entryModVlanIdInstruction = (ModVlanIdInstruction) flowEntry.treatment()
+                            .immediate().stream()
+                            .filter(instruction -> instruction instanceof ModVlanIdInstruction)
+                            .findFirst().orElse(null);
+
+                    // If the entry modVlan is not null we need to make sure that the packet has been updated and there
+                    // is a flow rule that matches on same criteria and with updated vlanId
+                    if (entryModVlanIdInstruction != null) {
+
+                        FlowEntry secondVlanFlow = getSecondFlowEntryOnTable10(currentPacket,
+                                packetVlanIdCriterion, entryModVlanIdInstruction, input.flows());
+
+                        // We found the flow that we expected
+                        if (secondVlanFlow != null) {
+                            currentHitChain.addDataPlaneEntity(new DataPlaneEntity(secondVlanFlow));
+                        } else {
+                            currentHitChain.setEgressPacket(currentPacket);
+                            currentHitChain.dropped();
+                            return outputBuilder.appendToLog("Missing forwarding rule for tagged"
+                                    + " packet on " + deviceId)
+                                    .noFlows()
+                                    .addHitChain(currentHitChain)
+                                    .build();
+                        }
+                    }
+                }
+            }
+        }
+
+        // Creating a modifiable builder for the egress packet
+        TrafficSelector.Builder egressPacket = DefaultTrafficSelector.builder(currentPacket);
+
+        log.debug("Current packet {} - applying output flows", currentPacket);
+        // Handling output flows which basically means handling output to controller.
+        // OVS and OFDPA have both immediate -> OUTPUT:CONTROLLER. Theoretically there is no
+        // need to reflect the updates performed on the packets and on the chain.
+        List<PortNumber> outputPorts = new ArrayList<>();
+        handleOutputFlows(currentPacket, outputFlows, egressPacket, outputPorts, currentHitChain,
+                outputBuilder, input.ingressPacket());
+
+        // Immediate instructions
+        log.debug("Current packet {} - applying immediate instructions", currentPacket);
+        // Handling immediate instructions which basically means handling output to controller.
+        // OVS has immediate -> group -> OUTPUT:CONTROLLER.
+        List<DataPlaneEntity> entries = ImmutableList.copyOf(currentHitChain.getHitChain());
+        // Go to the next step - using a copy of the egress packet and of the hit chain
+        PipelineTraceableHitChain newHitChain = PipelineTraceableHitChain.emptyHitChain();
+        currentHitChain.getHitChain().forEach(newHitChain::addDataPlaneEntity);
+        TrafficSelector.Builder newEgressPacket = DefaultTrafficSelector.builder(egressPacket.build());
+        for (DataPlaneEntity entry : entries) {
+            flowEntry = entry.getFlowEntry();
+            if (flowEntry != null) {
+                getGroupsFromInstructions(input.groups(), flowEntry.treatment().immediate(), newEgressPacket,
+                        outputPorts, newHitChain, outputBuilder, input, false);
+            }
+        }
+
+        // Deferred instructions
+        log.debug("Current packet {} - applying deferred instructions", egressPacket.build());
+        // If we have deferred instructions at this point we handle them.
+        // Here, we are basically handling the normal forwarding scenarios that
+        // always happen through deferred:group. Here we don't care about the
+        // egress packet and of the hit chain. This is the last step.
+        if (deferredInstructions.size() > 0) {
+            handleDeferredActions(egressPacket.build(), input.groups(), deferredInstructions, outputPorts,
+                    currentHitChain, outputBuilder, input);
+        }
+
+        // If there are no outputs - packet is dropped
+        // Let's store the partial hit chain and set a message
+        if (outputPorts.isEmpty()) {
+            currentHitChain.setEgressPacket(egressPacket.build());
+            currentHitChain.dropped();
+            outputBuilder.appendToLog("Packet has no output in device " + deviceId + ". Dropping")
+                    .dropped()
+                    .addHitChain(currentHitChain);
+        }
+
+        // Done!
+        return outputBuilder.build();
+    }
+
+    // Finds the flow entry with the minimum next table Id.
+    private FlowEntry findNextTableIdEntry(int currentId, List<FlowEntry> flows) {
+        return flows.stream()
+                .filter(f -> ((IndexTableId) f.table()).id() > currentId)
+                .min(comparatorById).orElse(null);
+    }
+
+    // Finds the rule in the device that matches the input packet and has the highest priority.
+    // TODO Candidate for an AbstractBehavior implementation
+    private FlowEntry matchHighestPriority(TrafficSelector packet, TableId tableId, List<FlowEntry> flows) {
+        //Computing the possible match rules.
+        return flows.stream()
+                .filter(flowEntry -> flowEntry.table().equals(tableId))
+                .filter(flowEntry -> match(packet, flowEntry))
+                .max(comparatorByPriority).orElse(null);
+    }
+
+    // Matches the packet with the given flow entry
+    // TODO Candidate for an AbstractBehavior implementation
+    private boolean match(TrafficSelector packet, FlowEntry flowEntry) {
+        return flowEntry.selector().criteria().stream().allMatch(criterion -> {
+            Criterion.Type type = criterion.type();
+            //If the criterion has IP we need to do LPM to establish matching.
+            if (type.equals(Criterion.Type.IPV4_SRC) || type.equals(Criterion.Type.IPV4_DST) ||
+                    type.equals(Criterion.Type.IPV6_SRC) || type.equals(Criterion.Type.IPV6_DST)) {
+                return matchIp(packet, (IPCriterion) criterion);
+                //we check that the packet contains the criterion provided by the flow rule.
+            } else if (type.equals(Criterion.Type.ETH_SRC_MASKED)) {
+                return matchMac(packet, (EthCriterion) criterion, false);
+            } else if (type.equals(Criterion.Type.ETH_DST_MASKED)) {
+                return matchMac(packet, (EthCriterion) criterion, true);
+            } else {
+                return packet.criteria().contains(criterion);
+            }
+        });
+    }
+
+    // Checks if the packet has an dst or src IP and if that IP matches the subnet of the ip criterion
+    // TODO Candidate for an AbstractBehavior implementation
+    private boolean matchIp(TrafficSelector packet, IPCriterion criterion) {
+        IPCriterion matchCriterion = (IPCriterion) packet.getCriterion(criterion.type());
+        // if the packet does not have an IPv4 or IPv6 criterion we return true
+        if (matchCriterion == null) {
+            return false;
+        }
+        log.debug("Checking if {} is under {}", matchCriterion.ip(), criterion.ip());
+        IpPrefix subnet = criterion.ip();
+        return subnet.contains(matchCriterion.ip().address());
+    }
+
+    // Checks if the packet has a dst or src MAC and if that Mac matches the mask of the mac criterion
+    // TODO Candidate for an AbstractBehavior implementation
+    private boolean matchMac(TrafficSelector packet, EthCriterion hitCriterion, boolean dst) {
+        //Packet can have only one EthCriterion
+        EthCriterion matchCriterion;
+        if (dst) {
+            matchCriterion = (EthCriterion) packet.criteria().stream().filter(criterion1 ->
+                    criterion1.type().equals(Criterion.Type.ETH_DST_MASKED) ||
+                            criterion1.type().equals(Criterion.Type.ETH_DST))
+                    .findFirst().orElse(null);
+        } else {
+            matchCriterion = (EthCriterion) packet.criteria().stream().filter(criterion1 ->
+                    criterion1.type().equals(Criterion.Type.ETH_SRC_MASKED) ||
+                            criterion1.type().equals(Criterion.Type.ETH_SRC))
+                    .findFirst().orElse(null);
+        }
+        //if the packet does not have an ETH criterion we return true
+        if (matchCriterion == null) {
+            return true;
+        }
+        log.debug("Checking if {} is under {}/{}", matchCriterion.mac(), hitCriterion.mac(), hitCriterion.mask());
+        return matchCriterion.mac().inRange(hitCriterion.mac(), hitCriterion.mask());
+    }
+
+    // Handles table 27 in Ofpda which is a fixed table not visible to any controller that handles Mpls Labels.
+    private TrafficSelector handleOfdpa27FixedTable(TrafficSelector initialPacket, TrafficSelector packet) {
+        log.debug("Handling table 27 on OFDPA, removing mpls ETH Type and change mpls label");
+
+        Criterion mplsCriterion = packet.getCriterion(Criterion.Type.ETH_TYPE);
+        // T3 was using the initial packet of the trace - using the metadata in the packet to carry this info
+        Criterion metadataCriterion = initialPacket.getCriterion(Criterion.Type.METADATA);
+        ImmutableList.Builder<Instruction> builder = ImmutableList.builder();
+
+        // If the packet comes in with the expected elements we update it as per OFDPA spec.
+        if (mplsCriterion != null && ((EthTypeCriterion) mplsCriterion).ethType()
+                .equals(EthType.EtherType.MPLS_UNICAST.ethType()) && metadataCriterion != null) {
+
+            // Get the metadata to restore the original ethertype
+            long ethType = ((MetadataCriterion) metadataCriterion).metadata();
+            //TODO update with parsing with eth MPLS pop Instruction for treating label an bos
+            Instruction ethInstruction = Instructions.popMpls(EthType.EtherType.lookup((short) ethType).ethType());
+            //FIXME what do we use as L3_Unicast mpls Label ?
+            //translateInstruction(builder, ethInstruction);
+            builder.add(ethInstruction);
+
+            // Filtering out metadata
+            TrafficSelector.Builder currentPacketBuilder = DefaultTrafficSelector.builder();
+            packet.criteria().stream()
+                    .filter(criterion -> criterion.type() != Criterion.Type.METADATA)
+                    .forEach(currentPacketBuilder::add);
+            packet = currentPacketBuilder.build();
+        }
+        packet = updatePacket(packet, builder.build()).build();
+        return packet;
+    }
+
+    // Applies all give instructions to the input packet
+    private TrafficSelector.Builder updatePacket(TrafficSelector packet, List<Instruction> instructions) {
+        TrafficSelector.Builder newSelector = DefaultTrafficSelector.builder(packet);
+
+        //FIXME optimize
+        for (Instruction instruction : instructions) {
+            newSelector = translateInstruction(newSelector, instruction);
+        }
+        return newSelector;
+    }
+
+    // Applies an instruction to the packet in the form of a selector
+    private TrafficSelector.Builder translateInstruction(TrafficSelector.Builder newSelector, Instruction instruction) {
+        log.debug("Translating instruction {}", instruction);
+        log.debug("New Selector {}", newSelector.build());
+        //TODO add as required
+        Criterion criterion = null;
+        if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+            L2ModificationInstruction l2Instruction = (L2ModificationInstruction) instruction;
+            switch (l2Instruction.subtype()) {
+                case VLAN_ID:
+                    ModVlanIdInstruction vlanIdInstruction =
+                            (ModVlanIdInstruction) instruction;
+                    VlanId id = vlanIdInstruction.vlanId();
+                    criterion = Criteria.matchVlanId(id);
+                    break;
+                case VLAN_POP:
+                    criterion = Criteria.matchVlanId(VlanId.NONE);
+                    break;
+                case MPLS_PUSH:
+                    L2ModificationInstruction.ModMplsHeaderInstruction mplsEthInstruction =
+                            (L2ModificationInstruction.ModMplsHeaderInstruction) instruction;
+                    criterion = Criteria.matchEthType(mplsEthInstruction.ethernetType().toShort());
+
+                    // When pushing MPLS adding metadata to remember the original ethtype
+                    if (isHardwareSwitch()) {
+                        TrafficSelector temporaryPacket = newSelector.build();
+                        Criterion ethCriterion = temporaryPacket.getCriterion(Criterion.Type.ETH_TYPE);
+                        if (ethCriterion != null) {
+                            TrafficSelector.Builder tempSelector = DefaultTrafficSelector.builder(temporaryPacket);
+                            // Store the old ether type for the
+                            tempSelector.matchMetadata(((EthTypeCriterion) ethCriterion).ethType().toShort());
+                            newSelector = tempSelector;
+                        }
+                    }
+
+                    break;
+                case MPLS_POP:
+                    L2ModificationInstruction.ModMplsHeaderInstruction mplsPopInstruction =
+                            (L2ModificationInstruction.ModMplsHeaderInstruction) instruction;
+                    criterion = Criteria.matchEthType(mplsPopInstruction.ethernetType().toShort());
+
+                    //When popping MPLS we remove label and BOS
+                    TrafficSelector temporaryPacket = newSelector.build();
+                    if (temporaryPacket.getCriterion(Criterion.Type.MPLS_LABEL) != null) {
+                        TrafficSelector.Builder noMplsSelector = DefaultTrafficSelector.builder();
+                        temporaryPacket.criteria().stream().filter(c ->
+                                !c.type().equals(Criterion.Type.MPLS_LABEL) &&
+                                        !c.type().equals(Criterion.Type.MPLS_BOS))
+                                .forEach(noMplsSelector::add);
+                        newSelector = noMplsSelector;
+                    }
+
+                    break;
+                case MPLS_LABEL:
+                    L2ModificationInstruction.ModMplsLabelInstruction mplsLabelInstruction =
+                            (L2ModificationInstruction.ModMplsLabelInstruction) instruction;
+                    criterion = Criteria.matchMplsLabel(mplsLabelInstruction.label());
+                    newSelector.matchMplsBos(true);
+                    break;
+                case ETH_DST:
+                    L2ModificationInstruction.ModEtherInstruction modEtherDstInstruction =
+                            (L2ModificationInstruction.ModEtherInstruction) instruction;
+                    criterion = Criteria.matchEthDst(modEtherDstInstruction.mac());
+                    break;
+                case ETH_SRC:
+                    L2ModificationInstruction.ModEtherInstruction modEtherSrcInstruction =
+                            (L2ModificationInstruction.ModEtherInstruction) instruction;
+                    criterion = Criteria.matchEthSrc(modEtherSrcInstruction.mac());
+                    break;
+                default:
+                    log.debug("Unsupported L2 Instruction");
+                    break;
+            }
+        } else {
+            log.debug("Unsupported Instruction");
+        }
+        if (criterion != null) {
+            log.debug("Adding criterion {}", criterion);
+            newSelector.add(criterion);
+        }
+        return newSelector;
+    }
+
+    // Method that finds a flow rule on table 10 that matches the packet and the VLAN of the already
+    // found rule on table 10. This is because OFDPA needs two rules on table 10, first to apply the rule,
+    // second to transition to following table
+    private FlowEntry getSecondFlowEntryOnTable10(TrafficSelector packet, VlanIdCriterion packetVlanIdCriterion,
+                                                  ModVlanIdInstruction entryModVlanIdInstruction,
+                                                  List<FlowEntry> flows) {
+        FlowEntry secondVlanFlow = null;
+        // Check the packet has been update from the first rule.
+        if (packetVlanIdCriterion.vlanId().equals(entryModVlanIdInstruction.vlanId())) {
+            // find a rule on the same table that matches the vlan and
+            // also all the other elements of the flow such as input port
+            secondVlanFlow = flows.stream()
+                    .filter(entry -> entry.table().equals(IndexTableId.of(VLAN_TABLE)))
+                    .filter(entry -> {
+                        VlanIdCriterion criterion = (VlanIdCriterion) entry.selector()
+                                .getCriterion(Criterion.Type.VLAN_VID);
+                        return criterion != null && match(packet, entry)
+                                && criterion.vlanId().equals(entryModVlanIdInstruction.vlanId());
+                    }).findFirst().orElse(null);
+
+        }
+        return secondVlanFlow;
+    }
+
+    // Handles output flows
+    private List<FlowEntry> handleOutputFlows(TrafficSelector currentPacket, List<FlowEntry> outputFlows,
+                                              TrafficSelector.Builder egressPacket, List<PortNumber> outputPorts,
+                                              PipelineTraceableHitChain currentHitChain,
+                                              PipelineTraceableOutput.Builder outputBuilder,
+                                              TrafficSelector initialPacket) {
+        // TODO optimization
+        // outputFlows contains also last rule of device, so we need filtering for OUTPUT instructions.
+        List<FlowEntry> outputFlowEntries = outputFlows.stream().filter(flow -> flow.treatment()
+                .allInstructions().stream().filter(instruction -> instruction.type()
+                        .equals(Instruction.Type.OUTPUT)).count() > 0).collect(Collectors.toList());
+
+        if (outputFlowEntries.size() > 1) {
+            outputBuilder.appendToLog("More than one flow rule with OUTPUT instruction");
+            log.warn("There cannot be more than one flow entry with OUTPUT instruction for {}", currentPacket);
+        }
+
+        if (outputFlowEntries.size() == 1) {
+            OutputInstruction outputInstruction = (OutputInstruction) outputFlowEntries.get(0).treatment()
+                    .allInstructions().stream()
+                    .filter(instruction -> instruction.type().equals(Instruction.Type.OUTPUT))
+                    .findFirst().get();
+            buildOutputFromDevice(egressPacket, outputPorts, outputInstruction, currentHitChain,
+                    outputBuilder, initialPacket, false);
+        }
+
+        return outputFlowEntries;
+    }
+
+    // Builds a possible output from this device
+    private void buildOutputFromDevice(TrafficSelector.Builder egressPacket,
+                                       List<PortNumber> outputPorts,
+                                       OutputInstruction outputInstruction,
+                                       PipelineTraceableHitChain currentHitChain,
+                                       PipelineTraceableOutput.Builder outputBuilder,
+                                       TrafficSelector initialPacket,
+                                       boolean dropped) {
+        // Store the output port for further processing
+        outputPorts.add(outputInstruction.port());
+        // Create the final hit chain from the current one (deep copy)
+        ConnectPoint outputPort = new ConnectPoint(deviceId, outputInstruction.port());
+        PipelineTraceableHitChain finalHitChain = new PipelineTraceableHitChain(outputPort,
+                Lists.newArrayList(currentHitChain.getHitChain()),
+                egressPacket.build());
+        // Dropped early
+        if (dropped) {
+            log.debug("Packet {} has been dropped", egressPacket.build());
+        } else {
+            finalHitChain.pass();
+        }
+        if (outputPort.port().equals(PortNumber.CONTROLLER)) {
+            handleVlanToController(finalHitChain, initialPacket);
+        }
+        // If there is already a chain do not add a copy
+        outputBuilder.addHitChain(finalHitChain);
+    }
+
+    // If the initial packet comes tagged with a Vlan we output it with that to ONOS.
+    // If ONOS applied a vlan we remove it.
+    // TODO Candidate for an AbstractBehavior implementation
+    private void handleVlanToController(PipelineTraceableHitChain currentHitChain, TrafficSelector initialPacket) {
+
+        VlanIdCriterion initialVid = (VlanIdCriterion) initialPacket
+                .getCriterion(Criterion.Type.VLAN_VID);
+        VlanIdCriterion finalVid = (VlanIdCriterion) currentHitChain.getEgressPacket()
+                .getCriterion(Criterion.Type.VLAN_VID);
+
+        if (initialVid != null && !initialVid.equals(finalVid) && initialVid.vlanId().equals(VlanId.NONE)) {
+            Set<Criterion> finalCriteria = new HashSet<>(currentHitChain.getEgressPacket().criteria());
+            //removing the final vlanId
+            finalCriteria.remove(finalVid);
+            TrafficSelector.Builder packetUpdated = DefaultTrafficSelector.builder();
+            finalCriteria.forEach(packetUpdated::add);
+            //Initial was none so we set it to that
+            packetUpdated.add(Criteria.matchVlanId(VlanId.NONE));
+            //Update final packet
+            currentHitChain.setEgressPacket(packetUpdated.build());
+        }
+    }
+
+    // Gets group information from instructions.
+    private void getGroupsFromInstructions(Map<GroupId, Group> groups, List<Instruction> instructions,
+                                           TrafficSelector.Builder egressPacket, List<PortNumber> outputPorts,
+                                           PipelineTraceableHitChain currentHitChain,
+                                           PipelineTraceableOutput.Builder outputBuilder,
+                                           PipelineTraceableInput input,
+                                           boolean dropped) {
+
+        List<Instruction> groupInstructionlist = new ArrayList<>();
+        // sort instructions according to priority (larger Instruction.Type ENUM constant first)
+        // which enables to treat other actions before the OUTPUT action
+        // TODO improve the priority scheme according to the OpenFlow ActionSet spec
+        List<Instruction> instructionsSorted = new ArrayList<>();
+        instructionsSorted.addAll(instructions);
+        instructionsSorted.sort((instr1, instr2) ->
+                Integer.compare(instr2.type().ordinal(), instr1.type().ordinal()));
+
+        // Handles first all non-group instructions
+        for (Instruction instruction : instructionsSorted) {
+            log.debug("Considering Instruction {}", instruction);
+            // if the instruction is not group we need to update the packet or add the output
+            // to the possible outputs for this packet
+            if (!instruction.type().equals(Instruction.Type.GROUP)) {
+                // FIXME ?? if the instruction is not group we need to update the packet
+                // or add the output to the possible outputs for this packet
+                if (instruction.type().equals(Instruction.Type.OUTPUT)) {
+                    buildOutputFromDevice(egressPacket, outputPorts, (OutputInstruction) instruction,
+                            currentHitChain, outputBuilder, input.ingressPacket(), dropped);
+                } else {
+                    egressPacket = translateInstruction(egressPacket, instruction);
+                }
+            } else {
+                // Store for later if the instruction is pointing to a group
+                groupInstructionlist.add(instruction);
+            }
+        }
+
+        // handle all the internal instructions pointing to a group.
+        for (Instruction instr : groupInstructionlist) {
+            Instructions.GroupInstruction groupInstruction = (Instructions.GroupInstruction) instr;
+            Group group = groups.get(groupInstruction.groupId());
+
+            // group does not exist in the dataplane
+            if (group == null) {
+                currentHitChain.setEgressPacket(egressPacket.build());
+                currentHitChain.dropped();
+                outputBuilder.appendToLog("Null group for Instruction " + instr)
+                        .noGroups()
+                        .addHitChain(currentHitChain);
+                break;
+            }
+
+            log.debug("Analyzing group {}", group.id());
+
+            // group is there but there are no members/buckets
+            if (group.buckets().buckets().size() == 0) {
+                // add the group to the traversed groups
+                currentHitChain.addDataPlaneEntity(new DataPlaneEntity(group));
+                currentHitChain.setEgressPacket(egressPacket.build());
+                currentHitChain.dropped();
+                outputBuilder.appendToLog("Group " + group.id() + " has no buckets")
+                        .noMembers()
+                        .addHitChain(currentHitChain);
+                break;
+            }
+
+            PipelineTraceableHitChain newHitChain;
+            TrafficSelector.Builder newEgressPacket;
+            // Cycle in each of the group's buckets and add them to the groups for this Device.
+            for (GroupBucket bucket : group.buckets().buckets()) {
+
+                // add the group to the traversed groups
+                currentHitChain.addDataPlaneEntity(new DataPlaneEntity(group));
+
+                // Go to the next step - using a copy of the egress packet and of the hit chain
+                newHitChain = PipelineTraceableHitChain.emptyHitChain();
+                currentHitChain.getHitChain().forEach(newHitChain::addDataPlaneEntity);
+                newEgressPacket = DefaultTrafficSelector.builder(egressPacket.build());
+                getGroupsFromInstructions(groups, bucket.treatment().allInstructions(), newEgressPacket,
+                        outputPorts, newHitChain, outputBuilder, input,
+                        dropped | isDropped(group.id(), bucket, input.ingressPort()));
+            }
+        }
+    }
+
+    private boolean isDropped(GroupId groupId, GroupBucket bucket, ConnectPoint ingressPort) {
+        log.debug("Verify if the packet has to be dropped by the input port {}",
+                ingressPort);
+        // if It is not a l2 flood group and l2/l3 mcast skip
+        int maskedId = groupId.id() & 0xF0000000;
+        if (maskedId != L2_FLOOD_TYPE && maskedId != L2_MULTICAST_TYPE &&
+                maskedId != L3_MULTICAST_TYPE) {
+            return false;
+        }
+        // Verify if the bucket points to the ingress port
+        Instructions.GroupInstruction groupInstruction;
+        for (Instruction instr : bucket.treatment().allInstructions()) {
+            if (instr.type().equals(Instruction.Type.GROUP)) {
+                groupInstruction = (Instructions.GroupInstruction) instr;
+                // FIXME According to the OFDPA spec for L3 MCAST if the VLAN is changed packet is not dropped
+                if ((groupInstruction.groupId().id() & 0xF0000000) == L2_INTERFACE_TYPE) {
+                    return (groupInstruction.groupId().id() & 0x0000FFFF) == ingressPort.port().toLong();
+                }
+            }
+        }
+        return false;
+    }
+
+    // Handles deferred instructions taken from the flows
+    private void handleDeferredActions(TrafficSelector egressPacket, Map<GroupId, Group> groups,
+                                       List<Instruction> deferredInstructions, List<PortNumber> outputPorts,
+                                       PipelineTraceableHitChain currentHitChain,
+                                       PipelineTraceableOutput.Builder outputBuilder,
+                                       PipelineTraceableInput input) {
+        // Update the packet with the deferred instructions
+        TrafficSelector.Builder newEgressPacket = updatePacket(egressPacket, deferredInstructions);
+
+        //Gather any output instructions from the deferred instruction
+        List<Instruction> outputFlowInstruction = deferredInstructions.stream().filter(instruction ->
+                instruction.type().equals(Instruction.Type.OUTPUT))
+                .collect(Collectors.toList());
+
+        //We are considering deferred instructions from flows, there can only be one output.
+        if (outputFlowInstruction.size() > 1) {
+            outputBuilder.appendToLog("More than one flow rule with OUTPUT instruction");
+            log.warn("There cannot be more than one flow entry with OUTPUT instruction for {}", egressPacket);
+        }
+
+        // If there is one output let's go through that. No need to make a copy
+        // of the egress packet and of the current hit chain.
+        if (outputFlowInstruction.size() == 1) {
+            buildOutputFromDevice(newEgressPacket, outputPorts, (OutputInstruction) outputFlowInstruction.get(0),
+                    currentHitChain, outputBuilder, input.ingressPacket(), false);
+        }
+
+        // If there is no output let's see if there any deferred instruction point to groups.
+        // No need to make a copy of the egress packet and of the current chain.
+        if (outputFlowInstruction.size() == 0) {
+            getGroupsFromInstructions(groups, deferredInstructions, newEgressPacket, outputPorts,
+                    currentHitChain, outputBuilder, input, false);
+        }
+    }
+
+    // Checks whether it is an hw device based on different means.
+    // throws an exception if the behavior has been used with wrong drivers
+    private boolean isHardwareSwitch() {
+        // Check if we are using ofdpa hw device by looking at the pipeliner
+        // if we need to support a device that does not have a pipeliner
+        // we can add an exclusion rules before this
+        if (!this.handler().hasBehaviour(Pipeliner.class)) {
+            throw new UnsupportedOperationException("Not supported device");
+        }
+        Pipeliner pipeliner = this.handler().behaviour(Pipeliner.class);
+        if (pipeliner instanceof OvsOfdpaPipeline) {
+            return false;
+        } else if (pipeliner instanceof Ofdpa2Pipeline) {
+            return true;
+        }
+        throw new UnsupportedOperationException("Not supported device");
+    }
+
+    // OF-DPA hardware requires one VLAN filtering rule and one VLAN assignment flow in the VLAN table.
+    // This method is used to determine whether there is a need to match a second VLAN flow after
+    // matching the given flowEntry.
+    private boolean shouldMatchSecondVlanFlow(FlowEntry flowEntry) {
+        // if we need to support a device that does not have a pipeliner
+        // we can add an exclusion rules before this
+        if (!this.handler().hasBehaviour(Pipeliner.class)) {
+            throw new UnsupportedOperationException("Not supported device");
+        }
+        Pipeliner pipeliner = this.handler().behaviour(Pipeliner.class);
+        if (!(pipeliner instanceof Ofdpa2Pipeline)) {
+            return false;
+        }
+        return ((Ofdpa2Pipeline) pipeliner).requireSecondVlanTableEntry() &&
+                flowEntry.table().equals(IndexTableId.of(VLAN_TABLE)) &&
+                flowEntry.selector().getCriterion(Criterion.Type.VLAN_VID) != null &&
+                ((VlanIdCriterion) flowEntry.selector().getCriterion(Criterion.Type.VLAN_VID))
+                        .vlanId().equals(VlanId.NONE);
+    }
+
+}
diff --git a/drivers/default/src/main/java/org/onosproject/driver/traceable/package-info.java b/drivers/default/src/main/java/org/onosproject/driver/traceable/package-info.java
new file mode 100644
index 0000000..ec4d9ad
--- /dev/null
+++ b/drivers/default/src/main/java/org/onosproject/driver/traceable/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2016-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Implementations of the pipeline traceable behaviours.
+ */
+package org.onosproject.driver.traceable;
\ No newline at end of file
diff --git a/drivers/default/src/main/resources/onos-drivers.xml b/drivers/default/src/main/resources/onos-drivers.xml
index f566132..fff45dc 100644
--- a/drivers/default/src/main/resources/onos-drivers.xml
+++ b/drivers/default/src/main/resources/onos-drivers.xml
@@ -71,6 +71,8 @@
                    impl="org.onosproject.driver.extensions.OfdpaExtensionSelectorInterpreter" />
         <behaviour api="org.onosproject.net.behaviour.ExtensionSelectorResolver"
                    impl="org.onosproject.driver.extensions.OfdpaExtensionSelectorInterpreter" />
+        <behaviour api="org.onosproject.net.behaviour.PipelineTraceable"
+                   impl="org.onosproject.driver.traceable.OfdpaPipelineTraceable" />
         <property name="meterCapable">false</property>
         <property name="accumulatorEnabled">true</property>
     </driver>
@@ -167,6 +169,8 @@
                    impl="org.onosproject.driver.pipeline.ofdpa.OvsOfdpaPipeline"/>
         <behaviour api="org.onosproject.openflow.controller.ExtensionSelectorInterpreter"
                    impl="org.onosproject.driver.extensions.OvsOfdpaExtensionSelectorInterpreter" />
+        <behaviour api="org.onosproject.net.behaviour.PipelineTraceable"
+                   impl="org.onosproject.driver.traceable.OfdpaPipelineTraceable" />
     </driver>
 
     <driver name="celestica" extends="default"
diff --git a/drivers/default/src/test/java/org/onosproject/driver/traceable/OfdpaPipelineTraceableTest.java b/drivers/default/src/test/java/org/onosproject/driver/traceable/OfdpaPipelineTraceableTest.java
new file mode 100644
index 0000000..49cb15a
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/traceable/OfdpaPipelineTraceableTest.java
@@ -0,0 +1,768 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.driver.traceable;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.onosproject.driver.pipeline.ofdpa.Ofdpa2Pipeline;
+import org.onosproject.driver.pipeline.ofdpa.OvsOfdpaPipeline;
+import org.onosproject.net.DataPlaneEntity;
+import org.onosproject.net.PipelineTraceableHitChain;
+import org.onosproject.net.PipelineTraceableInput;
+import org.onosproject.net.PipelineTraceableOutput;
+import org.onosproject.net.PipelineTraceableOutput.PipelineTraceableResult;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.behaviour.PipelineTraceable;
+import org.onosproject.net.behaviour.Pipeliner;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.DriverData;
+import org.onosproject.net.driver.DriverHandler;
+
+import java.util.List;
+
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.onosproject.driver.traceable.TraceableDataPlaneObjects.getDataPlaneEntities;
+import static org.onosproject.driver.traceable.TraceableDataPlaneObjects.getHitChains;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_ARP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_L2_BRIDG_UNTAG_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_L2_BROAD_UNTAG_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_L3_ECMP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_L3_UCAST_UNTAG_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_MPLS_ECMP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_MPLS_ECMP_PACKET_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_PUNT_IP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.IN_PUNT_LLDP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OFDPA_CP;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OFDPA_DEVICE;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OFDPA_DRIVER;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L2_BROAD_EMPTY;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L3_ECMP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L3_ECMP_PACKET_1;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L3_ECMP_PACKET_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L3_ECMP_PACKET_OFDPA_1;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_L3_UCAST_UNTAG_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_MPLS_ECMP_PACKET;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OUT_PORT;
+import static org.onosproject.driver.traceable.TraceableTestObjects.OVS_OFDPA_DRIVER;
+import static org.onosproject.driver.traceable.TraceableTestObjects.PORT;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.ARP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.ARP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_NOT_ORDERED_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_NOT_ORDERED_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_EMPTY_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_EMPTY_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_ECMP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_ECMP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_UCAST_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_UCAST_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.MPLS_ECMP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.MPLS_ECMP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_IP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_IP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_LLDP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_LLDP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.UP_OFDPA_CP;
+import static org.onosproject.driver.traceable.TraceableTestObjects.UP_PORT;
+import static org.onosproject.driver.traceable.TraceableTestObjects.UP_PORT_1;
+
+/**
+ * Tests for Ofdpa pipeline traceable implementation.
+ */
+public class OfdpaPipelineTraceableTest {
+
+    private TraceableTestObjects.TestDriver ofdpaDriver = new TraceableTestObjects.TestDriver(OFDPA_DRIVER);
+    private TraceableTestObjects.TestDriver ovsOfdpaDriver = new TraceableTestObjects.TestDriver(OVS_OFDPA_DRIVER);
+
+    private DriverHandler testDriverHandlerOfdpa;
+    private DriverHandler testDriverHandlerOvsOfdpa;
+
+    @Before
+    public void setUp() {
+        testDriverHandlerOfdpa = createNiceMock(DriverHandler.class);
+        testDriverHandlerOvsOfdpa = createNiceMock(DriverHandler.class);
+        expect(testDriverHandlerOfdpa.hasBehaviour(Pipeliner.class)).andReturn(true).anyTimes();
+        expect(testDriverHandlerOvsOfdpa.hasBehaviour(Pipeliner.class)).andReturn(true).anyTimes();
+        expect(testDriverHandlerOfdpa.behaviour(Pipeliner.class)).andReturn(new Ofdpa2Pipeline()).anyTimes();
+        expect(testDriverHandlerOvsOfdpa.behaviour(Pipeliner.class)).andReturn(new OvsOfdpaPipeline()).anyTimes();
+        replay(testDriverHandlerOfdpa);
+        replay(testDriverHandlerOvsOfdpa);
+    }
+
+    private PipelineTraceable setUpOfdpa() {
+        PipelineTraceable behaviour = new OfdpaPipelineTraceable();
+        DriverData driverData = new DefaultDriverData(ofdpaDriver, OFDPA_DEVICE);
+        behaviour.setData(driverData);
+        behaviour.setHandler(testDriverHandlerOfdpa);
+        behaviour.init();
+        return behaviour;
+    }
+
+    private PipelineTraceable setUpOvsOfdpa() {
+        PipelineTraceable behaviour = new OfdpaPipelineTraceable();
+        DriverData driverData = new DefaultDriverData(ovsOfdpaDriver, OFDPA_DEVICE);
+        behaviour.setData(driverData);
+        behaviour.setHandler(testDriverHandlerOvsOfdpa);
+        behaviour.init();
+        return behaviour;
+    }
+
+    /**
+     * Test punt ip for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaPuntIP() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_PUNT_IP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, PUNT_IP_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(PUNT_IP_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(IN_PUNT_IP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test punt ip for ofdpa.
+     */
+    @Test
+    public void testOfdpaPuntIP() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_PUNT_IP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, PUNT_IP_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(PUNT_IP_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(IN_PUNT_IP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test punt arp for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaArp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_ARP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, ARP_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(3));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(ARP_OVS_OFDPA);
+        assertThat(chains.size(), is(3));
+
+        // This is the copy sent to the controller
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        // This is the copy sent to the member port
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(8));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+
+        // This is the copy sent on the input port
+        hitChain = pipelineOutput.getHitChains().get(2);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PORT));
+        assertThat(hitChain.getHitChain().size(), is(8));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(2), hitChain.getHitChain());
+    }
+
+    /**
+     * Test punt arp for ovs-ofdpa.
+     */
+    @Test
+    public void testOfdpaArp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_ARP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, ARP_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(3));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(ARP_OFDPA);
+        assertThat(chains.size(), is(3));
+
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+
+        hitChain = pipelineOutput.getHitChains().get(2);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PORT));
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(IN_ARP_PACKET, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(2), hitChain.getHitChain());
+    }
+
+    /**
+     * Test punt lldp for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaPuntLldp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_PUNT_LLDP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, PUNT_LLDP_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(PUNT_LLDP_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(IN_PUNT_LLDP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test punt lldp for ovs-ofdpa.
+     */
+    @Test
+    public void testOfdpaPuntLldp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_PUNT_LLDP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, PUNT_LLDP_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(PUNT_LLDP_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PortNumber.CONTROLLER));
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(IN_PUNT_LLDP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 bridging with untagged hosts for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL2BridingUntagged() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BRIDG_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L2_BRIDG_UNTAG_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BRIDG_UNTAG_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(IN_L2_BRIDG_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 bridging with untagged hosts for ofdpa.
+     */
+    @Test
+    public void testOfdpaL2BridingUntagged() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BRIDG_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L2_BRIDG_UNTAG_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BRIDG_UNTAG_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(IN_L2_BRIDG_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 broadcast with untagged hosts for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL2BroadcastUntagged() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BROAD_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L2_BROAD_UNTAG_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(2));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BROAD_UNTAG_OVS_OFDPA);
+        assertThat(chains.size(), is(2));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(IN_L2_BROAD_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        // Dropped chain - input port!
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PORT));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(IN_L2_BROAD_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 broadcast with untagged hosts for ofdpa.
+     */
+    @Test
+    public void testOfdpaL2BroadcastUntagged() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BROAD_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L2_BROAD_UNTAG_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(2));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BROAD_UNTAG_OFDPA);
+        assertThat(chains.size(), is(2));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(5));
+        assertEquals(IN_L2_BROAD_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        // Dropped chain - input port!
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(PORT));
+        assertThat(hitChain.getHitChain().size(), is(5));
+        assertEquals(IN_L2_BROAD_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l3 unicast routing for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL3Unicast() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L3_UCAST_UNTAG_PACKET, UP_OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L3_UCAST_UNTAG_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L3_UCAST_UNTAG_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertEquals(OUT_L3_UCAST_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l3 unicast routing for ofdpa.
+     */
+    @Test
+    public void testOfdpaL3Unicast() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L3_UCAST_UNTAG_PACKET, UP_OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L3_UCAST_UNTAG_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L3_UCAST_UNTAG_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(OUT_L3_UCAST_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l3 ecmp routing for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL3Ecmp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L3_ECMP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L3_ECMP_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(2));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L3_ECMP_OVS_OFDPA);
+        assertThat(chains.size(), is(2));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT));
+        assertThat(hitChain.getHitChain().size(), is(9));
+        assertEquals(OUT_L3_ECMP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        // 2nd spine!
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT_1));
+        assertThat(hitChain.getHitChain().size(), is(9));
+        assertEquals(OUT_L3_ECMP_PACKET_1, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l3 ecmp routing for ofdpa.
+     */
+    @Test
+    public void testOfdpaL3Ecmp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L3_ECMP_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L3_ECMP_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(2));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L3_ECMP_OFDPA);
+        assertThat(chains.size(), is(2));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT));
+        assertThat(hitChain.getHitChain().size(), is(8));
+        assertEquals(OUT_L3_ECMP_PACKET_OFDPA, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+
+        hitChain = pipelineOutput.getHitChains().get(1);
+        assertNotNull(hitChain);
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT_1));
+        assertThat(hitChain.getHitChain().size(), is(8));
+        assertEquals(OUT_L3_ECMP_PACKET_OFDPA_1, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(1), hitChain.getHitChain());
+    }
+
+    /**
+     * Test mpls ecmp routing for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaMplsEcmp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_MPLS_ECMP_PACKET, UP_OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, MPLS_ECMP_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(MPLS_ECMP_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT_1));
+        assertThat(hitChain.getHitChain().size(), is(9));
+        assertEquals(OUT_MPLS_ECMP_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test mpls ecmp routing for ofdpa.
+     */
+    @Test
+    public void testOfdpaMplsEcmp() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_MPLS_ECMP_PACKET_OFDPA, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, MPLS_ECMP_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(MPLS_ECMP_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(UP_PORT_1));
+        assertThat(hitChain.getHitChain().size(), is(7));
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+        assertEquals(OUT_MPLS_ECMP_PACKET, hitChain.getEgressPacket());
+    }
+
+    /**
+     * Test failure due l2 flood group with no buckets for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL2BroadEmpty() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BROAD_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L2_BROAD_EMPTY_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.NO_GROUP_MEMBERS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BROAD_EMPTY_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNull(hitChain.getOutputPort());
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(OUT_L2_BROAD_EMPTY, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test failure due l2 flood group with no buckets for ofdpa.
+     */
+    @Test
+    public void testOfdpaL2BroadEmpty() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BROAD_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L2_BROAD_EMPTY_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.NO_GROUP_MEMBERS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BROAD_EMPTY_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNull(hitChain.getOutputPort());
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(OUT_L2_BROAD_EMPTY, hitChain.getEgressPacket());
+        assertTrue(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 bridging with l2 interface group that has actions not in order for ovs-ofdpa.
+     */
+    @Test
+    public void testOvsOfdpaL2BridingNotOrdered() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BRIDG_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OVS_OFDPA_DRIVER, L2_BRIDG_NOT_ORDERED_OVS_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOvsOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BRIDG_NOT_ORDERED_OVS_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(6));
+        assertEquals(IN_L2_BRIDG_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+    /**
+     * Test l2 bridging with l2 interface group that has actions not in order for ofdpa.
+     */
+    @Test
+    public void testOfdpaL2BridingNotOrdered() {
+        PipelineTraceableInput pipelineInput = new PipelineTraceableInput(IN_L2_BRIDG_UNTAG_PACKET, OFDPA_CP,
+                getDataPlaneEntities(OFDPA_DRIVER, L2_BRIDG_NOT_ORDERED_OFDPA));
+        PipelineTraceable pipelineTraceable = setUpOfdpa();
+
+        PipelineTraceableOutput pipelineOutput = pipelineTraceable.apply(pipelineInput);
+        assertNotNull(pipelineOutput);
+        assertThat(pipelineOutput.getHitChains().size(), is(1));
+        assertThat(pipelineOutput.getResult(), is(PipelineTraceableResult.SUCCESS));
+
+        PipelineTraceableHitChain hitChain = pipelineOutput.getHitChains().get(0);
+        assertNotNull(hitChain);
+        List<List<DataPlaneEntity>> chains = getHitChains(L2_BRIDG_NOT_ORDERED_OFDPA);
+        assertThat(chains.size(), is(1));
+
+        assertNotNull(hitChain.getOutputPort());
+        assertThat(hitChain.getOutputPort().port(), is(OUT_PORT));
+        assertThat(hitChain.getHitChain().size(), is(4));
+        assertEquals(IN_L2_BRIDG_UNTAG_PACKET, hitChain.getEgressPacket());
+        assertFalse(hitChain.isDropped());
+        assertEquals(chains.get(0), hitChain.getHitChain());
+    }
+
+}
\ No newline at end of file
diff --git a/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableDataPlaneObjects.java b/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableDataPlaneObjects.java
new file mode 100644
index 0000000..5e52dde
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableDataPlaneObjects.java
@@ -0,0 +1,1000 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.driver.traceable;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Lists;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.DefaultApplicationId;
+import org.onosproject.core.GroupId;
+import org.onosproject.driver.extensions.Ofdpa3MplsType;
+import org.onosproject.driver.extensions.Ofdpa3SetMplsType;
+import org.onosproject.driver.pipeline.ofdpa.OfdpaPipelineUtility;
+import org.onosproject.driver.pipeline.ofdpa.OvsOfdpaPipeline;
+import org.onosproject.net.DataPlaneEntity;
+import org.onosproject.net.flow.DefaultFlowEntry;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.group.DefaultGroup;
+import org.onosproject.net.group.DefaultGroupBucket;
+import org.onosproject.net.group.Group;
+import org.onosproject.net.group.GroupBucket;
+import org.onosproject.net.group.GroupBuckets;
+
+import java.util.List;
+
+import static org.onlab.packet.EthType.EtherType.ARP;
+import static org.onlab.packet.EthType.EtherType.IPV4;
+import static org.onlab.packet.EthType.EtherType.LLDP;
+import static org.onlab.packet.EthType.EtherType.MPLS_UNICAST;
+import static org.onosproject.driver.traceable.TraceableTestObjects.*;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.ARP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.ARP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_NOT_ORDERED_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_NOT_ORDERED_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BRIDG_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_EMPTY_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_EMPTY_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L2_BROAD_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_ECMP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_ECMP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_UCAST_UNTAG_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.L3_UCAST_UNTAG_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.MPLS_ECMP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.MPLS_ECMP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_IP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_IP_OVS_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_LLDP_OFDPA;
+import static org.onosproject.driver.traceable.TraceableTestObjects.TraceableTest.PUNT_LLDP_OVS_OFDPA;
+
+/**
+ * Helper class for dataplane objects related to the Traceable tests.
+ */
+final class TraceableDataPlaneObjects {
+
+    private TraceableDataPlaneObjects() {
+        // Banning construction
+    }
+
+    // Groups
+    private static final GroupId L2_FLOOD_GROUP_ID = GroupId.valueOf(0x40140000);
+
+    private static final GroupId PUNT_GROUP_ID = GroupId.valueOf(OvsOfdpaPipeline.POP_VLAN_PUNT_GROUP_ID);
+    private static final TrafficTreatment PUNT_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .punt()
+            .build();
+    private static final GroupBucket PUNT_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            PUNT_BUCKET_TREATMENT);
+    private static final GroupBuckets PUNT_BUCKETS = new GroupBuckets(ImmutableList.of(PUNT_BUCKET));
+    private static final Group PUNT_GROUP = new DefaultGroup(PUNT_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, PUNT_BUCKETS);
+
+    private static final GroupId L2_IFACE_GROUP_ID = GroupId.valueOf(0x140000 | (int) OUT_PORT.toLong());
+    private static final TrafficTreatment L2_IFACE_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .setOutput(OUT_PORT)
+            .build();
+    private static final GroupBucket L2_IFACE_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            L2_IFACE_BUCKET_TREATMENT);
+    private static final GroupBuckets L2_IFACE_BUCKETS = new GroupBuckets(ImmutableList.of(L2_IFACE_BUCKET));
+    private static final Group L2_IFACE_GROUP = new DefaultGroup(L2_IFACE_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L2_IFACE_BUCKETS);
+
+    private static final GroupId L2_IFACE_GROUP_ID_1 = GroupId.valueOf(0x140000 | (int) PORT.toLong());
+    private static final TrafficTreatment L2_IFACE_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .setOutput(PORT)
+            .build();
+    private static final GroupBucket L2_IFACE_BUCKET_1 = DefaultGroupBucket.createIndirectGroupBucket(
+            L2_IFACE_BUCKET_TREATMENT_1);
+    private static final GroupBuckets L2_IFACE_BUCKETS_1 = new GroupBuckets(ImmutableList.of(L2_IFACE_BUCKET_1));
+    private static final Group L2_IFACE_GROUP_1 = new DefaultGroup(L2_IFACE_GROUP_ID_1, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L2_IFACE_BUCKETS_1);
+
+    private static final GroupId L2_IFACE_GROUP_ID_2 = GroupId.valueOf(0xffe000 | (int) UP_PORT.toLong());
+    private static final TrafficTreatment L2_IFACE_BUCKET_TREATMENT_2 = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .setOutput(UP_PORT)
+            .build();
+    private static final GroupBucket L2_IFACE_BUCKET_2 = DefaultGroupBucket.createIndirectGroupBucket(
+            L2_IFACE_BUCKET_TREATMENT_2);
+    private static final GroupBuckets L2_IFACE_BUCKETS_2 = new GroupBuckets(ImmutableList.of(L2_IFACE_BUCKET_2));
+    private static final Group L2_IFACE_GROUP_2 = new DefaultGroup(L2_IFACE_GROUP_ID_2, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L2_IFACE_BUCKETS_2);
+
+    private static final GroupId L2_IFACE_GROUP_ID_3 = GroupId.valueOf(0xffe000 | (int) UP_PORT_1.toLong());
+    private static final TrafficTreatment L2_IFACE_BUCKET_TREATMENT_3 = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .setOutput(UP_PORT_1)
+            .build();
+    private static final GroupBucket L2_IFACE_BUCKET_3 = DefaultGroupBucket.createIndirectGroupBucket(
+            L2_IFACE_BUCKET_TREATMENT_3);
+    private static final GroupBuckets L2_IFACE_BUCKETS_3 = new GroupBuckets(ImmutableList.of(L2_IFACE_BUCKET_3));
+    private static final Group L2_IFACE_GROUP_3 = new DefaultGroup(L2_IFACE_GROUP_ID_3, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L2_IFACE_BUCKETS_3);
+
+    private static final GroupId L2_IFACE_GROUP_ID_NOT_ORDERED = GroupId.valueOf(0x140000 | (int) OUT_PORT.toLong());
+    private static final TrafficTreatment L2_IFACE_BUCKET_TREATMENT_NOT_ORDERED = DefaultTrafficTreatment.builder()
+            .setOutput(OUT_PORT)
+            .popVlan()
+            .build();
+    private static final GroupBucket L2_IFACE_BUCKET_NOT_ORDERED = DefaultGroupBucket.createIndirectGroupBucket(
+            L2_IFACE_BUCKET_TREATMENT_NOT_ORDERED);
+    private static final GroupBuckets L2_IFACE_BUCKETS_NOT_ORDERED = new GroupBuckets(ImmutableList.of(
+            L2_IFACE_BUCKET_NOT_ORDERED));
+    private static final Group L2_IFACE_GROUP_NOT_ORDERED = new DefaultGroup(L2_IFACE_GROUP_ID_NOT_ORDERED,
+            OFDPA_DEVICE, Group.Type.INDIRECT, L2_IFACE_BUCKETS_NOT_ORDERED);
+
+    private static final TrafficTreatment L2_FLOOD_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(L2_IFACE_GROUP_ID)
+            .build();
+    private static final GroupBucket L2_FLOOD_BUCKET = DefaultGroupBucket.createAllGroupBucket(
+            L2_FLOOD_BUCKET_TREATMENT);
+    private static final TrafficTreatment L2_FLOOD_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .group(L2_IFACE_GROUP_ID_1)
+            .build();
+    private static final GroupBucket L2_FLOOD_BUCKET_1 = DefaultGroupBucket.createAllGroupBucket(
+            L2_FLOOD_BUCKET_TREATMENT_1);
+    private static final GroupBuckets L2_FLOOD_BUCKETS = new GroupBuckets(ImmutableList.of(
+            L2_FLOOD_BUCKET, L2_FLOOD_BUCKET_1));
+    private static final Group L2_FLOOD_GROUP = new DefaultGroup(L2_FLOOD_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.ALL, L2_FLOOD_BUCKETS);
+
+    private static final GroupBuckets L2_FLOOD_EMPTY_BUCKETS = new GroupBuckets(ImmutableList.of());
+    private static final Group L2_FLOOD_EMPTY_GROUP = new DefaultGroup(L2_FLOOD_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.ALL, L2_FLOOD_EMPTY_BUCKETS);
+
+    private static final GroupId L3_UCAST_GROUP_ID = GroupId.valueOf(0x20000026);
+    private static final TrafficTreatment L3_UCAST_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .setEthSrc(LEAF_MAC)
+            .setEthDst(HOST_MAC)
+            .setVlanId(HOST_VLAN)
+            .group(L2_IFACE_GROUP_ID)
+            .build();
+    private static final GroupBucket L3_UCAST_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            L3_UCAST_BUCKET_TREATMENT);
+    private static final GroupBuckets L3_UCAST_BUCKETS = new GroupBuckets(ImmutableList.of(L3_UCAST_BUCKET));
+    private static final Group L3_UCAST_GROUP = new DefaultGroup(L3_UCAST_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L3_UCAST_BUCKETS);
+
+    private static final GroupId L3_UCAST_GROUP_ID_1 = GroupId.valueOf(0x20000027);
+    private static final TrafficTreatment L3_UCAST_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .setEthSrc(LEAF_MAC)
+            .setEthDst(SPINE_MAC)
+            .setVlanId(DEFAULT_VLAN)
+            .group(L2_IFACE_GROUP_ID_3)
+            .build();
+    private static final GroupBucket L3_UCAST_BUCKET_1 = DefaultGroupBucket.createIndirectGroupBucket(
+            L3_UCAST_BUCKET_TREATMENT_1);
+    private static final GroupBuckets L3_UCAST_BUCKETS_1 = new GroupBuckets(ImmutableList.of(L3_UCAST_BUCKET_1));
+    private static final Group L3_UCAST_GROUP_1 = new DefaultGroup(L3_UCAST_GROUP_ID_1, OFDPA_DEVICE,
+            Group.Type.INDIRECT, L3_UCAST_BUCKETS_1);
+
+    private static final GroupId MPLS_IFACE_GROUP_ID = GroupId.valueOf(0x9000000c);
+    private static final TrafficTreatment MPLS_IFACE_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .setEthSrc(LEAF_MAC)
+            .setEthDst(SPINE_MAC)
+            .setVlanId(DEFAULT_VLAN)
+            .group(L2_IFACE_GROUP_ID_2)
+            .build();
+    private static final GroupBucket MPLS_IFACE_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_IFACE_BUCKET_TREATMENT);
+    private static final GroupBuckets MPLS_IFACE_BUCKETS = new GroupBuckets(ImmutableList.of(MPLS_IFACE_BUCKET));
+    private static final Group MPLS_IFACE_GROUP = new DefaultGroup(MPLS_IFACE_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_IFACE_BUCKETS);
+
+    private static final GroupId MPLS_IFACE_GROUP_ID_1 = GroupId.valueOf(0x9000000d);
+    private static final TrafficTreatment MPLS_IFACE_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .setEthSrc(LEAF_MAC)
+            .setEthDst(SPINE_MAC_1)
+            .setVlanId(DEFAULT_VLAN)
+            .group(L2_IFACE_GROUP_ID_3)
+            .build();
+    private static final GroupBucket MPLS_IFACE_BUCKET_1 = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_IFACE_BUCKET_TREATMENT_1);
+    private static final GroupBuckets MPLS_IFACE_BUCKETS_1 = new GroupBuckets(ImmutableList.of(MPLS_IFACE_BUCKET_1));
+    private static final Group MPLS_IFACE_GROUP_1 = new DefaultGroup(MPLS_IFACE_GROUP_ID_1, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_IFACE_BUCKETS_1);
+
+    private static final GroupId MPLS_L3VPN_GROUP_ID = GroupId.valueOf(0x9200000d);
+    private static final TrafficTreatment MPLS_L3VPN_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .pushMpls()
+            .setMpls(MPLS_LABEL)
+            .group(MPLS_IFACE_GROUP_ID)
+            .pushVlan()
+            .setVlanId(VlanId.vlanId(VlanId.RESERVED))
+            .build();
+    private static final GroupBucket MPLS_L3VPN_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_L3VPN_BUCKET_TREATMENT);
+    private static final GroupBuckets MPLS_L3VPN_BUCKETS = new GroupBuckets(ImmutableList.of(MPLS_L3VPN_BUCKET));
+    private static final Group MPLS_L3VPN_GROUP = new DefaultGroup(MPLS_L3VPN_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_L3VPN_BUCKETS);
+
+    private static final GroupId MPLS_L3VPN_GROUP_ID_1 = GroupId.valueOf(0x9200000e);
+    private static final TrafficTreatment MPLS_L3VPN_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .popVlan()
+            .pushMpls()
+            .setMpls(MPLS_LABEL)
+            .group(MPLS_IFACE_GROUP_ID_1)
+            .pushVlan()
+            .setVlanId(VlanId.vlanId(VlanId.RESERVED))
+            .build();
+    private static final GroupBucket MPLS_L3VPN_BUCKET_1 = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_L3VPN_BUCKET_TREATMENT_1);
+    private static final GroupBuckets MPLS_L3VPN_BUCKETS_1 = new GroupBuckets(ImmutableList.of(MPLS_L3VPN_BUCKET_1));
+    private static final Group MPLS_L3VPN_GROUP_1 = new DefaultGroup(MPLS_L3VPN_GROUP_ID_1, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_L3VPN_BUCKETS_1);
+
+    private static final TrafficTreatment MPLS_L3VPN_OFDPA_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .pushMpls()
+            .setMpls(MPLS_LABEL)
+            .group(MPLS_IFACE_GROUP_ID)
+            .copyTtlOut()
+            .setMplsBos(true)
+            .build();
+    private static final GroupBucket MPLS_L3VPN_OFDPA_BUCKET = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_L3VPN_OFDPA_BUCKET_TREATMENT);
+    private static final GroupBuckets MPLS_L3VPN_OFDPA_BUCKETS = new GroupBuckets(ImmutableList.of(
+            MPLS_L3VPN_OFDPA_BUCKET));
+    private static final Group MPLS_L3VPN_OFDPA_GROUP = new DefaultGroup(MPLS_L3VPN_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_L3VPN_OFDPA_BUCKETS);
+
+    private static final TrafficTreatment MPLS_L3VPN_OFDPA_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .pushMpls()
+            .setMpls(MPLS_LABEL)
+            .group(MPLS_IFACE_GROUP_ID_1)
+            .copyTtlOut()
+            .setMplsBos(true)
+            .build();
+    private static final GroupBucket MPLS_L3VPN_OFDPA_BUCKET_1 = DefaultGroupBucket.createIndirectGroupBucket(
+            MPLS_L3VPN_OFDPA_BUCKET_TREATMENT_1);
+    private static final GroupBuckets MPLS_L3VPN_OFDPA_BUCKETS_1 = new GroupBuckets(ImmutableList.of(
+            MPLS_L3VPN_OFDPA_BUCKET_1));
+    private static final Group MPLS_L3VPN_OFDPA_GROUP_1 = new DefaultGroup(MPLS_L3VPN_GROUP_ID_1, OFDPA_DEVICE,
+            Group.Type.INDIRECT, MPLS_L3VPN_OFDPA_BUCKETS_1);
+
+    private static final GroupId L3_ECMP_GROUP_ID = GroupId.valueOf(0x7000000e);
+    private static final TrafficTreatment L3_ECMP_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(MPLS_L3VPN_GROUP_ID)
+            .build();
+    private static final GroupBucket L3_ECMP_BUCKET = DefaultGroupBucket.createSelectGroupBucket(
+            L3_ECMP_BUCKET_TREATMENT);
+    private static final TrafficTreatment L3_ECMP_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .group(MPLS_L3VPN_GROUP_ID_1)
+            .build();
+    private static final GroupBucket L3_ECMP_BUCKET_1 = DefaultGroupBucket.createSelectGroupBucket(
+            L3_ECMP_BUCKET_TREATMENT_1);
+    private static final GroupBuckets L3_ECMP_BUCKETS = new GroupBuckets(ImmutableList.of(L3_ECMP_BUCKET,
+            L3_ECMP_BUCKET_1));
+    private static final Group L3_ECMP_GROUP = new DefaultGroup(L3_ECMP_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.SELECT, L3_ECMP_BUCKETS);
+
+    private static final TrafficTreatment L3_ECMP_OFDPA_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(MPLS_L3VPN_GROUP_ID)
+            .build();
+    private static final GroupBucket L3_ECMP_OFDPA_BUCKET = DefaultGroupBucket.createSelectGroupBucket(
+            L3_ECMP_OFDPA_BUCKET_TREATMENT);
+    private static final TrafficTreatment L3_ECMP_OFDPA_BUCKET_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .group(MPLS_L3VPN_GROUP_ID_1)
+            .build();
+    private static final GroupBucket L3_ECMP_OFDPA_BUCKET_1 = DefaultGroupBucket.createSelectGroupBucket(
+            L3_ECMP_OFDPA_BUCKET_TREATMENT_1);
+    private static final GroupBuckets L3_ECMP_OFDPA_BUCKETS = new GroupBuckets(ImmutableList.of(L3_ECMP_OFDPA_BUCKET,
+            L3_ECMP_OFDPA_BUCKET_1));
+    private static final Group L3_ECMP_OFDPA_GROUP = new DefaultGroup(L3_ECMP_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.SELECT, L3_ECMP_OFDPA_BUCKETS);
+
+    private static final GroupId MPLS_ECMP_GROUP_ID = GroupId.valueOf(0x7000000f);
+    private static final TrafficTreatment MPLS_ECMP_BUCKET_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(L3_UCAST_GROUP_ID_1)
+            .build();
+    private static final GroupBucket MPLS_ECMP_BUCKET = DefaultGroupBucket.createSelectGroupBucket(
+            MPLS_ECMP_BUCKET_TREATMENT);
+    private static final GroupBuckets MPLS_ECMP_BUCKETS = new GroupBuckets(ImmutableList.of(MPLS_ECMP_BUCKET));
+    private static final Group MPLS_ECMP_GROUP = new DefaultGroup(MPLS_ECMP_GROUP_ID, OFDPA_DEVICE,
+            Group.Type.SELECT, MPLS_ECMP_BUCKETS);
+
+    // Flows
+    private static final TrafficSelector EMPTY_SELECTOR = DefaultTrafficSelector.emptySelector();
+    private static final TrafficTreatment EMPTY_TREATMENT = DefaultTrafficTreatment.emptyTreatment();
+
+    private static final TrafficTreatment TABLE_0_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.VLAN_TABLE)
+            .build();
+    private static final FlowRule TABLE_0_MISS_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.PORT_TABLE)
+            .withPriority(0)
+            .withSelector(EMPTY_SELECTOR)
+            .withTreatment(TABLE_0_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_0_MISS_FLOW_ENTRY_OVS = new DefaultFlowEntry(TABLE_0_MISS_OVS);
+
+    private static final TrafficSelector TABLE_10_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(PORT)
+            .matchVlanId(VlanId.NONE)
+            .build();
+    private static final TrafficTreatment TABLE_10_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .pushVlan()
+            .setVlanId(HOST_VLAN)
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_FLOW_SELECTOR)
+            .withTreatment(TABLE_10_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_FLOW_ENTRY = new DefaultFlowEntry(TABLE_10_FLOW);
+
+    private static final TrafficTreatment TABLE_10_FLOW_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .setVlanId(HOST_VLAN)
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_FLOW_1 = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_FLOW_SELECTOR)
+            .withTreatment(TABLE_10_FLOW_TREATMENT_1)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_FLOW_ENTRY_1 = new DefaultFlowEntry(TABLE_10_FLOW_1);
+
+    private static final TrafficSelector TABLE_10_FLOW_SELECTOR_2 = DefaultTrafficSelector.builder()
+            .matchInPort(PORT)
+            .matchVlanId(HOST_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_10_FLOW_TREATMENT_2 = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_FLOW_2 = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_FLOW_SELECTOR_2)
+            .withTreatment(TABLE_10_FLOW_TREATMENT_2)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_FLOW_ENTRY_2 = new DefaultFlowEntry(TABLE_10_FLOW_2);
+
+    private static final TrafficSelector TABLE_10_DEFAULT_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(UP_PORT)
+            .matchVlanId(VlanId.NONE)
+            .build();
+    private static final TrafficTreatment TABLE_10_DEFAULT_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .pushVlan()
+            .setVlanId(DEFAULT_VLAN)
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_DEFAULT_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_DEFAULT_FLOW_SELECTOR)
+            .withTreatment(TABLE_10_DEFAULT_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_DEFAULT_FLOW_ENTRY = new DefaultFlowEntry(TABLE_10_DEFAULT_FLOW);
+
+    private static final TrafficSelector TABLE_10_DEFAULT_FLOW_SELECTOR_1 = DefaultTrafficSelector.builder()
+            .matchInPort(UP_PORT)
+            .matchVlanId(VlanId.NONE)
+            .build();
+    private static final TrafficTreatment TABLE_10_DEFAULT_FLOW_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .setVlanId(DEFAULT_VLAN)
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_DEFAULT_FLOW_1 = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_DEFAULT_FLOW_SELECTOR_1)
+            .withTreatment(TABLE_10_DEFAULT_FLOW_TREATMENT_1)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_DEFAULT_FLOW_ENTRY_1 = new DefaultFlowEntry(TABLE_10_DEFAULT_FLOW_1);
+
+    private static final TrafficSelector TABLE_10_DEFAULT_FLOW_SELECTOR_2 = DefaultTrafficSelector.builder()
+            .matchInPort(UP_PORT)
+            .matchVlanId(DEFAULT_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_10_DEFAULT_FLOW_TREATMENT_2 = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.TMAC_TABLE)
+            .build();
+    private static final FlowRule TABLE_10_DEFAULT_FLOW_2 = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.VLAN_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_10_DEFAULT_FLOW_SELECTOR_2)
+            .withTreatment(TABLE_10_DEFAULT_FLOW_TREATMENT_2)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_10_DEFAULT_FLOW_ENTRY_2 = new DefaultFlowEntry(TABLE_10_DEFAULT_FLOW_2);
+
+    private static final TrafficTreatment TABLE_20_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.BRIDGING_TABLE)
+            .build();
+    private static final FlowRule TABLE_20_MISS_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.TMAC_TABLE)
+            .withPriority(0)
+            .withSelector(EMPTY_SELECTOR)
+            .withTreatment(TABLE_20_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_20_MISS_FLOW_ENTRY_OVS = new DefaultFlowEntry(TABLE_20_MISS_OVS);
+
+    private static final TrafficSelector TABLE_20_IPV4_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(UP_PORT)
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(DEFAULT_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_20_IPV4_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.UNICAST_ROUTING_TABLE)
+            .build();
+    private static final FlowRule TABLE_20_IPV4_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.TMAC_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_20_IPV4_FLOW_SELECTOR)
+            .withTreatment(TABLE_20_IPV4_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_20_IPV4_FLOW_ENTRY = new DefaultFlowEntry(TABLE_20_IPV4_FLOW);
+
+    private static final TrafficSelector TABLE_20_IPV4_FLOW_SELECTOR_1 = DefaultTrafficSelector.builder()
+            .matchInPort(PORT)
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(HOST_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_20_IPV4_FLOW_TREATMENT_1 = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.UNICAST_ROUTING_TABLE)
+            .build();
+    private static final FlowRule TABLE_20_IPV4_FLOW_1 = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.TMAC_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_20_IPV4_FLOW_SELECTOR_1)
+            .withTreatment(TABLE_20_IPV4_FLOW_TREATMENT_1)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_20_IPV4_FLOW_ENTRY_1 = new DefaultFlowEntry(TABLE_20_IPV4_FLOW_1);
+
+    private static final TrafficSelector TABLE_20_MPLS_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(UP_PORT)
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchVlanId(DEFAULT_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_20_MPLS_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.MPLS_TABLE_0)
+            .build();
+    private static final FlowRule TABLE_20_MPLS_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.TMAC_TABLE)
+            .withPriority(32768)
+            .withSelector(TABLE_20_MPLS_FLOW_SELECTOR)
+            .withTreatment(TABLE_20_MPLS_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_20_MPLS_FLOW_ENTRY = new DefaultFlowEntry(TABLE_20_MPLS_FLOW);
+
+    private static final TrafficTreatment TABLE_23_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.MPLS_TABLE_1)
+            .build();
+    private static final FlowRule TABLE_23_MISS_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.MPLS_TABLE_0)
+            .withPriority(0)
+            .withSelector(EMPTY_SELECTOR)
+            .withTreatment(TABLE_23_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_23_MISS_FLOW_ENTRY_OVS = new DefaultFlowEntry(TABLE_23_MISS_OVS);
+
+    private static final TrafficSelector TABLE_24_MPLS_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .build();
+    private static final TrafficTreatment TABLE_24_MPLS_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.ACL_TABLE)
+            .deferred()
+            .popMpls(IPV4.ethType())
+            .decMplsTtl()
+            .group(MPLS_ECMP_GROUP_ID)
+            .build();
+    private static final FlowRule TABLE_24_MPLS_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.MPLS_TABLE_1)
+            .withPriority(100)
+            .withSelector(TABLE_24_MPLS_FLOW_SELECTOR)
+            .withTreatment(TABLE_24_MPLS_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_24_MPLS_FLOW_ENTRY = new DefaultFlowEntry(TABLE_24_MPLS_FLOW);
+
+    private static final TrafficTreatment TABLE_24_MPLS_FLOW_TREATMENT_OFDPA = DefaultTrafficTreatment.builder()
+            .transition(OfdpaPipelineUtility.MPLS_L3_TYPE_TABLE)
+            .copyTtlIn()
+            .decMplsTtl()
+            .extension(new Ofdpa3SetMplsType(Ofdpa3MplsType.L3_PHP), OFDPA_DEVICE)
+            .deferred()
+            .group(MPLS_ECMP_GROUP_ID)
+            .build();
+    private static final FlowRule TABLE_24_MPLS_FLOW_OFDPA = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.MPLS_TABLE_1)
+            .withPriority(100)
+            .withSelector(TABLE_24_MPLS_FLOW_SELECTOR)
+            .withTreatment(TABLE_24_MPLS_FLOW_TREATMENT_OFDPA)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_24_MPLS_FLOW_ENTRY_OFDPA = new DefaultFlowEntry(TABLE_24_MPLS_FLOW_OFDPA);
+
+    private static final TrafficSelector TABLE_30_UNI_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(IPV4.ethType().toShort())
+            .matchIPDst(IP_DST)
+            .build();
+    private static final TrafficTreatment TABLE_30_UNI_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .deferred()
+            .group(L3_UCAST_GROUP_ID)
+            .transition(OfdpaPipelineUtility.ACL_TABLE)
+            .build();
+    private static final FlowRule TABLE_30_UNI_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.UNICAST_ROUTING_TABLE)
+            .withPriority(64010)
+            .withSelector(TABLE_30_UNI_FLOW_SELECTOR)
+            .withTreatment(TABLE_30_UNI_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_30_UNI_FLOW_ENTRY = new DefaultFlowEntry(TABLE_30_UNI_FLOW);
+
+    private static final TrafficSelector TABLE_30_ECMP_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(IPV4.ethType().toShort())
+            .matchIPDst(PREFIX_DST)
+            .build();
+    private static final TrafficTreatment TABLE_30_ECMP_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .deferred()
+            .group(L3_ECMP_GROUP_ID)
+            .transition(OfdpaPipelineUtility.ACL_TABLE)
+            .build();
+    private static final FlowRule TABLE_30_ECMP_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.UNICAST_ROUTING_TABLE)
+            .withPriority(48010)
+            .withSelector(TABLE_30_ECMP_FLOW_SELECTOR)
+            .withTreatment(TABLE_30_ECMP_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_30_ECMP_FLOW_ENTRY = new DefaultFlowEntry(TABLE_30_ECMP_FLOW);
+
+    private static final TrafficSelector TABLE_50_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchVlanId(HOST_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_50_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .deferred()
+            .group(L2_FLOOD_GROUP_ID)
+            .transition(OfdpaPipelineUtility.ACL_TABLE)
+            .build();
+    private static final FlowRule TABLE_50_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.BRIDGING_TABLE)
+            .withPriority(5)
+            .withSelector(TABLE_50_FLOW_SELECTOR)
+            .withTreatment(TABLE_50_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_50_FLOW_ENTRY = new DefaultFlowEntry(TABLE_50_FLOW);
+
+    private static final TrafficSelector TABLE_50_FLOW_SELECTOR_BRIDG = DefaultTrafficSelector.builder()
+            .matchVlanId(HOST_VLAN)
+            .matchEthDst(HOST_MAC)
+            .build();
+    private static final TrafficTreatment TABLE_50_FLOW_TREATMENT_BRIDG = DefaultTrafficTreatment.builder()
+            .deferred()
+            .group(L2_IFACE_GROUP_ID)
+            .transition(OfdpaPipelineUtility.ACL_TABLE)
+            .build();
+    private static final FlowRule TABLE_50_FLOW_BRIDG = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.BRIDGING_TABLE)
+            .withPriority(100)
+            .withSelector(TABLE_50_FLOW_SELECTOR_BRIDG)
+            .withTreatment(TABLE_50_FLOW_TREATMENT_BRIDG)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_50_FLOW_ENTRY_BRIDG = new DefaultFlowEntry(TABLE_50_FLOW_BRIDG);
+
+    private static final TrafficSelector TABLE_60_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchEthType(IPV4.ethType().toShort())
+            .matchIPDst(IP_PUNT)
+            .build();
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_OVS = DefaultTrafficTreatment.builder()
+            .wipeDeferred()
+            .transition(OvsOfdpaPipeline.PUNT_TABLE)
+            .build();
+    private static final FlowRule TABLE_60_FLOW_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(40000)
+            .withSelector(TABLE_60_FLOW_SELECTOR)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_OVS)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY = new DefaultFlowEntry(TABLE_60_FLOW_OVS);
+
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_OFDPA = DefaultTrafficTreatment.builder()
+            .wipeDeferred()
+            .punt()
+            .build();
+    private static final FlowRule TABLE_60_FLOW_OFDPA = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(40000)
+            .withSelector(TABLE_60_FLOW_SELECTOR)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_OFDPA)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY_OFDPA = new DefaultFlowEntry(TABLE_60_FLOW_OFDPA);
+
+    private static final FlowRule TABLE_60_MISS_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(0)
+            .withSelector(EMPTY_SELECTOR)
+            .withTreatment(EMPTY_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_MISS_FLOW_ENTRY_OVS = new DefaultFlowEntry(TABLE_60_MISS_OVS);
+
+    private static final TrafficSelector TABLE_60_FLOW_SELECTOR_ARP = DefaultTrafficSelector.builder()
+            .matchEthType(ARP.ethType().toShort())
+            .build();
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_ARP_OVS = DefaultTrafficTreatment.builder()
+            .transition(OvsOfdpaPipeline.PUNT_TABLE)
+            .build();
+    private static final FlowRule TABLE_60_FLOW_ARP_OVS = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(30000)
+            .withSelector(TABLE_60_FLOW_SELECTOR_ARP)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_ARP_OVS)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY_ARP_OVS = new DefaultFlowEntry(TABLE_60_FLOW_ARP_OVS);
+
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_ARP_OFDPA = DefaultTrafficTreatment.builder()
+            .punt()
+            .build();
+    private static final FlowRule TABLE_60_FLOW_ARP_OFDPA = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(30000)
+            .withSelector(TABLE_60_FLOW_SELECTOR_ARP)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_ARP_OFDPA)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY_ARP_OFDPA = new DefaultFlowEntry(TABLE_60_FLOW_ARP_OFDPA);
+
+    private static final TrafficSelector TABLE_60_FLOW_SELECTOR_LLDP = DefaultTrafficSelector.builder()
+            .matchEthType(LLDP.ethType().toShort())
+            .build();
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_LLDP = DefaultTrafficTreatment.builder()
+            .wipeDeferred()
+            .transition(OvsOfdpaPipeline.PUNT_TABLE)
+            .build();
+    private static final FlowRule TABLE_60_FLOW_LLDP = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(40000)
+            .withSelector(TABLE_60_FLOW_SELECTOR_LLDP)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_LLDP)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY_LLDP = new DefaultFlowEntry(TABLE_60_FLOW_LLDP);
+
+    private static final TrafficTreatment TABLE_60_FLOW_TREATMENT_LLDP_OFDPA = DefaultTrafficTreatment.builder()
+            .wipeDeferred()
+            .punt()
+            .build();
+    private static final FlowRule TABLE_60_FLOW_LLDP_OFDPA = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OfdpaPipelineUtility.ACL_TABLE)
+            .withPriority(40000)
+            .withSelector(TABLE_60_FLOW_SELECTOR_LLDP)
+            .withTreatment(TABLE_60_FLOW_TREATMENT_LLDP_OFDPA)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_60_FLOW_ENTRY_LLDP_OFDPA = new DefaultFlowEntry(TABLE_60_FLOW_LLDP_OFDPA);
+
+    private static final TrafficSelector TABLE_63_FLOW_SELECTOR = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchVlanId(HOST_VLAN)
+            .build();
+    private static final TrafficTreatment TABLE_63_FLOW_TREATMENT = DefaultTrafficTreatment.builder()
+            .group(GroupId.valueOf(OvsOfdpaPipeline.POP_VLAN_PUNT_GROUP_ID))
+            .build();
+    private static final FlowRule TABLE_63_FLOW = DefaultFlowEntry.builder().forDevice(OFDPA_DEVICE)
+            .forTable(OvsOfdpaPipeline.PUNT_TABLE)
+            .withPriority(40000)
+            .withSelector(TABLE_63_FLOW_SELECTOR)
+            .withTreatment(TABLE_63_FLOW_TREATMENT)
+            .fromApp(new DefaultApplicationId(0, "TestApp"))
+            .makePermanent()
+            .build();
+    private static final FlowEntry TABLE_63_FLOW_ENTRY = new DefaultFlowEntry(TABLE_63_FLOW);
+
+    // Represents the device state
+    public static List<DataPlaneEntity> getDataPlaneEntities(String driverName, TraceableTest test) {
+        List<FlowEntry> flowRules = ImmutableList.of();
+        List<Group> groups = ImmutableList.of();
+        // Flow and groups by device
+        if (driverName.equals(OFDPA_DRIVER)) {
+            flowRules = ImmutableList.of(
+                    // Vlan 1 table
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2, TABLE_10_DEFAULT_FLOW_ENTRY_1,
+                    TABLE_10_DEFAULT_FLOW_ENTRY_2,
+                    // TMAC table
+                    TABLE_20_IPV4_FLOW_ENTRY, TABLE_20_IPV4_FLOW_ENTRY_1, TABLE_20_MPLS_FLOW_ENTRY,
+                    // MPLS 1 table
+                    TABLE_24_MPLS_FLOW_ENTRY_OFDPA,
+                    // Unicast table
+                    TABLE_30_UNI_FLOW_ENTRY, TABLE_30_ECMP_FLOW_ENTRY,
+                    // Bridging table
+                    TABLE_50_FLOW_ENTRY, TABLE_50_FLOW_ENTRY_BRIDG,
+                    // ACL table
+                    TABLE_60_FLOW_ENTRY_OFDPA, TABLE_60_FLOW_ENTRY_ARP_OFDPA, TABLE_60_FLOW_ENTRY_LLDP_OFDPA);
+            groups = Lists.newArrayList(
+                    // L3 ECMP groups
+                    L3_ECMP_OFDPA_GROUP,
+                    // MPLS ECMP groups
+                    MPLS_ECMP_GROUP,
+                    // L3 groups
+                    L3_UCAST_GROUP, L3_UCAST_GROUP_1,
+                    // MPLS L3 VPN groups
+                    MPLS_L3VPN_OFDPA_GROUP, MPLS_L3VPN_OFDPA_GROUP_1,
+                    // MPLS iface groups
+                    MPLS_IFACE_GROUP, MPLS_IFACE_GROUP_1,
+                    // L2 groups
+                    L2_FLOOD_GROUP,
+                    L2_IFACE_GROUP, L2_IFACE_GROUP_1, L2_IFACE_GROUP_2, L2_IFACE_GROUP_3);
+        } else if (driverName.equals(OVS_OFDPA_DRIVER)) {
+            flowRules = ImmutableList.of(
+                    // Port table
+                    TABLE_0_MISS_FLOW_ENTRY_OVS,
+                    // Vlan 1 table
+                    TABLE_10_FLOW_ENTRY, TABLE_10_DEFAULT_FLOW_ENTRY,
+                    // TMAC table
+                    TABLE_20_MISS_FLOW_ENTRY_OVS, TABLE_20_IPV4_FLOW_ENTRY, TABLE_20_IPV4_FLOW_ENTRY_1,
+                    TABLE_20_MPLS_FLOW_ENTRY,
+                    // MPLS 0 table
+                    TABLE_23_MISS_FLOW_ENTRY_OVS,
+                    // MPLS 1 table
+                    TABLE_24_MPLS_FLOW_ENTRY,
+                    // Unicast table
+                    TABLE_30_UNI_FLOW_ENTRY, TABLE_30_ECMP_FLOW_ENTRY,
+                    // Bridging table
+                    TABLE_50_FLOW_ENTRY, TABLE_50_FLOW_ENTRY_BRIDG,
+                    // ACL table
+                    TABLE_60_MISS_FLOW_ENTRY_OVS, TABLE_60_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OVS,
+                    TABLE_60_FLOW_ENTRY_LLDP,
+                    // Punt table
+                    TABLE_63_FLOW_ENTRY);
+            groups = Lists.newArrayList(
+                    // Punt groups
+                    PUNT_GROUP,
+                    // L3 ECMP groups
+                    L3_ECMP_GROUP,
+                    // MPLS ECMP groups
+                    MPLS_ECMP_GROUP,
+                    // L3 groups
+                    L3_UCAST_GROUP, L3_UCAST_GROUP_1,
+                    // MPLS L3 VPN groups
+                    MPLS_L3VPN_GROUP, MPLS_L3VPN_GROUP_1,
+                    // MPLS iface groups
+                    MPLS_IFACE_GROUP, MPLS_IFACE_GROUP_1,
+                    // L2 groups
+                    L2_FLOOD_GROUP,
+                    L2_IFACE_GROUP, L2_IFACE_GROUP_1, L2_IFACE_GROUP_2, L2_IFACE_GROUP_3);
+        }
+        // Inject failure scenarios
+        if (test.equals(L2_BROAD_EMPTY_OFDPA) || test.equals(L2_BROAD_EMPTY_OVS_OFDPA)) {
+            groups.remove(L2_FLOOD_GROUP);
+            groups.add(L2_FLOOD_EMPTY_GROUP);
+        } else if (test.equals(L2_BRIDG_NOT_ORDERED_OFDPA) || test.equals(L2_BRIDG_NOT_ORDERED_OVS_OFDPA)) {
+            groups.remove(L2_IFACE_GROUP);
+            groups.add(L2_IFACE_GROUP_NOT_ORDERED);
+        }
+        List<DataPlaneEntity> dataPlaneEntities = Lists.newArrayList();
+        flowRules.forEach(flowRule -> dataPlaneEntities.add(new DataPlaneEntity(flowRule)));
+        groups.forEach(group -> dataPlaneEntities.add(new DataPlaneEntity(group)));
+        return dataPlaneEntities;
+    }
+
+    // Returns the expected hit chains (order matters!)
+    public static List<List<DataPlaneEntity>> getHitChains(TraceableTest test) {
+        List<List<FlowEntry>> flowRules = Lists.newArrayList();
+        List<List<Group>> groups = Lists.newArrayList();
+        // Flows and groups by test
+        if (test.equals(PUNT_IP_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY));
+        } else if (test.equals(PUNT_IP_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY, TABLE_63_FLOW_ENTRY));
+            groups.add(ImmutableList.of(PUNT_GROUP));
+        } else if (test.equals(ARP_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OFDPA));
+            groups.add(ImmutableList.of());
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OFDPA));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP));
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OFDPA));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP_1));
+        } else if (test.equals(ARP_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OVS, TABLE_63_FLOW_ENTRY));
+            groups.add(ImmutableList.of(PUNT_GROUP));
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OVS, TABLE_63_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP));
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_ARP_OVS, TABLE_63_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP_1));
+        } else if (test.equals(PUNT_LLDP_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_LLDP_OFDPA));
+        } else if (test.equals(PUNT_LLDP_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_FLOW_ENTRY_LLDP, TABLE_63_FLOW_ENTRY));
+            groups.add(ImmutableList.of(PUNT_GROUP));
+        } else if (test.equals(L2_BRIDG_UNTAG_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY_BRIDG));
+            groups.add(ImmutableList.of(L2_IFACE_GROUP));
+        } else if (test.equals(L2_BRIDG_UNTAG_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY_BRIDG, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L2_IFACE_GROUP));
+        } else if (test.equals(L2_BROAD_UNTAG_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP));
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP_1));
+        } else if (test.equals(L2_BROAD_UNTAG_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP));
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L2_FLOOD_GROUP, L2_IFACE_GROUP_1));
+        } else if (test.equals(L3_UCAST_UNTAG_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_DEFAULT_FLOW_ENTRY_1, TABLE_10_DEFAULT_FLOW_ENTRY_2, TABLE_20_IPV4_FLOW_ENTRY,
+                    TABLE_30_UNI_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L3_UCAST_GROUP, L2_IFACE_GROUP));
+        } else if (test.equals(L3_UCAST_UNTAG_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_DEFAULT_FLOW_ENTRY, TABLE_20_IPV4_FLOW_ENTRY,
+                    TABLE_30_UNI_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L3_UCAST_GROUP, L2_IFACE_GROUP));
+        } else if (test.equals(L3_ECMP_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_IPV4_FLOW_ENTRY_1,
+                    TABLE_30_ECMP_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L3_ECMP_GROUP, MPLS_L3VPN_GROUP, MPLS_IFACE_GROUP, L2_IFACE_GROUP_2));
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_IPV4_FLOW_ENTRY_1,
+                    TABLE_30_ECMP_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L3_ECMP_GROUP, MPLS_L3VPN_GROUP_1, MPLS_IFACE_GROUP_1, L2_IFACE_GROUP_3));
+        } else if (test.equals(L3_ECMP_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2, TABLE_20_IPV4_FLOW_ENTRY_1,
+                    TABLE_30_ECMP_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L3_ECMP_OFDPA_GROUP, MPLS_L3VPN_OFDPA_GROUP, MPLS_IFACE_GROUP,
+                    L2_IFACE_GROUP_2));
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2, TABLE_20_IPV4_FLOW_ENTRY_1,
+                    TABLE_30_ECMP_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L3_ECMP_OFDPA_GROUP, MPLS_L3VPN_OFDPA_GROUP_1, MPLS_IFACE_GROUP_1,
+                    L2_IFACE_GROUP_3));
+        } else if (test.equals(MPLS_ECMP_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_DEFAULT_FLOW_ENTRY, TABLE_20_MPLS_FLOW_ENTRY,
+                    TABLE_23_MISS_FLOW_ENTRY_OVS, TABLE_24_MPLS_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(MPLS_ECMP_GROUP, L3_UCAST_GROUP_1, L2_IFACE_GROUP_3));
+        } else if (test.equals(MPLS_ECMP_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_DEFAULT_FLOW_ENTRY_1, TABLE_10_DEFAULT_FLOW_ENTRY_2, TABLE_20_MPLS_FLOW_ENTRY,
+                    TABLE_24_MPLS_FLOW_ENTRY_OFDPA));
+            groups.add(ImmutableList.of(MPLS_ECMP_GROUP, L3_UCAST_GROUP_1, L2_IFACE_GROUP_3));
+        } else if (test.equals(L2_BROAD_EMPTY_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY));
+            groups.add(ImmutableList.of(L2_FLOOD_EMPTY_GROUP));
+        } else if (test.equals(L2_BROAD_EMPTY_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L2_FLOOD_EMPTY_GROUP));
+        } else if (test.equals(L2_BRIDG_NOT_ORDERED_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_10_FLOW_ENTRY_1, TABLE_10_FLOW_ENTRY_2,
+                    TABLE_50_FLOW_ENTRY_BRIDG));
+            groups.add(ImmutableList.of(L2_IFACE_GROUP_NOT_ORDERED));
+        } else if (test.equals(L2_BRIDG_NOT_ORDERED_OVS_OFDPA)) {
+            flowRules.add(ImmutableList.of(
+                    TABLE_0_MISS_FLOW_ENTRY_OVS, TABLE_10_FLOW_ENTRY, TABLE_20_MISS_FLOW_ENTRY_OVS,
+                    TABLE_50_FLOW_ENTRY_BRIDG, TABLE_60_MISS_FLOW_ENTRY_OVS));
+            groups.add(ImmutableList.of(L2_IFACE_GROUP_NOT_ORDERED));
+        }
+        List<List<DataPlaneEntity>> chains = Lists.newArrayList();
+        List<DataPlaneEntity> dataPlaneEntities = Lists.newArrayList();
+        int end = Math.max(flowRules.size(), groups.size());
+        int i = 0;
+        while (i < end) {
+            if (i < flowRules.size()) {
+                flowRules.get(i).forEach(flowRule -> dataPlaneEntities.add(new DataPlaneEntity(flowRule)));
+            }
+            if (i < groups.size()) {
+                groups.get(i).forEach(group -> dataPlaneEntities.add(new DataPlaneEntity(group)));
+            }
+            chains.add(ImmutableList.copyOf(dataPlaneEntities));
+            dataPlaneEntities.clear();
+            i = i + 1;
+        }
+        return chains;
+    }
+
+}
diff --git a/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableTestObjects.java b/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableTestObjects.java
new file mode 100644
index 0000000..4ea803c
--- /dev/null
+++ b/drivers/default/src/test/java/org/onosproject/driver/traceable/TraceableTestObjects.java
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2020-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.driver.traceable;
+
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.MplsLabel;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.driver.DriverAdapter;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+
+import static org.onlab.packet.EthType.EtherType.IPV4;
+import static org.onlab.packet.EthType.EtherType.MPLS_UNICAST;
+
+/**
+ * Helper class for objects related to the Traceable tests.
+ */
+final class TraceableTestObjects {
+
+    private TraceableTestObjects() {
+        // Banning construction
+    }
+
+    // Test drivers name
+    static final String OFDPA_DRIVER = "ofdpa";
+    static final String OVS_OFDPA_DRIVER = "ofdpa-ovs";
+
+    // Test device ids
+    static final DeviceId OFDPA_DEVICE = DeviceId.deviceId("ofdpaDevice");
+
+    // Input ports
+    static final PortNumber PORT = PortNumber.portNumber("1");
+    static final PortNumber OUT_PORT = PortNumber.portNumber("3");
+    static final PortNumber UP_PORT = PortNumber.portNumber("10");
+    static final PortNumber UP_PORT_1 = PortNumber.portNumber("11");
+    static final ConnectPoint OFDPA_CP = ConnectPoint.deviceConnectPoint(OFDPA_DEVICE + "/" + PORT.toLong());
+    static final ConnectPoint UP_OFDPA_CP = ConnectPoint.deviceConnectPoint(OFDPA_DEVICE + "/" + UP_PORT.toLong());
+
+    // Misc
+    static final VlanId HOST_VLAN = VlanId.vlanId((short) 100);
+    static final VlanId DEFAULT_VLAN = VlanId.vlanId((short) 4094);
+    static final IpPrefix IP_PUNT = IpPrefix.valueOf("10.0.2.254/32");
+    static final MacAddress HOST_MAC = MacAddress.valueOf("00:AA:00:00:00:02");
+    static final IpPrefix IP_DST = IpPrefix.valueOf("10.0.2.2/32");
+    static final IpPrefix IP_DST_1 = IpPrefix.valueOf("10.0.3.1/32");
+    static final MacAddress LEAF_MAC = MacAddress.valueOf("00:00:00:00:02:04");
+    static final IpPrefix PREFIX_DST = IpPrefix.valueOf("10.0.3.0/24");
+    static final MacAddress SPINE_MAC = MacAddress.valueOf("00:00:00:00:02:26");
+    static final MacAddress SPINE_MAC_1 = MacAddress.valueOf("00:00:00:00:02:26");
+    static final MplsLabel MPLS_LABEL = MplsLabel.mplsLabel(205);
+
+    // Input packets
+    static final TrafficSelector IN_PUNT_IP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_PUNT)
+            .build();
+
+    static final TrafficSelector IN_ARP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchIPDst(IpPrefix.valueOf("255.255.255.255/32"))
+            .matchEthType(EthType.EtherType.ARP.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .build();
+
+    static final TrafficSelector IN_PUNT_LLDP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchEthType(EthType.EtherType.LLDP.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .build();
+
+    static final TrafficSelector IN_L2_BRIDG_UNTAG_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchEthDst(HOST_MAC)
+            .build();
+
+    static final TrafficSelector IN_L2_BROAD_UNTAG_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchVlanId(VlanId.NONE)
+            .build();
+
+    static final TrafficSelector IN_L3_UCAST_UNTAG_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(UP_OFDPA_CP.port())
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_DST)
+            .build();
+
+    static final TrafficSelector IN_L3_ECMP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_DST_1)
+            .build();
+
+    static final TrafficSelector IN_MPLS_ECMP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(UP_OFDPA_CP.port())
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_DST_1)
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .build();
+
+    static final TrafficSelector IN_MPLS_ECMP_PACKET_OFDPA = DefaultTrafficSelector.builder()
+            .matchInPort(UP_OFDPA_CP.port())
+            .matchEthDst(LEAF_MAC)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_DST_1)
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .matchMetadata(IPV4.ethType().toShort())
+            .build();
+
+    // Egress packets
+    static final TrafficSelector OUT_L3_UCAST_UNTAG_PACKET = DefaultTrafficSelector.builder(IN_L3_UCAST_UNTAG_PACKET)
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(HOST_MAC)
+            .build();
+
+    static final TrafficSelector OUT_L3_ECMP_PACKET = DefaultTrafficSelector.builder(IN_L3_ECMP_PACKET)
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(SPINE_MAC)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .build();
+
+    static final TrafficSelector OUT_L3_ECMP_PACKET_1 = DefaultTrafficSelector.builder(IN_L3_ECMP_PACKET)
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(SPINE_MAC_1)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .build();
+
+    static final TrafficSelector OUT_L3_ECMP_PACKET_OFDPA = DefaultTrafficSelector.builder(IN_L3_ECMP_PACKET)
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(SPINE_MAC)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .matchMetadata(IPV4.ethType().toShort())
+            .build();
+
+    static final TrafficSelector OUT_L3_ECMP_PACKET_OFDPA_1 = DefaultTrafficSelector.builder(IN_L3_ECMP_PACKET)
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(SPINE_MAC_1)
+            .matchEthType(MPLS_UNICAST.ethType().toShort())
+            .matchMplsLabel(MPLS_LABEL)
+            .matchMplsBos(true)
+            .matchMetadata(IPV4.ethType().toShort())
+            .build();
+
+    static final TrafficSelector OUT_MPLS_ECMP_PACKET = DefaultTrafficSelector.builder()
+            .matchInPort(UP_OFDPA_CP.port())
+            .matchEthSrc(LEAF_MAC)
+            .matchEthDst(SPINE_MAC)
+            .matchEthType(IPV4.ethType().toShort())
+            .matchVlanId(VlanId.NONE)
+            .matchIPDst(IP_DST_1)
+            .build();
+
+    static final TrafficSelector OUT_L2_BROAD_EMPTY = DefaultTrafficSelector.builder()
+            .matchInPort(OFDPA_CP.port())
+            .matchVlanId(HOST_VLAN)
+            .build();
+
+    // Test cases
+    enum TraceableTest {
+        PUNT_IP_OFDPA,
+        PUNT_IP_OVS_OFDPA,
+        ARP_OFDPA,
+        ARP_OVS_OFDPA,
+        PUNT_LLDP_OFDPA,
+        PUNT_LLDP_OVS_OFDPA,
+        L2_BRIDG_UNTAG_OFDPA,
+        L2_BRIDG_UNTAG_OVS_OFDPA,
+        L2_BROAD_UNTAG_OFDPA,
+        L2_BROAD_UNTAG_OVS_OFDPA,
+        L3_UCAST_UNTAG_OFDPA,
+        L3_UCAST_UNTAG_OVS_OFDPA,
+        L3_ECMP_OFDPA,
+        L3_ECMP_OVS_OFDPA,
+        MPLS_ECMP_OFDPA,
+        MPLS_ECMP_OVS_OFDPA,
+        L2_BROAD_EMPTY_OFDPA,
+        L2_BROAD_EMPTY_OVS_OFDPA,
+        L2_BRIDG_NOT_ORDERED_OFDPA,
+        L2_BRIDG_NOT_ORDERED_OVS_OFDPA,
+    }
+
+    // Test driver class
+    static class TestDriver extends DriverAdapter {
+
+        private String name;
+
+        public TestDriver(String name) {
+            this.name = name;
+        }
+
+        @Override
+        public String name() {
+            return name;
+        }
+
+    }
+}
