Drivers for HP3800 and HP3500, switches inter-operate correctly

Change-Id: I9c9d512db46939693c958a04cd112273a8e61a4c

Drivers for HP3800 and HP3500, switches inter-operate correctly

Change-Id: I9c9d512db46939693c958a04cd112273a8e61a4c
diff --git a/drivers/hp/src/main/java/org/onosproject/drivers/hp/AbstractHPPipeline.java b/drivers/hp/src/main/java/org/onosproject/drivers/hp/AbstractHPPipeline.java
index 16f92f2..51c4f7f 100644
--- a/drivers/hp/src/main/java/org/onosproject/drivers/hp/AbstractHPPipeline.java
+++ b/drivers/hp/src/main/java/org/onosproject/drivers/hp/AbstractHPPipeline.java
@@ -22,33 +22,35 @@
 import com.google.common.cache.RemovalNotification;
 import com.google.common.collect.ImmutableList;
 import org.onlab.osgi.ServiceDirectory;
-import org.onlab.packet.Ethernet;
 import org.onlab.util.KryoNamespace;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.net.Device;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.behaviour.NextGroup;
 import org.onosproject.net.behaviour.Pipeliner;
 import org.onosproject.net.behaviour.PipelinerContext;
 import org.onosproject.net.device.DeviceService;
 import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.FlowRuleOperations;
 import org.onosproject.net.flow.FlowRuleOperationsContext;
 import org.onosproject.net.flow.FlowRuleService;
 import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.DefaultFlowRule;
 import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.DefaultTrafficSelector;
 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.PortCriterion;
 import org.onosproject.net.flow.criteria.VlanIdCriterion;
 import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction;
+import org.onosproject.net.flow.instructions.L4ModificationInstruction;
 import org.onosproject.net.flowobjective.FilteringObjective;
 import org.onosproject.net.flowobjective.FlowObjectiveStore;
 import org.onosproject.net.flowobjective.ForwardingObjective;
@@ -56,28 +58,100 @@
 import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.group.DefaultGroupKey;
+import org.onosproject.net.group.Group;
 import org.onosproject.net.group.GroupKey;
 import org.onosproject.net.group.GroupService;
 import org.onosproject.net.meter.MeterService;
 import org.slf4j.Logger;
 
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
 import static org.onosproject.net.flow.FlowRule.Builder;
 import static org.onosproject.net.flowobjective.Objective.Operation.ADD;
 import static org.slf4j.LoggerFactory.getLogger;
 
-
 /**
  * Abstraction of the HP pipeline handler.
- * Possibly compliant with all HP OF switches but tested only with HP3800.
+ * Possibly compliant with all HP switches: tested with HP3800 (v2 module) and HP3500 (v1 module).
+ *
+ * These switches supports multiple OpenFlow instances.
+ * Each instance can be created with different pipeline models.
+ * This driver refers to OpenFlow instances created with "pipeline-model standard-match"
+ *
+ * With this model Table 100 is used for all entries that can be processed in hardware,
+ * whereas table 200 is used for entries processed in software.
+ *
+ * Trying to install a flow entries only supported in software in table 100 generates
+ * an OpenFlow error message from the switch.
+ *
+ * Installation of a flow entry supported in hardware in table 200 is allowed. But it strongly
+ * degrades forwarding performance.
+ *
+ * ---------------------------------------------
+ * --- SELECTION OF PROPER TABLE ID ---
+ * --- from device manual OpenFlow v1.3 for firmware 16.04 - (Appendix A)
+ * ---------------------------------------------
+ * --- Hardware differences between v1, v2 and v3 modules affect which features are supported
+ * in hardware/software. In this driver "TableIdForForwardingObjective()" function selects the
+ * proper table ID considering the hardware features of the device and the actual FlowObjective.
+ *
+ * ---------------------------------------------
+ * --- HPE switches support OpenFlow version 1.3.1 with following limitations.
+ * --- from device manual OpenFlow v1.3 for firmware 16.04 - (Appendix A)
+ *
+ *** UNSUPPORTED FLOW MATCHES --- (implemented using unsupported_criteria)
+ * ---------------------------------------------
+ * - METADATA - DONE
+ * - IP_ECN - DONE
+ * - SCTP_SRC, SCTP_DST - DONE
+ * - IPV6_ND_SLL, IPV6_ND_TLL - DONE
+ * - MPLS_LABEL, MPLS_TC, MPLS_BOS - DONE
+ * - PBB_ISID - DONE
+ * - TUNNEL_ID - DONE
+ * - IPV6_EXTHDR - DONE
+ *
+ *** UNSUPPORTED ACTIONS ---
+ * ---------------------------------------------
+ * - METADATA - DONE
+ * - QUEUE - DONE
+ * - OFPP_TABLE action - TODO
+ * - MPLS actions: Push-MPLS, Pop-MPLS, Set-MPLS TTL, Decrement MPLS TTL - DONE
+ * - Push-PBB, Pop-PBB actions - TODO
+ * - Copy TTL inwards/outwards actions - DONE
+ * - Decrement IP TTL - DONE
+ *
+ * ---------------------------------------------
+ * --- OTHER UNSUPPORTED FEATURES ---
+ * --- from device manual OpenFlow v1.3 for firmware 16.04
+ * ---------------------------------------------
+ * - Port commands: OFPPC_NO_STP, OFPPC_NO_RECV, OFPPC_NO_RECV_STP, OFPPC_NO_FWD - TODO
+ * - Handling of IP Fragments: OFPC_IP_REASM, OFPC_FRAG_REASM - TODO
+ *
+ * TODO MINOR: include above actions in the lists of unsupported features
+ *
+ * With current implementation, in case of unsupported features a WARNING message in generated
+ * in the ONOS log, but FlowRule is sent anyway to the device.
+ * The device will reply with an OFP_ERROR message.
+ * Use "debug openflow events" and "debug openflow errors" on the device to locally
+ * visualize detailed information on the specific error.
+ *
+ * TODO MAJOR: use OFP_TABLE_FEATURE messages to automate learning of unsupported features
+ *
  */
+
 public abstract class AbstractHPPipeline extends AbstractHandlerBehaviour implements Pipeliner {
 
-
     protected static final String APPLICATION_ID = "org.onosproject.drivers.hp.HPPipeline";
+
+    protected static final int HP_TABLE_ZERO = 0;
+    protected static final int HP_HARDWARE_TABLE = 100;
+    protected static final int HP_SOFTWARE_TABLE = 200;
+
     public static final int CACHE_ENTRY_EXPIRATION_PERIOD = 20;
+
     private final Logger log = getLogger(getClass());
     protected FlowRuleService flowRuleService;
     protected GroupService groupService;
@@ -86,6 +160,8 @@
     protected DeviceId deviceId;
     protected ApplicationId appId;
     protected DeviceService deviceService;
+    protected Device device;
+    protected String deviceHwVersion;
     protected KryoNamespace appKryo = new KryoNamespace.Builder()
             .register(GroupKey.class)
             .register(DefaultGroupKey.class)
@@ -103,20 +179,58 @@
                 }
             }).build();
 
+    /** Lists of unsupported features (firmware version K 16.04)
+     * If a FlowObjective uses one of these features a warning log message is generated.
+     */
+    protected Set<Criterion.Type> unsupportedCriteria = new HashSet<>();
+    protected Set<Instruction.Type> unsupportedInstructions = new HashSet<>();
+    protected Set<L2ModificationInstruction.L2SubType> unsupportedL2mod = new HashSet<>();
+    protected Set<L3ModificationInstruction.L3SubType> unsupportedL3mod = new HashSet<>();
+
+    /** Lists of Criteria and Instructions supported in hardware
+     * If a FlowObjective uses one of these features the FlowRule is intalled in HP_SOFTWARE_TABLE.
+     */
+    protected Set<Criterion.Type> hardwareCriteria = new HashSet<>();
+    protected Set<Instruction.Type> hardwareInstructions = new HashSet<>();
+    protected Set<L2ModificationInstruction.L2SubType> hardwareInstructionsL2mod = new HashSet<>();
+    protected Set<L3ModificationInstruction.L3SubType> hardwareInstructionsL3mod = new HashSet<>();
+    protected Set<L4ModificationInstruction.L4SubType> hardwareInstructionsL4mod = new HashSet<>();
+    protected Set<Group.Type> hardwareGroups = new HashSet<>();
+
     /**
      * Sets default table id.
-     * HP3800 switches have 3 tables, so one of them has to be default.
+     * Using this solution all flow rules are installed on the "default" table
      *
      * @param ruleBuilder flow rule builder to be set table id
      * @return flow rule builder with set table id for flow
      */
     protected abstract FlowRule.Builder setDefaultTableIdForFlowObjective(Builder ruleBuilder);
 
+    /**
+     * Return the proper table ID depending on the specific ForwardingObjective.
+     *
+     * HP switches supporting openflow have 3 tables (Pipeline Model: Standard Match)
+     * Table 0 is just a shortcut to table 100
+     * Table 100/200 are respectively used for rules processed in HARDWARE/SOFTWARE
+     *
+     * @param fwd ForwardingObjective
+     * @return table id
+     */
+    protected abstract int tableIdForForwardingObjective(ForwardingObjective fwd);
+
+    /**
+     * Return TRUE if ForwardingObjective fwd includes unsupported features.
+     *
+     * @param fwd ForwardingObjective
+     * @return boolean
+     */
+    protected abstract boolean checkUnSupportedFeatures(ForwardingObjective fwd);
+
     @Override
     public void init(DeviceId deviceId, PipelinerContext context) {
-        this.serviceDirectory = context.directory();
         this.deviceId = deviceId;
 
+        serviceDirectory = context.directory();
         coreService = serviceDirectory.get(CoreService.class);
         flowRuleService = serviceDirectory.get(FlowRuleService.class);
         groupService = serviceDirectory.get(GroupService.class);
@@ -126,13 +240,115 @@
 
         appId = coreService.registerApplication(APPLICATION_ID);
 
-        initializePipeline();
+        device = deviceService.getDevice(deviceId);
+        deviceHwVersion = device.hwVersion();
+
+        //Initialization of model specific features
+        log.info("HP Driver - Initializing unsupported features for switch {}", deviceHwVersion);
+        initUnSupportedFeatures();
+
+        log.debug("HP Driver - Initializing features supported in hardware");
+        initHardwareCriteria();
+        initHardwareInstructions();
+
+        log.debug("HP Driver - Initializing pipeline");
+        installHPTableZero();
+        installHPHardwareTable();
+        installHPSoftwareTable();
     }
 
     /**
-     * Initializes pipeline.
+     * UnSupported features are specific of each model.
      */
