diff --git a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
index e7c9203..fc3dd17 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
+++ b/apps/segmentrouting/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/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java b/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
index 81a161f..123da37 100644
--- a/apps/segmentrouting/app/src/main/java/org/onosproject/segmentrouting/config/DeviceConfiguration.java
+++ b/apps/segmentrouting/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/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/IcmpHandlerTest.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/IcmpHandlerTest.java
new file mode 100644
index 0000000..cc7c6a8
--- /dev/null
+++ b/apps/segmentrouting/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/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockInterfaceService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockInterfaceService.java
index 17422d2..6e170b0 100644
--- a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockInterfaceService.java
+++ b/apps/segmentrouting/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/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockNeighbourResolutionService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockNeighbourResolutionService.java
new file mode 100644
index 0000000..5a41149
--- /dev/null
+++ b/apps/segmentrouting/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/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockNetworkConfigRegistry.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockNetworkConfigRegistry.java
index 09f8da2..e18483e 100644
--- a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockNetworkConfigRegistry.java
+++ b/apps/segmentrouting/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/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockPacketService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockPacketService.java
new file mode 100644
index 0000000..73a8b65
--- /dev/null
+++ b/apps/segmentrouting/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/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRouteService.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRouteService.java
index bfeca1f..c3730dd 100644
--- a/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/MockRouteService.java
+++ b/apps/segmentrouting/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/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/TestUtils.java b/apps/segmentrouting/app/src/test/java/org/onosproject/segmentrouting/TestUtils.java
new file mode 100644
index 0000000..339b2c8
--- /dev/null
+++ b/apps/segmentrouting/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));
+}
diff --git a/utils/misc/src/main/java/org/onlab/packet/Ethernet.java b/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
index 5fd07bf..fb249a9 100644
--- a/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
+++ b/utils/misc/src/main/java/org/onlab/packet/Ethernet.java
@@ -514,13 +514,13 @@
      */
     @Override
     public String toString() {
-
         final StringBuilder sb = new StringBuilder("\n");
-
         final IPacket pkt = this.getPayload();
 
         if (pkt instanceof ARP) {
             sb.append("arp");
+        } else if (pkt instanceof MPLS) {
+            sb.append("mpls");
         } else if (pkt instanceof LLDP) {
             sb.append("lldp");
         } else if (pkt instanceof ICMP) {
@@ -530,11 +530,7 @@
         } else if (pkt instanceof DHCP) {
             sb.append("dhcp");
         } else {
-            /*
-             * When we don't know the protocol, we print using
-             * the well known hex format instead of a decimal
-             * value.
-             */
+            // Just print the ethertype
             sb.append(String.format(HEX_PROTO,
                                     Integer.toHexString(this.getEtherType() & 0xffff)));
         }
@@ -567,6 +563,12 @@
             sb.append("\nnw_dst: ");
             sb.append(IPv4.fromIPv4Address(IPv4.toIPv4Address(p
                     .getTargetProtocolAddress())));
+        } else if (pkt instanceof MPLS) {
+            final MPLS p = (MPLS) pkt;
+            sb.append("\nmpls: ");
+            sb.append(this.etherType == MPLS_UNICAST ? "unicast" : "multicast");
+            sb.append("\nmpls_label: ");
+            sb.append(p.label);
         } else if (pkt instanceof LLDP) {
             sb.append("lldp packet");
         } else if (pkt instanceof ICMP) {
@@ -593,7 +595,6 @@
                     sb.append(((TCP) payload).getSourcePort());
                     sb.append("\ntp_dst: ");
                     sb.append(((TCP) payload).getDestinationPort());
-
                 } else if (payload instanceof UDP) {
                     sb.append("\ntp_src: ");
                     sb.append(((UDP) payload).getSourcePort());
@@ -705,7 +706,6 @@
         } else {
             sb.append("\nunknown packet");
         }
-
         return sb.toString();
     }
 
diff --git a/utils/misc/src/main/java/org/onlab/packet/MPLS.java b/utils/misc/src/main/java/org/onlab/packet/MPLS.java
index 948075b..07ead0c 100644
--- a/utils/misc/src/main/java/org/onlab/packet/MPLS.java
+++ b/utils/misc/src/main/java/org/onlab/packet/MPLS.java
@@ -30,13 +30,15 @@
     public static final int HEADER_LENGTH = 4;
 
     public static final byte PROTOCOL_IPV4 = 0x1;
