diff --git a/apps/routing/cpr/BUCK b/apps/routing/cpr/BUCK
new file mode 100644
index 0000000..89a499d
--- /dev/null
+++ b/apps/routing/cpr/BUCK
@@ -0,0 +1,30 @@
+COMPILE_DEPS = [
+    '//lib:CORE_DEPS',
+    '//incubator/api:onos-incubator-api',
+    '//apps/routing-api:onos-apps-routing-api',
+]
+
+TEST_DEPS = [
+    '//lib:TEST_ADAPTERS',
+    '//incubator/api:onos-incubator-api-tests',
+    '//apps/routing-api:onos-apps-routing-api-tests',
+]
+
+osgi_jar_with_tests (
+    deps = COMPILE_DEPS,
+    test_deps = TEST_DEPS,
+)
+
+BUNDLES = [
+    '//apps/routing/cpr:onos-apps-routing-cpr',
+    '//apps/routing-api:onos-apps-routing-api',
+]
+
+onos_app (
+    app_name = 'org.onosproject.cpr',
+    title = 'Control plane redirect',
+    category = 'Traffic Steering',
+    url = 'http://onosproject.org',
+    description = 'Redirects routing control traffic to a control plane',
+    included_bundles = BUNDLES,
+)
diff --git a/apps/routing/cpr/pom.xml b/apps/routing/cpr/pom.xml
new file mode 100644
index 0000000..cbc03df
--- /dev/null
+++ b/apps/routing/cpr/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Copyright 2017-present Open Networking Laboratory
+  ~
+  ~ 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.
+  -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>onos-app-routing-parent</artifactId>
+        <groupId>org.onosproject</groupId>
+        <version>1.9.0-SNAPSHOT</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>onos-apps-routing-cpr</artifactId>
+    <packaging>bundle</packaging>
+
+
+</project>
diff --git a/apps/routing/cpr/src/main/java/org/onosproject/routing/cpr/ControlPlaneRedirectManager.java b/apps/routing/cpr/src/main/java/org/onosproject/routing/cpr/ControlPlaneRedirectManager.java
new file mode 100644
index 0000000..e1d2d39
--- /dev/null
+++ b/apps/routing/cpr/src/main/java/org/onosproject/routing/cpr/ControlPlaneRedirectManager.java
@@ -0,0 +1,724 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.routing.cpr;
+
+import com.google.common.collect.ImmutableSortedSet;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.EthType;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Host;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.host.HostEvent;
+import org.onosproject.net.host.HostListener;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.routing.AsyncDeviceFetcher;
+import org.onosproject.routing.RouterInterfaceManager;
+import org.onosproject.routing.RoutingService;
+import org.onosproject.routing.config.RouterConfig;
+import org.slf4j.Logger;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+import static com.google.common.base.Preconditions.checkState;
+import static org.onlab.packet.Ethernet.TYPE_ARP;
+import static org.onlab.packet.Ethernet.TYPE_IPV4;
+import static org.onlab.packet.Ethernet.TYPE_IPV6;
+import static org.onlab.packet.ICMP6.NEIGHBOR_ADVERTISEMENT;
+import static org.onlab.packet.ICMP6.NEIGHBOR_SOLICITATION;
+import static org.onlab.packet.IPv6.PROTOCOL_ICMP6;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Manages connectivity between peers redirecting control traffic to a routing
+ * control plane available on the dataplane.
+ */
+@Component(immediate = true)
+public class ControlPlaneRedirectManager {
+
+    private final Logger log = getLogger(getClass());
+
+    public static final short ASSIGNED_VLAN = 4094;
+
+    private static final int MIN_IP_PRIORITY = 10;
+    private static final int IPV4_PRIORITY = 2000;
+    private static final int IPV6_PRIORITY = 500;
+    static final int ACL_PRIORITY = 40001;
+    private static final int OSPF_IP_PROTO = 0x59;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected CoreService coreService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected InterfaceService interfaceService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected NetworkConfigService networkConfigService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected MastershipService mastershipService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected HostService hostService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected ApplicationService applicationService;
+
+    private static final String APP_NAME = "org.onosproject.vrouter";
+    private ApplicationId appId;
+
+    private ConnectPoint controlPlaneConnectPoint;
+    private boolean ospfEnabled = false;
+    private Map<Host, Set<Integer>> peerNextId = Maps.newConcurrentMap();
+
+    private RouterInterfaceManager interfaceManager;
+    private AsyncDeviceFetcher asyncDeviceFetcher;
+
+    private final InternalNetworkConfigListener networkConfigListener =
+            new InternalNetworkConfigListener();
+    private final InternalHostListener hostListener = new InternalHostListener();
+
+    @Activate
+    public void activate() {
+        this.appId = coreService.registerApplication(APP_NAME);
+
+        networkConfigService.addListener(networkConfigListener);
+        hostService.addListener(hostListener);
+
+        asyncDeviceFetcher = AsyncDeviceFetcher.create(deviceService);
+
+        processRouterConfig();
+
+
+        // FIXME There can be an issue when this component is deactivated before vRouter
+        applicationService.registerDeactivateHook(this.appId, () -> {
+            if (interfaceManager != null) {
+                interfaceManager.cleanup();
+            }
+        });
+    }
+
+    @Deactivate
+    public void deactivate() {
+        networkConfigService.removeListener(networkConfigListener);
+        hostService.removeListener(hostListener);
+        asyncDeviceFetcher.shutdown();
+    }
+
+    /**
+     * Sets up the router interfaces if router config is available.
+     */
+    private void processRouterConfig() {
+        ApplicationId routingAppId =
+                coreService.registerApplication(RoutingService.ROUTER_APP_ID);
+
+        RouterConfig config = networkConfigService.getConfig(
+                routingAppId, RoutingService.ROUTER_CONFIG_CLASS);
+
+        if (config == null) {
+            log.warn("Router config not available");
+            return;
+        }
+
+        if (interfaceManager == null) {
+            controlPlaneConnectPoint = config.getControlPlaneConnectPoint();
+            ospfEnabled = config.getOspfEnabled();
+
+            DeviceId deviceId = config.getControlPlaneConnectPoint().deviceId();
+
+            asyncDeviceFetcher.getDevice(deviceId)
+                    .thenAccept(deviceId1 ->
+                            interfaceManager = createRouter(deviceId,
+                                    Sets.newHashSet(config.getInterfaces())));
+
+        } else {
+            interfaceManager.changeConfiguredInterfaces(Sets.newHashSet(config.getInterfaces()));
+        }
+    }
+
+    /**
+     * Cleans up after router config was removed.
+     */
+    private void removeRouterConfig() {
+        if (interfaceManager != null) {
+            interfaceManager.cleanup();
+        }
+    }
+
+    private RouterInterfaceManager createRouter(DeviceId deviceId, Set<String> configuredInterfaces) {
+        return new RouterInterfaceManager(deviceId,
+                configuredInterfaces,
+                interfaceService,
+                this::provisionInterface,
+                this::unprovisionInterface);
+    }
+
+    private void provisionInterface(Interface intf) {
+        updateInterfaceObjectives(intf, true);
+    }
+
+    private void unprovisionInterface(Interface intf) {
+        updateInterfaceObjectives(intf, false);
+    }
+
+    /**
+     * Installs or removes flow objectives relating to a give interface.
+     *
+     * @param intf interface to change objectives for
+     * @param install true to install the objectives, false to remove them
+     */
+    private void updateInterfaceObjectives(Interface intf, boolean install) {
+        updateInterfaceForwarding(intf, install);
+        updateOspfForwarding(intf, install);
+    }
+
+    /**
+     * Installs or removes the basic forwarding flows for each interface.
+     *
+     * @param intf the Interface on which event is received
+     * @param install true to install the objectives, false to remove them
+     */
+    private void updateInterfaceForwarding(Interface intf, boolean install) {
+        log.debug("{} interface objectives for {}", operation(install), intf);
+
+        DeviceId deviceId = intf.connectPoint().deviceId();
+        PortNumber controlPlanePort = controlPlaneConnectPoint.port();
+        for (InterfaceIpAddress ip : intf.ipAddresses()) {
+            // create nextObjectives for forwarding to this interface and the
+            // controlPlaneConnectPoint
+            int cpNextId, intfNextId;
+            if (intf.vlan() == VlanId.NONE) {
+                cpNextId = modifyNextObjective(deviceId, controlPlanePort,
+                               VlanId.vlanId(ASSIGNED_VLAN),
+                               true, install);
+                intfNextId = modifyNextObjective(deviceId, intf.connectPoint().port(),
+                               VlanId.vlanId(ASSIGNED_VLAN),
+                               true, install);
+            } else {
+                cpNextId = modifyNextObjective(deviceId, controlPlanePort,
+                                               intf.vlan(), false, install);
+                intfNextId = modifyNextObjective(deviceId, intf.connectPoint().port(),
+                                                 intf.vlan(), false, install);
+            }
+            List<ForwardingObjective> fwdToSend = Lists.newArrayList();
+            TrafficSelector selector;
+            // IP traffic toward the router.
+            selector = buildIPDstSelector(
+                    ip.ipAddress().toIpPrefix(),
+                    intf.connectPoint().port(),
+                    null,
+                    intf.mac(),
+                    intf.vlan()
+            );
+            fwdToSend.add(buildForwardingObjective(selector, null, cpNextId, install, ACL_PRIORITY));
+            // IP traffic from the router.
+            selector = buildIPSrcSelector(
+                    ip.ipAddress().toIpPrefix(),
+                    controlPlanePort,
+                    intf.mac(),
+                    null,
+                    intf.vlan()
+            );
+            fwdToSend.add(buildForwardingObjective(selector, null, intfNextId, install, ACL_PRIORITY));
+            // We build the punt treatment.
+            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
+                    .punt()
+                    .build();
+            // Handling of neighbour discovery protocols.
+            // IPv4 traffic - we have to deal with the ARP protocol.
+            // IPv6 traffic - we have to deal with the NDP protocol.
+            if (ip.ipAddress().isIp4()) {
+                 // ARP traffic towards the router.
+                selector = buildArpSelector(
+                        intf.connectPoint().port(),
+                        intf.vlan(),
+                        null,
+                        null
+                );
+                fwdToSend.add(buildForwardingObjective(selector, treatment, cpNextId, install, ACL_PRIORITY + 1));
+                // ARP traffic from the router.
+                selector = buildArpSelector(
+                        controlPlanePort,
+                        intf.vlan(),
+                        ip.ipAddress().getIp4Address(),
+                        intf.mac()
+                );
+                fwdToSend.add(buildForwardingObjective(selector, treatment, intfNextId, install, ACL_PRIORITY + 1));
+            } else {
+                // Neighbour solicitation traffic towards the router.
+                selector = buildNdpSelector(
+                        intf.connectPoint().port(),
+                        intf.vlan(),
+                        null,
+                        NEIGHBOR_SOLICITATION,
+                        null
+                );
+                fwdToSend.add(buildForwardingObjective(selector, treatment, cpNextId, install, ACL_PRIORITY + 1));
+                // Neighbour solicitation traffic from the router.
+                selector = buildNdpSelector(
+                        controlPlanePort,
+                        intf.vlan(),
+                        ip.ipAddress().toIpPrefix(),
+                        NEIGHBOR_SOLICITATION,
+                        intf.mac()
+                );
+                fwdToSend.add(buildForwardingObjective(selector, treatment, intfNextId, install, ACL_PRIORITY + 1));
+                 // Neighbour advertisement traffic towards the router.
+                selector = buildNdpSelector(
+                        intf.connectPoint().port(),
+                        intf.vlan(),
+                        null,
+                        NEIGHBOR_ADVERTISEMENT,
+                        null
+                );
+                fwdToSend.add(buildForwardingObjective(selector, treatment, cpNextId, install, ACL_PRIORITY + 1));
+                // Neighbour advertisement traffic from the router.
+                selector = buildNdpSelector(
+                        controlPlanePort,
+                        intf.vlan(),
+                        ip.ipAddress().toIpPrefix(),
+                        NEIGHBOR_ADVERTISEMENT,
+                        intf.mac()
+                );
+                fwdToSend.add(buildForwardingObjective(selector, treatment, intfNextId, install, ACL_PRIORITY + 1));
+            }
+            // Finally we push the fwd objectives through the flow objective service.
+            fwdToSend.stream().forEach(forwardingObjective ->
+                flowObjectiveService.forward(deviceId, forwardingObjective)
+            );
+        }
+    }
+
+    /**
+     * Installs or removes OSPF forwarding rules.
+     *
+     * @param intf the interface on which event is received
+     * @param install true to create an add objective, false to create a remove
+     *            objective
+     */
+    private void updateOspfForwarding(Interface intf, boolean install) {
+        // TODO IPv6 support has not been implemented yet
+
+        log.debug("{} OSPF flows for {}", operation(install), intf);
+
+        // OSPF to router
+        TrafficSelector toSelector = DefaultTrafficSelector.builder()
+                .matchInPort(intf.connectPoint().port())
+                .matchEthType(EthType.EtherType.IPV4.ethType().toShort())
+                .matchVlanId(intf.vlan())
+                .matchIPProtocol((byte) OSPF_IP_PROTO)
+                .build();
+
+        // create nextObjectives for forwarding to the controlPlaneConnectPoint
+        DeviceId deviceId = intf.connectPoint().deviceId();
+        PortNumber controlPlanePort = intf.connectPoint().port();
+        int cpNextId;
+        if (intf.vlan() == VlanId.NONE) {
+            cpNextId = modifyNextObjective(deviceId, controlPlanePort,
+                           VlanId.vlanId(ASSIGNED_VLAN),
+                           true, install);
+        } else {
+            cpNextId = modifyNextObjective(deviceId, controlPlanePort,
+                                           intf.vlan(), false, install);
+        }
+        flowObjectiveService.forward(intf.connectPoint().deviceId(),
+                buildForwardingObjective(toSelector, null, cpNextId,
+                        install ? ospfEnabled : install, ACL_PRIORITY));
+    }
+
+    /**
+     * Creates a next objective for forwarding to a port. Handles metadata for
+     * some pipelines that require vlan information for egress port.
+     *
+     * @param deviceId the device on which the next objective is being created
+     * @param portNumber the egress port
+     * @param vlanId vlan information for egress port
+     * @param popVlan if vlan tag should be popped or not
+     * @param install true to create an add next objective, false to create a remove
+     *            next objective
+     * @return nextId of the next objective created
+     */
+    private int modifyNextObjective(DeviceId deviceId, PortNumber portNumber,
+                                    VlanId vlanId, boolean popVlan, boolean install) {
+        int nextId = flowObjectiveService.allocateNextId();
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective
+                .builder().withId(nextId)
+                .withType(NextObjective.Type.SIMPLE)
+                .fromApp(appId);
+
+        TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
+        if (popVlan) {
+            ttBuilder.popVlan();
+        }
+        ttBuilder.setOutput(portNumber);
+
+        // setup metadata to pass to nextObjective - indicate the vlan on egress
+        // if needed by the switch pipeline.
+        TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
+        metabuilder.matchVlanId(vlanId);
+
+        nextObjBuilder.withMeta(metabuilder.build());
+        nextObjBuilder.addTreatment(ttBuilder.build());
+        log.debug("Submitted next objective {} in device {} for port/vlan {}/{}",
+                nextId, deviceId, portNumber, vlanId);
+        if (install) {
+             flowObjectiveService.next(deviceId, nextObjBuilder.add());
+        } else {
+             flowObjectiveService.next(deviceId, nextObjBuilder.remove());
+        }
+        return nextId;
+    }
+
+    /**
+     * Builds a forwarding objective from the given selector, treatment and nextId.
+     *
+     * @param selector selector
+     * @param treatment treatment to apply to packet, can be null
+     * @param nextId next objective to point to for forwarding packet
+     * @param add true to create an add objective, false to create a remove
+     *            objective
+     * @return forwarding objective
+     */
+    private ForwardingObjective buildForwardingObjective(TrafficSelector selector,
+                                                         TrafficTreatment treatment,
+                                                         int nextId,
+                                                         boolean add,
+                                                         int priority) {
+        DefaultForwardingObjective.Builder fobBuilder = DefaultForwardingObjective.builder();
+        fobBuilder.withSelector(selector);
+        if (treatment != null) {
+            fobBuilder.withTreatment(treatment);
+        }
+        if (nextId != -1) {
+            fobBuilder.nextStep(nextId);
+        }
+        fobBuilder.fromApp(appId)
+            .withPriority(priority)
+            .withFlag(ForwardingObjective.Flag.VERSATILE);
+
+        return add ? fobBuilder.add() : fobBuilder.remove();
+    }
+
+
+    static TrafficSelector.Builder buildBaseSelectorBuilder(PortNumber inPort,
+                                                            MacAddress srcMac,
+                                                            MacAddress dstMac,
+                                                            VlanId vlanId) {
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+        if (inPort != null) {
+            selectorBuilder.matchInPort(inPort);
+        }
+        if (srcMac != null) {
+            selectorBuilder.matchEthSrc(srcMac);
+        }
+        if (dstMac != null) {
+            selectorBuilder.matchEthDst(dstMac);
+        }
+        if (vlanId != null) {
+            selectorBuilder.matchVlanId(vlanId);
+        }
+        return selectorBuilder;
+    }
+
+    static TrafficSelector buildIPDstSelector(IpPrefix dstIp,
+                                              PortNumber inPort,
+                                              MacAddress srcMac,
+                                              MacAddress dstMac,
+                                              VlanId vlanId) {
+        TrafficSelector.Builder selector = buildBaseSelectorBuilder(inPort, srcMac, dstMac, vlanId);
+        if (dstIp.isIp4()) {
+            selector.matchEthType(TYPE_IPV4);
+            selector.matchIPDst(dstIp);
+        } else {
+            selector.matchEthType(TYPE_IPV6);
+            selector.matchIPv6Dst(dstIp);
+        }
+        return selector.build();
+    }
+
+    static TrafficSelector buildIPSrcSelector(IpPrefix srcIp,
+                                              PortNumber inPort,
+                                              MacAddress srcMac,
+                                              MacAddress dstMac,
+                                              VlanId vlanId) {
+        TrafficSelector.Builder selector = buildBaseSelectorBuilder(inPort, srcMac, dstMac, vlanId);
+        if (srcIp.isIp4()) {
+            selector.matchEthType(TYPE_IPV4);
+            selector.matchIPSrc(srcIp);
+        } else {
+            selector.matchEthType(TYPE_IPV6);
+            selector.matchIPv6Src(srcIp);
+        }
+        return selector.build();
+    }
+
+    static TrafficSelector buildArpSelector(PortNumber inPort,
+                                            VlanId vlanId,
+                                            Ip4Address arpSpa,
+                                            MacAddress srcMac) {
+        TrafficSelector.Builder selector = buildBaseSelectorBuilder(inPort, null, null, vlanId);
+        selector.matchEthType(TYPE_ARP);
+        if (arpSpa != null) {
+            selector.matchArpSpa(arpSpa);
+        }
+        if (srcMac != null) {
+            selector.matchEthSrc(srcMac);
+        }
+        return selector.build();
+    }
+
+    static TrafficSelector buildNdpSelector(PortNumber inPort,
+                                            VlanId vlanId,
+                                            IpPrefix srcIp,
+                                            byte subProto,
+                                            MacAddress srcMac) {
+        TrafficSelector.Builder selector = buildBaseSelectorBuilder(inPort, null, null, vlanId);
+        selector.matchEthType(TYPE_IPV6)
+                .matchIPProtocol(PROTOCOL_ICMP6)
+                .matchIcmpv6Type(subProto);
+        if (srcIp != null) {
+            selector.matchIPv6Src(srcIp);
+        }
+        if (srcMac != null) {
+            selector.matchEthSrc(srcMac);
+        }
+        return selector.build();
+    }
+
+    private int getPriorityFromPrefix(IpPrefix prefix) {
+        return (prefix.isIp4()) ?
+               IPV4_PRIORITY * prefix.prefixLength() + MIN_IP_PRIORITY :
+               IPV6_PRIORITY * prefix.prefixLength() + MIN_IP_PRIORITY;
+    }
+
+    private String operation(boolean install) {
+        return install ? "Installing" : "Removing";
+    }
+
+
+    /**
+     * Listener for network config events.
+     */
+    private class InternalNetworkConfigListener implements NetworkConfigListener {
+
+        @Override
+        public void event(NetworkConfigEvent event) {
+            if (event.configClass().equals(RoutingService.ROUTER_CONFIG_CLASS)) {
+                switch (event.type()) {
+                    case CONFIG_ADDED:
+                    case CONFIG_UPDATED:
+                        processRouterConfig();
+                        break;
+                    case CONFIG_REGISTERED:
+                        break;
+                    case CONFIG_UNREGISTERED:
+                        break;
+                    case CONFIG_REMOVED:
+                        removeRouterConfig();
+                        break;
+                default:
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Listener for host events.
+     */
+    private class InternalHostListener implements HostListener {
+
+        private Optional<Interface> getPeerInterface(Host peer) {
+            return interfaceService.getInterfacesByPort(peer.location()).stream()
+                    .filter(intf -> interfaceManager.configuredInterfaces().isEmpty()
+                            || interfaceManager.configuredInterfaces().contains(intf.name()))
+                    .filter(intf -> peer.vlan().equals(intf.vlan()))
+                    .findFirst();
+        }
+
+        private void peerAdded(HostEvent event) {
+            Host peer = event.subject();
+            if (interfaceManager == null) {
+                return;
+            }
+
+            Optional<Interface> peerIntf = getPeerInterface(peer);
+            if (!peerIntf.isPresent()) {
+                log.debug("Adding peer {}/{} on {} but the interface is not configured",
+                        peer.mac(), peer.vlan(), peer.location());
+                return;
+            }
+
+            // Generate L3 Unicast groups and store it in the map
+            int toRouterL3Unicast = createPeerGroup(peer.mac(), peerIntf.get().mac(),
+                    peer.vlan(), peer.location().deviceId(), peerIntf.get().connectPoint().port());
+            int toPeerL3Unicast = createPeerGroup(peerIntf.get().mac(), peer.mac(),
+                    peer.vlan(), peer.location().deviceId(), peer.location().port());
+            peerNextId.put(peer, ImmutableSortedSet.of(toRouterL3Unicast, toPeerL3Unicast));
+
+            // From peer to router
+            peerIntf.get().ipAddresses().forEach(routerIp -> {
+                flowObjectiveService.forward(peer.location().deviceId(),
+                        createPeerObjBuilder(toRouterL3Unicast, routerIp.ipAddress().toIpPrefix()).add());
+            });
+
+            // From router to peer
+            peer.ipAddresses().forEach(peerIp -> {
+                flowObjectiveService.forward(peer.location().deviceId(),
+                        createPeerObjBuilder(toPeerL3Unicast, peerIp.toIpPrefix()).add());
+            });
+        }
+
+        private void peerRemoved(HostEvent event) {
+            Host peer = event.subject();
+            Optional<Interface> peerIntf = getPeerInterface(peer);
+            if (!peerIntf.isPresent()) {
+                log.debug("Removing peer {}/{} on {} but the interface is not configured",
+                        peer.mac(), peer.vlan(), peer.location());
+                return;
+            }
+
+            checkState(peerNextId.get(peer) != null,
+                    "Peer nextId should not be null");
+            checkState(peerNextId.get(peer).size() == 2,
+                    "Wrong nextId associated with the peer");
+            Iterator<Integer> iter = peerNextId.get(peer).iterator();
+            int toRouterL3Unicast = iter.next();
+            int toPeerL3Unicast = iter.next();
+
+            // From peer to router
+            peerIntf.get().ipAddresses().forEach(routerIp -> {
+                flowObjectiveService.forward(peer.location().deviceId(),
+                        createPeerObjBuilder(toRouterL3Unicast, routerIp.ipAddress().toIpPrefix()).remove());
+            });
+
+            // From router to peer
+            peer.ipAddresses().forEach(peerIp -> {
+                flowObjectiveService.forward(peer.location().deviceId(),
+                        createPeerObjBuilder(toPeerL3Unicast, peerIp.toIpPrefix()).remove());
+            });
+        }
+
+        private ForwardingObjective.Builder createPeerObjBuilder(
+                int nextId, IpPrefix ipAddresses) {
+            TrafficSelector selector = buildIPDstSelector(ipAddresses, null, null, null, null);
+            DefaultForwardingObjective.Builder builder =
+                    DefaultForwardingObjective.builder()
+                    .withSelector(selector)
+                    .fromApp(appId)
+                    .withPriority(getPriorityFromPrefix(ipAddresses))
+                    .withFlag(ForwardingObjective.Flag.SPECIFIC);
+            if (nextId != -1) {
+                builder.nextStep(nextId);
+            }
+            return builder;
+        }
+
+        private int createPeerGroup(MacAddress srcMac, MacAddress dstMac,
+                VlanId vlanId, DeviceId deviceId, PortNumber port) {
+            int nextId = flowObjectiveService.allocateNextId();
+            NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder()
+                    .withId(nextId)
+                    .withType(NextObjective.Type.SIMPLE)
+                    .fromApp(appId);
+
+            TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
+            ttBuilder.setEthSrc(srcMac);
+            ttBuilder.setEthDst(dstMac);
+            ttBuilder.setOutput(port);
+            nextObjBuilder.addTreatment(ttBuilder.build());
+
+            TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
+            VlanId matchVlanId = (vlanId.equals(VlanId.NONE)) ?
+                    VlanId.vlanId(ASSIGNED_VLAN) :
+                    vlanId;
+            metabuilder.matchVlanId(matchVlanId);
+            nextObjBuilder.withMeta(metabuilder.build());
+
+            flowObjectiveService.next(deviceId, nextObjBuilder.add());
+            return nextId;
+        }
+
+        @Override
+        public void event(HostEvent event) {
+            DeviceId deviceId = event.subject().location().deviceId();
+            if (!mastershipService.isLocalMaster(deviceId)) {
+                return;
+            }
+            switch (event.type()) {
+                case HOST_ADDED:
+                    peerAdded(event);
+                    break;
+                case HOST_MOVED:
+                    //TODO We assume BGP peer does not move for now
+                    break;
+                case HOST_REMOVED:
+                    peerRemoved(event);
+                    break;
+                case HOST_UPDATED:
+                    //FIXME We assume BGP peer does not change IP for now
+                    // but we can discover new address.
+                    break;
+                default:
+                    break;
+            }
+        }
+    }
+
+}
+
diff --git a/apps/routing/cpr/src/main/java/org/onosproject/routing/cpr/package-info.java b/apps/routing/cpr/src/main/java/org/onosproject/routing/cpr/package-info.java
new file mode 100644
index 0000000..b098961
--- /dev/null
+++ b/apps/routing/cpr/src/main/java/org/onosproject/routing/cpr/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.
+ */
+
+/**
+ * Control plane redirect.
+ */
+package org.onosproject.routing.cpr;
diff --git a/apps/routing/cpr/src/test/java/org/onosproject/routing/cpr/ControlPlaneRedirectManagerTest.java b/apps/routing/cpr/src/test/java/org/onosproject/routing/cpr/ControlPlaneRedirectManagerTest.java
new file mode 100644
index 0000000..1291f8f
--- /dev/null
+++ b/apps/routing/cpr/src/test/java/org/onosproject/routing/cpr/ControlPlaneRedirectManagerTest.java
@@ -0,0 +1,645 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * 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.routing.cpr;
+
+import com.google.common.collect.Sets;
+import org.easymock.EasyMock;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onlab.packet.EthType;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.app.ApplicationService;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.core.CoreServiceAdapter;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceEvent;
+import org.onosproject.incubator.net.intf.InterfaceListener;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
+import org.onosproject.mastership.MastershipService;
+import org.onosproject.mastership.MastershipServiceAdapter;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Device;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.NetTestTools;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.config.Config;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigEvent.Type;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.config.NetworkConfigServiceAdapter;
+import org.onosproject.net.device.DeviceEvent;
+import org.onosproject.net.device.DeviceListener;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.flow.TrafficTreatment;
+import org.onosproject.net.flowobjective.DefaultForwardingObjective;
+import org.onosproject.net.flowobjective.DefaultNextObjective;
+import org.onosproject.net.flowobjective.FlowObjectiveService;
+import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
+import org.onosproject.net.host.HostService;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.routing.RoutingService;
+import org.onosproject.routing.config.RouterConfig;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.createNiceMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.expectLastCall;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.onlab.packet.ICMP6.NEIGHBOR_ADVERTISEMENT;
+import static org.onlab.packet.ICMP6.NEIGHBOR_SOLICITATION;
+import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.ACL_PRIORITY;
+import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildArpSelector;
+import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildIPDstSelector;
+import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildIPSrcSelector;
+import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildNdpSelector;
+
+/**
+ * UnitTests for ControlPlaneRedirectManager.
+ */
+@Ignore("Too many dependencies on internal implementation, too hard to maintain")
+public class ControlPlaneRedirectManagerTest {
+
+    private DeviceService deviceService;
+    private FlowObjectiveService flowObjectiveService;
+    private NetworkConfigService networkConfigService;
+    private final Set<Interface> interfaces = Sets.newHashSet();
+    static Device dev3 = NetTestTools.device("0000000000000001");
+    private static final int OSPF_IP_PROTO = 0x59;
+    private CoreService coreService = new TestCoreService();
+    private InterfaceService interfaceService;
+    private static final ApplicationId APPID = TestApplicationId.create("org.onosproject.vrouter");
+
+    private static final DeviceId DEVICE_ID = DeviceId.deviceId("of:0000000000000001");
+
+    private ConnectPoint controlPlaneConnectPoint = new ConnectPoint(DEVICE_ID,
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW1_ETH1 = new ConnectPoint(DEVICE_ID,
+            PortNumber.portNumber(1));
+
+    private static final ConnectPoint SW1_ETH2 = new ConnectPoint(DEVICE_ID,
+            PortNumber.portNumber(2));
+
+    private static final ConnectPoint SW1_ETH3 = new ConnectPoint(DEVICE_ID,
+            PortNumber.portNumber(3));
+
+    private ControlPlaneRedirectManager controlPlaneRedirectManager = new ControlPlaneRedirectManager();
+    private RouterConfig routerConfig = new TestRouterConfig();
+    private NetworkConfigListener networkConfigListener;
+    private DeviceListener deviceListener;
+    private MastershipService mastershipService = new InternalMastershipServiceTest();
+    private InterfaceListener interfaceListener;
+    private ApplicationService applicationService;
+
+    @Before
+    public void setUp() {
+        networkConfigListener = createMock(NetworkConfigListener.class);
+        deviceService = new TestDeviceService();
+        deviceListener = createMock(DeviceListener.class);
+
+        interfaceListener = createMock(InterfaceListener.class);
+        deviceService.addListener(deviceListener);
+        setUpInterfaceService();
+        interfaceService = new InternalInterfaceService();
+        interfaceService.addListener(interfaceListener);
+        networkConfigService = new TestNetworkConfigService();
+        networkConfigService.addListener(networkConfigListener);
+        flowObjectiveService = createMock(FlowObjectiveService.class);
+        applicationService = createNiceMock(ApplicationService.class);
+        replay(applicationService);
+        setUpFlowObjectiveService();
+        controlPlaneRedirectManager.coreService = coreService;
+        controlPlaneRedirectManager.flowObjectiveService = flowObjectiveService;
+        controlPlaneRedirectManager.networkConfigService = networkConfigService;
+        controlPlaneRedirectManager.interfaceService = interfaceService;
+        controlPlaneRedirectManager.deviceService = deviceService;
+        controlPlaneRedirectManager.hostService = createNiceMock(HostService.class);
+        controlPlaneRedirectManager.mastershipService = mastershipService;
+        controlPlaneRedirectManager.applicationService = applicationService;
+        controlPlaneRedirectManager.activate();
+        verify(flowObjectiveService);
+    }
+
+    /**
+     * Tests adding new Device to a openflow router.
+     */
+    @Test
+    public void testAddDevice() {
+        ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
+        List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
+        interfaceIpAddresses.add(
+                new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
+        );
+        interfaceIpAddresses.add(
+                new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
+        );
+
+        Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
+                MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
+        interfaces.add(sw1Eth4);
+        EasyMock.reset(flowObjectiveService);
+        setUpFlowObjectiveService();
+        deviceListener.event(new DeviceEvent(DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED, dev3));
+        verify(flowObjectiveService);
+    }
+
+    /**
+     * Tests adding while updating the networkConfig.
+     */
+    @Test
+    public void testUpdateNetworkConfig() {
+        ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
+        List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
+        interfaceIpAddresses.add(
+                new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
+        );
+        interfaceIpAddresses.add(
+                new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
+        );
+
+        Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
+                MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
+        interfaces.add(sw1Eth4);
+        EasyMock.reset(flowObjectiveService);
+        setUpFlowObjectiveService();
+        networkConfigListener
+                .event(new NetworkConfigEvent(Type.CONFIG_UPDATED, dev3, RoutingService.ROUTER_CONFIG_CLASS));
+        networkConfigService.addListener(networkConfigListener);
+        verify(flowObjectiveService);
+    }
+
+    /**
+     * Tests adding while updating the networkConfig.
+     */
+    @Test
+    public void testAddInterface() {
+        ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
+        List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
+        interfaceIpAddresses.add(
+                new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
+        );
+        interfaceIpAddresses.add(
+                new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
+        );
+
+        Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
+                MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
+        interfaces.add(sw1Eth4);
+
+        EasyMock.reset(flowObjectiveService);
+        expect(flowObjectiveService.allocateNextId()).andReturn(1).anyTimes();
+
+        setUpInterfaceConfiguration(sw1Eth4, true);
+        replay(flowObjectiveService);
+        interfaceListener.event(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, sw1Eth4, 500L));
+        verify(flowObjectiveService);
+    }
+
+    @Test
+    public void testRemoveInterface() {
+        ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
+        List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
+        interfaceIpAddresses.add(
+                new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
+        );
+        interfaceIpAddresses.add(
+                new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
+        );
+
+        Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
+                MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
+        EasyMock.reset(flowObjectiveService);
+        expect(flowObjectiveService.allocateNextId()).andReturn(1).anyTimes();
+
+        setUpInterfaceConfiguration(sw1Eth4, false);
+        replay(flowObjectiveService);
+        interfaceListener.event(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, sw1Eth4, 500L));
+        verify(flowObjectiveService);
+    }
+
+    /**
+     * Setup flow Configuration for all configured Interfaces.
+     *
+     **/
+    private void setUpFlowObjectiveService() {
+        expect(flowObjectiveService.allocateNextId()).andReturn(1).anyTimes();
+        for (Interface intf : interfaceService.getInterfaces()) {
+            setUpInterfaceConfiguration(intf, true);
+        }
+        replay(flowObjectiveService);
+    }
+
+    /**
+     * Setting up flowobjective expectations for basic forwarding and ospf.
+     **/
+    private void setUpInterfaceConfiguration(Interface intf, boolean install) {
+        DeviceId deviceId = controlPlaneConnectPoint.deviceId();
+        PortNumber controlPlanePort = controlPlaneConnectPoint.port();
+
+        for (InterfaceIpAddress ip : intf.ipAddresses()) {
+            int cpNextId, intfNextId;
+
+            cpNextId = modifyNextObjective(deviceId, controlPlanePort,
+                    VlanId.vlanId(ControlPlaneRedirectManager.ASSIGNED_VLAN), true, install);
+            intfNextId = modifyNextObjective(deviceId, intf.connectPoint().port(),
+                    VlanId.vlanId(ControlPlaneRedirectManager.ASSIGNED_VLAN), true, install);
+
+            // IP to router
+            TrafficSelector toSelector = buildIPDstSelector(
+                    ip.ipAddress().toIpPrefix(),
+                    intf.connectPoint().port(),
+                    null,
+                    intf.mac(),
+                    intf.vlan());
+
+            flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, null,
+                                                                            cpNextId, install, ACL_PRIORITY));
+            expectLastCall().once();
+
+            // IP from router
+            TrafficSelector fromSelector = buildIPSrcSelector(
+                    ip.ipAddress().toIpPrefix(),
+                    controlPlanePort,
+                    intf.mac(),
+                    null,
+                    intf.vlan()
+            );
+
+            flowObjectiveService.forward(deviceId, buildForwardingObjective(fromSelector, null,
+                                                                            intfNextId, install, ACL_PRIORITY));
+            expectLastCall().once();
+
+            TrafficTreatment puntTreatment = DefaultTrafficTreatment.builder().punt().build();
+            if (ip.ipAddress().isIp4()) {
+                // ARP to router
+                toSelector = buildArpSelector(
+                        intf.connectPoint().port(),
+                        intf.vlan(),
+                        null,
+                        null
+                );
+
+                flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, puntTreatment,
+                                                                                cpNextId, install, ACL_PRIORITY + 1));
+                expectLastCall().once();
+
+                // ARP from router
+                fromSelector = buildArpSelector(
+                        controlPlanePort,
+                        intf.vlan(),
+                        ip.ipAddress().getIp4Address(),
+                        intf.mac()
+                );
+
+                flowObjectiveService.forward(deviceId,
+                                             buildForwardingObjective(fromSelector, puntTreatment,
+                                                                      intfNextId, install, ACL_PRIORITY + 1));
+                expectLastCall().once();
+            } else {
+                // NDP solicitation to router
+                toSelector = buildNdpSelector(
+                        intf.connectPoint().port(),
+                        intf.vlan(),
+                        null,
+                        NEIGHBOR_SOLICITATION,
+                        null
+                );
+
+                flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, puntTreatment,
+                                                                                cpNextId, install, ACL_PRIORITY + 1));
+                expectLastCall().once();
+
+                // NDP solicitation from router
+                fromSelector = buildNdpSelector(
+                        controlPlanePort,
+                        intf.vlan(),
+                        ip.ipAddress().toIpPrefix(),
+                        NEIGHBOR_SOLICITATION,
+                        intf.mac()
+                );
+
+                flowObjectiveService.forward(deviceId,
+                                             buildForwardingObjective(fromSelector, puntTreatment,
+                                                                      intfNextId, install, ACL_PRIORITY + 1));
+
+                // NDP advertisement to router
+                toSelector = buildNdpSelector(
+                        intf.connectPoint().port(),
+                        intf.vlan(),
+                        null,
+                        NEIGHBOR_ADVERTISEMENT,
+                        null
+                );
+
+                flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, puntTreatment,
+                                                                                cpNextId, install, ACL_PRIORITY + 1));
+                expectLastCall().once();
+
+                // NDP advertisement from router
+                fromSelector = buildNdpSelector(
+                        controlPlanePort,
+                        intf.vlan(),
+                        ip.ipAddress().toIpPrefix(),
+                        NEIGHBOR_ADVERTISEMENT,
+                        intf.mac()
+                );
+
+                flowObjectiveService.forward(deviceId,
+                                             buildForwardingObjective(fromSelector, puntTreatment,
+                                                                      intfNextId, install, ACL_PRIORITY + 1));
+            }
+        }
+        // setting expectations for ospf forwarding.
+        TrafficSelector toSelector = DefaultTrafficSelector.builder().matchInPort(intf.connectPoint().port())
+                .matchEthType(EthType.EtherType.IPV4.ethType().toShort()).matchVlanId(intf.vlan())
+                .matchIPProtocol((byte) OSPF_IP_PROTO).build();
+
+        modifyNextObjective(deviceId, controlPlanePort, VlanId.vlanId((short) 4094), true, install);
+        flowObjectiveService.forward(controlPlaneConnectPoint.deviceId(),
+                buildForwardingObjective(toSelector, null, 1, install, 40001));
+        expectLastCall().once();
+    }
+
+    /**
+     * Setup expectations on flowObjectiveService.next for NextObjective.
+     *
+     **/
+    private int modifyNextObjective(DeviceId deviceId, PortNumber portNumber, VlanId vlanId, boolean popVlan,
+            boolean modifyFlag) {
+        NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder().withId(1)
+                .withType(NextObjective.Type.SIMPLE).fromApp(APPID);
+
+        TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
+        if (popVlan) {
+            ttBuilder.popVlan();
+        }
+        ttBuilder.setOutput(portNumber);
+
+        TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
+        metabuilder.matchVlanId(vlanId);
+
+        nextObjBuilder.withMeta(metabuilder.build());
+        nextObjBuilder.addTreatment(ttBuilder.build());
+        if (modifyFlag) {
+            flowObjectiveService.next(deviceId, nextObjBuilder.add());
+            expectLastCall().once();
+        } else {
+            flowObjectiveService.next(deviceId, nextObjBuilder.remove());
+            expectLastCall().once();
+        }
+        return 1;
+    }
+
+    /**
+     * Setup Interface expectation for all Testcases.
+     **/
+    private void setUpInterfaceService() {
+        List<InterfaceIpAddress> interfaceIpAddresses1 = new ArrayList<>();
+        interfaceIpAddresses1
+                .add(new InterfaceIpAddress(IpAddress.valueOf("192.168.10.101"), IpPrefix.valueOf("192.168.10.0/24")));
+        Interface sw1Eth1 = new Interface(SW1_ETH1.deviceId().toString(), SW1_ETH1, interfaceIpAddresses1,
+                MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE);
+        interfaces.add(sw1Eth1);
+
+        List<InterfaceIpAddress> interfaceIpAddresses2 = new ArrayList<>();
+        interfaceIpAddresses2
+                .add(new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"), IpPrefix.valueOf("192.168.20.0/24")));
+        Interface sw1Eth2 = new Interface(SW1_ETH1.deviceId().toString(), SW1_ETH2, interfaceIpAddresses2,
+                MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE);
+        interfaces.add(sw1Eth2);
+
+        List<InterfaceIpAddress> interfaceIpAddresses3 = new ArrayList<>();
+        interfaceIpAddresses3
+                .add(new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"), IpPrefix.valueOf("192.168.30.0/24")));
+        Interface sw1Eth3 = new Interface(SW1_ETH1.deviceId().toString(), SW1_ETH3, interfaceIpAddresses3,
+                MacAddress.valueOf("00:00:00:00:00:03"), VlanId.NONE);
+        interfaces.add(sw1Eth3);
+
+    }
+
+    private ForwardingObjective buildForwardingObjective(TrafficSelector selector, TrafficTreatment treatment,
+            int nextId, boolean add, int priority) {
+        DefaultForwardingObjective.Builder fobBuilder = DefaultForwardingObjective.builder();
+        fobBuilder.withSelector(selector);
+        if (treatment != null) {
+            fobBuilder.withTreatment(treatment);
+        }
+        if (nextId != -1) {
+            fobBuilder.nextStep(nextId);
+        }
+        fobBuilder.fromApp(APPID).withPriority(priority).withFlag(ForwardingObjective.Flag.VERSATILE);
+
+        return add ? fobBuilder.add() : fobBuilder.remove();
+    }
+
+    private class TestCoreService extends CoreServiceAdapter {
+
+        @Override
+        public ApplicationId getAppId(String name) {
+            return APPID;
+        }
+
+        @Override
+        public ApplicationId registerApplication(String name) {
+            return new TestApplicationId(name);
+        }
+
+    }
+
+    private class TestDeviceService extends DeviceServiceAdapter {
+
+        @Override
+        public boolean isAvailable(DeviceId deviceId) {
+            boolean flag = false;
+            if (deviceId.equals(controlPlaneConnectPoint.deviceId())) {
+                flag = true;
+            }
+            return flag;
+        }
+
+        @Override
+        public void addListener(DeviceListener listener) {
+            ControlPlaneRedirectManagerTest.this.deviceListener = listener;
+        }
+
+    }
+
+    private class TestRouterConfig extends RouterConfig {
+
+        @Override
+        public ConnectPoint getControlPlaneConnectPoint() {
+            return controlPlaneConnectPoint;
+        }
+
+        @Override
+        public boolean getOspfEnabled() {
+            return true;
+        }
+
+        @Override
+        public List<String> getInterfaces() {
+            ArrayList<String> interfaces = new ArrayList<>();
+            interfaces.add("of:0000000000000001");
+            interfaces.add("of:0000000000000001/2");
+            interfaces.add("of:0000000000000001/3");
+            return interfaces;
+        }
+
+    }
+
+    private class TestNetworkConfigService extends NetworkConfigServiceAdapter {
+
+        @Override
+        public void addListener(NetworkConfigListener listener) {
+            ControlPlaneRedirectManagerTest.this.networkConfigListener = listener;
+        }
+
+        @Override
+        public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
+            return (C) ControlPlaneRedirectManagerTest.this.routerConfig;
+        }
+
+    }
+
+    private static class TestApplicationId implements ApplicationId {
+
+        private final String name;
+        private final short id;
+
+        public TestApplicationId(String name) {
+            this.name = name;
+            this.id = (short) Objects.hash(name);
+        }
+
+        public static ApplicationId create(String name) {
+            return new TestApplicationId(name);
+        }
+
+        @Override
+        public short id() {
+            return id;
+        }
+
+        @Override
+        public String name() {
+            return name;
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = 1;
+            result = prime * result + id;
+            result = prime * result + ((name == null) ? 0 : name.hashCode());
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null) {
+                return false;
+            }
+            if (getClass() != obj.getClass()) {
+                return false;
+            }
+            TestApplicationId other = (TestApplicationId) obj;
+            if (id != other.id) {
+                return false;
+            }
+            if (name == null) {
+                if (other.name != null) {
+                    return false;
+                }
+            } else if (!name.equals(other.name)) {
+                return false;
+            }
+            return true;
+        }
+    }
+
+    private class InternalMastershipServiceTest extends MastershipServiceAdapter {
+
+        @Override
+        public boolean isLocalMaster(DeviceId deviceId) {
+            boolean flag = deviceId.equals(controlPlaneConnectPoint.deviceId());
+            return flag;
+        }
+
+    }
+
+    private class InternalInterfaceService extends InterfaceServiceAdapter {
+
+        @Override
+        public void addListener(InterfaceListener listener) {
+            ControlPlaneRedirectManagerTest.this.interfaceListener = listener;
+        }
+
+        @Override
+        public Set<Interface> getInterfaces() {
+            return interfaces;
+        }
+
+        @Override
+        public Set<Interface> getInterfacesByPort(ConnectPoint port) {
+            Set<Interface> setIntf = new HashSet<Interface>();
+            for (Interface intf : interfaces) {
+                if (intf.connectPoint().equals(port)) {
+                    setIntf.add(intf);
+                }
+            }
+            return setIntf;
+        }
+
+        @Override
+        public Interface getMatchingInterface(IpAddress ip) {
+            Interface intff = null;
+            for (Interface intf : interfaces) {
+                for (InterfaceIpAddress address : intf.ipAddresses()) {
+                    if (address.ipAddress().equals(ip)) {
+                        intff = intf;
+                        break;
+                    }
+                }
+            }
+
+            return intff;
+        }
+
+    }
+}