-    protected abstract void initializePipeline();
+    protected abstract void initUnSupportedFeatures();
+
+    /**
+     * Criteria supported in hardware are specific of each model.
+     */
+    protected abstract void initHardwareCriteria();
+
+    /**
+     * Instructions supported in hardware are specific of each model.
+     */
+    protected abstract void initHardwareInstructions();
+
+    /**
+     * HP Table 0 initialization.
+     * Installs rule goto HP_HARDWARE_TABLE in HP_TABLE_ZERO
+     */
+    private void installHPTableZero() {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+
+        treatment.transition(HP_HARDWARE_TABLE);
+
+        FlowRule rule = DefaultFlowRule.builder().forDevice(this.deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(0)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(HP_TABLE_ZERO)
+                .build();
+
+        this.applyRules(true, rule);
+    }
+
+    /**
+     * HP hardware table initialization.
+     * Installs rule goto HP_SOFTWARE_TABLE in HP_HARDWARE_TABLE
+     */
+    private void installHPHardwareTable() {
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        //treatment.setOutput(PortNumber.NORMAL);
+        treatment.transition(HP_SOFTWARE_TABLE);
+
+        FlowRule rule = DefaultFlowRule.builder().forDevice(this.deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(0)
+                .fromApp(appId)
+                .makePermanent()
+                .forTable(HP_HARDWARE_TABLE)
+                .build();
+
+        this.applyRules(true, rule);
+    }
+
+    /**
+     * Applies FlowRule.
+     * Installs or removes FlowRule.
+     *
+     * @param install - whether to install or remove rule
+     * @param rule    - the rule to be installed or removed
+     */
+    private void applyRules(boolean install, FlowRule rule) {
+        FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+
+        ops = install ? ops.add(rule) : ops.remove(rule);
+        flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                log.trace("HP Driver: provisioned " + rule.toString());
+
+                log.debug("HP Driver: - applyRules onSuccess rule {}", rule.toString());
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                log.debug("HP Driver: applyRules onError rule: "
+                        + rule.toString() + " in table: " + rule.tableId());
+            }
+        }));
+    }
+
+    /**
+     * HP software table initialization.
+     * No rules required.
+     */
+    private void installHPSoftwareTable() {}
 
     protected void pass(Objective obj) {
         obj.context().ifPresent(context -> context.onSuccess(obj));
@@ -148,30 +364,25 @@
         if (fwd.treatment() != null) {
             // Deal with SPECIFIC and VERSATILE in the same manner.
 
-            TrafficTreatment.Builder noClearTreatment = DefaultTrafficTreatment.builder();
-            fwd.treatment().allInstructions().stream()
-                    .filter(i -> i.type() != Instruction.Type.QUEUE).forEach(noClearTreatment::add);
-            if (fwd.treatment().metered() != null) {
-                noClearTreatment.meter(fwd.treatment().metered().meterId());
+            /** If UNSUPPORTED features included in ForwardingObjective a warning message is generated.
+             * FlowRule is anyway sent to the device, device will reply with an OFP_ERROR.
+             * Moreover, checkUnSupportedFeatures function generates further warnings specifying
+             * each unsupported feature.
+             * */
+            if (checkUnSupportedFeatures(fwd)) {
+                log.warn("HP Driver - specified ForwardingObjective contains UNSUPPORTED FEATURES");
             }
 
-            TrafficSelector.Builder noVlanSelector = DefaultTrafficSelector.builder();
-            fwd.selector().criteria().stream()
-                    .filter(c -> c.type() != Criterion.Type.ETH_TYPE || (c.type() == Criterion.Type.ETH_TYPE
-                            && ((EthTypeCriterion) c).ethType().toShort() != Ethernet.TYPE_VLAN))
-                    .forEach(noVlanSelector::add);
-
-            // Then we create a new forwarding rule without the unsupported actions
+            //Create the FlowRule starting from the ForwardingObjective
             FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
                     .forDevice(deviceId)
-                    .withSelector(noVlanSelector.build())
-                    .withTreatment(noClearTreatment.build())
-                    .withPriority(fwd.priority())
+                    .withSelector(fwd.selector())
+                    .withTreatment(fwd.treatment())
                     .withPriority(fwd.priority())
                     .fromApp(fwd.appId());
 
-            //TODO: check whether ForwardingObjective can specify table
-            setDefaultTableIdForFlowObjective(ruleBuilder);
+            //Table to be used depends on the specific switch hardware and ForwardingObjective
+            ruleBuilder.forTable(tableIdForForwardingObjective(fwd));
 
             if (fwd.permanent()) {
                 ruleBuilder.makePermanent();
@@ -179,6 +390,8 @@
                 ruleBuilder.makeTemporary(fwd.timeout());
             }
 
+            log.debug("HP Driver - installing fwd.treatment {}", fwd.toString());
+
             installObjective(ruleBuilder, fwd);
 
         } else {
@@ -246,33 +459,35 @@
 
         switch (objective.op()) {
             case ADD:
-                log.trace("Requested installation of objective " + objective.toString());
+                log.trace("HP Driver - Requested ADD of objective " + objective.toString());
                 FlowRule addRule = ruleBuilder.build();
-                log.trace("built rule is " + addRule.toString());
+
+                log.trace("HP Driver - built rule is " + addRule.toString());
                 flowBuilder.add(addRule);
                 break;
             case REMOVE:
-                log.trace("Requested installation of objective " + objective.toString());
+                log.trace("HP Driver - Requested REMOVE of objective " + objective.toString());
                 FlowRule removeRule = ruleBuilder.build();
-                log.trace("built rule is " + removeRule.toString());
+
+                log.trace("HP Driver - built rule is " + removeRule.toString());
                 flowBuilder.remove(removeRule);
                 break;
             default:
-                log.warn("Unknown operation {}", objective.op());
+                log.warn("HP Driver - Unknown operation {}", objective.op());
         }
 
         flowRuleService.apply(flowBuilder.build(new FlowRuleOperationsContext() {
             @Override
             public void onSuccess(FlowRuleOperations ops) {
                 objective.context().ifPresent(context -> context.onSuccess(objective));
-                log.trace("Installed objective " + objective.toString());
+                log.trace("HP Driver - Installed objective " + objective.toString());
             }
 
             @Override
             public void onError(FlowRuleOperations ops) {
                 objective.context()
                         .ifPresent(context -> context.onError(objective, ObjectiveError.FLOWINSTALLATIONFAILED));
-                log.trace("Objective installation failed" + objective.toString());
+                log.trace("HP Driver - Objective installation failed" + objective.toString());
             }
         }));
     }
@@ -341,14 +556,14 @@
         for (Criterion c : filt.conditions()) {
             if (c.type() == Criterion.Type.ETH_DST) {
                 EthCriterion eth = (EthCriterion) c;
-                FlowRule.Builder rule = processEthFiler(filt, eth, port);
+                FlowRule.Builder rule = processEthFilter(filt, eth, port);
                 rule.forDevice(deviceId)
                         .fromApp(applicationId);
                 ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
 
             } else if (c.type() == Criterion.Type.VLAN_VID) {
                 VlanIdCriterion vlan = (VlanIdCriterion) c;
-                FlowRule.Builder rule = processVlanFiler(filt, vlan, port);
+                FlowRule.Builder rule = processVlanFilter(filt, vlan, port);
                 rule.forDevice(deviceId)
                         .fromApp(applicationId);
                 ops = install ? ops.add(rule.build()) : ops.remove(rule.build());
@@ -371,21 +586,21 @@
             @Override
             public void onSuccess(FlowRuleOperations ops) {
                 pass(filt);
-                log.trace("Applied filtering rules");
+                log.trace("HP Driver - Applied filtering rules");
             }
 
             @Override
             public void onError(FlowRuleOperations ops) {
                 fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
-                log.info("Failed to apply filtering rules");
+                log.trace("HP Driver - Failed to apply filtering rules");
             }
         }));
     }
 
