diff --git a/app/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/app/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
index e7c9203..fc3dd17 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
@@ -44,8 +44,10 @@
 
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * Handler of ICMP packets that responses or forwards ICMP packets that
@@ -69,49 +71,94 @@
      *
      * @param outport the output port
      * @param payload the packet to send
-     * @param sid the segment id
+     * @param destSid the segment id of the dest device
      * @param destIpAddress the destination ip address
      * @param allowedHops the hop limit/ttl
      */
     private void sendPacketOut(ConnectPoint outport,
                                Ethernet payload,
-                               int sid,
+                               int destSid,
                                IpAddress destIpAddress,
                                byte allowedHops) {
-        int destSid;
-        if (destIpAddress.isIp4()) {
-            destSid = config.getIPv4SegmentId(payload.getDestinationMAC());
-        } else {
-            destSid = config.getIPv6SegmentId(payload.getDestinationMAC());
+        int origSid;
+        try {
+            if (destIpAddress.isIp4()) {
+                origSid = config.getIPv4SegmentId(outport.deviceId());
+            } else {
+                origSid = config.getIPv6SegmentId(outport.deviceId());
+            }
+        } catch (DeviceConfigNotFoundException e) {
+            log.warn(e.getMessage() + " Aborting sendPacketOut");
+            return;
         }
 
-        if (sid == -1 || destSid == sid ||
-                config.inSameSubnet(outport.deviceId(), destIpAddress)) {
+        if (destSid == -1 || origSid == destSid ||
+                srManager.interfaceService.isConfigured(outport)) {
             TrafficTreatment treatment = DefaultTrafficTreatment.builder().
                     setOutput(outport.port()).build();
             OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
                                                               treatment, ByteBuffer.wrap(payload.serialize()));
+            log.trace("Sending packet {} to {}", payload, outport);
             srManager.packetService.emit(packet);
         } else {
-            log.trace("Send a MPLS packet as a ICMP response");
             TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                     .setOutput(outport.port())
                     .build();
 
             payload.setEtherType(Ethernet.MPLS_UNICAST);
             MPLS mplsPkt = new MPLS();
-            mplsPkt.setLabel(sid);
+            mplsPkt.setLabel(destSid);
             mplsPkt.setTtl(allowedHops);
             mplsPkt.setPayload(payload.getPayload());
             payload.setPayload(mplsPkt);
-
             OutboundPacket packet = new DefaultOutboundPacket(outport.deviceId(),
                                                               treatment, ByteBuffer.wrap(payload.serialize()));
-
+            log.trace("Sending packet {} to {}", payload, outport);
             srManager.packetService.emit(packet);
         }
     }
 
+    private IpAddress selectRouterIpAddress(IpAddress destIpAddress, ConnectPoint outPort,
+                                            Set<ConnectPoint> connectPoints) {
+        IpAddress routerIpAddress;
+        // Let's get first the online connect points
+        Set<ConnectPoint> onlineCps =  connectPoints.stream()
+                .filter(connectPoint -> srManager.deviceService.isAvailable(connectPoint.deviceId()))
+                .collect(Collectors.toSet());
+        // Check if ping is local
+        if (onlineCps.contains(outPort)) {
+            routerIpAddress = config.getRouterIpAddress(destIpAddress, outPort.deviceId());
+            log.trace("Local ping received from {} - send to {}", destIpAddress, routerIpAddress);
+            return routerIpAddress;
+        }
+        // Check if it comes from a remote device. Loopbacks are sorted comparing byte by byte
+        // FIXME if we lose both links from the chosen leaf to spine - ping will fail
+        routerIpAddress = onlineCps.stream()
+                .filter(onlineCp -> !onlineCp.deviceId().equals(outPort.deviceId()))
+                .map(selectedCp -> config.getRouterIpAddress(destIpAddress, selectedCp.deviceId()))
+                .filter(Objects::nonNull)
+                .sorted()
+                .findFirst().orElse(null);
+        if (routerIpAddress != null) {
+            log.trace("Remote ping received from {} - send to {}", destIpAddress, routerIpAddress);
+        } else {
+            log.warn("Not found a valid loopback for ping coming from {} - {}", destIpAddress, outPort);
+        }
+        return routerIpAddress;
+    }
+
+    private Ip4Address selectRouterIp4Address(IpAddress destIpAddress, ConnectPoint outPort,
+                                              Set<ConnectPoint> connectPoints) {
+        IpAddress routerIpAddress = selectRouterIpAddress(destIpAddress, outPort, connectPoints);
+        return routerIpAddress != null ? routerIpAddress.getIp4Address() : null;
+    }
+
+    private Ip6Address selectRouterIp6Address(IpAddress destIpAddress, ConnectPoint outPort,
+                                              Set<ConnectPoint> connectPoints) {
+        IpAddress routerIpAddress = selectRouterIpAddress(destIpAddress, outPort, connectPoints);
+        return routerIpAddress != null ? routerIpAddress.getIp6Address() : null;
+    }
+
     //////////////////////////////////////
     //     ICMP Echo/Reply Protocol     //
     //////////////////////////////////////
@@ -127,25 +174,40 @@
     public void processIcmp(Ethernet eth, ConnectPoint inPort) {
         DeviceId deviceId = inPort.deviceId();
         IPv4 ipv4Packet = (IPv4) eth.getPayload();
+        ICMP icmp = (ICMP) ipv4Packet.getPayload();
         Ip4Address destinationAddress = Ip4Address.valueOf(ipv4Packet.getDestinationAddress());
         Set<IpAddress> gatewayIpAddresses = config.getPortIPs(deviceId);
         IpAddress routerIp;
+
+        // Only proceed with echo request
+        if (icmp.getIcmpType() != ICMP.TYPE_ECHO_REQUEST) {
+            return;
+        }
+
         try {
             routerIp = config.getRouterIpv4(deviceId);
         } catch (DeviceConfigNotFoundException e) {
             log.warn(e.getMessage() + " Aborting processPacketIn.");
             return;
         }
+
+        // Get pair ip - if it exists
+        IpAddress pairRouterIp;
+        try {
+            DeviceId pairDeviceId = config.getPairDeviceId(deviceId);
+            pairRouterIp = pairDeviceId != null ? config.getRouterIpv4(pairDeviceId) : null;
+        } catch (DeviceConfigNotFoundException e) {
+            pairRouterIp = null;
+        }
+
         // ICMP to the router IP or gateway IP
-        if (((ICMP) ipv4Packet.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST &&
-                (destinationAddress.equals(routerIp.getIp4Address()) ||
-                        gatewayIpAddresses.contains(destinationAddress))) {
+        if (destinationAddress.equals(routerIp.getIp4Address()) ||
+                (pairRouterIp != null && destinationAddress.equals(pairRouterIp.getIp4Address())) ||
+                gatewayIpAddresses.contains(destinationAddress)) {
             sendIcmpResponse(eth, inPort);
         } else {
             log.trace("Ignore ICMP that targets for {}", destinationAddress);
         }
-        // We remove the packet from the queue
-        srManager.ipHandler.dequeuePacket(ipv4Packet, destinationAddress);
     }
 
     /**
@@ -159,7 +221,11 @@
         IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload();
         IPv4 icmpReplyIpv4 = (IPv4) icmpReplyEth.getPayload();
         Ip4Address destIpAddress = Ip4Address.valueOf(icmpRequestIpv4.getSourceAddress());
-        Ip4Address destRouterAddress = config.getRouterIpAddressForASubnetHost(destIpAddress);
+
+        // Get the available connect points
+        Set<ConnectPoint> destConnectPoints = config.getConnectPointsForASubnetHost(destIpAddress);
+        // Select a router
+        Ip4Address destRouterAddress = selectRouterIp4Address(destIpAddress, outport, destConnectPoints);
 
         // Note: Source IP of the ICMP request doesn't belong to any configured subnet.
         //       The source might be an indirectly attached host (e.g. behind a router)
@@ -215,18 +281,29 @@
 
         try {
             routerIp = config.getRouterIpv6(deviceId);
-
-            Optional<Ip6Address> linkLocalIp = getLinkLocalIp(inPort);
-            // Ensure ICMP to the router IP, EUI-64 link-local IP, or gateway IP
-            if (destinationAddress.equals(routerIp.getIp6Address()) ||
-                    (linkLocalIp.isPresent() && destinationAddress.equals(linkLocalIp.get())) ||
-                    gatewayIpAddresses.contains(destinationAddress)) {
-                sendIcmpv6Response(eth, inPort);
-            } else {
-                log.trace("Ignore ICMPv6 that targets for {}", destinationAddress);
-            }
         } catch (DeviceConfigNotFoundException e) {
-            log.warn(e.getMessage() + " Ignore ICMPv6 that targets to {}.", destinationAddress);
+            log.warn(e.getMessage() + " Aborting processPacketIn.");
+            return;
+        }
+
+        // Get pair ip - if it exists
+        IpAddress pairRouterIp;
+        try {
+            DeviceId pairDeviceId = config.getPairDeviceId(deviceId);
+            pairRouterIp = pairDeviceId != null ? config.getRouterIpv6(pairDeviceId) : null;
+        } catch (DeviceConfigNotFoundException e) {
+            pairRouterIp = null;
+        }
+
+        Optional<Ip6Address> linkLocalIp = getLinkLocalIp(inPort);
+        // Ensure ICMP to the router IP, EUI-64 link-local IP, or gateway IP
+        if (destinationAddress.equals(routerIp.getIp6Address()) ||
+                (linkLocalIp.isPresent() && destinationAddress.equals(linkLocalIp.get())) ||
+                (pairRouterIp != null && destinationAddress.equals(pairRouterIp.getIp6Address())) ||
+                gatewayIpAddresses.contains(destinationAddress)) {
+            sendIcmpv6Response(eth, inPort);
+        } else {
+            log.trace("Ignore ICMPv6 that targets for {}", destinationAddress);
         }
     }
 
@@ -237,7 +314,7 @@
      * @param outport the output port where the ICMP reply should be sent to
      */
     private void sendIcmpv6Response(Ethernet ethRequest, ConnectPoint outport) {
-        int sid = -1;
+        int destSid = -1;
         Ethernet ethReply = ICMP6.buildIcmp6Reply(ethRequest);
         IPv6 icmpRequestIpv6 = (IPv6) ethRequest.getPayload();
         IPv6 icmpReplyIpv6 = (IPv6) ethRequest.getPayload();
@@ -246,14 +323,18 @@
         // Destination IP of the echo "reply"
         Ip6Address destIpAddress = Ip6Address.valueOf(icmpRequestIpv6.getSourceAddress());
         Optional<Ip6Address> linkLocalIp = getLinkLocalIp(outport);
-        Ip6Address destRouterAddress = config.getRouterIpAddressForASubnetHost(destIpAddress);
 
         // Fast path if the echo request targets the link-local address of switch interface
         if (linkLocalIp.isPresent() && srcIpAddress.equals(linkLocalIp.get())) {
-            sendPacketOut(outport, ethReply, sid, destIpAddress, icmpReplyIpv6.getHopLimit());
+            sendPacketOut(outport, ethReply, destSid, destIpAddress, icmpReplyIpv6.getHopLimit());
             return;
         }
 
+        // Get the available connect points
+        Set<ConnectPoint> destConnectPoints = config.getConnectPointsForASubnetHost(destIpAddress);
+        // Select a router
+        Ip6Address destRouterAddress = selectRouterIp6Address(destIpAddress, outport, destConnectPoints);
+
         // Note: Source IP of the ICMP request doesn't belong to any configured subnet.
         //       The source might be an indirect host behind a router.
         //       Lookup the route store for the nexthop instead.
@@ -272,16 +353,13 @@
             }
         }
 
-        // Search SID only if store lookup is success otherwise proceed with "sid=-1"
-        if (destRouterAddress != null) {
-            sid = config.getIPv6SegmentId(destRouterAddress);
-            if (sid < 0) {
-                log.warn("Failed to lookup SID of the switch that {} attaches to. " +
-                        "Unable to process ICMPv6 request.", destIpAddress);
-                return;
-            }
+        destSid = config.getIPv6SegmentId(destRouterAddress);
+        if (destSid < 0) {
+            log.warn("Failed to lookup SID of the switch that {} attaches to. " +
+                    "Unable to process ICMPv6 request.", destIpAddress);
+            return;
         }
-        sendPacketOut(outport, ethReply, sid, destIpAddress, icmpReplyIpv6.getHopLimit());
+        sendPacketOut(outport, ethReply, destSid, destIpAddress, icmpReplyIpv6.getHopLimit());
     }
 
     ///////////////////////////////////////////
diff --git a/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java b/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
index 81a161f..123da37 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
@@ -351,6 +351,24 @@
         }
     }
 
