diff --git a/core/api/src/main/java/org/onosproject/net/DataPlaneEntity.java b/core/api/src/main/java/org/onosproject/net/DataPlaneEntity.java
new file mode 100644
index 0000000..0c4628c
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/DataPlaneEntity.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2017-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.net;
+
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.group.Group;
+
+import java.util.Objects;
+
+/**
+ * Generic abstraction to hold dataplane entities.
+ */
+public class DataPlaneEntity {
+    private FlowEntry flowEntry;
+    private Group groupEntry;
+    private Type type;
+
+    /**
+     * Types of entity.
+     */
+    public enum Type {
+        /**
+         * Flow rule entity.
+         */
+        FLOWRULE,
+
+        /**
+         * Group entity.
+         */
+        GROUP
+    }
+
+    /**
+     * Creates a dataplane entity from a flow entry.
+     *
+     * @param flow the inner flow entry
+     */
+    public DataPlaneEntity(FlowEntry flow) {
+        flowEntry = flow;
+        type = Type.FLOWRULE;
+    }
+
+    /**
+     * Creates a dataplane entity from a group entry.
+     *
+     * @param group the inner group entry
+     */
+    public DataPlaneEntity(Group group) {
+        groupEntry = group;
+        type = Type.GROUP;
+    }
+
+    /**
+     * Returns the flow entry.
+     *
+     * @return the flow entry
+     */
+    public FlowEntry getFlowEntry() {
+        return flowEntry;
+    }
+
+    /**
+     * Returns the group entry.
+     *
+     * @return the group entry
+     */
+    public Group getGroupEntry() {
+        return groupEntry;
+    }
+
+    /**
+     * Returns the type of the entry.
+     *
+     * @return the type
+     */
+    public Type getType() {
+        return type;
+    }
+
+    @Override
+    public int hashCode() {
+        return type == Type.FLOWRULE ? flowEntry.hashCode() : groupEntry.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof DataPlaneEntity) {
+            DataPlaneEntity that = (DataPlaneEntity) obj;
+            if (this.type == that.type) {
+                return Objects.equals(flowEntry, that.flowEntry) &&
+                        Objects.equals(groupEntry, that.groupEntry);
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        Object entity = type == Type.FLOWRULE ? flowEntry : groupEntry;
+        return "DataPlaneEntity{" +
+                "entity=" + entity +
+                '}';
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/PipelineTraceableHitChain.java b/core/api/src/main/java/org/onosproject/net/PipelineTraceableHitChain.java
new file mode 100644
index 0000000..4eb26b5
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/PipelineTraceableHitChain.java
@@ -0,0 +1,183 @@
+/*
+ * 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.net;
+
+import com.google.common.collect.Lists;
+import org.onosproject.net.flow.TrafficSelector;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Class to represent the pipeline hit chain and the result of the pipeline processing.
+ */
+public class PipelineTraceableHitChain {
+
+    private ConnectPoint outputPort;
+    private List<DataPlaneEntity> hitChain;
+    private TrafficSelector egressPacket;
+    // By default packets are dropped
+    private boolean dropped = true;
+
+    private PipelineTraceableHitChain() {
+        hitChain = Lists.newArrayList();
+    }
+
+    /**
+     * Creates a new PipelineTraceableHitChain.
+     *
+     * @param output   the output connect point
+     * @param hits     the hits in the pipeline (flows, groups and other abstractions)
+     * @param packet   the selector representing the final packet
+     */
+    public PipelineTraceableHitChain(ConnectPoint output, List<DataPlaneEntity> hits,
+                                     TrafficSelector packet) {
+        this.outputPort = output;
+        this.hitChain = hits;
+        this.egressPacket = packet;
+    }
+
+    /**
+     * Creates an empty pipeline hit chain.
+     *
+     * @return an empty pipeline hit chain
+     */
+    public static PipelineTraceableHitChain emptyHitChain() {
+        return new PipelineTraceableHitChain();
+    }
+
+    /**
+     * Returns the output connect point.
+     *
+     * @return the connect point
+     */
+    public ConnectPoint getOutputPort() {
+        return outputPort;
+    }
+
+    /**
+     * Sets the output port.
+     *
+     * @param outputPort the output port
+     */
+    public void setOutputPort(ConnectPoint outputPort) {
+        this.outputPort = outputPort;
+    }
+
+    /**
+     * Returns the hit chain.
+     *
+     * @return flows and groups that matched.
+     */
+    public List<DataPlaneEntity> getHitChain() {
+        return hitChain;
+    }
+
+    /**
+     * Adds the provided dataplane entity to the end of the chain.
+     *
+     * @param dataPlaneEntity the dataplane entity
+     */
+    public void addDataPlaneEntity(DataPlaneEntity dataPlaneEntity) {
+        if (!hitChain.contains(dataPlaneEntity)) {
+            hitChain.add(dataPlaneEntity);
+        }
+    }
+
+    /**
+     * Removes the provided dataplane entity from the chain.
+     *
+     * @param dataPlaneEntity the dataplane entity
+     */
+    public void removeDataPlaneEntity(DataPlaneEntity dataPlaneEntity) {
+        if (hitChain.isEmpty()) {
+            return;
+        }
+        hitChain.remove(dataPlaneEntity);
+    }
+
+    /**
+     * Returns the egress packet after traversing the pipeline.
+     *
+     * @return the selector representing the packet infos
+     */
+    public TrafficSelector getEgressPacket() {
+        return egressPacket;
+    }
+
+    /**
+     * Sets the egress packet.
+     *
+     * @param egressPacket the egress packet
+     */
+    public void setEgressPacket(TrafficSelector egressPacket) {
+        this.egressPacket = egressPacket;
+    }
+
+    /**
+     * Return whether or not the packet has been dropped by the pipeline.
+     *
+     * @return true if the packet has been dropped. False, otherwise.
+     */
+    public boolean isDropped() {
+        return dropped;
+    }
+
+    /**
+     * Set the dropped flag.
+     */
+    public void dropped() {
+        this.dropped = true;
+    }
+
+    /**
+     * Unset the dropped flag.
+     */
+    public void pass() {
+        this.dropped = false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(outputPort, hitChain, egressPacket, dropped);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof PipelineTraceableHitChain) {
+            PipelineTraceableHitChain that = (PipelineTraceableHitChain) obj;
+            return Objects.equals(this.outputPort, that.outputPort) &&
+                    Objects.equals(this.hitChain, that.getHitChain()) &&
+                    Objects.equals(this.egressPacket, that.egressPacket) &&
+                    Objects.equals(this.dropped, that.dropped);
+        }
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "PipelineTraceableHitChain{" +
+                "outputPort=" + outputPort +
+                ", hitChain=" + hitChain +
+                ", egressPacket=" + egressPacket +
+                ", dropped=" + dropped +
+                '}';
+    }
+}
diff --git a/core/api/src/main/java/org/onosproject/net/PipelineTraceableInput.java b/core/api/src/main/java/org/onosproject/net/PipelineTraceableInput.java
new file mode 100644
index 0000000..2403c5e
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/PipelineTraceableInput.java
@@ -0,0 +1,106 @@
+/*
+ * 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.net;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.group.Group;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Represents the input of the pipeline traceable processing.
+ */
+public class PipelineTraceableInput {
+
+    // Input state for the traceable behavior
+    TrafficSelector ingressPacket;
+    ConnectPoint ingressPort;
+    // List here all possible device state using
+    // possibly an optimized reference
+    List<FlowEntry> flows = Lists.newArrayList();
+    Map<GroupId, Group> groups = Maps.newHashMap();
+
+    public PipelineTraceableInput(TrafficSelector ingressPacket, ConnectPoint ingressPort,
+                                  List<DataPlaneEntity> deviceState) {
+        this.ingressPacket = ingressPacket;
+        this.ingressPort = ingressPort;
+        processDeviceState(deviceState);
+    }
+
+    // Init internal device state (flows, groups, etc)
+    private void processDeviceState(List<DataPlaneEntity> deviceState) {
+        deviceState.forEach(entity -> {
+            if (entity.getType() == DataPlaneEntity.Type.FLOWRULE) {
+                flows.add(entity.getFlowEntry());
+            } else if (entity.getType() == DataPlaneEntity.Type.GROUP) {
+                groups.put(entity.getGroupEntry().id(), entity.getGroupEntry());
+            }
+        });
+    }
+
+    /**
+     * Getter for the ingress packet.
+     *
+     * @return the ingress packet
+     */
+    public TrafficSelector ingressPacket() {
+        return ingressPacket;
+    }
+
+    /**
+     * Getter for the ingress port.
+     *
+     * @return the ingress port
+     */
+    public ConnectPoint ingressPort() {
+        return ingressPort;
+    }
+
+    /**
+     * Getter for the flows.
+     *
+     * @return the flows
+     */
+    public List<FlowEntry> flows() {
+        return flows;
+    }
+
+    /**
+     * Getter for the groups.
+     *
+     * @return the groups
+     */
+    public Map<GroupId, Group> groups() {
+        return groups;
+    }
+
+    /**
+     * Returns the group associated with the given group id.
+     *
+     * @param groupId the group id
+     * @return the group, otherwise null.
+     */
+    public Group getGroup(GroupId groupId) {
+        return groups.get(groupId);
+    }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/PipelineTraceableOutput.java b/core/api/src/main/java/org/onosproject/net/PipelineTraceableOutput.java
new file mode 100644
index 0000000..21a9819
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/PipelineTraceableOutput.java
@@ -0,0 +1,199 @@
+/*
+ * 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.net;
+
+import com.google.common.collect.Lists;
+
+import java.util.List;
+
+/**
+ * Represents the output of the pipeline traceable processing.
+ */
+public final class PipelineTraceableOutput {
+
+    /**
+     * Represents the result of the pipeline traceable processing.
+     */
+    public enum PipelineTraceableResult {
+        /**
+         * Means packet went through the pipeline.
+         */
+        SUCCESS,
+        /**
+         * Means packet stopped due to missing flows.
+         */
+        NO_FLOWS,
+        /**
+         * Means packet stopped due to missing groups.
+         */
+        NO_GROUPS,
+        /**
+         * Means packet stopped due to an empty group.
+         */
+        NO_GROUP_MEMBERS,
+        /**
+         * Means packet is dropped by the pipeline.
+         */
+        DROPPED
+    }
+
+    private String log;
+    private List<PipelineTraceableHitChain> hitChains;
+    private PipelineTraceableResult result;
+
+    /**
+     * Creates a new pipeline traceable output with the specified input.
+     *
+     * @param log the trace log
+     * @param hitChains the hit chains
+     * @param result the apply result
+     */
+    private PipelineTraceableOutput(String log, List<PipelineTraceableHitChain> hitChains,
+                                    PipelineTraceableResult result) {
+        this.log = log;
+        this.hitChains = hitChains;
+        this.result = result;
+    }
+
+    /**
+     * Returns the log message as string.
+     *
+     * @return the log message
+     */
+    public String getLog() {
+        return log;
+    }
+
+    /**
+     * Returns the hit chains.
+     *
+     * @return the pipeline hit chains
+     */
+    public List<PipelineTraceableHitChain> getHitChains() {
+        return hitChains;
+    }
+
+    /**
+     * Returns the result of the computation.
+     *
+     * @return the pipeline traceable result
+     */
+    public PipelineTraceableResult getResult() {
+        return result;
+    }
+
+    /**
+     * Returns a new builder.
+     *
+     * @return an empty builder
+     */
+    public static PipelineTraceableOutput.Builder builder() {
+        return new PipelineTraceableOutput.Builder();
+    }
+
+    /**
+     * Builder of pipeline traceable entities.
+     */
+    public static final class Builder {
+
+        private StringBuilder log = new StringBuilder();
+        private List<PipelineTraceableHitChain> hitChains = Lists.newArrayList();
+        private PipelineTraceableResult result = PipelineTraceableResult.SUCCESS;
+
+        /**
+         * Appends a message to the log.
+         *
+         * @param message the log message to be appended
+         * @return this builder
+         */
+        public Builder appendToLog(String message) {
+            if (log.length() != 0) {
+                log.append("\n");
+            }
+            log.append(message);
+            return this;
+        }
+
+        private Builder setResult(PipelineTraceableResult result) {
+            // Do not override original failure
+            if (this.result == PipelineTraceableResult.SUCCESS) {
+                this.result = result;
+            }
+            return this;
+        }
+
+        /**
+         * Sets no flows in the result.
+         *
+         * @return this builder
+         */
+        public Builder noFlows() {
+            return setResult(PipelineTraceableResult.NO_FLOWS);
+        }
+
+        /**
+         * Sets no groups in the result.
+         *
+         * @return this builder
+         */
+        public Builder noGroups() {
+            return setResult(PipelineTraceableResult.NO_GROUPS);
+        }
+
+        /**
+         * Sets no flows in the result.
+         *
+         * @return this builder
+         */
+        public Builder noMembers() {
+            return setResult(PipelineTraceableResult.NO_GROUP_MEMBERS);
+        }
+
+        /**
+         * Sets dropped in the result.
+         *
+         * @return this builder
+         */
+        public Builder dropped() {
+            return setResult(PipelineTraceableResult.DROPPED);
+        }
+
+        /**
+         * Stores the provided hit chain.
+         *
+         * @param hitChain the provided hit chain
+         * @return this builder
+         */
+        public Builder addHitChain(PipelineTraceableHitChain hitChain) {
+            if (!hitChains.contains(hitChain)) {
+                hitChains.add(hitChain);
+            }
+            return this;
+        }
+
+        /**
+         * Builds a new pipeline traceable output.
+         *
+         * @return a pipeline traceable object
+         */
+        public PipelineTraceableOutput build() {
+            return new PipelineTraceableOutput(log.toString(), hitChains, result);
+        }
+
+    }
+
+}
diff --git a/core/api/src/main/java/org/onosproject/net/behaviour/PipelineTraceable.java b/core/api/src/main/java/org/onosproject/net/behaviour/PipelineTraceable.java
new file mode 100644
index 0000000..eff59db
--- /dev/null
+++ b/core/api/src/main/java/org/onosproject/net/behaviour/PipelineTraceable.java
@@ -0,0 +1,41 @@
+/*
+ * 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.net.behaviour;
+
+import org.onosproject.net.PipelineTraceableInput;
+import org.onosproject.net.PipelineTraceableOutput;
+import org.onosproject.net.driver.HandlerBehaviour;
+
+/**
+ * Represents a driver behavior that enables a logical packet to trace existing flows and groups in a device.
+ */
+public interface PipelineTraceable extends HandlerBehaviour {
+
+    /**
+     * Initializes the traceable with a context required for its operation.
+     */
+    void init();
+
+    /**
+     * Applies pipeline processing on the given ingress state.
+     *
+     * @param input the input of the apply process
+     * @return the output of the apply process
+     */
+    PipelineTraceableOutput apply(PipelineTraceableInput input);
+
+}
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;
+        }
+
+    }
+}