-    protected abstract Builder processEthFiler(FilteringObjective filt,
+    protected abstract Builder processEthFilter(FilteringObjective filt,
                                                EthCriterion eth, PortCriterion port);
 
-    protected abstract Builder processVlanFiler(FilteringObjective filt,
+    protected abstract Builder processVlanFilter(FilteringObjective filt,
                                                 VlanIdCriterion vlan, PortCriterion port);
 
     protected abstract Builder processIpFilter(FilteringObjective filt,
diff --git a/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineOld.java b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineOld.java
deleted file mode 100644
index 6b82e6a..0000000
--- a/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineOld.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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.
- */
-package org.onosproject.drivers.hp;
-
-
-import org.onlab.osgi.ServiceDirectory;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.behaviour.NextGroup;
-import org.onosproject.net.behaviour.Pipeliner;
-import org.onosproject.net.behaviour.PipelinerContext;
-import org.onosproject.net.driver.AbstractHandlerBehaviour;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleOperations;
-import org.onosproject.net.flow.FlowRuleOperationsContext;
-import org.onosproject.net.flow.FlowRuleService;
-import org.onosproject.net.flowobjective.FilteringObjective;
-import org.onosproject.net.flowobjective.FlowObjectiveStore;
-import org.onosproject.net.flowobjective.ForwardingObjective;
-import org.onosproject.net.flowobjective.NextObjective;
-import org.onosproject.net.flowobjective.Objective;
-import org.onosproject.net.flowobjective.ObjectiveError;
-
-import org.slf4j.Logger;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Objects;
-
-
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- *  Driver for Hp. Default table starts from 200.
- */
-public class HPPipelineOld extends AbstractHandlerBehaviour implements Pipeliner {
-
-
-    private final Logger log = getLogger(getClass());
-
-    private ServiceDirectory serviceDirectory;
-    private FlowRuleService flowRuleService;
-    private CoreService coreService;
-    private DeviceId deviceId;
-    private ApplicationId appId;
-    protected FlowObjectiveStore flowObjectiveStore;
-
-    //FIXME: hp table numbers are configurable . Set this parameter configurable
-    private static final int SOFTWARE_TABLE_START = 200;
-    private static final int TIME_OUT = 30;
-
-    @Override
-    public void init(DeviceId deviceId, PipelinerContext context) {
-        log.debug("Initiate HP pipeline");
-        this.serviceDirectory = context.directory();
-        this.deviceId = deviceId;
-
-        flowRuleService = serviceDirectory.get(FlowRuleService.class);
-        coreService = serviceDirectory.get(CoreService.class);
-        flowObjectiveStore = context.store();
-
-        appId = coreService.registerApplication(
-                "org.onosproject.driver.HpPipeline");
-    }
-
-    @Override
-    public void filter(FilteringObjective filter)  {
-        //Do nothing
-    }
-
-    @Override
-    public void forward(ForwardingObjective forwardObjective) {
-
-        Collection<FlowRule> rules;
-        FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder();
-
-        rules = processForward(forwardObjective);
-
-        switch (forwardObjective.op()) {
-            case ADD:
-                rules.stream()
-                        .filter(Objects::nonNull)
-                        .forEach(flowOpsBuilder::add);
-                break;
-            case REMOVE:
-                rules.stream()
-                        .filter(Objects::nonNull)
-                        .forEach(flowOpsBuilder::remove);
-                break;
-            default:
-                fail(forwardObjective, ObjectiveError.UNKNOWN);
-                log.warn("Unknown forwarding type {}");
-        }
-
-        flowRuleService.apply(flowOpsBuilder.build(new FlowRuleOperationsContext() {
-            @Override
-            public void onSuccess(FlowRuleOperations ops) {
-                pass(forwardObjective);
-            }
-
-            @Override
-            public void onError(FlowRuleOperations ops) {
-                fail(forwardObjective, ObjectiveError.FLOWINSTALLATIONFAILED);
-            }
-        }));
-
-    }
-
-    private Collection<FlowRule> processForward(ForwardingObjective fwd) {
-
-        log.debug("Processing forwarding object");
-
-        FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
-                .forDevice(deviceId)
-                .withSelector(fwd.selector())
-                .withTreatment(fwd.treatment())
-                .withPriority(fwd.priority())
-                .fromApp(fwd.appId())
-                .forTable(SOFTWARE_TABLE_START);
-
-        if (fwd.permanent()) {
-            ruleBuilder.makePermanent();
-        } else {
-            ruleBuilder.makeTemporary(TIME_OUT);
-        }
-
-        return Collections.singletonList(ruleBuilder.build());
-    }
-
-
-
-    @Override
-    public void next(NextObjective nextObjective) {
-        // Do nothing
-    }
-
-    @Override
-    public List<String> getNextMappings(NextGroup nextGroup) {
-        // TODO Implementation deferred to vendor
-        return null;
-    }
-
-    private void pass(Objective obj) {
-        obj.context().ifPresent(context -> context.onSuccess(obj));
-    }
-
-    private void fail(Objective obj, ObjectiveError error) {
-        obj.context().ifPresent(context -> context.onError(obj, error));
-    }
-
-
-}
diff --git a/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV1.java b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV1.java
new file mode 100644
index 0000000..48e6122
--- /dev/null
+++ b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV1.java
@@ -0,0 +1,311 @@
+/*
+ * 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.drivers.hp;
+
+import org.onlab.packet.Ethernet;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.FlowRule;
+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.PortCriterion;
+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.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Driver for HP hybrid switches employing V1 hardware module.
+ *
+ * - HP2910
+ * - HP3500, tested
+ * - HP5400, depends on switch configuration if "allow-v1-modules" it operates as V1
+ * - HP6200
+ * - HP6600
+ * - HP8200, depends on switch configuration if "allow-v1-modules" it operates as V1
+ *
+ * Refer to the device manual to check unsupported features and features supported in hardware
+ */
+
+public class HPPipelineV1 extends AbstractHPPipeline {
+
+    private Logger log = getLogger(getClass());
+
+    @Override
+    protected FlowRule.Builder setDefaultTableIdForFlowObjective(FlowRule.Builder ruleBuilder) {
+        log.debug("HP V1 Driver - Setting default table id to software table {}", HP_SOFTWARE_TABLE);
+
+        return ruleBuilder.forTable(HP_SOFTWARE_TABLE);
+    }
+
+    @Override
+    protected void initUnSupportedFeatures() {
+        //Initialize unsupported criteria
+        unsupportedCriteria.add(Criterion.Type.METADATA);
+        unsupportedCriteria.add(Criterion.Type.IP_ECN);
+        unsupportedCriteria.add(Criterion.Type.SCTP_SRC);
+        unsupportedCriteria.add(Criterion.Type.SCTP_SRC_MASKED);
+        unsupportedCriteria.add(Criterion.Type.SCTP_DST);
+        unsupportedCriteria.add(Criterion.Type.SCTP_DST_MASKED);
+        unsupportedCriteria.add(Criterion.Type.IPV6_ND_SLL);
+        unsupportedCriteria.add(Criterion.Type.IPV6_ND_TLL);
+        unsupportedCriteria.add(Criterion.Type.MPLS_LABEL);
+        unsupportedCriteria.add(Criterion.Type.MPLS_TC);
+        unsupportedCriteria.add(Criterion.Type.MPLS_BOS);
+        unsupportedCriteria.add(Criterion.Type.PBB_ISID);
+        unsupportedCriteria.add(Criterion.Type.TUNNEL_ID);
+        unsupportedCriteria.add(Criterion.Type.IPV6_EXTHDR);
+
+        //Initialize unsupported instructions
+        unsupportedInstructions.add(Instruction.Type.QUEUE);
+        unsupportedInstructions.add(Instruction.Type.METADATA);
+        unsupportedInstructions.add(Instruction.Type.L0MODIFICATION);
+        unsupportedInstructions.add(Instruction.Type.L1MODIFICATION);
+        unsupportedInstructions.add(Instruction.Type.PROTOCOL_INDEPENDENT);
+        unsupportedInstructions.add(Instruction.Type.EXTENSION);
+        unsupportedInstructions.add(Instruction.Type.STAT_TRIGGER);
+
+        //Initialize unsupported L2MODIFICATION actions
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_PUSH);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_POP);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_LABEL);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_BOS);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL);
+
+        //Initialize unsupported L3MODIFICATION actions
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.TTL_IN);
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.TTL_OUT);
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.DEC_TTL);
+
+        //All L4MODIFICATION actions are supported
+    }
+
+    @Override
+    protected void initHardwareCriteria() {
+        log.debug("HP V1 Driver - Initializing hardware supported criteria");
+
+        hardwareCriteria.add(Criterion.Type.IN_PORT);
+        hardwareCriteria.add(Criterion.Type.VLAN_VID);
+
+        //Match in hardware is supported only for ETH_TYPE == IPv4 (0x0800)
+        hardwareCriteria.add(Criterion.Type.ETH_TYPE);
+
+        hardwareCriteria.add(Criterion.Type.IPV4_SRC);
+        hardwareCriteria.add(Criterion.Type.IPV4_DST);
+        hardwareCriteria.add(Criterion.Type.IP_PROTO);
+        hardwareCriteria.add(Criterion.Type.IP_DSCP);
+        hardwareCriteria.add(Criterion.Type.TCP_SRC);
+        hardwareCriteria.add(Criterion.Type.TCP_DST);
+    }
+
+    @Override
+    protected void initHardwareInstructions() {
+        log.debug("HP V1 Driver - Initializing hardware supported instructions");
+
+        //If the output is on CONTROLLER PORT the rule is processed in software
+        hardwareInstructions.add(Instruction.Type.OUTPUT);
+
+        //Only modification of VLAN priority (VLAN_PCP) is supported in hardware
+        hardwareInstructions.add(Instruction.Type.L2MODIFICATION);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.VLAN_PCP);
+
+        //TODO also L3MODIFICATION of IP_DSCP is supported in hardware
+    }
+
+    //Return TRUE if ForwardingObjective fwd includes unsupported features
+    @Override
+    protected boolean checkUnSupportedFeatures(ForwardingObjective fwd) {
+        boolean unsupportedFeatures = false;
+
+        for (Criterion criterion : fwd.selector().criteria()) {
+            if (this.unsupportedCriteria.contains(criterion.type())) {
+                log.warn("HP V1 Driver - unsupported criteria {}", criterion.type());
+
+                unsupportedFeatures = true;
+            }
+        }
+
+        for (Instruction instruction : fwd.treatment().allInstructions()) {
+            if (this.unsupportedInstructions.contains(instruction.type())) {
+                log.warn("HP V1 Driver - unsupported instruction {}", instruction.type());
+
+                unsupportedFeatures = true;
+            }
+
+            if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+                if (this.unsupportedL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
+                    log.warn("HP V1 Driver - unsupported L2MODIFICATION instruction {}",
+                            ((L2ModificationInstruction) instruction).subtype());
+
+                    unsupportedFeatures = true;
+                }
+            }
+
+            if (instruction.type() == Instruction.Type.L3MODIFICATION) {
+                if (this.unsupportedL3mod.contains(((L3ModificationInstruction) instruction).subtype())) {
+                    log.warn("HP V1 Driver - unsupported L3MODIFICATION instruction {}",
+                            ((L3ModificationInstruction) instruction).subtype());
+
+                    unsupportedFeatures = true;
+                }
+            }
+        }
+
+        return unsupportedFeatures;
+    }
+
+    @Override
+    protected int tableIdForForwardingObjective(ForwardingObjective fwd) {
+        boolean hardwareProcess = true;
+
+        log.debug("HP V1 Driver - Evaluating the ForwardingObjective for proper TableID");
+
+        //Check criteria supported in hardware
+        for (Criterion criterion : fwd.selector().criteria()) {
+
+            if (!this.hardwareCriteria.contains(criterion.type())) {
+                log.warn("HP V1 Driver - criterion {} only supported in SOFTWARE", criterion.type());
+
+                hardwareProcess = false;
+                break;
+            }
+
+            //HP3500 supports hardware match on ETH_TYPE only with value TYPE_IPV4
+            if (criterion.type() == Criterion.Type.ETH_TYPE) {
+
+                if (((EthTypeCriterion) criterion).ethType().toShort() != Ethernet.TYPE_IPV4) {
+                    log.warn("HP V1 Driver - only ETH_TYPE == IPv4 (0x0800) is supported in hardware");
+
+                    hardwareProcess = false;
+                    break;
+                }
+            }
+
+            //HP3500 supports IN_PORT criterion in hardware only if associated with ETH_TYPE criterion
+            if (criterion.type() == Criterion.Type.IN_PORT) {
+                hardwareProcess = false;
+
+                for (Criterion requiredCriterion : fwd.selector().criteria()) {
+                    if (requiredCriterion.type() == Criterion.Type.ETH_TYPE) {
+                        hardwareProcess = true;
+                    }
+                }
+
+                if (!hardwareProcess) {
+                    log.warn("HP V1 Driver - IN_PORT criterion without ETH_TYPE is not supported in hardware");
+
+                    break;
+                }
+            }
+
+        }
+
+        //Check if a CLEAR action is included
+        if (fwd.treatment().clearedDeferred()) {
+            log.warn("HP V1 Driver - CLEAR action only supported in SOFTWARE");
+
+            hardwareProcess = false;
+        }
+
+        //If criteria can be processed in hardware, then check treatment
+        if (hardwareProcess) {
+
+            for (Instruction instruction : fwd.treatment().allInstructions()) {
+
+                //Check if the instruction type is contained in the hardware instruction
+                if (!this.hardwareInstructions.contains(instruction.type())) {
+                    log.warn("HP V1 Driver - instruction {} only supported in SOFTWARE", instruction.type());
+
+                    hardwareProcess = false;
+                    break;
+                }
+
+                /** All GROUP types are supported in software by V2 switches
+                 */
+
+                /** If output is CONTROLLER_PORT the flow entry could be installed in hardware
+                 * but is anyway processed in software because openflow header has to be added
+                 */
+                if (instruction.type() == Instruction.Type.OUTPUT) {
+                    if (((Instructions.OutputInstruction) instruction).port() == PortNumber.CONTROLLER) {
+                        log.warn("HP V1 Driver - Forwarding to CONTROLLER only supported in software");
+
+                        hardwareProcess = false;
+                        break;
+                    }
+                }
+
+                /** Only L2MODIFICATION supported in hardware is MODIFY VLAN_PRIORITY.
+                 * Check if the specific L2MODIFICATION.subtype is supported in hardware
+                 */
+                if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+
+                    if (!this.hardwareInstructionsL3mod.contains(((L2ModificationInstruction) instruction).subtype())) {
+                        log.warn("HP V1 Driver - L2MODIFICATION.subtype {} only supported in SOFTWARE",
+                                ((L2ModificationInstruction) instruction).subtype());
+
+                        hardwareProcess = false;
+                        break;
+                    }
+
+                }
+            }
+        }
+
+        if (hardwareProcess) {
+            log.warn("HP V1 Driver - This flow rule is supported in HARDWARE");
+            return HP_HARDWARE_TABLE;
+        } else {
+            //TODO: create a specific flow in table 100 to redirect selected traffic on table 200
+
+            log.warn("HP V1 Driver - This flow rule is only supported in SOFTWARE");
+            return HP_SOFTWARE_TABLE;
+        }
+
+    }
+
+    @Override
+    public void filter(FilteringObjective filter) {
+        log.error("HP V1 Driver - Unsupported FilteringObjective: filtering method send");
+    }
+
+    @Override
+    protected FlowRule.Builder processEthFilter(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
+        log.error("HP V1 Driver - Unsupported FilteringObjective: processEthFilter invoked");
+        return null;
+    }
+
+    @Override
+    protected FlowRule.Builder processVlanFilter(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
+        log.error("HP V1 Driver - Unsupported FilteringObjective: processVlanFilter invoked");
+        return null;
+    }
+
+    @Override
+    protected FlowRule.Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
+        log.error("HP V1 Driver - Unsupported FilteringObjective: processIpFilter invoked");
+        return null;
+    }
+}
+
diff --git a/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV2.java b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV2.java
new file mode 100644
index 0000000..b82a86d
--- /dev/null
+++ b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV2.java
@@ -0,0 +1,342 @@
+/*
+ * 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.drivers.hp;
+
+import org.onlab.packet.Ethernet;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.FlowRule;
+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.PortCriterion;
+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.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.group.Group;
+
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Driver for HP hybrid switches employing V2 hardware module.
+ *
+ * - HP2920
+ * - HP3800, tested
+ * - HP5400, depends on switch configuration if "no-allow-v1-modules" it operates as V2
+ * - HP5400R, depends on switch configuration if "allow-v2-modules" it operates as V2
+ * - HP8200, depends on switch configuration if "no-allow-v1-modules" it operates as V2
+ *
+ * Refer to the device manual to check unsupported features and features supported in hardware
+ *
+ */
+
+public class HPPipelineV2 extends AbstractHPPipeline {
+
+    private final Logger log = getLogger(getClass());
+
+    @Override
+    protected FlowRule.Builder setDefaultTableIdForFlowObjective(FlowRule.Builder ruleBuilder) {
+        log.debug("HP V2 Driver - Setting default table id to hardware table {}", HP_HARDWARE_TABLE);
+        return ruleBuilder.forTable(HP_HARDWARE_TABLE);
+    }
+
+    @Override
+    protected void initUnSupportedFeatures() {
+        //Initialize unsupported criteria
+        unsupportedCriteria.add(Criterion.Type.METADATA);
+        unsupportedCriteria.add(Criterion.Type.IP_ECN);
+        unsupportedCriteria.add(Criterion.Type.SCTP_SRC);
+        unsupportedCriteria.add(Criterion.Type.SCTP_SRC_MASKED);
+        unsupportedCriteria.add(Criterion.Type.SCTP_DST);
+        unsupportedCriteria.add(Criterion.Type.SCTP_DST_MASKED);
+        unsupportedCriteria.add(Criterion.Type.IPV6_ND_SLL);
+        unsupportedCriteria.add(Criterion.Type.IPV6_ND_TLL);
+        unsupportedCriteria.add(Criterion.Type.MPLS_LABEL);
+        unsupportedCriteria.add(Criterion.Type.MPLS_TC);
+        unsupportedCriteria.add(Criterion.Type.MPLS_BOS);
+        unsupportedCriteria.add(Criterion.Type.PBB_ISID);
+        unsupportedCriteria.add(Criterion.Type.TUNNEL_ID);
+        unsupportedCriteria.add(Criterion.Type.IPV6_EXTHDR);
+
+        //Initialize unsupported instructions
+        unsupportedInstructions.add(Instruction.Type.QUEUE);
+        unsupportedInstructions.add(Instruction.Type.METADATA);
+        unsupportedInstructions.add(Instruction.Type.L0MODIFICATION);
+        unsupportedInstructions.add(Instruction.Type.L1MODIFICATION);
+        unsupportedInstructions.add(Instruction.Type.PROTOCOL_INDEPENDENT);
+        unsupportedInstructions.add(Instruction.Type.EXTENSION);
+        unsupportedInstructions.add(Instruction.Type.STAT_TRIGGER);
+
+        //Initialize unsupportet L2MODIFICATION actions
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_PUSH);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_POP);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_LABEL);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_BOS);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL);
+
+        //Initialize unsupported L3MODIFICATION actions
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.TTL_IN);
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.TTL_OUT);
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.DEC_TTL);
+
+        //All L4MODIFICATION actions are supported
+    }
+
+    @Override
+    protected void initHardwareCriteria() {
+        log.debug("HP V2 Driver - Initializing hardware supported criteria");
+
+        hardwareCriteria.add(Criterion.Type.IN_PORT);
+        hardwareCriteria.add(Criterion.Type.VLAN_VID);
+        hardwareCriteria.add(Criterion.Type.VLAN_PCP);
+
+        //Match in hardware is not supported ETH_TYPE == VLAN (0x8100)
+        hardwareCriteria.add(Criterion.Type.ETH_TYPE);
+
+        hardwareCriteria.add(Criterion.Type.ETH_SRC);
+        hardwareCriteria.add(Criterion.Type.ETH_DST);
+        hardwareCriteria.add(Criterion.Type.IPV4_SRC);
+        hardwareCriteria.add(Criterion.Type.IPV4_DST);
+        hardwareCriteria.add(Criterion.Type.IP_PROTO);
+        hardwareCriteria.add(Criterion.Type.IP_DSCP);
+        hardwareCriteria.add(Criterion.Type.TCP_SRC);
+        hardwareCriteria.add(Criterion.Type.TCP_DST);
+    }
+
+    @Override
+    protected void initHardwareInstructions() {
+        log.debug("HP V2 Driver - Initializing hardware supported instructions");
+
+        hardwareInstructions.add(Instruction.Type.OUTPUT);
+
+        //Only modification of VLAN priority (VLAN_PCP) is supported in hardware
+        hardwareInstructions.add(Instruction.Type.L2MODIFICATION);
+
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.ETH_SRC);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.ETH_DST);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.VLAN_ID);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.VLAN_PCP);
+
+        //Only GROUP of type ALL is supported in hardware
+        //Moreover, for hardware support, each bucket must contain one and only one instruction of type OUTPUT
+        hardwareInstructions.add(Instruction.Type.GROUP);
+
+        hardwareGroups.add(Group.Type.ALL);
+
+        //TODO also L3MODIFICATION of IP_DSCP is supported in hardware
+    }
+
+    //Return TRUE if ForwardingObjective fwd includes UNSUPPORTED features
+    @Override
+    protected boolean checkUnSupportedFeatures(ForwardingObjective fwd) {
+        boolean unsupportedFeatures = false;
+
+        for (Criterion criterion : fwd.selector().criteria()) {
+            if (this.unsupportedCriteria.contains(criterion.type())) {
+                log.warn("HP V2 Driver - unsupported criteria {}", criterion.type());
+
+                unsupportedFeatures = true;
+            }
+        }
+
+        for (Instruction instruction : fwd.treatment().allInstructions()) {
+            if (this.unsupportedInstructions.contains(instruction.type())) {
+                log.warn("HP V2 Driver - unsupported instruction {}", instruction.type());
+
+                unsupportedFeatures = true;
+            }
+
+            if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+                if (this.unsupportedL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
+                    log.warn("HP V2 Driver - unsupported L2MODIFICATION instruction {}",
+                            ((L2ModificationInstruction) instruction).subtype());
+
+                    unsupportedFeatures = true;
+                }
+            }
+
+            if (instruction.type() == Instruction.Type.L3MODIFICATION) {
+                if (this.unsupportedL3mod.contains(((L3ModificationInstruction) instruction).subtype())) {
+                    log.warn("HP V2 Driver - unsupported L3MODIFICATION instruction {}",
+                            ((L3ModificationInstruction) instruction).subtype());
+
+                    unsupportedFeatures = true;
+                }
+            }
+        }
+
+        return unsupportedFeatures;
+    }
+
+    @Override
+    protected int tableIdForForwardingObjective(ForwardingObjective fwd) {
+        boolean hardwareProcess = true;
+
+        log.debug("HP V2 Driver - Evaluating the ForwardingObjective for proper TableID");
+
+        //Check criteria supported in hardware
+        for (Criterion criterion : fwd.selector().criteria()) {
+
+            if (!this.hardwareCriteria.contains(criterion.type())) {
+                log.warn("HP V2 Driver - criterion {} only supported in SOFTWARE", criterion.type());
+
+                hardwareProcess = false;
+                break;
+            }
+
+            //V2 does not support hardware match on ETH_TYPE of value TYPE_VLAN (tested on HP3800 16.04)
+            if (criterion.type() == Criterion.Type.ETH_TYPE) {
+
+                if (((EthTypeCriterion) criterion).ethType().toShort() == Ethernet.TYPE_VLAN) {
+                    log.warn("HP V2 Driver - ETH_TYPE == VLAN (0x8100) is only supported in software");
+
+                    hardwareProcess = false;
+                    break;
+                }
+            }
+
+            //HP2920 cannot match in hardware the ETH_DST in non-IP packets - TO BE REFINED AND TESTED
+            if (deviceHwVersion.contains("2920")) {
+
+                 if (criterion.type() == Criterion.Type.ETH_DST) {
+                     log.warn("HP V2 Driver (specific for HP2920) " +
+                             "- criterion {} only supported in SOFTWARE", criterion.type());
+
+                     hardwareProcess = false;
+                     break;
+                 }
+            }
+        }
+
+        //Check if a CLEAR action is included
+        if (fwd.treatment().clearedDeferred()) {
+            log.warn("HP V2 Driver - CLEAR action only supported in SOFTWARE");
+
+            hardwareProcess = false;
+        }
+
+        //If criteria can be processed in hardware, then check treatment
+        if (hardwareProcess) {
+            for (Instruction instruction : fwd.treatment().allInstructions()) {
+
+                //Check if the instruction type is contained in the hardware instruction
+                if (!this.hardwareInstructions.contains(instruction.type())) {
+                    log.warn("HP V2 Driver - instruction {} only supported in SOFTWARE", instruction.type());
+
+                    hardwareProcess = false;
+                    break;
+                }
+
+                /** If output is CONTROLLER_PORT the flow entry could be installed in hardware
+                 * but is anyway processed in software because OPENFLOW header has to be added
+                 */
+                if (instruction.type() == Instruction.Type.OUTPUT) {
+                    if (((Instructions.OutputInstruction) instruction).port() == PortNumber.CONTROLLER) {
+                        log.warn("HP V2 Driver - Forwarding to CONTROLLER only supported in software");
+
+                        hardwareProcess = false;
+                        break;
+                    }
+                }
+
+                //Check if the specific L2MODIFICATION.subtype is supported in hardware
+                if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+
+                    if (!this.hardwareInstructionsL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
+                        log.warn("HP V2 Driver - L2MODIFICATION.subtype {} only supported in SOFTWARE",
+                                ((L2ModificationInstruction) instruction).subtype());
+
+                        hardwareProcess = false;
+                        break;
+                    }
+                }
+
+                //Check if the specific GROUP addressed in the instruction is:
+                // --- installed in the device
+                // --- type ALL
+                // TODO --- check if all the buckets contains one and only one output action
+                if (instruction.type() == Instruction.Type.GROUP) {
+                    boolean groupInstalled = false;
+
+                    GroupId groupId = ((Instructions.GroupInstruction) instruction).groupId();
+
+                    Iterable<Group> groupsOnDevice = groupService.getGroups(deviceId);
+
+                    for (Group group : groupsOnDevice) {
+
+                        if ((group.state() == Group.GroupState.ADDED) && (group.id().equals(groupId))) {
+                            groupInstalled = true;
+
+                            if (group.type() != Group.Type.ALL) {
+                                log.warn("HP V2 Driver - group type {} only supported in SOFTWARE",
+                                        group.type().toString());
+                                hardwareProcess = false;
+                            }
+
+                            break;
+                        }
+                    }
+
+                    if (!groupInstalled) {
+                        log.warn("HP V2 Driver - referenced group is not installed on the device.");
+                        hardwareProcess = false;
+                    }
+                }
+            }
+        }
+
+        if (hardwareProcess) {
+            log.warn("HP V2 Driver - This flow rule is supported in HARDWARE");
+            return HP_HARDWARE_TABLE;
+        } else {
+            //TODO: create a specific flow in table 100 to redirect selected traffic on table 200
+
+            log.warn("HP V2 Driver - This flow rule is only supported in SOFTWARE");
+            return HP_SOFTWARE_TABLE;
+        }
+    }
+
+    @Override
+    public void filter(FilteringObjective filter) {
+        log.error("Unsupported FilteringObjective: : filtering method send");
+    }
+
+    @Override
+    protected FlowRule.Builder processEthFilter(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
+        log.error("Unsupported FilteringObjective: processEthFilter invoked");
+        return null;
+    }
+
+    @Override
+    protected FlowRule.Builder processVlanFilter(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
+        log.error("Unsupported FilteringObjective: processVlanFilter invoked");
+        return null;
+    }
+
+    @Override
+    protected FlowRule.Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
+        log.error("Unsupported FilteringObjective: processIpFilter invoked");
+        return null;
+    }
+}
diff --git a/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV3.java b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV3.java
new file mode 100644
index 0000000..9aa4a91
--- /dev/null
+++ b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV3.java
@@ -0,0 +1,365 @@
+/*
+ * 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.drivers.hp;
+
+import org.onlab.packet.Ethernet;
+import org.onosproject.core.GroupId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.FlowRule;
+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.PortCriterion;
+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.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction;
+import org.onosproject.net.flow.instructions.L4ModificationInstruction;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.group.Group;
+
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Driver for HP hybrid switches employing V3 hardware module.
+ * NOT TESTED ON V3 HARDWARE DEVICES
+ *
+ * - HP2930
+ * - HP3810
+ * - HP5400R, depends on switch configuration if "no-allow-v2-modules" it operates as V3
+ *
+ * Refer to the device manual to check unsupported features and features supported in hardware
+ *
+ */
+
+public class HPPipelineV3 extends AbstractHPPipeline {
+
+    private final Logger log = getLogger(getClass());
+
+    @Override
+    protected FlowRule.Builder setDefaultTableIdForFlowObjective(FlowRule.Builder ruleBuilder) {
+        log.debug("HP V3 Driver - Setting default table id to hardware table {}", HP_HARDWARE_TABLE);
+        return ruleBuilder.forTable(HP_HARDWARE_TABLE);
+    }
+
+    @Override
+    protected void initUnSupportedFeatures() {
+        //Initialize unsupported criteria
+        unsupportedCriteria.add(Criterion.Type.METADATA);
+        unsupportedCriteria.add(Criterion.Type.IP_ECN);
+        unsupportedCriteria.add(Criterion.Type.SCTP_SRC);
+        unsupportedCriteria.add(Criterion.Type.SCTP_SRC_MASKED);
+        unsupportedCriteria.add(Criterion.Type.SCTP_DST);
+        unsupportedCriteria.add(Criterion.Type.SCTP_DST_MASKED);
+        unsupportedCriteria.add(Criterion.Type.IPV6_ND_SLL);
+        unsupportedCriteria.add(Criterion.Type.IPV6_ND_TLL);
+        unsupportedCriteria.add(Criterion.Type.MPLS_LABEL);
+        unsupportedCriteria.add(Criterion.Type.MPLS_TC);
+        unsupportedCriteria.add(Criterion.Type.MPLS_BOS);
+        unsupportedCriteria.add(Criterion.Type.PBB_ISID);
+        unsupportedCriteria.add(Criterion.Type.TUNNEL_ID);
+        unsupportedCriteria.add(Criterion.Type.IPV6_EXTHDR);
+
+        //Initialize unsupported instructions
+        unsupportedInstructions.add(Instruction.Type.QUEUE);
+        unsupportedInstructions.add(Instruction.Type.METADATA);
+        unsupportedInstructions.add(Instruction.Type.L0MODIFICATION);
+        unsupportedInstructions.add(Instruction.Type.L1MODIFICATION);
+        unsupportedInstructions.add(Instruction.Type.PROTOCOL_INDEPENDENT);
+        unsupportedInstructions.add(Instruction.Type.EXTENSION);
+        unsupportedInstructions.add(Instruction.Type.STAT_TRIGGER);
+
+        //Initialize unsupportet L2MODIFICATION actions
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_PUSH);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_POP);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_LABEL);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_BOS);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL);
+
+        //Initialize unsupported L3MODIFICATION actions
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.TTL_IN);
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.TTL_OUT);
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.DEC_TTL);
+
+        //All L4MODIFICATION actions are supported
+    }
+
+    @Override
+    protected void initHardwareCriteria() {
+        log.debug("HP V3 Driver - Initializing hardware supported criteria");
+
+        hardwareCriteria.add(Criterion.Type.IN_PORT);
+        hardwareCriteria.add(Criterion.Type.VLAN_VID);
+        hardwareCriteria.add(Criterion.Type.VLAN_PCP);
+
+        //Match in hardware is not supported ETH_TYPE == VLAN (0x8100)
+        hardwareCriteria.add(Criterion.Type.ETH_TYPE);
+
+        hardwareCriteria.add(Criterion.Type.ETH_SRC);
+        hardwareCriteria.add(Criterion.Type.ETH_DST);
+        hardwareCriteria.add(Criterion.Type.IPV4_SRC);
+        hardwareCriteria.add(Criterion.Type.IPV4_DST);
+        hardwareCriteria.add(Criterion.Type.IP_PROTO);
+        hardwareCriteria.add(Criterion.Type.IP_DSCP);
+        hardwareCriteria.add(Criterion.Type.TCP_SRC);
+        hardwareCriteria.add(Criterion.Type.TCP_DST);
+    }
+
+    @Override
+    protected void initHardwareInstructions() {
+        log.debug("HP V3 Driver - Initializing hardware supported instructions");
+
+        hardwareInstructions.add(Instruction.Type.OUTPUT);
+
+        hardwareInstructions.add(Instruction.Type.L2MODIFICATION);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.ETH_SRC);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.ETH_DST);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.VLAN_ID);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.VLAN_PCP);
+
+        hardwareInstructions.add(Instruction.Type.L3MODIFICATION);
+        hardwareInstructionsL3mod.add(L3ModificationInstruction.L3SubType.IPV4_SRC);
+        hardwareInstructionsL3mod.add(L3ModificationInstruction.L3SubType.IPV4_DST);
+
+        hardwareInstructions.add(Instruction.Type.L4MODIFICATION);
+        hardwareInstructionsL4mod.add(L4ModificationInstruction.L4SubType.TCP_DST);
+        hardwareInstructionsL4mod.add(L4ModificationInstruction.L4SubType.UDP_DST);
+        hardwareInstructionsL4mod.add(L4ModificationInstruction.L4SubType.TCP_SRC);
+        hardwareInstructionsL4mod.add(L4ModificationInstruction.L4SubType.UDP_SRC);
+
+        /** Only GROUP of type ALL is supported in hardware.
+         *
+         * Moreover, each bucket must contain one and only one instruction of type OUTPUT
+         */
+        hardwareInstructions.add(Instruction.Type.GROUP);
+        hardwareGroups.add(Group.Type.ALL);
+
+        //TODO also L3MODIFICATION of IP_DSCP is supported in hardware
+    }
+
+    //Return TRUE if ForwardingObjective fwd includes UNSUPPORTED features
+    @Override
+    protected boolean checkUnSupportedFeatures(ForwardingObjective fwd) {
+        boolean unsupportedFeatures = false;
+
+        for (Criterion criterion : fwd.selector().criteria()) {
+            if (this.unsupportedCriteria.contains(criterion.type())) {
+                log.warn("HP V3 Driver - unsupported criteria {}", criterion.type());
+
+                unsupportedFeatures = true;
+            }
+        }
+
+        for (Instruction instruction : fwd.treatment().allInstructions()) {
+            if (this.unsupportedInstructions.contains(instruction.type())) {
+                log.warn("HP V3 Driver - unsupported instruction {}", instruction.type());
+
+                unsupportedFeatures = true;
+            }
+
+            if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+                if (this.unsupportedL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
+                    log.warn("HP V3 Driver - unsupported L2MODIFICATION instruction {}",
+                            ((L2ModificationInstruction) instruction).subtype());
+
+                    unsupportedFeatures = true;
+                }
+            }
+
+            if (instruction.type() == Instruction.Type.L3MODIFICATION) {
+                if (this.unsupportedL3mod.contains(((L3ModificationInstruction) instruction).subtype())) {
+                    log.warn("HP V3 Driver - unsupported L3MODIFICATION instruction {}",
+                            ((L3ModificationInstruction) instruction).subtype());
+
+                    unsupportedFeatures = true;
+                }
+            }
+        }
+
+        return unsupportedFeatures;
+    }
+
+    @Override
+    protected int tableIdForForwardingObjective(ForwardingObjective fwd) {
+        boolean hardwareProcess = true;
+
+        log.debug("HP V3 Driver - Evaluating the ForwardingObjective for proper TableID");
+
+        //Check criteria supported in hardware
+        for (Criterion criterion : fwd.selector().criteria()) {
+
+            if (!this.hardwareCriteria.contains(criterion.type())) {
+                log.warn("HP V3 Driver - criterion {} only supported in SOFTWARE", criterion.type());
+
+                hardwareProcess = false;
+                break;
+            }
+
+            //HP3800 does not support hardware match on ETH_TYPE of value TYPE_VLAN
+            if (criterion.type() == Criterion.Type.ETH_TYPE) {
+
+                if (((EthTypeCriterion) criterion).ethType().toShort() == Ethernet.TYPE_VLAN) {
+                    log.warn("HP V3 Driver -  ETH_TYPE == VLAN (0x8100) is only supported in software");
+
+                    hardwareProcess = false;
+                    break;
+                }
+            }
+
+        }
+
+        //TODO: CLEAR ations should be supported by V3 hardware modules - To be TESTED
+        //This commented code is required if  CLEAR action is not supported in hardware
+        /*if (fwd.treatment().clearedDeferred()) {
+            log.warn("HP V3 Driver - CLEAR action only supported in SOFTWARE");
+
+            hardwareProcess = false;
+        }*/
+
+        //If criteria can be processed in hardware, then check treatment
+        if (hardwareProcess) {
+            for (Instruction instruction : fwd.treatment().allInstructions()) {
+
+                //Check if the instruction type is contained in the hardware instruction
+                if (!this.hardwareInstructions.contains(instruction.type())) {
+                    log.warn("HP V3 Driver - instruction {} only supported in SOFTWARE", instruction.type());
+
+                    hardwareProcess = false;
+                    break;
+                }
+
+                /** If output is CONTROLLER_PORT the flow entry could be installed in hardware
+                 * but is anyway processed in software because OPENFLOW header has to be added
+                 */
+                if (instruction.type() == Instruction.Type.OUTPUT) {
+                    if (((Instructions.OutputInstruction) instruction).port() == PortNumber.CONTROLLER) {
+                        log.warn("HP V3 Driver - Forwarding to CONTROLLER only supported in software");
+
+                        hardwareProcess = false;
+                        break;
+                    }
+                }
+
+                //Check if the specific L2MODIFICATION.subtype is supported in hardware
+                if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+
+                    if (!this.hardwareInstructionsL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
+                        log.warn("HP V3 Driver - L2MODIFICATION.subtype {} only supported in SOFTWARE",
+                                ((L2ModificationInstruction) instruction).subtype());
+
+                        hardwareProcess = false;
+                        break;
+                    }
+                }
+
+                //Check if the specific L3MODIFICATION.subtype is supported in hardware
+                if (instruction.type() == Instruction.Type.L3MODIFICATION) {
+
+                    if (!this.hardwareInstructionsL3mod.contains(((L3ModificationInstruction) instruction).subtype())) {
+                        log.warn("HP V3 Driver - L3MODIFICATION.subtype {} only supported in SOFTWARE",
+                                ((L3ModificationInstruction) instruction).subtype());
+
+                        hardwareProcess = false;
+                        break;
+                    }
+                }
+
+                //Check if the specific L4MODIFICATION.subtype is supported in hardware
+                if (instruction.type() == Instruction.Type.L4MODIFICATION) {
+
+                    if (!this.hardwareInstructionsL4mod.contains(((L4ModificationInstruction) instruction).subtype())) {
+                        log.warn("HP V3 Driver - L4MODIFICATION.subtype {} only supported in SOFTWARE",
+                                ((L4ModificationInstruction) instruction).subtype());
+
+                        hardwareProcess = false;
+                        break;
+                    }
+                }
+
+                //Check if the specific GROUP addressed in the instruction is:
+                // --- installed in the device
+                // --- type ALL
+                // TODO --- check if all the buckets contains one and only one output action
+                if (instruction.type() == Instruction.Type.GROUP) {
+                    boolean groupInstalled = false;
+
+                    GroupId groupId = ((Instructions.GroupInstruction) instruction).groupId();
+
+                    Iterable<Group> groupsOnDevice = groupService.getGroups(deviceId);
+
+                    for (Group group : groupsOnDevice) {
+
+                        if ((group.state() == Group.GroupState.ADDED) && (group.id().equals(groupId))) {
+                            groupInstalled = true;
+
+                            if (group.type() != Group.Type.ALL) {
+                                log.warn("HP V3 Driver - group type {} only supported in SOFTWARE",
+                                        group.type().toString());
+                                hardwareProcess = false;
+                            }
+
+                            break;
+                        }
+                    }
+
+                    if (!groupInstalled) {
+                        log.warn("HP V3 Driver - referenced group is not installed on the device.");
+                        hardwareProcess = false;
+                    }
+                }
+            }
+        }
+
+        if (hardwareProcess) {
+            log.warn("HP V3 Driver - This flow rule is supported in HARDWARE");
+            return HP_HARDWARE_TABLE;
+        } else {
+            //TODO: create a specific flow in table 100 to redirect selected traffic on table 200
+
+            log.warn("HP V3 Driver - This flow rule is only supported in SOFTWARE");
+            return HP_SOFTWARE_TABLE;
+        }
+    }
+
+    @Override
+    public void filter(FilteringObjective filter) {
+        log.error("Unsupported FilteringObjective: : filtering method send");
+    }
+
+    @Override
+    protected FlowRule.Builder processEthFilter(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
+        log.error("Unsupported FilteringObjective: processEthFilter invoked");
+        return null;
+    }
+
+    @Override
+    protected FlowRule.Builder processVlanFilter(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
+        log.error("Unsupported FilteringObjective: processVlanFilter invoked");
+        return null;
+    }
+
+    @Override
+    protected FlowRule.Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
+        log.error("Unsupported FilteringObjective: processIpFilter invoked");
+        return null;
+    }
+}
diff --git a/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV3500.java b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV3500.java
new file mode 100644
index 0000000..a488439
--- /dev/null
+++ b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV3500.java
@@ -0,0 +1,302 @@
+/*
+ * 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.drivers.hp;
+
+import org.onlab.packet.Ethernet;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.flow.FlowRule;
+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.PortCriterion;
+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.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction;
+import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Driver for HP3500 hybrid switches employing V1 hardware module.
+ *
+ * Refer to the device manual to check unsupported features and features supported in hardware
+ *
+ */
+
+public class HPPipelineV3500 extends AbstractHPPipeline {
+
+    private Logger log = getLogger(getClass());
+
+    @Override
+    protected FlowRule.Builder setDefaultTableIdForFlowObjective(FlowRule.Builder ruleBuilder) {
+        log.debug("HP V3500 Driver - Setting default table id to software table {}", HP_SOFTWARE_TABLE);
+
+        return ruleBuilder.forTable(HP_SOFTWARE_TABLE);
+    }
+
+    @Override
+    protected void initUnSupportedFeatures() {
+        //Initialize unsupported criteria
+        unsupportedCriteria.add(Criterion.Type.METADATA);
+        unsupportedCriteria.add(Criterion.Type.IP_ECN);
+        unsupportedCriteria.add(Criterion.Type.SCTP_SRC);
+        unsupportedCriteria.add(Criterion.Type.SCTP_SRC_MASKED);
+        unsupportedCriteria.add(Criterion.Type.SCTP_DST);
+        unsupportedCriteria.add(Criterion.Type.SCTP_DST_MASKED);
+        unsupportedCriteria.add(Criterion.Type.IPV6_ND_SLL);
+        unsupportedCriteria.add(Criterion.Type.IPV6_ND_TLL);
+        unsupportedCriteria.add(Criterion.Type.MPLS_LABEL);
+        unsupportedCriteria.add(Criterion.Type.MPLS_TC);
+        unsupportedCriteria.add(Criterion.Type.MPLS_BOS);
+        unsupportedCriteria.add(Criterion.Type.PBB_ISID);
+        unsupportedCriteria.add(Criterion.Type.TUNNEL_ID);
+        unsupportedCriteria.add(Criterion.Type.IPV6_EXTHDR);
+
+        //Initialize unsupported instructions
+        unsupportedInstructions.add(Instruction.Type.QUEUE);
+        unsupportedInstructions.add(Instruction.Type.METADATA);
+        unsupportedInstructions.add(Instruction.Type.L0MODIFICATION);
+        unsupportedInstructions.add(Instruction.Type.L1MODIFICATION);
+        unsupportedInstructions.add(Instruction.Type.PROTOCOL_INDEPENDENT);
+        unsupportedInstructions.add(Instruction.Type.EXTENSION);
+        unsupportedInstructions.add(Instruction.Type.STAT_TRIGGER);
+
+        //Initialize unsupported L2MODIFICATION actions
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_PUSH);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_POP);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_LABEL);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_BOS);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL);
+
+        //Initialize unsupported L3MODIFICATION actions
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.TTL_IN);
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.TTL_OUT);
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.DEC_TTL);
+
+        //All L4MODIFICATION actions are supported
+    }
+
+    @Override
+    protected void initHardwareCriteria() {
+        log.debug("HP V3500 Driver - Initializing hardware supported criteria");
+
+        hardwareCriteria.add(Criterion.Type.IN_PORT);
+        hardwareCriteria.add(Criterion.Type.VLAN_VID);
+
+        //Match in hardware is supported only for ETH_TYPE == IPv4 (0x0800)
+        hardwareCriteria.add(Criterion.Type.ETH_TYPE);
+
+        hardwareCriteria.add(Criterion.Type.IPV4_SRC);
+        hardwareCriteria.add(Criterion.Type.IPV4_DST);
+        hardwareCriteria.add(Criterion.Type.IP_PROTO);
+        hardwareCriteria.add(Criterion.Type.IP_DSCP);
+        hardwareCriteria.add(Criterion.Type.TCP_SRC);
+        hardwareCriteria.add(Criterion.Type.TCP_DST);
+    }
+
+    @Override
+    protected void initHardwareInstructions() {
+        log.debug("HP V3500 Driver - Initializing hardware supported instructions");
+
+        //If the output is on CONTROLLER PORT the rule is processed in software
+        hardwareInstructions.add(Instruction.Type.OUTPUT);
+
+        //Only modification of VLAN priority (VLAN_PCP) is supported in hardware
+        hardwareInstructions.add(Instruction.Type.L2MODIFICATION);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.VLAN_PCP);
+
+        //TODO also L3MODIFICATION of IP_DSCP is supported in hardware
+    }
+
+    //Return TRUE if ForwardingObjective fwd includes unsupported features
+    @Override
+    protected boolean checkUnSupportedFeatures(ForwardingObjective fwd) {
+        boolean unsupportedFeatures = false;
+
+        for (Criterion criterion : fwd.selector().criteria()) {
+            if (this.unsupportedCriteria.contains(criterion.type())) {
+                log.warn("HP V3500 Driver - unsupported criteria {}", criterion.type());
+
+                unsupportedFeatures = true;
+            }
+        }
+
+        for (Instruction instruction : fwd.treatment().allInstructions()) {
+            if (this.unsupportedInstructions.contains(instruction.type())) {
+                log.warn("HP V3500 Driver - unsupported instruction {}", instruction.type());
+
+                unsupportedFeatures = true;
+            }
+
+            if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+                if (this.unsupportedL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
+                    log.warn("HP V3500 Driver - unsupported L2MODIFICATION instruction {}",
+                            ((L2ModificationInstruction) instruction).subtype());
+
+                    unsupportedFeatures = true;
+                }
+            }
+
+            if (instruction.type() == Instruction.Type.L3MODIFICATION) {
+                if (this.unsupportedL3mod.contains(((L3ModificationInstruction) instruction).subtype())) {
+                    log.warn("HP V3500 Driver - unsupported L3MODIFICATION instruction {}",
+                            ((L3ModificationInstruction) instruction).subtype());
+
+                    unsupportedFeatures = true;
+                }
+            }
+        }
+
+        return unsupportedFeatures;
+    }
+
+    @Override
+    protected int tableIdForForwardingObjective(ForwardingObjective fwd) {
+        boolean hardwareProcess = true;
+
+        log.debug("HP V3500 Driver - Evaluating the ForwardingObjective for proper TableID");
+
+        //Check criteria supported in hardware
+        for (Criterion criterion : fwd.selector().criteria()) {
+
+            if (!this.hardwareCriteria.contains(criterion.type())) {
+                log.warn("HP V3500 Driver - criterion {} only supported in SOFTWARE", criterion.type());
+
+                hardwareProcess = false;
+                break;
+            }
+
+            //HP3500 supports hardware match on ETH_TYPE only with value TYPE_IPV4
+            if (criterion.type() == Criterion.Type.ETH_TYPE) {
+
+                if (((EthTypeCriterion) criterion).ethType().toShort() != Ethernet.TYPE_IPV4) {
+                    log.warn("HP V3500 Driver - only ETH_TYPE == IPv4 (0x0800) is supported in hardware");
+
+                    hardwareProcess = false;
+                    break;
+                }
+            }
+
+            //HP3500 supports IN_PORT criterion in hardware only if associated with ETH_TYPE criterion
+            if (criterion.type() == Criterion.Type.IN_PORT) {
+                hardwareProcess = false;
+
+                for (Criterion requiredCriterion : fwd.selector().criteria()) {
+                    if (requiredCriterion.type() == Criterion.Type.ETH_TYPE) {
+                        hardwareProcess = true;
+                    }
+                }
+
+                if (!hardwareProcess) {
+                    log.warn("HP V3500 Driver - IN_PORT criterion without ETH_TYPE is not supported in hardware");
+
+                    break;
+                }
+            }
+
+        }
+
+        //Check if a CLEAR action is included
+        if (fwd.treatment().clearedDeferred()) {
+            log.warn("HP V3500 Driver - CLEAR action only supported in SOFTWARE");
+
+            hardwareProcess = false;
+        }
+
+        //If criteria can be processed in hardware, then check treatment
+        if (hardwareProcess) {
+
+            for (Instruction instruction : fwd.treatment().allInstructions()) {
+
+                //Check if the instruction type is contained in the hardware instruction
+                if (!this.hardwareInstructions.contains(instruction.type())) {
+                    log.warn("HP V3500 Driver - instruction {} only supported in SOFTWARE", instruction.type());
+
+                    hardwareProcess = false;
+                    break;
+                }
+
+                /** If output is CONTROLLER_PORT the flow entry could be installed in hardware
+                 * but is anyway processed in software because openflow header has to be added
+                 */
+                if (instruction.type() == Instruction.Type.OUTPUT) {
+                    if (((Instructions.OutputInstruction) instruction).port() == PortNumber.CONTROLLER) {
+                        log.warn("HP V3500 Driver - Forwarding to CONTROLLER only supported in software");
+
+                        hardwareProcess = false;
+                        break;
+                    }
+                }
+
+                /** Only L2MODIFICATION supported in hardware is MODIFY VLAN_PRIORITY.
+                 * Check if the specific L2MODIFICATION.subtype is supported in hardware
+                 * */
+                if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+
+                    if (!this.hardwareInstructionsL3mod.contains(((L2ModificationInstruction) instruction).subtype())) {
+                        log.warn("HP V3500 Driver - L2MODIFICATION.subtype {} only supported in SOFTWARE",
+                                ((L2ModificationInstruction) instruction).subtype());
+
+                        hardwareProcess = false;
+                        break;
+                    }
+
+                }
+            }
+        }
+
+        if (hardwareProcess) {
+            log.warn("HP V3500 Driver - This flow rule is supported in HARDWARE");
+            return HP_HARDWARE_TABLE;
+        } else {
+            //TODO: create a specific flow in table 100 to redirect selected traffic on table 200
+
+            log.warn("HP V3500 Driver - This flow rule is only supported in SOFTWARE");
+            return HP_SOFTWARE_TABLE;
+        }
+
+    }
+
+    @Override
+    public void filter(FilteringObjective filter) {
+        log.error("HP V3500 Driver - Unsupported FilteringObjective: filtering method send");
+    }
+
+    @Override
+    protected FlowRule.Builder processEthFilter(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
+        log.error("HP V3500 Driver - Unsupported FilteringObjective: processEthFilter invoked");
+        return null;
+    }
+
+    @Override
+    protected FlowRule.Builder processVlanFilter(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
+        log.error("HP V3500 Driver - Unsupported FilteringObjective: processVlanFilter invoked");
+        return null;
+    }
+
+    @Override
+    protected FlowRule.Builder processIpFilter(FilteringObjective filt, IPCriterion ip, PortCriterion port) {
+        log.error("HP V3500 Driver - Unsupported FilteringObjective: processIpFilter invoked");
+        return null;
+    }
+}
+
diff --git a/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV3800.java b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV3800.java
index 9c16815..fafa06e 100644
--- a/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV3800.java
+++ b/drivers/hp/src/main/java/org/onosproject/drivers/hp/HPPipelineV3800.java
@@ -16,52 +16,288 @@
 
 package org.onosproject.drivers.hp;
 
