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