+    /**
+     * Gets router ip address based on the destination ip address.
+     *
+     * @param destIpAddress the destination ip address
+     * @param routerDeviceId the device id
+     * @return the ip address of the routes
+     */
+    public IpAddress getRouterIpAddress(IpAddress destIpAddress, DeviceId routerDeviceId) {
+        IpAddress routerIpAddress;
+        try {
+            routerIpAddress = destIpAddress.isIp4() ? getRouterIpv4(routerDeviceId) :
+                    getRouterIpv6(routerDeviceId);
+        } catch (DeviceConfigNotFoundException e) {
+            routerIpAddress = null;
+        }
+        return routerIpAddress;
+    }
+
     @Override
     public boolean isEdgeDevice(DeviceId deviceId) throws DeviceConfigNotFoundException {
         SegmentRouterInfo srinfo = deviceConfigMap.get(deviceId);
@@ -624,6 +642,19 @@
     }
 
     /**
+     * Returns all the connect points of the segment routers that have the
+     * specified ip address in their subnets.
+     *
+     * @param destIpAddress target ip address
+     * @return connect points of the segment routers
+     */
+    public Set<ConnectPoint> getConnectPointsForASubnetHost(IpAddress destIpAddress) {
+        return srManager.interfaceService.getMatchingInterfaces(destIpAddress).stream()
+                .map(Interface::connectPoint)
+                .collect(Collectors.toSet());
+    }
+
+    /**
      * Returns the router ip address of segment router that has the
      * specified ip address in its subnets.
      *
diff --git a/app/src/test/java/org/onosproject/segmentrouting/IcmpHandlerTest.java b/app/src/test/java/org/onosproject/segmentrouting/IcmpHandlerTest.java
new file mode 100644
index 0000000..cc7c6a8
--- /dev/null
+++ b/app/src/test/java/org/onosproject/segmentrouting/IcmpHandlerTest.java
@@ -0,0 +1,794 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.MPLS;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.config.basics.InterfaceConfig;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
+import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
+
+import java.util.Collections;
+
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.*;
+import static org.onlab.packet.ICMP.*;
+import static org.onlab.packet.ICMP6.ECHO_REPLY;
+import static org.onosproject.segmentrouting.TestUtils.*;
+
+/**
+ * Tests for IcmpHandler.
+ */
+public class IcmpHandlerTest {
+
+    private IcmpHandler icmpHandler;
+    private MockPacketService packetService;
+    private SegmentRoutingManager segmentRoutingManager;
+    private ApplicationId testApplicationId = TestApplicationId.create("test");
+
+    @Before
+    public void setUp() {
+
+        // Init
+        ObjectMapper mapper = new ObjectMapper();
+        ConfigApplyDelegate delegate = config -> { };
+
+        // Setup configuration for app
+        SegmentRoutingAppConfig appConfig = new SegmentRoutingAppConfig();
+        JsonNode appTree = mapper.createObjectNode();
+        appConfig.init(testApplicationId, "icmp-handler-test", appTree, mapper, delegate);
+        appConfig.setSuppressSubnet(Collections.emptySet());
+
+        // Setup configuration for the devices
+        SegmentRoutingDeviceConfig remoteLeafConfig = new SegmentRoutingDeviceConfig();
+        JsonNode remoteLeafTree = mapper.createObjectNode();
+        remoteLeafConfig.init(REMOTE_LEAF, "icmp-handler-test", remoteLeafTree, mapper, delegate);
+        remoteLeafConfig.setNodeSidIPv4(REMOTE_LEAF_SID4)
+                .setNodeSidIPv6(REMOTE_LEAF_SID6)
+                .setRouterIpv4(REMOTE_LEAF_LB4)
+                .setRouterIpv6(REMOTE_LEAF_LB6)
+                .setIsEdgeRouter(true)
+                .setRouterMac(REMOTE_MAC.toString());
+        SegmentRoutingDeviceConfig localLeafConfig = new SegmentRoutingDeviceConfig();
+        JsonNode localLeafTree = mapper.createObjectNode();
+        localLeafConfig.init(LOCAL_LEAF, "icmp-handler-test", localLeafTree, mapper, delegate);
+        localLeafConfig.setNodeSidIPv4(LOCAL_LEAF_SID4)
+                .setRouterIpv4(LOCAL_LEAF_LB4)
+                .setNodeSidIPv6(LOCAL_LEAF_SID6)
+                .setRouterIpv6(LOCAL_LEAF_LB6)
+                .setIsEdgeRouter(true)
+                .setRouterMac(LOCAL_MAC.toString());
+        SegmentRoutingDeviceConfig localLeaf1Config = new SegmentRoutingDeviceConfig();
+        JsonNode localLeaf1Tree = mapper.createObjectNode();
+        localLeaf1Config.init(LOCAL_LEAF1, "icmp-handler-test", localLeaf1Tree, mapper, delegate);
+        localLeaf1Config.setNodeSidIPv4(LOCAL_LEAF1_SID4)
+                .setRouterIpv4(LOCAL_LEAF1_LB4)
+                .setNodeSidIPv6(LOCAL_LEAF1_SID6)
+                .setRouterIpv6(LOCAL_LEAF1_LB6)
+                .setIsEdgeRouter(true)
+                .setRouterMac(LOCAL_MAC1.toString())
+                .setPairDeviceId(LOCAL_LEAF2)
+                .setPairLocalPort(P3);
+        SegmentRoutingDeviceConfig localLeaf2Config = new SegmentRoutingDeviceConfig();
+        JsonNode localLeaf2Tree = mapper.createObjectNode();
+        localLeaf2Config.init(LOCAL_LEAF2, "icmp-handler-test", localLeaf2Tree, mapper, delegate);
+        localLeaf2Config.setNodeSidIPv4(LOCAL_LEAF2_SID4)
+                .setRouterIpv4(LOCAL_LEAF2_LB4)
+                .setNodeSidIPv6(LOCAL_LEAF2_SID6)
+                .setRouterIpv6(LOCAL_LEAF2_LB6)
+                .setIsEdgeRouter(true)
+                .setRouterMac(LOCAL_MAC2.toString())
+                .setPairDeviceId(LOCAL_LEAF1)
+                .setPairLocalPort(P3);
+
+        // Setup configuration for ports
+        InterfaceConfig remoteLeafPorts1Config = new InterfaceConfig();
+        ArrayNode remoteLeafPorts1Tree = mapper.createArrayNode();
+        remoteLeafPorts1Config.init(CP12, "icmp-handler-test", remoteLeafPorts1Tree, mapper, delegate);
+        remoteLeafPorts1Config.addInterface(INTF1);
+        InterfaceConfig remoteLeafPorts2Config = new InterfaceConfig();
+        ArrayNode remoteLeafPorts2Tree = mapper.createArrayNode();
+        remoteLeafPorts2Config.init(CP13, "icmp-handler-test", remoteLeafPorts2Tree, mapper, delegate);
+        remoteLeafPorts2Config.addInterface(INTF2);
+        InterfaceConfig localLeafPortsConfig = new InterfaceConfig();
+        ArrayNode localLeafPortsTree = mapper.createArrayNode();
+        localLeafPortsConfig.init(CP1011, "icmp-handler-test", localLeafPortsTree, mapper, delegate);
+        localLeafPortsConfig.addInterface(INTF111);
+        InterfaceConfig localLeaf1PortsConfig = new InterfaceConfig();
+        ArrayNode localLeaf1PortsTree = mapper.createArrayNode();
+        localLeaf1PortsConfig.init(CP2011, "icmp-handler-test", localLeaf1PortsTree, mapper, delegate);
+        localLeaf1PortsConfig.addInterface(INTF211);
+        InterfaceConfig localLeaf2Ports1Config = new InterfaceConfig();
+        ArrayNode localLeaf2Ports1Tree = mapper.createArrayNode();
+        localLeaf2Ports1Config.init(CP2021, "icmp-handler-test", localLeaf2Ports1Tree, mapper, delegate);
+        localLeaf2Ports1Config.addInterface(INTF212);
+        InterfaceConfig localLeaf2Ports2Config = new InterfaceConfig();
+        ArrayNode localLeaf2Ports2Tree = mapper.createArrayNode();
+        localLeaf2Ports2Config.init(CP2024, "icmp-handler-test", localLeaf2Ports2Tree, mapper, delegate);
+        localLeaf2Ports2Config.addInterface(INTF213);
+
+        // Apply config
+        MockNetworkConfigRegistry mockNetworkConfigRegistry = new MockNetworkConfigRegistry();
+        mockNetworkConfigRegistry.applyConfig(remoteLeafConfig);
+        mockNetworkConfigRegistry.applyConfig(remoteLeafPorts1Config);
+        mockNetworkConfigRegistry.applyConfig(remoteLeafPorts2Config);
+        mockNetworkConfigRegistry.applyConfig(localLeafConfig);
+        mockNetworkConfigRegistry.applyConfig(localLeafPortsConfig);
+        mockNetworkConfigRegistry.applyConfig(localLeaf1Config);
+        mockNetworkConfigRegistry.applyConfig(localLeaf1PortsConfig);
+        mockNetworkConfigRegistry.applyConfig(localLeaf2Config);
+        mockNetworkConfigRegistry.applyConfig(localLeaf2Ports1Config);
+        mockNetworkConfigRegistry.applyConfig(localLeaf2Ports2Config);
+
+        segmentRoutingManager = new SegmentRoutingManager();
+        segmentRoutingManager.appId = testApplicationId;
+        packetService = new MockPacketService();
+        segmentRoutingManager.packetService = packetService;
+        segmentRoutingManager.cfgService = mockNetworkConfigRegistry;
+        segmentRoutingManager.neighbourResolutionService = new MockNeighbourResolutionService();
+        segmentRoutingManager.interfaceService = new MockInterfaceService(ImmutableSet.of(
+                INTF1, INTF2, INTF111, INTF211, INTF212, INTF213));
+        segmentRoutingManager.deviceConfiguration = new DeviceConfiguration(segmentRoutingManager);
+        segmentRoutingManager.ipHandler = new IpHandler(segmentRoutingManager);
+        segmentRoutingManager.deviceService = createMock(DeviceService.class);
+        segmentRoutingManager.routeService = new MockRouteService(ROUTE_STORE);
+        segmentRoutingManager.hostService = new MockHostService(Collections.emptySet());
+        icmpHandler = new IcmpHandler(segmentRoutingManager);
+    }
+
+    // Ping to our gateway
+    @Test
+    public void testPing4MyGateway() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmp(ETH_REQ_IPV4_MY, CP12);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_MY.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_MY.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_MY.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv4);
+        IPv4 ip = (IPv4) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV4.toInt()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV4_MY.toInt()));
+        assertTrue(ip.getPayload() instanceof ICMP);
+        ICMP icmp = (ICMP) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+        assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 to our gateway
+    @Test
+    public void testPing6MyGateway() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV6_MY, CP12);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_MY.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_MY.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_MY.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv6);
+        IPv6 ip = (IPv6) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV6.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV6_MY.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping to a gateway attached to our leaf
+    @Test
+    public void testPing4LocalGateway() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmp(ETH_REQ_IPV4_LOCAL, CP12);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_LOCAL.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_LOCAL.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_LOCAL.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv4);
+        IPv4 ip = (IPv4) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV4_LOCAL.toInt()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV4_MY.toInt()));
+        assertTrue(ip.getPayload() instanceof ICMP);
+        ICMP icmp = (ICMP) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+        assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 to a gateway attached to our leaf
+    @Test
+    public void testPing6LocalGateway() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV6_LOCAL, CP12);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LOCAL.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LOCAL.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LOCAL.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv6);
+        IPv6 ip = (IPv6) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV6_LOCAL.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV6_MY.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping to a gateway attached only to the pair leaf (routing through spine)
+    @Test
+    public void testPing4RemoteGatewaySamePair() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(true)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmp(ETH_REQ_IPV4_SAME, CP2025);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_SAME.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_SAME.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_SAME.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof MPLS);
+        MPLS mpls = (MPLS) ethernet.getPayload();
+        assertThat(mpls.getLabel(), is(LOCAL_LEAF1_SID4));
+        assertTrue(mpls.getPayload() instanceof IPv4);
+        IPv4 ip = (IPv4) mpls.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV4_SAME.toInt()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+        assertTrue(ip.getPayload() instanceof ICMP);
+        ICMP icmp = (ICMP) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+        assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 to a gateway attached only to the pair leaf (routing through spine)
+    @Test
+    public void testPing6RemoteGatewaySamePair() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(true)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV6_SAME, CP2025);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_SAME.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_SAME.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_SAME.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof MPLS);
+        MPLS mpls = (MPLS) ethernet.getPayload();
+        assertThat(mpls.getLabel(), is(LOCAL_LEAF1_SID6));
+        assertTrue(mpls.getPayload() instanceof IPv6);
+        IPv6 ip = (IPv6) mpls.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV6_SAME.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping to a gateway but destination leaf is down
+    @Test
+    public void testPing4RemoteGatewayLeafDown() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF))
+                .andReturn(false)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmp(ETH_REQ_IPV4, CP11);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4.getSourceMAC());
+        assertNull(ethernet);
+
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 to a gateway but destination leaf is down
+    @Test
+    public void testPing6RemoteGatewayLeafDown() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF))
+                .andReturn(false)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV6, CP11);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6.getSourceMAC());
+        assertNull(ethernet);
+
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping to a gateway but one of the destination leaf is down
+    @Test
+    public void testPing4RemoteGatewayLeaf1Down() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(false)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmp(ETH_REQ_IPV41, CP11);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV41.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV41.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV41.getSourceMAC()));
+        assertThat(ethernet.getEtherType(), is(Ethernet.MPLS_UNICAST));
+        assertTrue(ethernet.getPayload() instanceof MPLS);
+        MPLS mpls = (MPLS) ethernet.getPayload();
+        assertThat(mpls.getLabel(), is(LOCAL_LEAF2_SID4));
+        assertTrue(mpls.getPayload() instanceof IPv4);
+        IPv4 ip = (IPv4) mpls.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV4.toInt()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+        assertTrue(ip.getPayload() instanceof ICMP);
+        ICMP icmp = (ICMP) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+        assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 to a gateway but one of the destination leaf is down
+    @Test
+    public void testPing6RemoteGatewayLeaf2Down() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(true)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(false)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV61, CP11);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV61.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV61.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV61.getSourceMAC()));
+        assertThat(ethernet.getEtherType(), is(Ethernet.MPLS_UNICAST));
+        assertTrue(ethernet.getPayload() instanceof MPLS);
+        MPLS mpls = (MPLS) ethernet.getPayload();
+        assertThat(mpls.getLabel(), is(LOCAL_LEAF1_SID6));
+        assertTrue(mpls.getPayload() instanceof IPv6);
+        IPv6 ip = (IPv6) mpls.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV6.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 to a link local address
+    @Test
+    public void testPing6LinkLocalAddress() {
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV6_LL, CP12);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LL.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LL.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LL.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv6);
+        IPv6 ip = (IPv6) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV6_LL.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV6_LL.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+    }
+
+    // Ping to the looback of our leaf
+    @Test
+    public void testPing4Loopback() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmp(ETH_REQ_IPV4_LOOPBACK, CP12);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_LOOPBACK.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_LOOPBACK.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_LOOPBACK.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv4);
+        IPv4 ip = (IPv4) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV4_LOOPBACK.toInt()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV4_MY.toInt()));
+        assertTrue(ip.getPayload() instanceof ICMP);
+        ICMP icmp = (ICMP) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+        assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 to the looback of our leaf
+    @Test
+    public void testPing6Loopback() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV6_LOOPBACK, CP12);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LOOPBACK.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LOOPBACK.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LOOPBACK.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv6);
+        IPv6 ip = (IPv6) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV6_LOOPBACK.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV6_MY.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping to the looback of our leaf (pair)
+    @Test
+    public void testPing4LoopbackPair() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(true)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmp(ETH_REQ_IPV4_LOOPBACK_PAIR, CP2011);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv4);
+        IPv4 ip = (IPv4) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV4_LOOPBACK_PAIR.toInt()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+        assertTrue(ip.getPayload() instanceof ICMP);
+        ICMP icmp = (ICMP) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+        assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 to the looback of our leaf (pair)
+    @Test
+    public void testPing6LoopbackPair() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(true)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV6_LOOPBACK_PAIR, CP2021);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv6);
+        IPv6 ip = (IPv6) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV6_LOOPBACK_PAIR.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping to the loopback of the leaf but hashing of the bond interfaces sends to wrong leaf
+    @Test
+    public void testPing4LoopbackPairDifferentLeaf() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(true)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmp(ETH_REQ_IPV4_LOOPBACK_PAIR, CP2021);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv4);
+        IPv4 ip = (IPv4) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV4_LOOPBACK_PAIR.toInt()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+        assertTrue(ip.getPayload() instanceof ICMP);
+        ICMP icmp = (ICMP) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+        assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 to the loopback of the leaf but hashing of the bond interfaces sends to wrong leaf
+    @Test
+    public void testPing6LoopbackPairDifferentLeaf() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(true)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV6_LOOPBACK_PAIR, CP2011);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv6);
+        IPv6 ip = (IPv6) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV6_LOOPBACK_PAIR.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping loopback of a destination that is down but
+    // hashing of the bond interfaces sends to other leaf
+    @Test
+    public void testPing4LoopbackPairDifferentLeafDown() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(false)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmp(ETH_REQ_IPV4_LOOPBACK_PAIR, CP2021);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv4);
+        IPv4 ip = (IPv4) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV4_LOOPBACK_PAIR.toInt()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+        assertTrue(ip.getPayload() instanceof ICMP);
+        ICMP icmp = (ICMP) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+        assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 loopback of a destination that is down but
+    // hashing of the bond interfaces sends to other leaf
+    @Test
+    public void testPing6LoopbackPairDifferentLeafDown() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(true)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(false)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV6_LOOPBACK_PAIR, CP2011);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv6);
+        IPv6 ip = (IPv6) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV6_LOOPBACK_PAIR.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping to a dh gateway
+    @Test
+    public void testPing4GatewayPair() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(true)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmp(ETH_REQ_IPV4_GATEWAY_PAIR, CP2011);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_GATEWAY_PAIR.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_GATEWAY_PAIR.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_GATEWAY_PAIR.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv4);
+        IPv4 ip = (IPv4) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV4_GATEWAY_PAIR.toInt()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+        assertTrue(ip.getPayload() instanceof ICMP);
+        ICMP icmp = (ICMP) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+        assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+    // Ping6 to a dh gateway
+    @Test
+    public void testPing6GatewayPair() {
+        // Expected behavior
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+                .andReturn(true)
+                .times(1);
+        expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+                .andReturn(true)
+                .times(1);
+        replay(segmentRoutingManager.deviceService);
+
+        // Process
+        icmpHandler.processIcmpv6(ETH_REQ_IPV6_GATEWAY_PAIR, CP2021);
+
+        // Verify packet-out
+        Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_GATEWAY_PAIR.getSourceMAC());
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_GATEWAY_PAIR.getDestinationMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_GATEWAY_PAIR.getSourceMAC()));
+        assertTrue(ethernet.getPayload() instanceof IPv6);
+        IPv6 ip = (IPv6) ethernet.getPayload();
+        assertThat(ip.getSourceAddress(), is(DST_IPV6_GATEWAY_PAIR.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+        // Verify behavior
+        verify(segmentRoutingManager.deviceService);
+    }
+
+}
diff --git a/app/src/test/java/org/onosproject/segmentrouting/MockInterfaceService.java b/app/src/test/java/org/onosproject/segmentrouting/MockInterfaceService.java
index 17422d2..6e170b0 100644
--- a/app/src/test/java/org/onosproject/segmentrouting/MockInterfaceService.java
+++ b/app/src/test/java/org/onosproject/segmentrouting/MockInterfaceService.java
@@ -17,12 +17,17 @@
 package org.onosproject.segmentrouting;
 
 import com.google.common.collect.ImmutableSet;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.VlanId;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.intf.Interface;
 import org.onosproject.net.intf.impl.InterfaceManager;
 
 import java.util.Set;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.toSet;
 
 /**
  * Mock Interface Service.
@@ -44,4 +49,37 @@
     public Set<Interface> getInterfaces() {
         return interfaces;
     }
+
+    @Override
+    public Interface getMatchingInterface(IpAddress ip) {
+        return getMatchingInterfacesStream(ip).findFirst().orElse(null);
+    }
+
+    @Override
+    public Set<Interface> getMatchingInterfaces(IpAddress ip) {
+        return getMatchingInterfacesStream(ip).collect(toSet());
+    }
+
+    private Stream<Interface> getMatchingInterfacesStream(IpAddress ip) {
+        return interfaces.stream()
+                .filter(intf -> intf.ipAddressesList().stream()
+                        .anyMatch(intfIp -> intfIp.subnetAddress().contains(ip)));
+    }
+
+    @Override
+    public boolean isConfigured(ConnectPoint connectPoint) {
+        Set<Interface> intfs = getInterfacesByPort(connectPoint);
+        if (intfs == null) {
+            return false;
+        }
+        for (Interface intf : intfs) {
+            if (!intf.ipAddressesList().isEmpty() || intf.vlan() != VlanId.NONE
+                    || intf.vlanNative() != VlanId.NONE
+                    || intf.vlanUntagged() != VlanId.NONE
+                    || !intf.vlanTagged().isEmpty()) {
+                return true;
+            }
+        }
+        return false;
+    }
 }
diff --git a/app/src/test/java/org/onosproject/segmentrouting/MockNeighbourResolutionService.java b/app/src/test/java/org/onosproject/segmentrouting/MockNeighbourResolutionService.java
new file mode 100644
index 0000000..5a41149
--- /dev/null
+++ b/app/src/test/java/org/onosproject/segmentrouting/MockNeighbourResolutionService.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.net.neighbour.NeighbourHandlerRegistration;
+import org.onosproject.net.neighbour.NeighbourMessageHandler;
+import org.onosproject.net.neighbour.NeighbourResolutionService;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * Mock Neighbour Resolution Service.
+ */
+public class MockNeighbourResolutionService implements NeighbourResolutionService {
+    @Override
+    public void registerNeighbourHandler(ConnectPoint connectPoint,
+                                         NeighbourMessageHandler handler, ApplicationId appId) {
+
+    }
+
+    @Override
+    public void registerNeighbourHandler(Interface intf,
+                                         NeighbourMessageHandler handler, ApplicationId appId) {
+
+    }
+
+    @Override
+    public void unregisterNeighbourHandler(ConnectPoint connectPoint,
+                                           NeighbourMessageHandler handler, ApplicationId appId) {
+
+    }
+
+    @Override
+    public void unregisterNeighbourHandler(Interface intf,
+                                           NeighbourMessageHandler handler, ApplicationId appId) {
+
+    }
+
+    @Override
+    public void unregisterNeighbourHandlers(ApplicationId appId) {
+
+    }
+
+    @Override
+    public Map<ConnectPoint, Collection<NeighbourHandlerRegistration>> getHandlerRegistrations() {
+        return null;
+    }
+}
diff --git a/app/src/test/java/org/onosproject/segmentrouting/MockNetworkConfigRegistry.java b/app/src/test/java/org/onosproject/segmentrouting/MockNetworkConfigRegistry.java
index 09f8da2..e18483e 100644
--- a/app/src/test/java/org/onosproject/segmentrouting/MockNetworkConfigRegistry.java
+++ b/app/src/test/java/org/onosproject/segmentrouting/MockNetworkConfigRegistry.java
@@ -16,10 +16,12 @@
 
 package org.onosproject.segmentrouting;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 import org.onosproject.net.config.Config;
 import org.onosproject.net.config.NetworkConfigRegistryAdapter;
 
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -28,7 +30,7 @@
 class MockNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
     private Set<Config> configs = Sets.newHashSet();
 