+import org.onlab.packet.Ethernet;
+import org.onosproject.core.GroupId;
 import org.onosproject.net.PortNumber;
-import org.onosproject.net.flow.DefaultFlowRule;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
 import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleOperations;
-import org.onosproject.net.flow.FlowRuleOperationsContext;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
+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.PortCriterion;
 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.L2ModificationInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction;
 import org.onosproject.net.flowobjective.FilteringObjective;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.group.Group;
+
 import org.slf4j.Logger;
 
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
  * Driver for HP3800 hybrid switches.
+ *
+ * Refer to the device manual to check unsupported features and features supported in hardware
+ *
  */
-public class HPPipelineV3800 extends AbstractHPPipeline {
-    // FIXME: This class should probably be renamed not to imply it applies for the 3800 series solely.
 
-    private static final int HP_TABLE_ZERO = 0;
-    private static final int HP_HARDWARE_TABLE = 100;
-    private static final int HP_SOFTWARE_TABLE = 200;
+public class HPPipelineV3800 extends AbstractHPPipeline {
 
     private final Logger log = getLogger(getClass());
 
-
     @Override
     protected FlowRule.Builder setDefaultTableIdForFlowObjective(FlowRule.Builder ruleBuilder) {
-        log.debug("Setting default table id to hardware table {}", HP_HARDWARE_TABLE);
+        log.debug("HP V3800 Driver - Setting default table id to hardware table {}", HP_HARDWARE_TABLE);
         return ruleBuilder.forTable(HP_HARDWARE_TABLE);
     }
 
     @Override
-    protected void initializePipeline() {
-        log.debug("Installing table zero {}", HP_TABLE_ZERO);
-        installHPTableZero();
-        log.debug("Installing scavenger rule to hardware table {} because it is default objective table",
-                 HP_HARDWARE_TABLE);
-        installHPHardwareTable();
-        log.debug("Installing software table {}", HP_SOFTWARE_TABLE);
-        installHPSoftwareTable();
+    protected void initUnSupportedFeatures() {
+        //Initialize unsupported criteria
+        unsupportedCriteria.add(Criterion.Type.METADATA);
+        unsupportedCriteria.add(Criterion.Type.IP_ECN);
+        unsupportedCriteria.add(Criterion.Type.SCTP_SRC);
+        unsupportedCriteria.add(Criterion.Type.SCTP_SRC_MASKED);
+        unsupportedCriteria.add(Criterion.Type.SCTP_DST);
+        unsupportedCriteria.add(Criterion.Type.SCTP_DST_MASKED);
+        unsupportedCriteria.add(Criterion.Type.IPV6_ND_SLL);
+        unsupportedCriteria.add(Criterion.Type.IPV6_ND_TLL);
+        unsupportedCriteria.add(Criterion.Type.MPLS_LABEL);
+        unsupportedCriteria.add(Criterion.Type.MPLS_TC);
+        unsupportedCriteria.add(Criterion.Type.MPLS_BOS);
+        unsupportedCriteria.add(Criterion.Type.PBB_ISID);
+        unsupportedCriteria.add(Criterion.Type.TUNNEL_ID);
+        unsupportedCriteria.add(Criterion.Type.IPV6_EXTHDR);
+
+        //Initialize unsupported instructions
+        unsupportedInstructions.add(Instruction.Type.QUEUE);
+        unsupportedInstructions.add(Instruction.Type.METADATA);
+        unsupportedInstructions.add(Instruction.Type.L0MODIFICATION);
+        unsupportedInstructions.add(Instruction.Type.L1MODIFICATION);
+        unsupportedInstructions.add(Instruction.Type.PROTOCOL_INDEPENDENT);
+        unsupportedInstructions.add(Instruction.Type.EXTENSION);
+        unsupportedInstructions.add(Instruction.Type.STAT_TRIGGER);
+
+        //Initialize unsupportet L2MODIFICATION actions
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_PUSH);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_POP);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_LABEL);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.MPLS_BOS);
+        unsupportedL2mod.add(L2ModificationInstruction.L2SubType.DEC_MPLS_TTL);
+
+        //Initialize unsupported L3MODIFICATION actions
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.TTL_IN);
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.TTL_OUT);
+        unsupportedL3mod.add(L3ModificationInstruction.L3SubType.DEC_TTL);
+
+        //All L4MODIFICATION actions are supported
+    }
+
+    @Override
+    protected void initHardwareCriteria() {
+        log.debug("HP V3800 Driver - Initializing hardware supported criteria");
+
+        hardwareCriteria.add(Criterion.Type.IN_PORT);
+        hardwareCriteria.add(Criterion.Type.VLAN_VID);
+        hardwareCriteria.add(Criterion.Type.VLAN_PCP);
+
+        //Match in hardware is not supported ETH_TYPE == VLAN (0x8100)
+        hardwareCriteria.add(Criterion.Type.ETH_TYPE);
+
+        hardwareCriteria.add(Criterion.Type.ETH_SRC);
+        hardwareCriteria.add(Criterion.Type.ETH_DST);
+        hardwareCriteria.add(Criterion.Type.IPV4_SRC);
+        hardwareCriteria.add(Criterion.Type.IPV4_DST);
+        hardwareCriteria.add(Criterion.Type.IP_PROTO);
+        hardwareCriteria.add(Criterion.Type.IP_DSCP);
+        hardwareCriteria.add(Criterion.Type.TCP_SRC);
+        hardwareCriteria.add(Criterion.Type.TCP_DST);
+    }
+
+    @Override
+    protected void initHardwareInstructions() {
+        log.debug("HP V3800 Driver - Initializing hardware supported instructions");
+
+        hardwareInstructions.add(Instruction.Type.OUTPUT);
+
+        //Only modification of VLAN priority (VLAN_PCP) is supported in hardware
+        hardwareInstructions.add(Instruction.Type.L2MODIFICATION);
+
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.ETH_SRC);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.ETH_DST);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.VLAN_ID);
+        hardwareInstructionsL2mod.add(L2ModificationInstruction.L2SubType.VLAN_PCP);
+
+        //Only GROUP of type ALL is supported in hardware
+        //Moreover, for hardware support, each bucket must contain one and only one instruction of type OUTPUT
+        hardwareInstructions.add(Instruction.Type.GROUP);
+
+        hardwareGroups.add(Group.Type.ALL);
+
+        //TODO also L3MODIFICATION of IP_DSCP is supported in hardware
+    }
+
+    //Return TRUE if ForwardingObjective fwd includes UNSUPPORTED features
+    @Override
+    protected boolean checkUnSupportedFeatures(ForwardingObjective fwd) {
+        boolean unsupportedFeatures = false;
+
+        for (Criterion criterion : fwd.selector().criteria()) {
+            if (this.unsupportedCriteria.contains(criterion.type())) {
+                log.warn("HP V3800 Driver - unsupported criteria {}", criterion.type());
+
+                unsupportedFeatures = true;
+            }
+        }
+
+        for (Instruction instruction : fwd.treatment().allInstructions()) {
+            if (this.unsupportedInstructions.contains(instruction.type())) {
+                log.warn("HP V3800 Driver - unsupported instruction {}", instruction.type());
+
+                unsupportedFeatures = true;
+            }
+
+            if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+                if (this.unsupportedL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
+                    log.warn("HP V3800 Driver - unsupported L2MODIFICATION instruction {}",
+                            ((L2ModificationInstruction) instruction).subtype());
+
+                    unsupportedFeatures = true;
+                }
+            }
+
+            if (instruction.type() == Instruction.Type.L3MODIFICATION) {
+                if (this.unsupportedL3mod.contains(((L3ModificationInstruction) instruction).subtype())) {
+                    log.warn("HP V3800 Driver - unsupported L3MODIFICATION instruction {}",
+                            ((L3ModificationInstruction) instruction).subtype());
+
+                    unsupportedFeatures = true;
+                }
+            }
+        }
+
+        return unsupportedFeatures;
+    }
+
+    @Override
+    protected int tableIdForForwardingObjective(ForwardingObjective fwd) {
+        boolean hardwareProcess = true;
+
+        log.debug("HP V3800 Driver - Evaluating the ForwardingObjective for proper TableID");
+
+        //Check criteria supported in hardware
+        for (Criterion criterion : fwd.selector().criteria()) {
+
+            if (!this.hardwareCriteria.contains(criterion.type())) {
+                log.warn("HP V3800 Driver - criterion {} only supported in SOFTWARE", criterion.type());
+
+                hardwareProcess = false;
+                break;
+            }
+
+            //HP3800 does not support hardware match on ETH_TYPE of value TYPE_VLAN
+            if (criterion.type() == Criterion.Type.ETH_TYPE) {
+
+                if (((EthTypeCriterion) criterion).ethType().toShort() == Ethernet.TYPE_VLAN) {
+                    log.warn("HP V3800 Driver -  ETH_TYPE == VLAN (0x8100) is only supported in software");
+
+                    hardwareProcess = false;
+                    break;
+                }
+            }
+
+        }
+
+        //Check if a CLEAR action is included
+        if (fwd.treatment().clearedDeferred()) {
+            log.warn("HP V3800 Driver - CLEAR action only supported in SOFTWARE");
+
+            hardwareProcess = false;
+        }
+
+        //If criteria can be processed in hardware, then check treatment
+        if (hardwareProcess) {
+            for (Instruction instruction : fwd.treatment().allInstructions()) {
+
+                //Check if the instruction type is contained in the hardware instruction
+                if (!this.hardwareInstructions.contains(instruction.type())) {
+                    log.warn("HP V3800 Driver - instruction {} only supported in SOFTWARE", instruction.type());
+
+                    hardwareProcess = false;
+                    break;
+                }
+
+                /** If output is CONTROLLER_PORT the flow entry could be installed in hardware
+                 * but is anyway processed in software because OPENFLOW header has to be added
+                 */
+                if (instruction.type() == Instruction.Type.OUTPUT) {
+                    if (((Instructions.OutputInstruction) instruction).port() == PortNumber.CONTROLLER) {
+                        log.warn("HP V3800 Driver - Forwarding to CONTROLLER only supported in software");
+
+                        hardwareProcess = false;
+                        break;
+                    }
+                }
+
+                //Check if the specific L2MODIFICATION.subtype is supported in hardware
+                if (instruction.type() == Instruction.Type.L2MODIFICATION) {
+
+                    if (!this.hardwareInstructionsL2mod.contains(((L2ModificationInstruction) instruction).subtype())) {
+                        log.warn("HP V3800 Driver - L2MODIFICATION.subtype {} only supported in SOFTWARE",
+                                ((L2ModificationInstruction) instruction).subtype());
+
+                        hardwareProcess = false;
+                        break;
+                    }
+                }
+
+                //Check if the specific GROUP addressed in the instruction is:
+                // --- installed in the device
+                // --- type ALL
+                // TODO --- check if all the buckets contains one and only one output action
+                if (instruction.type() == Instruction.Type.GROUP) {
+                    boolean groupInstalled = false;
+
+                    GroupId groupId = ((Instructions.GroupInstruction) instruction).groupId();
+
+                    Iterable<Group> groupsOnDevice = groupService.getGroups(deviceId);
+
+                    for (Group group : groupsOnDevice) {
+
+                        if ((group.state() == Group.GroupState.ADDED) && (group.id().equals(groupId))) {
+                            groupInstalled = true;
+
+                            if (group.type() != Group.Type.ALL) {
+                                log.warn("HP V3800 Driver - group type {} only supported in SOFTWARE",
+                                        group.type().toString());
+                                hardwareProcess = false;
+                            }
+
+                            break;
+                        }
+                    }
+
+                    if (!groupInstalled) {
+                        log.warn("HP V3800 Driver - referenced group is not installed on the device.");
+                        hardwareProcess = false;
+                    }
+                }
+            }
+        }
+
+        if (hardwareProcess) {
+            log.warn("HP V3800 Driver - This flow rule is supported in HARDWARE");
+            return HP_HARDWARE_TABLE;
+        } else {
+            //TODO: create a specific flow in table 100 to redirect selected traffic on table 200
+
+            log.warn("HP V3800 Driver - This flow rule is only supported in SOFTWARE");
+            return HP_SOFTWARE_TABLE;
+        }
     }
 
     @Override
