diff --git a/impl/src/main/java/org/onosproject/segmentrouting/policy/impl/PolicyManager.java b/impl/src/main/java/org/onosproject/segmentrouting/policy/impl/PolicyManager.java
index dbd5667..8f7c69c 100644
--- a/impl/src/main/java/org/onosproject/segmentrouting/policy/impl/PolicyManager.java
+++ b/impl/src/main/java/org/onosproject/segmentrouting/policy/impl/PolicyManager.java
@@ -21,23 +21,32 @@
 import com.google.common.hash.HashFunction;
 import com.google.common.hash.Hashing;
 import org.glassfish.jersey.internal.guava.Sets;
+import org.onlab.packet.MacAddress;
 import org.onlab.util.KryoNamespace;
 import org.onlab.util.PredictableExecutor;
 import org.onosproject.cluster.ClusterService;
 import org.onosproject.cluster.NodeId;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+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.DefaultObjectiveContext;
 import org.onosproject.net.flowobjective.FlowObjectiveService;
 import org.onosproject.net.flowobjective.ForwardingObjective;
+import org.onosproject.net.flowobjective.NextObjective;
 import org.onosproject.net.flowobjective.Objective;
 import org.onosproject.net.flowobjective.ObjectiveContext;
 import org.onosproject.net.intent.WorkPartitionService;
+import org.onosproject.net.link.LinkService;
 import org.onosproject.segmentrouting.SegmentRoutingService;
+import org.onosproject.segmentrouting.config.DeviceConfigNotFoundException;
 import org.onosproject.segmentrouting.policy.api.DropPolicy;
 import org.onosproject.segmentrouting.policy.api.Policy;
 import org.onosproject.segmentrouting.policy.api.Policy.PolicyType;
@@ -45,6 +54,7 @@
 import org.onosproject.segmentrouting.policy.api.PolicyId;
 import org.onosproject.segmentrouting.policy.api.PolicyService;
 import org.onosproject.segmentrouting.policy.api.PolicyState;
+import org.onosproject.segmentrouting.policy.api.RedirectPolicy;
 import org.onosproject.segmentrouting.policy.api.TrafficMatch;
 import org.onosproject.segmentrouting.policy.api.TrafficMatchData;
 import org.onosproject.segmentrouting.policy.api.TrafficMatchId;
@@ -86,9 +96,18 @@
     private Logger log = getLogger(getClass());
     static final String KEY_SEPARATOR = "|";
 
+    // Supported policies
+    private static final Set<Policy.PolicyType> SUPPORTED_POLICIES = ImmutableSet.of(
+            PolicyType.DROP, PolicyType.REDIRECT);
+
+    // Driver should use this meta to match port_is_edge field in the ACL table
+    private static final long EDGE_PORT = 1;
+    private static final long INFRA_PORT = 0;
+
     // Policy/TrafficMatch store related objects. We use these consistent maps to keep track of the
     // lifecycle of a policy/traffic match. These are decomposed in multiple operations which have
     // to be performed on multiple devices in order to have a policy/traffic match in ADDED state.
+    // TODO Consider to add store and delegate
     private static final String POLICY_STORE = "sr-policy-store";
     private ConsistentMap<PolicyId, PolicyRequest> policies;
     private MapEventListener<PolicyId, PolicyRequest> mapPolListener = new InternalPolMapEventListener();
@@ -120,6 +139,7 @@
             .register(PolicyId.class)
             .register(PolicyType.class)
             .register(DropPolicy.class)
+            .register(RedirectPolicy.class)
             .register(PolicyState.class)
             .register(PolicyRequest.class)
             .register(TrafficMatchId.class)
@@ -139,13 +159,16 @@
     private ClusterService clusterService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    public WorkPartitionService workPartitionService;
+    private WorkPartitionService workPartitionService;
 
     @Reference(cardinality = ReferenceCardinality.OPTIONAL)