-    public void applyConfig(Config config) {
+    void applyConfig(Config config) {
         configs.add(config);
     }
 
@@ -40,4 +42,16 @@
                 .findFirst().orElse(null);
         return (C) c;
     }
+
+    @Override
+    public <S, C extends Config<S>> Set<S> getSubjects(Class<S> subject, Class<C> configClass) {
+        ImmutableSet.Builder<S> builder = ImmutableSet.builder();
+        String cName = configClass.getName();
+        configs.forEach(k -> {
+            if (subject.isInstance(k.subject()) && Objects.equals(cName, k.getClass().getName())) {
+                builder.add((S) k.subject());
+            }
+        });
+        return builder.build();
+    }
 }
\ No newline at end of file
diff --git a/app/src/test/java/org/onosproject/segmentrouting/MockPacketService.java b/app/src/test/java/org/onosproject/segmentrouting/MockPacketService.java
new file mode 100644
index 0000000..73a8b65
--- /dev/null
+++ b/app/src/test/java/org/onosproject/segmentrouting/MockPacketService.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import com.google.common.collect.Maps;
+import org.apache.commons.lang3.tuple.Pair;
+import org.onlab.packet.DeserializationException;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.MacAddress;
+import org.onosproject.net.packet.OutboundPacket;
+import org.onosproject.net.packet.PacketServiceAdapter;
+
+import java.util.Map;
+
+/**
+ * Mock Packet Service.
+ * It is used for tests related to packet-ins management.
+ */
+public class MockPacketService extends PacketServiceAdapter {
+
+    private final Map<MacAddress, Pair<OutboundPacket, Ethernet>> outBoundPackets = Maps.newHashMap();
+
+    @Override
+    public void emit(OutboundPacket packet) {
+        try {
+            Ethernet ethernetPacket = Ethernet.deserializer().deserialize(packet.data().array(),
+                                                                          packet.data().arrayOffset(),
+                                                                          packet.data().array().length);
+            outBoundPackets.put(ethernetPacket.getDestinationMAC(), Pair.of(packet, ethernetPacket));
+        } catch (DeserializationException e) {
+
+        }
+    }
+
+    Ethernet getEthernetPacket(MacAddress key) {
+        Pair<OutboundPacket, Ethernet> pair = outBoundPackets.get(key);
+        return pair != null ? pair.getRight() : null;
+    }
+}
diff --git a/app/src/test/java/org/onosproject/segmentrouting/MockRouteService.java b/app/src/test/java/org/onosproject/segmentrouting/MockRouteService.java
index bfeca1f..c3730dd 100644
--- a/app/src/test/java/org/onosproject/segmentrouting/MockRouteService.java
+++ b/app/src/test/java/org/onosproject/segmentrouting/MockRouteService.java
@@ -17,6 +17,7 @@
 package org.onosproject.segmentrouting;
 
 import com.google.common.collect.Sets;