@@ -70,13 +306,13 @@
     }
 
     @Override
-    protected FlowRule.Builder processEthFiler(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
+    protected FlowRule.Builder processEthFilter(FilteringObjective filt, EthCriterion eth, PortCriterion port) {
         log.error("Unsupported FilteringObjective: processEthFilter invoked");
         return null;
     }
 
     @Override
-    protected FlowRule.Builder processVlanFiler(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
+    protected FlowRule.Builder processVlanFilter(FilteringObjective filt, VlanIdCriterion vlan, PortCriterion port) {
         log.error("Unsupported FilteringObjective: processVlanFilter invoked");
         return null;
     }
@@ -86,85 +322,4 @@
         log.error("Unsupported FilteringObjective: processIpFilter invoked");
         return null;
     }
-
-    /**
-     * HP Table 0 initialization.
-     * Installs rule goto HP hardware table in HP table zero
-     */
-    private void installHPTableZero() {
-        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
-
-        treatment.transition(HP_HARDWARE_TABLE);
-
-        FlowRule rule = DefaultFlowRule.builder().forDevice(this.deviceId)
-                .withSelector(selector.build())
-                .withTreatment(treatment.build())
-                .withPriority(0)
-                .fromApp(appId)
-                .makePermanent()
-                .forTable(HP_TABLE_ZERO)
-                .build();
-
-        this.applyRules(true, rule);
-
-        log.info("Installed table {}", HP_TABLE_ZERO);
-    }
-
-    /**
-     * HP hardware table initialization.
-     * Installs scavenger rule in HP hardware table.
-     */
-    private void installHPHardwareTable() {
-        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
-
-        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
-        treatment.setOutput(PortNumber.NORMAL);
-
-        FlowRule rule = DefaultFlowRule.builder().forDevice(this.deviceId)
-                .withSelector(selector.build())
-                .withTreatment(treatment.build())
-                .withPriority(0)
-                .fromApp(appId)
-                .makePermanent()
-                .forTable(HP_HARDWARE_TABLE)
-                .build();
-
-        this.applyRules(true, rule);
-
-        log.info("Installed table {}", HP_HARDWARE_TABLE);
-    }
-
-    /**
-     * HP software table initialization.
-     */
-    private void installHPSoftwareTable() {
-        log.info("No rules installed in table {}", HP_SOFTWARE_TABLE);
-    }
-
-
-    /**
-     * Applies FlowRule.
-     * Installs or removes FlowRule.
-     *
-     * @param install - whether to install or remove rule
-     * @param rule    - the rule to be installed or removed
-     */
-    private void applyRules(boolean install, FlowRule rule) {
-        FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
-
-        ops = install ? ops.add(rule) : ops.remove(rule);
-        flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
-            @Override
-            public void onSuccess(FlowRuleOperations ops) {
-                log.trace("Provisioned rule: " + rule.toString());
-                log.trace("HP3800 driver: provisioned " + rule.tableId() + " table");
-            }
-
-            @Override
-            public void onError(FlowRuleOperations ops) {
-                log.info("HP3800 driver: failed to provision " + rule.tableId() + " table");
-            }
-        }));
-    }
 }
