diff --git a/drivers/src/main/java/org/onosproject/driver/handshaker/OFCorsaSwitchDriver.java b/drivers/src/main/java/org/onosproject/driver/handshaker/CorsaSwitchHandShaker.java
similarity index 94%
rename from drivers/src/main/java/org/onosproject/driver/handshaker/OFCorsaSwitchDriver.java
rename to drivers/src/main/java/org/onosproject/driver/handshaker/CorsaSwitchHandShaker.java
index 05c907e..f4a45b8 100644
--- a/drivers/src/main/java/org/onosproject/driver/handshaker/OFCorsaSwitchDriver.java
+++ b/drivers/src/main/java/org/onosproject/driver/handshaker/CorsaSwitchHandShaker.java
@@ -29,12 +29,11 @@
 import java.util.Collections;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-//import java.util.ArrayList;
 
 /**
- * Corsa switch driver for BGP Router deployment.
+ * Corsa switch handshaker.
  */
-public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch {
+public class CorsaSwitchHandShaker extends AbstractOpenFlowSwitch {
 
     private AtomicBoolean handShakeComplete = new AtomicBoolean(false);
 
diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/CorsaPipeline.java b/drivers/src/main/java/org/onosproject/driver/pipeline/CorsaPipeline.java
index 616eac1..0c95731 100644
--- a/drivers/src/main/java/org/onosproject/driver/pipeline/CorsaPipeline.java
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/CorsaPipeline.java
@@ -13,6 +13,10 @@
 import org.onosproject.net.flow.TrafficTreatment;
 import org.slf4j.Logger;
 
+/**
+ * Driver for Corsa TTP.
+ *
+ */
 public class CorsaPipeline extends OVSCorsaPipeline {
 
     private final Logger log = getLogger(getClass());
@@ -37,7 +41,6 @@
                 .makePermanent()
                 .forTable(VLAN_MPLS_TABLE).build();
 
-
         ops = install ? ops.add(rule) : ops.remove(rule);
 
         flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/OFDPA1Pipeline.java b/drivers/src/main/java/org/onosproject/driver/pipeline/OFDPA1Pipeline.java
index 31a4444..6ceb6d3 100644
--- a/drivers/src/main/java/org/onosproject/driver/pipeline/OFDPA1Pipeline.java
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/OFDPA1Pipeline.java
@@ -102,7 +102,6 @@
     protected static final int ACL_TABLE = 60;
     protected static final int MAC_LEARNING_TABLE = 254;
 
-    @SuppressWarnings("unused")
     private static final int HIGHEST_PRIORITY = 0xffff;
     private static final int DEFAULT_PRIORITY = 0x8000;
     private static final int LOWEST_PRIORITY = 0x0;
diff --git a/drivers/src/main/java/org/onosproject/driver/pipeline/SoftRouterPipeline.java b/drivers/src/main/java/org/onosproject/driver/pipeline/SoftRouterPipeline.java
new file mode 100644
index 0000000..bf87dc3
--- /dev/null
+++ b/drivers/src/main/java/org/onosproject/driver/pipeline/SoftRouterPipeline.java
@@ -0,0 +1,524 @@
+package org.onosproject.driver.pipeline;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.onlab.osgi.ServiceDirectory;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.util.KryoNamespace;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+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.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.TrafficTreatment;
+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.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 org.onosproject.store.serializers.KryoNamespaces;
+
+/**
+ *  Simple 2-Table Pipeline for Software/NPU based routers. This pipeline
+ *  does not forward IP traffic to next-hop groups. Instead it forwards traffic
+ *  using OF FlowMod actions.
+ */
+public class SoftRouterPipeline extends AbstractHandlerBehaviour implements Pipeliner {
+
+    protected static final int FILTER_TABLE = 0;
+    protected static final int FIB_TABLE = 1;
+
+    private static final int DROP_PRIORITY = 0;
+    private static final int DEFAULT_PRIORITY = 0x8000;
+    private static final int HIGHEST_PRIORITY = 0xffff;
+
+    private ServiceDirectory serviceDirectory;
+    protected FlowRuleService flowRuleService;
+    private CoreService coreService;
+    private FlowObjectiveStore flowObjectiveStore;
+    protected DeviceId deviceId;
+    protected ApplicationId appId;
+    private ApplicationId driverId;
+    private Collection<Filter> filters;
+    private Collection<ForwardingObjective> pendingVersatiles;
+
+    private KryoNamespace appKryo = new KryoNamespace.Builder()
+        .register(DummyGroup.class)
+        .register(KryoNamespaces.API)
+        .register(byte[].class)
+        .build();
+
+    private final Logger log = getLogger(getClass());
+
+    @Override
+    public void init(DeviceId deviceId, PipelinerContext context) {
+        this.serviceDirectory = context.directory();
+        this.deviceId = deviceId;
+        coreService = serviceDirectory.get(CoreService.class);
+        flowRuleService = serviceDirectory.get(FlowRuleService.class);
+        flowObjectiveStore = context.store();
+        driverId = coreService.registerApplication(
+                "org.onosproject.driver.OVSCorsaPipeline");
+        filters = Collections.newSetFromMap(new ConcurrentHashMap<Filter, Boolean>());
+        pendingVersatiles = Collections.newSetFromMap(
+                                new ConcurrentHashMap<ForwardingObjective, Boolean>());
+        initializePipeline();
+    }
+
+    @Override
+    public void filter(FilteringObjective filteringObjective) {
+        if (filteringObjective.type() == FilteringObjective.Type.PERMIT) {
+            processFilter(filteringObjective,
+                          filteringObjective.op() == Objective.Operation.ADD,
+                          filteringObjective.appId());
+        } else {
+            fail(filteringObjective, ObjectiveError.UNSUPPORTED);
+        }
+    }
+
+    @Override
+    public void forward(ForwardingObjective fwd) {
+        Collection<FlowRule> rules;
+        FlowRuleOperations.Builder flowOpsBuilder = FlowRuleOperations.builder();
+
+        rules = processForward(fwd);
+        switch (fwd.op()) {
+            case ADD:
+                rules.stream()
+                        .filter(rule -> rule != null)
+                        .forEach(flowOpsBuilder::add);
+                break;
+            case REMOVE:
+                rules.stream()
+                        .filter(rule -> rule != null)
+                        .forEach(flowOpsBuilder::remove);
+                break;
+            default:
+                fail(fwd, ObjectiveError.UNKNOWN);
+                log.warn("Unknown forwarding type {}", fwd.op());
+        }
+
+
+        flowRuleService.apply(flowOpsBuilder.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                pass(fwd);
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                fail(fwd, ObjectiveError.FLOWINSTALLATIONFAILED);
+            }
+        }));
+
+    }
+
+    @Override
+    public void next(NextObjective nextObjective) {
+        switch (nextObjective.type()) {
+        case SIMPLE:
+            Collection<TrafficTreatment> treatments = nextObjective.next();
+            if (treatments.size() != 1) {
+                log.error("Next Objectives of type Simple should only have a "
+                        + "single Traffic Treatment. Next Objective Id:{}", nextObjective.id());
+               fail(nextObjective, ObjectiveError.BADPARAMS);
+               return;
+            }
+            processSimpleNextObjective(nextObjective);
+            break;
+        case HASHED:
+        case BROADCAST:
+        case FAILOVER:
+            fail(nextObjective, ObjectiveError.UNSUPPORTED);
+            log.warn("Unsupported next objective type {}", nextObjective.type());
+            break;
+        default:
+            fail(nextObjective, ObjectiveError.UNKNOWN);
+            log.warn("Unknown next objective type {}", nextObjective.type());
+        }
+    }
+
+    private void pass(Objective obj) {
+        if (obj.context().isPresent()) {
+            obj.context().get().onSuccess(obj);
+        }
+    }
+
+    private void fail(Objective obj, ObjectiveError error) {
+        if (obj.context().isPresent()) {
+            obj.context().get().onError(obj, error);
+        }
+    }
+
+
+    private void initializePipeline() {
+        //Drop rules for both tables
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+
+        treatment.drop();
+
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(DROP_PRIORITY)
+                .fromApp(driverId)
+                .makePermanent()
+                .forTable(FILTER_TABLE)
+                .build();
+        ops = ops.add(rule);
+
+        rule = DefaultFlowRule.builder().forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(DROP_PRIORITY)
+                .fromApp(driverId)
+                .makePermanent()
+                .forTable(FIB_TABLE)
+                .build();
+        ops = ops.add(rule);
+
+        flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                log.info("Provisioned drop rules in both tables");
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                log.info("Failed to provision drop rules");
+            }
+        }));
+    }
+
+    private void processFilter(FilteringObjective filt, boolean install,
+                               ApplicationId applicationId) {
+        // This driver only processes filtering criteria defined with switch
+        // ports as the key
+        PortCriterion p; EthCriterion e = null; VlanIdCriterion v = null;
+        Collection<IPCriterion> ips = new ArrayList<IPCriterion>();
+        if (!filt.key().equals(Criteria.dummy()) &&
+                filt.key().type() == Criterion.Type.IN_PORT) {
+            p = (PortCriterion) filt.key();
+        } else {
+            log.warn("No key defined in filtering objective from app: {}. Not"
+                    + "processing filtering objective", applicationId);
+            fail(filt, ObjectiveError.UNKNOWN);
+            return;
+        }
+
+        // convert filtering conditions for switch-intfs into flowrules
+        FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
+        for (Criterion c : filt.conditions()) {
+            if (c.type() == Criterion.Type.ETH_DST) {
+                e = (EthCriterion) c;
+            } else if (c.type() == Criterion.Type.VLAN_VID) {
+                v = (VlanIdCriterion) c;
+            } else if (c.type() == Criterion.Type.IPV4_DST) {
+                ips.add((IPCriterion) c);
+            } else {
+                log.error("Unsupported filter {}", c);
+                fail(filt, ObjectiveError.UNSUPPORTED);
+                return;
+            }
+        }
+
+        log.debug("adding Port/VLAN/MAC filtering rules in filter table: {}/{}/{}",
+                  p.port(), v.vlanId(), e.mac());
+        TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+        TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
+        selector.matchInPort(p.port());
+        selector.matchVlanId(v.vlanId());
+        selector.matchEthDst(e.mac());
+        selector.matchEthType(Ethernet.TYPE_IPV4);
+        treatment.transition(FIB_TABLE);
+        FlowRule rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(DEFAULT_PRIORITY)
+                .fromApp(applicationId)
+                .makePermanent()
+                .forTable(FILTER_TABLE).build();
+        ops =  ops.add(rule);
+
+        for (IPCriterion ipaddr : ips) {
+            log.debug("adding IP filtering rules in FIB table: {}", ipaddr.ip());
+            selector = DefaultTrafficSelector.builder();
+            treatment = DefaultTrafficTreatment.builder();
+            selector.matchEthType(Ethernet.TYPE_IPV4);
+            selector.matchIPDst(ipaddr.ip());
+            treatment.setOutput(PortNumber.CONTROLLER);
+            rule = DefaultFlowRule.builder()
+                    .forDevice(deviceId)
+                    .withSelector(selector.build())
+                    .withTreatment(treatment.build())
+                    .withPriority(HIGHEST_PRIORITY)
+                    .fromApp(applicationId)
+                    .makePermanent()
+                    .forTable(FIB_TABLE).build();
+            ops =  ops.add(rule);
+        }
+
+        // cache for later use
+        Filter filter = new Filter(p, e, v, ips);
+        filters.add(filter);
+        // apply any pending versatile forwarding objectives
+        for (ForwardingObjective fwd : pendingVersatiles) {
+            Collection<FlowRule> ret = processVersatilesWithFilters(filter, fwd);
+            for (FlowRule fr : ret) {
+                ops.add(fr);
+            }
+        }
+
+        ops = install ? ops.add(rule) : ops.remove(rule);
+        // apply filtering flow rules
+        flowRuleService.apply(ops.build(new FlowRuleOperationsContext() {
+            @Override
+            public void onSuccess(FlowRuleOperations ops) {
+                log.info("Applied filtering rules");
+                pass(filt);
+            }
+
+            @Override
+            public void onError(FlowRuleOperations ops) {
+                log.info("Failed to apply filtering rules");
+                fail(filt, ObjectiveError.FLOWINSTALLATIONFAILED);
+            }
+        }));
+    }
+
+    private Collection<FlowRule> processForward(ForwardingObjective fwd) {
+        switch (fwd.flag()) {
+        case SPECIFIC:
+            return processSpecific(fwd);
+        case VERSATILE:
+            return processVersatile(fwd);
+        default:
+            fail(fwd, ObjectiveError.UNKNOWN);
+            log.warn("Unknown forwarding flag {}", fwd.flag());
+        }
+        return Collections.emptySet();
+    }
+
+    /**
+     * SoftRouter has a single versatile table - the filter table. All versatile
+     * flow rules must include the filtering rules.
+     *
+     * @param fwd The forwarding objective of type versatile
+     * @return  A collection of flow rules meant to be delivered to the flowrule
+     *          subsystem. May return empty collection in case of failures.
+     */
+    private Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
+        if (filters.isEmpty()) {
+            pendingVersatiles.add(fwd);
+            return Collections.emptySet();
+        }
+        Collection<FlowRule> flowrules = new ArrayList<FlowRule>();
+        for (Filter filter : filters) {
+            flowrules.addAll(processVersatilesWithFilters(filter, fwd));
+        }
+        return flowrules;
+    }
+
+    private Collection<FlowRule> processVersatilesWithFilters(
+                Filter filt, ForwardingObjective fwd) {
+        log.info("Processing versatile forwarding objective");
+        Collection<FlowRule> flows = new ArrayList<FlowRule>();
+        TrafficSelector match = fwd.selector();
+        EthTypeCriterion ethType =
+                (EthTypeCriterion) match.getCriterion(Criterion.Type.ETH_TYPE);
+        if (ethType == null) {
+            log.error("Versatile forwarding objective must include ethType");
+            fail(fwd, ObjectiveError.UNKNOWN);
+            return Collections.emptySet();
+        }
+
+        if (ethType.ethType() == Ethernet.TYPE_ARP) {
+            // need to install ARP request & reply flow rules for each interface filter
+
+            // rule for ARP replies
+            TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+            selector.matchInPort(filt.port());
+            selector.matchVlanId(filt.vlanId());
+            selector.matchEthDst(filt.mac());
+            selector.matchEthType(Ethernet.TYPE_ARP);
+            FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+                    .fromApp(fwd.appId())
+                    .withPriority(fwd.priority())
+                    .forDevice(deviceId)
+                    .withSelector(selector.build())
+                    .withTreatment(fwd.treatment())
+                    .makePermanent()
+                    .forTable(FILTER_TABLE);
+            flows.add(ruleBuilder.build());
+
+            //rule for ARP requests
+            selector = DefaultTrafficSelector.builder();
+            selector.matchInPort(filt.port());
+            selector.matchVlanId(filt.vlanId());
+            selector.matchEthDst(MacAddress.BROADCAST);
+            selector.matchEthType(Ethernet.TYPE_ARP);
+            ruleBuilder = DefaultFlowRule.builder()
+                    .fromApp(fwd.appId())
+                    .withPriority(fwd.priority())
+                    .forDevice(deviceId)
+                    .withSelector(selector.build())
+                    .withTreatment(fwd.treatment())
+                    .makePermanent()
+                    .forTable(FILTER_TABLE);
+            flows.add(ruleBuilder.build());
+
+            return flows;
+        }
+        // not handling other versatile flows
+        return Collections.emptySet();
+    }
+
+    /**
+     * SoftRouter has a single specific table - the FIB Table. It emulates
+     * LPM matching of dstIP by using higher priority flows for longer prefixes.
+     * Flows are forwarded using flow-actions
+     *
+     * @param fwd The forwarding objective of type simple
+     * @return A collection of flow rules meant to be delivered to the flowrule
+     *         subsystem. Typically the returned collection has a single flowrule.
+     *         May return empty collection in case of failures.
+     *
+     */
+    private Collection<FlowRule> processSpecific(ForwardingObjective fwd) {
+        log.debug("Processing specific forwarding objective");
+        TrafficSelector selector = fwd.selector();
+        EthTypeCriterion ethType =
+                (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
+        // XXX currently supporting only the L3 unicast table
+        if (ethType == null || ethType.ethType() != Ethernet.TYPE_IPV4) {
+            fail(fwd, ObjectiveError.UNSUPPORTED);
+            return Collections.emptySet();
+        }
+
+        TrafficSelector filteredSelector =
+                DefaultTrafficSelector.builder()
+                        .matchEthType(Ethernet.TYPE_IPV4)
+                        .matchIPDst(((IPCriterion)
+                                selector.getCriterion(Criterion.Type.IPV4_DST)).ip())
+                        .build();
+
+        TrafficTreatment tt = null;
+        if (fwd.nextId() != null) {
+            NextGroup next = flowObjectiveStore.getNextGroup(fwd.nextId());
+            if (next == null) {
+                log.error("next-id {} does not exist in store", fwd.nextId());
+                return Collections.emptySet();
+            }
+            tt = appKryo.deserialize(next.data());
+            if (tt == null)  {
+                log.error("Error in deserializing next-id {}", fwd.nextId());
+                return Collections.emptySet();
+            }
+        }
+
+        FlowRule.Builder ruleBuilder = DefaultFlowRule.builder()
+                .fromApp(fwd.appId())
+                .withPriority(fwd.priority())
+                .forDevice(deviceId)
+                .withSelector(filteredSelector)
+                .withTreatment(tt);
+
+        if (fwd.permanent()) {
+            ruleBuilder.makePermanent();
+        } else {
+            ruleBuilder.makeTemporary(fwd.timeout());
+        }
+
+        ruleBuilder.forTable(FIB_TABLE);
+        return Collections.singletonList(ruleBuilder.build());
+    }
+
+    /**
+     * Next Objectives are stored as dummy groups for retrieval later
+     * when Forwarding Objectives reference the next objective id. At that point
+     * the dummy group is fetched from the distributed store and the enclosed
+     * treatment is applied as a flow rule action.
+     *
+     * @param nextObjective the next objective of type simple
+     */
+    private void processSimpleNextObjective(NextObjective nextObj) {
+        // Simple next objective has a single treatment (not a collection)
+        flowObjectiveStore.putNextGroup(nextObj.id(),
+                                        new DummyGroup(nextObj.next().iterator().next()));
+    }
+
+    private class Filter {
+        private PortCriterion port;
+        private VlanIdCriterion vlan;
+        private EthCriterion eth;
+
+        @SuppressWarnings("unused")
+        private Collection<IPCriterion> ips;
+
+        public Filter(PortCriterion p, EthCriterion e, VlanIdCriterion v,
+                      Collection<IPCriterion> ips) {
+            this.eth = e;
+            this.port = p;
+            this.vlan = v;
+            this.ips = ips;
+        }
+
+        public PortNumber port() {
+            return port.port();
+        }
+
+        public VlanId vlanId() {
+            return vlan.vlanId();
+        }
+
+        public MacAddress mac() {
+            return eth.mac();
+        }
+    }
+
+    private class DummyGroup implements NextGroup {
+        TrafficTreatment nextActions;
+
+        public DummyGroup(TrafficTreatment next) {
+            this.nextActions = next;
+        }
+
+        @Override
+        public byte[] data() {
+            return appKryo.serialize(nextActions);
+        }
+
+    }
+
+}