+    public static final byte PROTOCOL_IPV6 = 0x2;
     public static final byte PROTOCOL_MPLS = 0x6;
     // mutable for Testing
     static Map<Byte, Deserializer<? extends IPacket>> protocolDeserializerMap =
             ImmutableMap.<Byte, Deserializer<? extends IPacket>>builder()
-                .put(PROTOCOL_IPV4, IPv4.deserializer())
-                .put(PROTOCOL_MPLS, MPLS.deserializer())
-                .build();
+                    .put(PROTOCOL_IPV6, IPv6.deserializer())
+                    .put(PROTOCOL_IPV4, IPv4.deserializer())
+                    .put(PROTOCOL_MPLS, MPLS.deserializer())
+                    .build();
 
     protected int label; //20bits
     protected byte bos; //1bit
@@ -108,6 +110,22 @@
         this.ttl = ttl;
     }
 
+    @Override
+    public IPacket setPayload(final IPacket payload) {
+        // We implicitly assume that traffic can be only of these three types
+        if (payload instanceof MPLS) {
+            this.bos = 0;
+            this.protocol = PROTOCOL_MPLS;
+        } else if (payload instanceof IPv6) {
+            this.bos = 1;
+            this.protocol = PROTOCOL_IPV6;
+        } else {
+            this.bos = 1;
+            this.protocol = PROTOCOL_IPV4;
+        }
+        return super.setPayload(payload);
+    }
+
     /**
      * Deserializer function for MPLS packets.
      *
@@ -124,7 +142,11 @@
             mpls.label = ((mplsheader & 0xfffff000) >>> 12);
             mpls.bos = (byte) ((mplsheader & 0x00000100) >> 8);
             mpls.ttl = (byte) (mplsheader & 0x000000ff);
-            mpls.protocol = (mpls.bos == 1) ? PROTOCOL_IPV4 : PROTOCOL_MPLS;
+
+            ByteBuffer duplicate = bb.duplicate();
+            short protocol = (short) ((duplicate.get() & 0xf0) >> 4);
+            mpls.protocol = (mpls.bos == 1) ? protocol == 4 ?
+                    PROTOCOL_IPV4 : PROTOCOL_IPV6 : PROTOCOL_MPLS;
 
             Deserializer<? extends IPacket> deserializer;
             if (protocolDeserializerMap.containsKey(mpls.protocol)) {
diff --git a/utils/misc/src/test/java/org/onlab/packet/MplsTest.java b/utils/misc/src/test/java/org/onlab/packet/MplsTest.java
index 4c247fa..6231636 100644
--- a/utils/misc/src/test/java/org/onlab/packet/MplsTest.java
+++ b/utils/misc/src/test/java/org/onlab/packet/MplsTest.java
@@ -21,10 +21,18 @@
 import org.junit.Test;
 
 import java.nio.ByteBuffer;
-import java.util.HashMap;
 
+import static junit.framework.TestCase.assertNotNull;
+import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
+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.onlab.packet.MPLS.PROTOCOL_IPV4;
+import static org.onlab.packet.MPLS.PROTOCOL_IPV6;
+import static org.onlab.packet.MPLS.PROTOCOL_MPLS;
 
 /**
  * Unit tests for MPLS class.
@@ -36,22 +44,91 @@
     private int label = 1048575;
     private byte bos = 1;
     private byte ttl = 20;
-    private byte protocol = MPLS.PROTOCOL_IPV4;
+    private byte protocol = PROTOCOL_IPV4;
 
     private byte[] bytes;
+    private byte[] truncatedBytes;
+
+    // Define packets to deserialize
+    private static final MacAddress SRC_MAC = MacAddress.valueOf("00:00:00:00:00:01");
+    private static final MacAddress DST_MAC = MacAddress.valueOf("00:00:00:00:00:02");
+
+    private static final ICMPEcho ICMP_ECHO = new ICMPEcho()
+            .setIdentifier((short) 0)
+            .setSequenceNum((short) 0);
+
+    private static final ICMP ICMP = (ICMP) new ICMP()
+            .setIcmpType(TYPE_ECHO_REQUEST)
+            .setPayload(ICMP_ECHO);
+
+    private static final Ip4Address SRC_IPV4 = Ip4Address.valueOf("10.0.1.1");
+    private static final Ip4Address DST_IPV4 = Ip4Address.valueOf("10.0.0.254");
+
+    private static final IPv4 IPV4 = (IPv4) new IPv4()
+            .setDestinationAddress(DST_IPV4.toInt())
+            .setSourceAddress(SRC_IPV4.toInt())
+            .setTtl((byte) 64)
+            .setProtocol(PROTOCOL_ICMP)
+            .setPayload(ICMP);
+
+    private static final ICMP6 ICMP6 = new ICMP6()
+            .setIcmpType(ECHO_REQUEST);
+
+    private static final Ip6Address SRC_IPV6 = Ip6Address.valueOf("2000::101");
+    private static final Ip6Address DST_IPV6 = Ip6Address.valueOf("2000::ff");
+
+    private static final IPv6 IPV6 = (IPv6) new IPv6()
+            .setDestinationAddress(DST_IPV6.toOctets())
+            .setSourceAddress(SRC_IPV6.toOctets())
+            .setHopLimit((byte) 255)
+            .setNextHeader(IPv6.PROTOCOL_ICMP6)
+            .setPayload(ICMP6);
+
+    private static final MPLS MPLS_IPV4 = new MPLS();
+    private static final MPLS MPLS_BOS_IPV4 = new MPLS();
+    private static final MPLS MPLS_IPV6 = new MPLS();
+    private static final MPLS MPLS_BOS_IPV6 = new MPLS();
+
+    private static final Ethernet ETH_IPV4 = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.MPLS_UNICAST)
+            .setDestinationMACAddress(DST_MAC)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(MPLS_IPV4);
+
+    private static final Ethernet ETH_IPV6 = (Ethernet) new Ethernet()
+            .setEtherType(Ethernet.MPLS_UNICAST)
+            .setDestinationMACAddress(DST_MAC)
+            .setSourceMACAddress(SRC_MAC)
+            .setPayload(MPLS_IPV6);
 
     @Before
     public void setUp() throws Exception {
-        // Replace normal deserializer map with an empty map. This will cause
-        // the DataDeserializer to be used which will silently handle 0-byte input.
-        MPLS.protocolDeserializerMap = new HashMap<>();
-
+        // Setup packets
         deserializer = MPLS.deserializer();
 
-        ByteBuffer bb = ByteBuffer.allocate(MPLS.HEADER_LENGTH);
+        byte[] ipv4 = IPV4.serialize();
+        ByteBuffer bb = ByteBuffer.allocate(MPLS.HEADER_LENGTH + IPV4.getTotalLength());
         bb.putInt(((label & 0x000fffff) << 12) | ((bos & 0x1) << 8 | (ttl & 0xff)));
+        bb.put(ipv4);
 
         bytes = bb.array();
+
+        bb = ByteBuffer.allocate(MPLS.HEADER_LENGTH);
+        bb.putInt(((label & 0x000fffff) << 12) | ((bos & 0x1) << 8 | (ttl & 0xff)));
+
+        truncatedBytes = bb.array();
+
+        MPLS_BOS_IPV4.setLabel(101);
+        MPLS_BOS_IPV4.setPayload(IPV4);
+        MPLS_IPV4.setLabel(1);
+        MPLS_IPV4.setPayload(MPLS_BOS_IPV4);
+        ETH_IPV4.setPayload(MPLS_IPV4);
+
+        MPLS_BOS_IPV6.setLabel(201);
+        MPLS_BOS_IPV6.setPayload(IPV6);
+        MPLS_IPV6.setLabel(2);
+        MPLS_IPV6.setPayload(MPLS_BOS_IPV6);
+        ETH_IPV6.setPayload(MPLS_IPV6);
     }
 
     @Test
@@ -61,7 +138,7 @@
 
     @Test
     public void testDeserializeTruncated() throws Exception {
-        PacketTestUtils.testDeserializeTruncated(deserializer, bytes);
+        PacketTestUtils.testDeserializeTruncated(deserializer, truncatedBytes);
     }
 
     /**
@@ -90,4 +167,78 @@
         assertTrue(StringUtils.contains(str, "ttl=" + ttl));
         assertTrue(StringUtils.contains(str, "protocol=" + protocol));
     }
+
+    @Test
+    public void testIpv4OverMplsDeserialize() throws Exception {
+        // Serialize
+        byte[] packet = ETH_IPV4.serialize();
+        assertThat(MPLS_IPV4.protocol, is(PROTOCOL_MPLS));
+        assertThat(MPLS_IPV4.bos, is((byte) 0));
+        assertThat(MPLS_BOS_IPV4.protocol, is(PROTOCOL_IPV4));
+        assertThat(MPLS_BOS_IPV4.bos, is((byte) 1));
+        // Deserialize
+        Ethernet ethernet;
+        ethernet = Ethernet.deserializer().deserialize(packet, 0, packet.length);
+
+        // Verify
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_IPV4.getSourceMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_IPV4.getDestinationMAC()));
+        assertThat(ethernet.getEtherType(), is(Ethernet.MPLS_UNICAST));
+        assertTrue(ethernet.getPayload() instanceof MPLS);
+        MPLS mpls = (MPLS) ethernet.getPayload();
+        assertThat(mpls.getLabel(), is(1));
+        assertThat(mpls.getTtl(), is((byte) 0));
+        assertThat(mpls.protocol, is(PROTOCOL_MPLS));
+        assertThat(mpls.bos, is((byte) 0));
+        assertTrue(mpls.getPayload() instanceof MPLS);
+        mpls = (MPLS) mpls.getPayload();
+        assertThat(mpls.getLabel(), is(101));
+        assertThat(mpls.getTtl(), is((byte) 0));
+        assertThat(mpls.protocol, is(PROTOCOL_IPV4));
+        assertThat(mpls.bos, is((byte) 1));
+        IPv4 ip = (IPv4) mpls.getPayload();
+        assertThat(ip.getSourceAddress(), is(SRC_IPV4.toInt()));
+        assertThat(ip.getDestinationAddress(), is(DST_IPV4.toInt()));
+        assertTrue(ip.getPayload() instanceof ICMP);
+        ICMP icmp = (ICMP) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REQUEST));
+    }
+
+    @Test
+    public void testIpv6OverMplsDeserialize() throws Exception {
+        // Serialize
+        byte[] packet = ETH_IPV6.serialize();
+        assertThat(MPLS_IPV6.protocol, is(PROTOCOL_MPLS));
+        assertThat(MPLS_IPV6.bos, is((byte) 0));
+        assertThat(MPLS_BOS_IPV6.protocol, is(PROTOCOL_IPV6));
+        assertThat(MPLS_BOS_IPV6.bos, is((byte) 1));
+        // Deserialize
+        Ethernet ethernet;
+        ethernet = Ethernet.deserializer().deserialize(packet, 0, packet.length);
+
+        // Verify
+        assertNotNull(ethernet);
+        assertThat(ethernet.getSourceMAC(), is(ETH_IPV6.getSourceMAC()));
+        assertThat(ethernet.getDestinationMAC(), is(ETH_IPV6.getDestinationMAC()));
+        assertThat(ethernet.getEtherType(), is(Ethernet.MPLS_UNICAST));
+        assertTrue(ethernet.getPayload() instanceof MPLS);
+        MPLS mpls = (MPLS) ethernet.getPayload();
+        assertThat(mpls.getLabel(), is(2));
+        assertThat(mpls.getTtl(), is((byte) 0));
+        assertThat(mpls.protocol, is(PROTOCOL_MPLS));
+        assertThat(mpls.bos, is((byte) 0));
+        assertTrue(mpls.getPayload() instanceof MPLS);
+        mpls = (MPLS) mpls.getPayload();
+        assertThat(mpls.getLabel(), is(201));
+        assertThat(mpls.getTtl(), is((byte) 0));
+        assertThat(mpls.protocol, is(PROTOCOL_IPV6));
+        assertThat(mpls.bos, is((byte) 1));
+        IPv6 ip = (IPv6) mpls.getPayload();
+        assertThat(ip.getSourceAddress(), is(SRC_IPV6.toOctets()));
+        assertThat(ip.getDestinationAddress(), is(DST_IPV6.toOctets()));
+        assertTrue(ip.getPayload() instanceof ICMP6);
+        ICMP6 icmp = (ICMP6) ip.getPayload();
+        assertThat(icmp.getIcmpType(), is(ECHO_REQUEST));
+    }
 }