diff --git a/drivers/hp/src/main/resources/hp-driver.xml b/drivers/hp/src/main/resources/hp-driver.xml
index d08a184..39e4d5e 100644
--- a/drivers/hp/src/main/resources/hp-driver.xml
+++ b/drivers/hp/src/main/resources/hp-driver.xml
@@ -14,26 +14,96 @@
   ~ See the License for the specific language governing permissions and
   ~ limitations under the License.
   -->
+
+<!--
+  ~ hp-switch drivers supports HP switches of types V1-V2-V3
+  ~
+  ~ Currently supported V1 switches  HP2910, HP3500, HP6200, HP6600
+  ~ Currently supported V2 switches  HP2920, HP3800, HP5400, HP8200
+  ~ Currently supported V3 switches  HP2930, HP3810, HP5400R
+  ~
+  ~ Switches 5400 and 8200 support V1 and V2 depending on switch configuration
+  ~ Switch 5400R supports V2 and V3 depending on switch configuration
+  ~
+  ~ Supported features and features supported in hardware increase from V1->V2->V3
+  ~ If the switch model is not recognized it will operate as V1
+  ~
+  ~ Driver tested for HP3500 and HP3800
+ -->
+
+<!--
+  ~ aruba-switch drivers recognizes Aruba switches
+  ~
+  ~ Currently supported Aruba switches: Aruba 7000, Aruba 7200
+  ~
+  ~ These switches simply operate using default ONOS driver, TO BE TESTED
+ -->
+
 <drivers>