-    public SegmentRoutingService srService;
+    private SegmentRoutingService srService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    public FlowObjectiveService flowObjectiveService;
+    private FlowObjectiveService flowObjectiveService;
+
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    private LinkService linkService;
 
     @Activate
     public void activate() {
@@ -211,6 +234,12 @@
     @Override
     public boolean removePolicy(PolicyId policyId) {
         boolean result;
+        if (dependingTrafficMatches(policyId).isPresent()) {
+            if (log.isDebugEnabled()) {
+                log.debug("Found depending traffic matches");
+            }
+            return false;
+        }
         try {
             result = Versioned.valueOrNull(policies.computeIfPresent(policyId, (k, v) -> {
                 if (v.policyState() != PolicyState.PENDING_REMOVE) {
@@ -332,39 +361,74 @@
 
     // Orchestrate policy installation according to the type
     private void installPolicyInDevice(DeviceId deviceId, Policy policy) {
-        PolicyKey policyKey;
-        Operation operation;
-        if (policy.policyType() == PolicyType.DROP) {
-            if (log.isDebugEnabled()) {
-                log.debug("Installing DROP policy {}", policy.policyId());
-            }
-            // DROP policies do not need the next objective installation phase
-            // we can update directly the map and signal the ops as done
-            policyKey = new PolicyKey(deviceId, policy.policyId());
-            operation = Operation.builder()
-                    .isDone(true)
-                    .isInstall(true)
-                    .policy(policy)
-                    .build();
-            operations.put(policyKey.toString(), operation);
-        } else if (policy.policyType() == PolicyType.REDIRECT) {
-            if (log.isDebugEnabled()) {
-                log.debug("Installing REDIRECT policy {}", policy.policyId());
-            }
-            // REDIRECT Uses objective context to update the ops as done when it returns
-            // successfully. In the other cases leaves the ops as undone and the
-            // relative policy will remain in pending.
-        } else {
+        if (!SUPPORTED_POLICIES.contains(policy.policyType())) {
             log.warn("Policy {} type {} not yet supported",
                     policy.policyId(), policy.policyType());
+            return;
+        }
+        PolicyKey policyKey;
+        Operation.Builder operation;
+        if (log.isDebugEnabled()) {
+            log.debug("Installing {} policy {} for dev: {}",
+                    policy.policyType(), policy.policyId(), deviceId);
+        }
+        policyKey = new PolicyKey(deviceId, policy.policyId());
+        operation = Operation.builder()
+                .isInstall(true)
+                .policy(policy);
+        // TODO To better handle different policy types consider the abstraction of a compiler (subtypes ?)
+        if (policy.policyType() == PolicyType.DROP) {
+            // DROP policies do not need the next objective installation phase
+            // we can update directly the map and signal the ops as done
+            operation.isDone(true);
+            operations.put(policyKey.toString(), operation.build());
+        } else if (policy.policyType() == PolicyType.REDIRECT) {
+            // REDIRECT Uses next objective context to update the ops as done when
+            // it returns successfully. In the other cases leaves the ops as undone
+            // and the relative policy will remain in pending.
+            operations.put(policyKey.toString(), operation.build());
+            NextObjective.Builder builder = redirectPolicyNextObjective(deviceId, (RedirectPolicy) policy);
+            // Handle error here - leave the operation as undone and pending
+            if (builder != null) {
+                CompletableFuture<Objective> future = new CompletableFuture<>();
+                if (log.isDebugEnabled()) {
+                    log.debug("Installing REDIRECT next objective for dev: {}", deviceId);
+                }
+                ObjectiveContext context = new DefaultObjectiveContext(
+                        (objective) -> {
+                            if (log.isDebugEnabled()) {
+                                log.debug("REDIRECT next objective for policy {} installed in dev: {}",
+                                        policy.policyId(), deviceId);
+                            }
+                            future.complete(objective);
+                        },
+                        (objective, error) -> {
+                            log.warn("Failed to install REDIRECT next objective for policy {}: {} in dev: {}",
+                                    policy.policyId(), error, deviceId);
+                            future.complete(null);
+                        });
+                // Context is not serializable
+                NextObjective serializableObjective = builder.add();
+                flowObjectiveService.next(deviceId, builder.add(context));
+                future.whenComplete((objective, ex) -> {
+                    if (ex != null) {
+                        log.error("Exception installing REDIRECT next objective", ex);
+                    } else if (objective != null) {
+                        operations.computeIfPresent(policyKey.toString(), (k, v) -> {
+                            if (!v.isDone() && v.isInstall()) {
+                                v.isDone(true);
+                                v.objectiveOperation(serializableObjective);
+                            }
+                            return v;
+                        });
+                    }
+                });
+            }
         }
     }
 
     // Remove policy in a device according to the type
     private void removePolicyInDevice(DeviceId deviceId, Policy policy) {
-        if (log.isDebugEnabled()) {
-            log.debug("Removing policy {}", policy.policyId());
-        }
         PolicyKey policyKey = new PolicyKey(deviceId, policy.policyId());
         Operation operation = Versioned.valueOrNull(operations.get(policyKey.toString()));
         // Policy might be still in pending or not present anymore
@@ -377,24 +441,52 @@
                     .build();
             operations.put(policyKey.toString(), operation);
         } else {
+            if (log.isDebugEnabled()) {
+                log.debug("Removing {} policy {} in device {}", policy.policyType(), policy.policyId(), deviceId);
+            }
+            Operation.Builder operationBuilder = Operation.builder()
+                    .isInstall(false)
+                    .policy(policy);
             if (policy.policyType() == PolicyType.DROP) {
-                if (log.isDebugEnabled()) {
-                    log.debug("Removing DROP policy {}", policy.policyId());
-                }
-                operation = Operation.builder()
-                        .isDone(true)
-                        .isInstall(false)
-                        .policy(policy)
-                        .build();
-                operations.put(policyKey.toString(), operation);
+                operationBuilder.isDone(true);
+                operations.put(policyKey.toString(), operationBuilder.build());
             } else if (policy.policyType() == PolicyType.REDIRECT) {
+                // REDIRECT has to remove the next objective first
+                NextObjective oldObj = (NextObjective) operation.objectiveOperation();
+                operations.put(policyKey.toString(), operationBuilder.build());
+                NextObjective.Builder builder = oldObj.copy();
+                CompletableFuture<Objective> future = new CompletableFuture<>();
                 if (log.isDebugEnabled()) {
-                    log.debug("Removing REDIRECT policy {}", policy.policyId());
+                    log.debug("Removing REDIRECT next objective for dev: {}", deviceId);
                 }
-                // REDIRECT has to remove first a next objective
-            } else {
-                log.warn("Policy {} type {} not yet supported",
-                        policy.policyId(), policy.policyType());
+                ObjectiveContext context = new DefaultObjectiveContext(
+                        (objective) -> {
+                            if (log.isDebugEnabled()) {
+                                log.debug("REDIRECT next objective for policy {} removed in dev: {}",
+                                        policy.policyId(), deviceId);
+                            }
+                            future.complete(objective);
+                        },
+                        (objective, error) -> {
+                            log.warn("Failed to remove REDIRECT next objective for policy {}: {} in dev: {}",
+                                    policy.policyId(), error, deviceId);
+                            future.complete(null);
+                        });
+                NextObjective serializableObjective = builder.remove();
+                flowObjectiveService.next(deviceId, builder.remove(context));
+                future.whenComplete((objective, ex) -> {
+                    if (ex != null) {
+                        log.error("Exception Removing REDIRECT next objective", ex);
+                    } else if (objective != null) {
+                        operations.computeIfPresent(policyKey.toString(), (k, v) -> {
+                            if (!v.isDone() && !v.isInstall())  {
+                                v.isDone(true);
+                                v.objectiveOperation(serializableObjective);
+                            }
+                            return v;
+                        });
+                    }
+                });
             }
         }
     }
@@ -468,67 +560,79 @@
             log.debug("Installing traffic match {} associated to policy {}",
                     trafficMatch.trafficMatchId(), trafficMatch.policyId());
         }
-        // Updates the store and then send the versatile fwd objective to the pipeliner
         TrafficMatchKey trafficMatchKey = new TrafficMatchKey(deviceId, trafficMatch.trafficMatchId());
-        Operation trafficOperation = Operation.builder()
-                .isInstall(true)
-                .trafficMatch(trafficMatch)
-                .build();
-        operations.put(trafficMatchKey.toString(), trafficOperation);
+        Operation trafficOperation = Versioned.valueOrNull(operations.get(trafficMatchKey.toString()));
+        if (trafficOperation != null && trafficOperation.isInstall()) {
+            if (log.isDebugEnabled()) {
+                log.debug("There is already an install operation for traffic match {} associated to policy {} " +
+                        "for device {}", trafficMatch.trafficMatchId(), trafficMatch.policyId(), deviceId);
+            }
+            return;
+        }
         // For the DROP policy we need to set an ACL drop in the fwd objective. The other
         // policies require to retrieve the next Id and sets the next step.
         PolicyKey policyKey = new PolicyKey(deviceId, trafficMatch.policyId());
         Operation policyOperation = Versioned.valueOrNull(operations.get(policyKey.toString()));
         if (policyOperation == null || !policyOperation.isDone() ||
-                !policyOperation.isInstall() || policyOperation.policy().isEmpty()) {
+                !policyOperation.isInstall() || policyOperation.policy().isEmpty() ||
+                (policyOperation.policy().get().policyType() == PolicyType.REDIRECT &&
+                        policyOperation.objectiveOperation() == null)) {
             log.info("Deferring traffic match {} installation on device {}. Policy {} not yet installed",
                     trafficMatch.trafficMatchId(), deviceId, trafficMatch.policyId());
             return;
         }
+        // Updates the store and then send the versatile fwd objective to the pipeliner
+        trafficOperation = Operation.builder()
+                .isInstall(true)
+                .trafficMatch(trafficMatch)
+                .build();
+        operations.put(trafficMatchKey.toString(), trafficOperation);
         Policy policy = policyOperation.policy().get();
-        ForwardingObjective.Builder builder = trafficMatchFwdObjective(trafficMatch);
-        // TODO we can try to reuse some code: context and completable future logic
+        ForwardingObjective.Builder builder = trafficMatchFwdObjective(trafficMatch, policy.policyType());
         if (policy.policyType() == PolicyType.DROP) {
-            // Firstly builds the fwd objective with the wipeDeferred action. Once, the fwd
-            // objective has completed its execution, we update the policiesOps map
+            // Firstly builds the fwd objective with the wipeDeferred action.
             TrafficTreatment dropTreatment = DefaultTrafficTreatment.builder()
                     .wipeDeferred()
                     .build();
             builder.withTreatment(dropTreatment);
-            CompletableFuture<Objective> future = new CompletableFuture<>();
-            if (log.isDebugEnabled()) {
-                log.debug("Installing ACL drop forwarding objectives for dev: {}", deviceId);
-            }
-            ObjectiveContext context = new DefaultObjectiveContext(
-                    (objective) -> {
-                        if (log.isDebugEnabled()) {
-                            log.debug("ACL drop rule for policy {} installed", trafficMatch.policyId());
-                        }
-                        future.complete(objective);
-                    },
-                    (objective, error) -> {
-                        log.warn("Failed to install ACL drop rule for policy {}: {}", trafficMatch.policyId(), error);
-                        future.complete(null);
-                    });
-            // Context is not serializable
-            ForwardingObjective serializableObjective = builder.add();
-            flowObjectiveService.forward(deviceId, builder.add(context));
-            future.whenComplete((objective, ex) -> {
-                if (ex != null) {
-                    log.error("Exception installing ACL drop rule", ex);
-                } else if (objective != null) {
-                    operations.computeIfPresent(trafficMatchKey.toString(), (k, v) -> {
-                        if (!v.isDone() && v.isInstall())  {
-                            v.isDone(true);
-                            v.objectiveOperation(serializableObjective);
-                        }
-                        return v;
-                    });
-                }
-            });
-        } else {
-            log.warn("Policy {} type {} not yet supported", policy.policyId(), policy.policyType());
+        } else if (policy.policyType() == PolicyType.REDIRECT) {
+
+            // Here we need to set only the next step
+            builder.nextStep(policyOperation.objectiveOperation().id());
         }
+        // Once, the fwd objective has completed its execution, we update the policiesOps map
+        CompletableFuture<Objective> future = new CompletableFuture<>();
+        if (log.isDebugEnabled()) {
+            log.debug("Installing forwarding objective for dev: {}", deviceId);
+        }
+        ObjectiveContext context = new DefaultObjectiveContext(
+                (objective) -> {
+                    if (log.isDebugEnabled()) {
+                        log.debug("Forwarding objective for policy {} installed", trafficMatch.policyId());
+                    }
+                    future.complete(objective);
+                },
+                (objective, error) -> {
+                    log.warn("Failed to install forwarding objective for policy {}: {}",
+                            trafficMatch.policyId(), error);
+                    future.complete(null);
+                });
+        // Context is not serializable
+        ForwardingObjective serializableObjective = builder.add();
+        flowObjectiveService.forward(deviceId, builder.add(context));
+        future.whenComplete((objective, ex) -> {
+            if (ex != null) {
+                log.error("Exception installing forwarding objective", ex);
+            } else if (objective != null) {
+                operations.computeIfPresent(trafficMatchKey.toString(), (k, v) -> {
+                    if (!v.isDone() && v.isInstall())  {
+                        v.isDone(true);
+                        v.objectiveOperation(serializableObjective);
+                    }
+                    return v;
+                });
+            }
+        });
     }
 
     // Updates traffic match status if all the pending ops are done
@@ -597,34 +701,39 @@
                     .trafficMatch(trafficMatch)
                     .build();
             operations.put(trafficMatchKey.toString(), operation);
+        } else if (!operation.isInstall()) {
+            if (log.isDebugEnabled()) {
+                log.debug("There is already an uninstall operation for traffic match {} associated to policy {}" +
+                        " for device {}", trafficMatch.trafficMatchId(), trafficMatch.policyId(), deviceId);
+            }
         } else {
             ForwardingObjective oldObj = (ForwardingObjective) operation.objectiveOperation();
             operation = Operation.builder(operation)
-                    .isDone(false)
                     .isInstall(false)
                     .build();
             operations.put(trafficMatchKey.toString(), operation);
             ForwardingObjective.Builder builder = DefaultForwardingObjective.builder(oldObj);
             CompletableFuture<Objective> future = new CompletableFuture<>();
             if (log.isDebugEnabled()) {
-                log.debug("Removing ACL drop forwarding objectives for dev: {}", deviceId);
+                log.debug("Removing forwarding objectives for dev: {}", deviceId);
             }
             ObjectiveContext context = new DefaultObjectiveContext(
                     (objective) -> {
                         if (log.isDebugEnabled()) {
-                            log.debug("ACL drop rule for policy {} removed", trafficMatch.policyId());
+                            log.debug("Forwarding objective for policy {} removed", trafficMatch.policyId());
                         }
                         future.complete(objective);
                     },
                     (objective, error) -> {
-                        log.warn("Failed to remove ACL drop rule for policy {}: {}", trafficMatch.policyId(), error);
+                        log.warn("Failed to remove forwarding objective for policy {}: {}",
+                                trafficMatch.policyId(), error);
                         future.complete(null);
                     });
             ForwardingObjective serializableObjective = builder.remove();
             flowObjectiveService.forward(deviceId, builder.remove(context));
             future.whenComplete((objective, ex) -> {
                 if (ex != null) {
-                    log.error("Exception removing ACL drop rule", ex);
+                    log.error("Exception removing forwarding objective", ex);
                 } else if (objective != null) {
                     operations.computeIfPresent(trafficMatchKey.toString(), (k, v) -> {
                         if (!v.isDone() && !v.isInstall())  {
@@ -638,32 +747,13 @@
         }
     }
 
-    // Update any depending traffic match on the policy. It is used when a policy
-    // has been removed but there are still traffic matches depending on it
-    private void updateDependingTrafficMatches(PolicyId policyId) {
-        if (!isLeader(policyId)) {
-            if (log.isDebugEnabled()) {
-                log.debug("Instance is not leader for policy {}", policyId);
-            }
-            return;
-        }
-        workers.execute(() -> updateDependingTrafficMatchesInternal(policyId), policyId.hashCode());
-    }
-
-    private void updateDependingTrafficMatchesInternal(PolicyId policyId) {
-        Set<TrafficMatchRequest> pendingTrafficMatches = trafficMatches.stream()
+    // It is used when a policy has been removed but there are still traffic matches depending on it
+    private Optional<TrafficMatchRequest> dependingTrafficMatches(PolicyId policyId) {
+        return trafficMatches.stream()
                 .filter(trafficMatchEntry -> trafficMatchEntry.getValue().value().policyId().equals(policyId) &&
                         trafficMatchEntry.getValue().value().trafficMatchState() == TrafficMatchState.ADDED)
                 .map(trafficMatchEntry -> trafficMatchEntry.getValue().value())
-                .collect(Collectors.toSet());
-        for (TrafficMatchRequest trafficMatchRequest : pendingTrafficMatches) {
-            trafficMatches.computeIfPresent(trafficMatchRequest.trafficMatchId(), (k, v) -> {
-                if (v.trafficMatchState() == TrafficMatchState.ADDED) {
-                    v.trafficMatchState(TrafficMatchState.PENDING_REMOVE);
-                }
-                return v;
-            });
-        }
+                .findFirst();
     }
 
     // Utility that removes operations related to a policy or to a traffic match.
@@ -688,15 +778,67 @@
         }
     }
 
-    private ForwardingObjective.Builder trafficMatchFwdObjective(TrafficMatch trafficMatch) {
+    private ForwardingObjective.Builder trafficMatchFwdObjective(TrafficMatch trafficMatch, PolicyType policyType) {
+        TrafficSelector.Builder metaBuilder = DefaultTrafficSelector.builder(trafficMatch.trafficSelector());
+        if (policyType == PolicyType.REDIRECT) {
+            metaBuilder.matchMetadata(EDGE_PORT);
+        }
         return DefaultForwardingObjective.builder()
                 .withPriority(PolicyService.TRAFFIC_MATCH_PRIORITY)
                 .withSelector(trafficMatch.trafficSelector())
+                .withMeta(metaBuilder.build())
                 .fromApp(appId)
                 .withFlag(ForwardingObjective.Flag.VERSATILE)
                 .makePermanent();
     }
 
+    private NextObjective.Builder redirectPolicyNextObjective(DeviceId srcDevice, RedirectPolicy redirectPolicy) {
+        Set<Link> egressLinks = linkService.getDeviceEgressLinks(srcDevice);
+        Map<ConnectPoint, DeviceId> egressPortsToEnforce = Maps.newHashMap();
+        List<DeviceId> edgeDevices = srService.getEdgeDeviceIds();
+        egressLinks.stream()
+                .filter(link -> redirectPolicy.spinesToEnforce().contains(link.dst().deviceId()) &&
+                                !edgeDevices.contains(link.dst().deviceId()))
+                .forEach(link -> egressPortsToEnforce.put(link.src(), link.dst().deviceId()));
+        // No ports no friend
+        if (egressPortsToEnforce.isEmpty()) {
+            log.warn("There are no port available for the REDIRECT policy {}", redirectPolicy.policyId());
+            return null;
+        }
+        // We need to add a treatment for each valid egress port. The treatment
+        // requires to set src and dst mac address and set the egress port. We are
+        // deliberately not providing the metadata to prevent the programming of
+        // some tables which are already controlled by SegmentRouting or are unnecessary
+        int nextId = flowObjectiveService.allocateNextId();
+        DefaultNextObjective.Builder builder = DefaultNextObjective.builder()
+                .withId(nextId)
+                .withType(NextObjective.Type.HASHED)
+                .fromApp(appId);
+        MacAddress srcDeviceMac;
+        try {
+            srcDeviceMac = srService.getDeviceMacAddress(srcDevice);
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting installation REDIRECT policy {}", redirectPolicy.policyId());
+            return null;
+        }
+        MacAddress neigborDeviceMac;
+        TrafficTreatment.Builder tBuilder;
+        for (Map.Entry<ConnectPoint, DeviceId> entry : egressPortsToEnforce.entrySet()) {
+            try {
+                neigborDeviceMac = srService.getDeviceMacAddress(entry.getValue());
+            } catch (DeviceConfigNotFoundException e) {
+                log.warn(e.getMessage() + " Aborting installation REDIRECT policy {}", redirectPolicy.policyId());
+                return null;
+            }
+            tBuilder = DefaultTrafficTreatment.builder()
+                    .setEthSrc(srcDeviceMac)
+                    .setEthDst(neigborDeviceMac)
+                    .setOutput(entry.getKey().port());
+            builder.addTreatment(tBuilder.build());
+        }
+        return builder;
+    }
+
     // Each map has an event listener enabling the events distribution across the cluster
     private class InternalPolMapEventListener implements MapEventListener<PolicyId, PolicyRequest> {
         @Override
@@ -723,7 +865,6 @@
                     break;
                 case REMOVE:
                     removeOperations(policy.policyId(), Optional.empty());
-                    updateDependingTrafficMatches(policy.policyId());
                     break;
                 default:
                     log.warn("Unknown event type {}", event.type());
@@ -812,6 +953,8 @@
                 .asLong();
     }
 
+    // TODO Periodic checker, consider to add store and delegates.
+
     // Check periodically for any issue and try to resolve automatically if possible
     private final class PolicyChecker implements Runnable {
         @Override