+import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
 import org.onosproject.routeservice.ResolvedRoute;
 import org.onosproject.routeservice.RouteInfo;
@@ -25,6 +26,7 @@
 
 import java.util.Collection;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -53,4 +55,10 @@
     public Collection<RouteTableId> getRouteTables() {
         return Sets.newHashSet(new RouteTableId("default"));
     }
+
+    @Override
+    public Optional<ResolvedRoute> longestPrefixLookup(IpAddress ip) {
+        return this.routeStore.get(ip.toIpPrefix()).stream()
+                .findFirst();
+    }
 }
\ No newline at end of file
diff --git a/app/src/test/java/org/onosproject/segmentrouting/TestUtils.java b/app/src/test/java/org/onosproject/segmentrouting/TestUtils.java
new file mode 100644
index 0000000..339b2c8
--- /dev/null
+++ b/app/src/test/java/org/onosproject/segmentrouting/TestUtils.java
@@ -0,0 +1,460 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.host.InterfaceIpAddress;
+import org.onosproject.net.intf.Interface;
+import org.onosproject.routeservice.ResolvedRoute;
+import org.onosproject.routeservice.Route;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.Ip4Address;
+import org.onlab.packet.Ip6Address;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.IpPrefix;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onlab.packet.ICMPEcho;
+
+import java.util.Map;
+import java.util.Set;
+
+import static org.onlab.packet.ICMP.TYPE_ECHO_REQUEST;
+import static org.onlab.packet.ICMP6.ECHO_REQUEST;
+import static org.onlab.packet.IPv4.PROTOCOL_ICMP;
+import static org.onosproject.routeservice.Route.Source.STATIC;
+
+/**
+ * Utilities class for unit tests.
+ */
+public final class TestUtils {
+
+    private TestUtils() {
+
+    }
+
+    // Device configuration section
+    static final DeviceId REMOTE_LEAF = DeviceId.deviceId("of:0000000000000001");
+    static final int REMOTE_LEAF_SID4 = 1;
+    static final String REMOTE_LEAF_LB4 = "192.168.0.1";
+    static final int REMOTE_LEAF_SID6 = 10;
+    static final String REMOTE_LEAF_LB6 = "2000::c0a8:1";
+    private static final PortNumber P1 = PortNumber.portNumber(1);
+    static final MacAddress REMOTE_MAC = MacAddress.valueOf("00:00:00:00:00:02");
+
+    static final DeviceId LOCAL_LEAF = DeviceId.deviceId("of:0000000000000101");
+    static final int LOCAL_LEAF_SID4 = 101;
+    static final String LOCAL_LEAF_LB4 = "192.168.0.101";
+    static final int LOCAL_LEAF_SID6 = 111;
+    static final String LOCAL_LEAF_LB6 = "2000::c0a8:101";
+    static final MacAddress LOCAL_MAC = MacAddress.valueOf("00:00:00:00:01:01");
+
+    // Configure a pair
+    static final DeviceId LOCAL_LEAF1 = DeviceId.deviceId("of:0000000000000201");
+    static final int LOCAL_LEAF1_SID4 = 201;
+    static final String LOCAL_LEAF1_LB4 = "192.168.0.201";
+    static final int LOCAL_LEAF1_SID6 = 211;
+    static final String LOCAL_LEAF1_LB6 = "2000::c0a8:201";
+    static final MacAddress LOCAL_MAC1 = MacAddress.valueOf("00:00:00:00:02:01");
+
+    static final DeviceId LOCAL_LEAF2 = DeviceId.deviceId("of:0000000000000202");
+    static final int LOCAL_LEAF2_SID4 = 202;
+    static final String LOCAL_LEAF2_LB4 = "192.168.0.202";
+    static final int LOCAL_LEAF2_SID6 = 212;
+    static final String LOCAL_LEAF2_LB6 = "2000::c0a8:202";
+    static final MacAddress LOCAL_MAC2 = MacAddress.valueOf("00:00:00:00:02:02");
+
+    // Pair port
+    static final PortNumber P3 = PortNumber.portNumber(3);
+
+    // Ports configuration section
+    static final ConnectPoint CP11 = new ConnectPoint(REMOTE_LEAF, P1);
+    private static final PortNumber P2 = PortNumber.portNumber(2);
+    static final ConnectPoint CP12 = new ConnectPoint(REMOTE_LEAF, P2);
+    private static final IpAddress IP4_1 = IpAddress.valueOf("10.0.0.254");
+    private static final IpPrefix PREFIX4_1 = IpPrefix.valueOf("10.0.0.254/24");
+    private static final IpAddress IP6_1 = IpAddress.valueOf("2000::ff");
+    private static final IpPrefix PREFIX6_1 = IpPrefix.valueOf("2000::ff/120");
+    private static final InterfaceIpAddress INTF_IP4_1 = new InterfaceIpAddress(
+            IP4_1, PREFIX4_1);
+    private static final InterfaceIpAddress INTF_IP6_1 = new InterfaceIpAddress(
+            IP6_1, PREFIX6_1);
+    private static final VlanId INTF_VLAN_UNTAGGED = VlanId.vlanId((short) 10);
+    static final Interface INTF1 = new Interface(
+            "INTF1", CP12, Lists.newArrayList(INTF_IP4_1, INTF_IP6_1), MacAddress.NONE,
+            null, INTF_VLAN_UNTAGGED, null, null);
+    static final ConnectPoint CP13 = new ConnectPoint(REMOTE_LEAF, P3);
+    private static final IpAddress IP4_2 = IpAddress.valueOf("10.0.3.254");
+    private static final IpPrefix PREFIX4_2 = IpPrefix.valueOf("10.0.3.254/24");
+    private static final IpAddress IP6_2 = IpAddress.valueOf("2000::3ff");
+    private static final IpPrefix PREFIX6_2 = IpPrefix.valueOf("2000::3ff/120");
+    private static final InterfaceIpAddress INTF_IP4_2 = new InterfaceIpAddress(
+            IP4_2, PREFIX4_2);
+    private static final InterfaceIpAddress INTF_IP6_2 = new InterfaceIpAddress(
+            IP6_2, PREFIX6_2);
+    static final Interface INTF2 = new Interface(
+            "INTF2", CP13, Lists.newArrayList(INTF_IP4_2, INTF_IP6_2), MacAddress.NONE,
+            null, INTF_VLAN_UNTAGGED, null, null);
+
+    static final ConnectPoint CP1011 = new ConnectPoint(LOCAL_LEAF, P1);
+    private static final IpAddress IP4_11 = IpAddress.valueOf("10.0.1.254");
+    private static final IpPrefix PREFIX4_11 = IpPrefix.valueOf("10.0.1.254/24");
+    private static final InterfaceIpAddress INTF_IP4_11 = new InterfaceIpAddress(
+            IP4_11, PREFIX4_11);
+    private static final IpAddress IP6_11 = IpAddress.valueOf("2000::1ff");
+    private static final IpPrefix PREFIX6_11 = IpPrefix.valueOf("2000::1ff/120");
+    private static final InterfaceIpAddress INTF_IP6_11 = new InterfaceIpAddress(
+            IP6_11, PREFIX6_11);
+    static final Interface INTF111 = new Interface(
+            "INTF111", CP1011, Lists.newArrayList(INTF_IP4_11, INTF_IP6_11), MacAddress.NONE, null,
+            INTF_VLAN_UNTAGGED, null, null);
+
+    static final ConnectPoint CP2011 = new ConnectPoint(LOCAL_LEAF1, P1);
+    private static final IpAddress IP4_21 = IpAddress.valueOf("10.0.2.254");
+    private static final IpPrefix PREFIX4_21 = IpPrefix.valueOf("10.0.2.254/24");
+    private static final InterfaceIpAddress INTF_IP4_21 = new InterfaceIpAddress(
+            IP4_21, PREFIX4_21);
+    private static final IpAddress IP6_21 = IpAddress.valueOf("2000::2ff");
+    private static final IpPrefix PREFIX6_21 = IpPrefix.valueOf("2000::2ff/120");
+    private static final InterfaceIpAddress INTF_IP6_21 = new InterfaceIpAddress(
+            IP6_21, PREFIX6_21);
+    static final Interface INTF211 = new Interface(
+            "INTF211", CP2011, Lists.newArrayList(INTF_IP4_21, INTF_IP6_21), MacAddress.NONE, null,
+            INTF_VLAN_UNTAGGED, null, null);
+
+    static final ConnectPoint CP2021 = new ConnectPoint(LOCAL_LEAF2, P1);
+    private static final IpAddress IP4_22 = IpAddress.valueOf("10.0.2.254");
+    private static final IpPrefix PREFIX4_22 = IpPrefix.valueOf("10.0.2.254/24");
+    private static final InterfaceIpAddress INTF_IP4_22 = new InterfaceIpAddress(
+            IP4_22, PREFIX4_22);
+    private static final IpAddress IP6_22 = IpAddress.valueOf("2000::2ff");
+    private static final IpPrefix PREFIX6_22 = IpPrefix.valueOf("2000::2ff/120");
+    private static final InterfaceIpAddress INTF_IP6_22 = new InterfaceIpAddress(
+            IP6_22, PREFIX6_22);
+    static final Interface INTF212 = new Interface(
+            "INTF212", CP2021, Lists.newArrayList(INTF_IP4_22, INTF_IP6_22), MacAddress.NONE, null,
+            INTF_VLAN_UNTAGGED, null, null);
+    private static final PortNumber P4 = PortNumber.portNumber(4);
+    static final ConnectPoint CP2024 = new ConnectPoint(LOCAL_LEAF2, P4);
+    private static final PortNumber P5 = PortNumber.portNumber(5);
+    static final ConnectPoint CP2025 = new ConnectPoint(LOCAL_LEAF2, P5);
+    private static final IpAddress IP4_23 = IpAddress.valueOf("10.0.4.254");
+    private static final IpPrefix PREFIX4_23 = IpPrefix.valueOf("10.0.4.254/24");
+    private static final InterfaceIpAddress INTF_IP4_23 = new InterfaceIpAddress(
+            IP4_23, PREFIX4_23);
+    private static final IpAddress IP6_23 = IpAddress.valueOf("2000::4ff");
+    private static final IpPrefix PREFIX6_23 = IpPrefix.valueOf("2000::4ff/120");
+    private static final InterfaceIpAddress INTF_IP6_23 = new InterfaceIpAddress(
+            IP6_23, PREFIX6_23);
+    static final Interface INTF213 = new Interface(
+            "INTF212", CP2024, Lists.newArrayList(INTF_IP4_23, INTF_IP6_23), MacAddress.NONE, null,
+            INTF_VLAN_UNTAGGED, null, null);
+
+    // Packet-ins section
+    private static final MacAddress SRC_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+
+    private static final ICMPEcho ICMP_ECHO = new ICMPEcho()
+            .setIdentifier((short) 0)
+            .setSequenceNum((short) 0);
+
+    private static final ICMP ICMP_REQUEST = (ICMP) new ICMP()
+            .setIcmpType(TYPE_ECHO_REQUEST)
+            .setPayload(ICMP_ECHO);
+
+    private static final Ip4Address SRC_IPV4 = Ip4Address.valueOf("10.0.1.1");
+    static final Ip4Address DST_IPV4 = Ip4Address.valueOf("10.0.0.254");
+
+    private static final IPv4 IPV4_REQUEST = (IPv4) new IPv4()
+            .setDestinationAddress(DST_IPV4.toInt())
+            .setSourceAddress(SRC_IPV4.toInt())
+            .setTtl((byte) 64)
+            .setProtocol(PROTOCOL_ICMP)
+            .setPayload(ICMP_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV4 = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV4)
+            .setDestinationMACAddress(REMOTE_MAC)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(IPV4_REQUEST);
+
+    private static final ICMP6 ICMP6_REQUEST = new ICMP6()
+            .setIcmpType(ECHO_REQUEST);
+
+    private static final Ip6Address SRC_IPV6 = Ip6Address.valueOf("2000::101");
+    static final Ip6Address DST_IPV6 = Ip6Address.valueOf("2000::ff");
+
+    private static final IPv6 IPV6_REQUEST = (IPv6) new IPv6()
+            .setDestinationAddress(DST_IPV6.toOctets())
+            .setSourceAddress(SRC_IPV6.toOctets())
+            .setHopLimit((byte) 255)
+            .setNextHeader(IPv6.PROTOCOL_ICMP6)
+            .setPayload(ICMP6_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV6 = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV6)
+            .setDestinationMACAddress(REMOTE_MAC)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(IPV6_REQUEST);
+
+    static final Ip4Address SRC_IPV41 = Ip4Address.valueOf("10.0.2.1");
+
+    private static final IPv4 IPV41_REQUEST = (IPv4) new IPv4()
+            .setDestinationAddress(DST_IPV4.toInt())
+            .setSourceAddress(SRC_IPV41.toInt())
+            .setTtl((byte) 64)
+            .setProtocol(PROTOCOL_ICMP)
+            .setPayload(ICMP_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV41 = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV4)
+            .setDestinationMACAddress(REMOTE_MAC)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(IPV41_REQUEST);
+
+    static final Ip6Address SRC_IPV61 = Ip6Address.valueOf("2000::201");
+
+    private static final IPv6 IPV61_REQUEST = (IPv6) new IPv6()
+            .setDestinationAddress(DST_IPV6.toOctets())
+            .setSourceAddress(SRC_IPV61.toOctets())
+            .setHopLimit((byte) 255)
+            .setNextHeader(IPv6.PROTOCOL_ICMP6)
+            .setPayload(ICMP6_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV61 = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV6)
+            .setDestinationMACAddress(REMOTE_MAC)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(IPV61_REQUEST);
+
+    private static final MacAddress SRC_MAC_MY = MacAddress.valueOf("00:01:00:00:00:01");
+    static final Ip4Address SRC_IPV4_MY = Ip4Address.valueOf("10.0.0.1");
+
+    private static final IPv4 IPV4_REQUEST_MY = (IPv4) new IPv4()
+            .setDestinationAddress(DST_IPV4.toInt())
+            .setSourceAddress(SRC_IPV4_MY.toInt())
+            .setTtl((byte) 64)
+            .setProtocol(PROTOCOL_ICMP)
+            .setPayload(ICMP_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV4_MY = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV4)
+            .setDestinationMACAddress(REMOTE_MAC)
+            .setSourceMACAddress(SRC_MAC_MY)
+            .setPayload(IPV4_REQUEST_MY);
+
+    static final Ip6Address SRC_IPV6_MY = Ip6Address.valueOf("2000::1");
+
+    private static final IPv6 IPV6_REQUEST_MY = (IPv6) new IPv6()
+            .setDestinationAddress(DST_IPV6.toOctets())
+            .setSourceAddress(SRC_IPV6_MY.toOctets())
+            .setHopLimit((byte) 255)
+            .setNextHeader(IPv6.PROTOCOL_ICMP6)
+            .setPayload(ICMP6_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV6_MY = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV6)
+            .setDestinationMACAddress(REMOTE_MAC)
+            .setSourceMACAddress(SRC_MAC_MY)
+            .setPayload(IPV6_REQUEST_MY);
+
+    static final Ip4Address DST_IPV4_LOCAL = Ip4Address.valueOf("10.0.3.254");
+
+    private static final IPv4 IPV4_REQUEST_LOCAL = (IPv4) new IPv4()
+            .setDestinationAddress(DST_IPV4_LOCAL.toInt())
+            .setSourceAddress(SRC_IPV4_MY.toInt())
+            .setTtl((byte) 64)
+            .setProtocol(PROTOCOL_ICMP)
+            .setPayload(ICMP_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV4_LOCAL = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV4)
+            .setDestinationMACAddress(REMOTE_MAC)
+            .setSourceMACAddress(SRC_MAC_MY)
+            .setPayload(IPV4_REQUEST_LOCAL);
+
+    static final Ip6Address DST_IPV6_LOCAL = Ip6Address.valueOf("2000::3ff");
+
+    private static final IPv6 IPV6_REQUEST_LOCAL = (IPv6) new IPv6()
+            .setDestinationAddress(DST_IPV6_LOCAL.toOctets())
+            .setSourceAddress(SRC_IPV6_MY.toOctets())
+            .setHopLimit((byte) 255)
+            .setNextHeader(IPv6.PROTOCOL_ICMP6)
+            .setPayload(ICMP6_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV6_LOCAL = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV6)
+            .setDestinationMACAddress(REMOTE_MAC)
+            .setSourceMACAddress(SRC_MAC_MY)
+            .setPayload(IPV6_REQUEST_LOCAL);
+
+    static final Ip4Address DST_IPV4_SAME = Ip4Address.valueOf("10.0.4.254");
+
+    private static final IPv4 IPV4_REQUEST_SAME = (IPv4) new IPv4()
+            .setDestinationAddress(DST_IPV4_SAME.toInt())
+            .setSourceAddress(SRC_IPV41.toInt())
+            .setTtl((byte) 64)
+            .setProtocol(PROTOCOL_ICMP)
+            .setPayload(ICMP_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV4_SAME = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV4)
+            .setDestinationMACAddress(LOCAL_MAC2)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(IPV4_REQUEST_SAME);
+
+    static final Ip6Address DST_IPV6_SAME = Ip6Address.valueOf("2000::4ff");
+
+    private static final IPv6 IPV6_REQUEST_SAME = (IPv6) new IPv6()
+            .setDestinationAddress(DST_IPV6_SAME.toOctets())
+            .setSourceAddress(SRC_IPV61.toOctets())
+            .setHopLimit((byte) 255)
+            .setNextHeader(IPv6.PROTOCOL_ICMP6)
+            .setPayload(ICMP6_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV6_SAME = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV6)
+            .setDestinationMACAddress(LOCAL_MAC2)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(IPV6_REQUEST_SAME);
+
+    static final Ip6Address DST_IPV6_LL = Ip6Address.valueOf(
+            IPv6.getLinkLocalAddress(MacAddress.NONE.toBytes()));
+    static final Ip6Address SRC_IPV6_LL = Ip6Address.valueOf(
+            IPv6.getLinkLocalAddress(SRC_MAC_MY.toBytes()));
+
+    private static final IPv6 IPV6_REQUEST_LL = (IPv6) new IPv6()
+            .setDestinationAddress(DST_IPV6_LL.toOctets())
+            .setSourceAddress(SRC_IPV6_LL.toOctets())
+            .setHopLimit((byte) 255)
+            .setNextHeader(IPv6.PROTOCOL_ICMP6)
+            .setPayload(ICMP6_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV6_LL = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV6)
+            .setDestinationMACAddress(MacAddress.NONE)
+            .setSourceMACAddress(SRC_MAC_MY)
+            .setPayload(IPV6_REQUEST_LL);
+
+    static final Ip4Address DST_IPV4_LOOPBACK = Ip4Address.valueOf(REMOTE_LEAF_LB4);
+
+    private static final IPv4 IPV4_REQUEST_LOOPBACK = (IPv4) new IPv4()
+            .setDestinationAddress(DST_IPV4_LOOPBACK.toInt())
+            .setSourceAddress(SRC_IPV4_MY.toInt())
+            .setTtl((byte) 64)
+            .setProtocol(PROTOCOL_ICMP)
+            .setPayload(ICMP_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV4_LOOPBACK = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV4)
+            .setDestinationMACAddress(REMOTE_MAC)
+            .setSourceMACAddress(SRC_MAC_MY)
+            .setPayload(IPV4_REQUEST_LOOPBACK);
+
+    static final Ip6Address DST_IPV6_LOOPBACK = Ip6Address.valueOf(REMOTE_LEAF_LB6);
+
+    private static final IPv6 IPV6_REQUEST_LOOPBACK = (IPv6) new IPv6()
+            .setDestinationAddress(DST_IPV6_LOOPBACK.toOctets())
+            .setSourceAddress(SRC_IPV6_MY.toOctets())
+            .setHopLimit((byte) 255)
+            .setNextHeader(IPv6.PROTOCOL_ICMP6)
+            .setPayload(ICMP6_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV6_LOOPBACK = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV6)
+            .setDestinationMACAddress(REMOTE_MAC)
+            .setSourceMACAddress(SRC_MAC_MY)
+            .setPayload(IPV6_REQUEST_LOOPBACK);
+
+    static final Ip4Address DST_IPV4_LOOPBACK_PAIR = Ip4Address.valueOf(LOCAL_LEAF1_LB4);
+
+    private static final IPv4 IPV4_REQUEST_LOOPBACK_PAIR = (IPv4) new IPv4()
+            .setDestinationAddress(DST_IPV4_LOOPBACK_PAIR.toInt())
+            .setSourceAddress(SRC_IPV41.toInt())
+            .setTtl((byte) 64)
+            .setProtocol(PROTOCOL_ICMP)
+            .setPayload(ICMP_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV4_LOOPBACK_PAIR = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV4)
+            .setDestinationMACAddress(LOCAL_MAC1)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(IPV4_REQUEST_LOOPBACK_PAIR);
+
+    static final Ip6Address DST_IPV6_LOOPBACK_PAIR = Ip6Address.valueOf(LOCAL_LEAF2_LB6);
+
+    private static final IPv6 IPV6_REQUEST_LOOPBACK_PAIR = (IPv6) new IPv6()
+            .setDestinationAddress(DST_IPV6_LOOPBACK_PAIR.toOctets())
+            .setSourceAddress(SRC_IPV61.toOctets())
+            .setHopLimit((byte) 255)
+            .setNextHeader(IPv6.PROTOCOL_ICMP6)
+            .setPayload(ICMP6_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV6_LOOPBACK_PAIR = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV6)
+            .setDestinationMACAddress(LOCAL_MAC2)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(IPV6_REQUEST_LOOPBACK_PAIR);
+
+    static final Ip4Address DST_IPV4_GATEWAY_PAIR = Ip4Address.valueOf("10.0.2.254");
+
+    private static final IPv4 IPV4_REQUEST_GATEWAY_PAIR = (IPv4) new IPv4()
+            .setDestinationAddress(DST_IPV4_GATEWAY_PAIR.toInt())
+            .setSourceAddress(SRC_IPV41.toInt())
+            .setTtl((byte) 64)
+            .setProtocol(PROTOCOL_ICMP)
+            .setPayload(ICMP_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV4_GATEWAY_PAIR = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV4)
+            .setDestinationMACAddress(LOCAL_MAC1)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(IPV4_REQUEST_GATEWAY_PAIR);
+
+    static final Ip6Address DST_IPV6_GATEWAY_PAIR = Ip6Address.valueOf("2000::2ff");
+
+    private static final IPv6 IPV6_REQUEST_GATEWAY_PAIR = (IPv6) new IPv6()
+            .setDestinationAddress(DST_IPV6_GATEWAY_PAIR.toOctets())
+            .setSourceAddress(SRC_IPV61.toOctets())
+            .setHopLimit((byte) 255)
+            .setNextHeader(IPv6.PROTOCOL_ICMP6)
+            .setPayload(ICMP6_REQUEST);
+
+    static final Ethernet ETH_REQ_IPV6_GATEWAY_PAIR = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.TYPE_IPV6)
+            .setDestinationMACAddress(LOCAL_MAC2)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(IPV6_REQUEST_GATEWAY_PAIR);
+
+    // Resolved route
+    private static final ResolvedRoute IPV4_ROUTE = new ResolvedRoute(
+            new Route(STATIC, SRC_IPV4.toIpPrefix(), SRC_IPV4), MacAddress.NONE);
+    private static final ResolvedRoute IPV6_ROUTE = new ResolvedRoute(
+            new Route(STATIC, SRC_IPV6.toIpPrefix(), SRC_IPV6), MacAddress.NONE);
+    static final Map<IpPrefix, Set<ResolvedRoute>> ROUTE_STORE = ImmutableMap.of(SRC_IPV4.toIpPrefix(),
+                                                                                 Sets.newHashSet(IPV4_ROUTE),
+                                                                                 SRC_IPV6.toIpPrefix(),
+                                                                                 Sets.newHashSet(IPV6_ROUTE));
+}