-    <driver name="hp-switch" extends="default" manufacturer="(HP|Aruba)" swVersion=".*">
+    <driver name="hp-switch" extends="default" manufacturer="HP" swVersion=".*">
         <behaviour api="org.onosproject.net.behaviour.Pipeliner"
-                   impl="org.onosproject.drivers.hp.HPPipelineV3800"/>
+                   impl="org.onosproject.drivers.hp.HPPipelineV1"/>
         <behaviour api="org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver"
                    impl="org.onosproject.drivers.hp.HPSwitchHandshaker"/>
     </driver>
 
-    <driver name="hp-2920"  extends="hp-switch" hwVersion=".*2920.*"/>
-    <driver name="hp-2930"  extends="hp-switch" hwVersion=".*2930.*"/>
-    <driver name="hp-3500"  extends="hp-switch" hwVersion=".*3500.*"/>
-    <driver name="hp-3800"  extends="hp-switch" hwVersion=".*3800.*"/>
-    <driver name="hp-3810"  extends="hp-switch" hwVersion=".*3810.*"/>
-    <driver name="hp-5400"  extends="hp-switch" hwVersion=".*54[0-9][0-9]z.*"/>
-    <driver name="hp-5400R" extends="hp-switch" hwVersion=".*54[0-9][0-9]R.*"/>
-    <driver name="hp-6200"  extends="hp-switch" hwVersion=".*6200.*"/>
-    <driver name="hp-6600"  extends="hp-switch" hwVersion=".*6600.*"/>
-    <driver name="hp-8200"  extends="hp-switch" hwVersion=".*82[0-9][0-9].*"/>
+    <driver name="hp-2910"  extends="hp-switch" hwVersion=".*2910.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.drivers.hp.HPPipelineV1"/>
+    </driver>
 
-    <driver name="aruba-7000" extends="hp-switch,ovs" hwVersion=".*Aruba70[0-9][0-9].*"/>
-    <driver name="aruba-7200" extends="hp-switch,ovs" hwVersion=".*Aruba72[0-9][0-9].*"/>
+    <driver name="hp-2920"  extends="hp-switch" hwVersion=".*2920.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+               impl="org.onosproject.drivers.hp.HPPipelineV2"/>
+    </driver>
+
+    <driver name="hp-2930"  extends="hp-switch" hwVersion=".*2930.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.drivers.hp.HPPipelineV3"/>
+    </driver>
+
+    <driver name="hp-3500"  extends="hp-switch" hwVersion=".*3500.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.drivers.hp.HPPipelineV1"/>
+    </driver>
+
+    <driver name="hp-3800"  extends="hp-switch" hwVersion=".*3800.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.drivers.hp.HPPipelineV2"/>
+    </driver>
+
+    <driver name="hp-3810"  extends="hp-switch" hwVersion=".*3810.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.drivers.hp.HPPipelineV3"/>
+    </driver>
+
+    <driver name="hp-5400"  extends="hp-switch" hwVersion=".*54[0-9][0-9]z.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.drivers.hp.HPPipelineV2"/>
+    </driver>
+
+    <driver name="hp-5400R" extends="hp-switch" hwVersion=".*54[0-9][0-9]R.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.drivers.hp.HPPipelineV3"/>
+    </driver>
+
+    <driver name="hp-6200"  extends="hp-switch" hwVersion=".*6200.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.drivers.hp.HPPipelineV1"/>
+    </driver>
+
+    <driver name="hp-6600"  extends="hp-switch" hwVersion=".*6600.*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.drivers.hp.HPPipelineV1"/>
+    </driver>
+
+    <driver name="hp-8200"  extends="hp-switch" hwVersion=".*82[0-9][0-9].*">
+        <behaviour api="org.onosproject.net.behaviour.Pipeliner"
+                   impl="org.onosproject.drivers.hp.HPPipelineV2"/>
+    </driver>
+
+    <driver name="aruba-switch" extends="default" manufacturer="Aruba" swVersion=".*"/>
+    <driver name="aruba-7000" extends="aruba-switch" hwVersion=".*Aruba70[0-9][0-9].*"/>
+    <driver name="aruba-7200" extends="aruba-switch" hwVersion=".*Aruba72[0-9][0-9].*"/>
 
 </drivers>