Improves ping responder
Patch contains several bugfixes and improvements:
- Fixes sid retrieval when the destination leaf is down
- Fixes sid retrieval when ping goes through the spine
- Fixes MPLS deserializer
- Improves Ethernet toString
- Fixes ping to looback for dh host when bond sends to wrong leaf
Change-Id: I05963e74b2976e526826ffd377cadeb462ba0a8d
diff --git a/app/src/test/java/org/onosproject/segmentrouting/IcmpHandlerTest.java b/app/src/test/java/org/onosproject/segmentrouting/IcmpHandlerTest.java
new file mode 100644
index 0000000..cc7c6a8
--- /dev/null
+++ b/app/src/test/java/org/onosproject/segmentrouting/IcmpHandlerTest.java
@@ -0,0 +1,794 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.segmentrouting;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.google.common.collect.ImmutableSet;
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.ICMP;
+import org.onlab.packet.ICMP6;
+import org.onlab.packet.IPv4;
+import org.onlab.packet.IPv6;
+import org.onlab.packet.MPLS;
+import org.onosproject.TestApplicationId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.net.config.ConfigApplyDelegate;
+import org.onosproject.net.config.basics.InterfaceConfig;
+import org.onosproject.net.device.DeviceService;
+import org.onosproject.segmentrouting.config.DeviceConfiguration;
+import org.onosproject.segmentrouting.config.SegmentRoutingAppConfig;
+import org.onosproject.segmentrouting.config.SegmentRoutingDeviceConfig;
+
+import java.util.Collections;
+
+import static org.easymock.EasyMock.*;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.*;
+import static org.onlab.packet.ICMP.*;
+import static org.onlab.packet.ICMP6.ECHO_REPLY;
+import static org.onosproject.segmentrouting.TestUtils.*;
+
+/**
+ * Tests for IcmpHandler.
+ */
+public class IcmpHandlerTest {
+
+ private IcmpHandler icmpHandler;
+ private MockPacketService packetService;
+ private SegmentRoutingManager segmentRoutingManager;
+ private ApplicationId testApplicationId = TestApplicationId.create("test");
+
+ @Before
+ public void setUp() {
+
+ // Init
+ ObjectMapper mapper = new ObjectMapper();
+ ConfigApplyDelegate delegate = config -> { };
+
+ // Setup configuration for app
+ SegmentRoutingAppConfig appConfig = new SegmentRoutingAppConfig();
+ JsonNode appTree = mapper.createObjectNode();
+ appConfig.init(testApplicationId, "icmp-handler-test", appTree, mapper, delegate);
+ appConfig.setSuppressSubnet(Collections.emptySet());
+
+ // Setup configuration for the devices
+ SegmentRoutingDeviceConfig remoteLeafConfig = new SegmentRoutingDeviceConfig();
+ JsonNode remoteLeafTree = mapper.createObjectNode();
+ remoteLeafConfig.init(REMOTE_LEAF, "icmp-handler-test", remoteLeafTree, mapper, delegate);
+ remoteLeafConfig.setNodeSidIPv4(REMOTE_LEAF_SID4)
+ .setNodeSidIPv6(REMOTE_LEAF_SID6)
+ .setRouterIpv4(REMOTE_LEAF_LB4)
+ .setRouterIpv6(REMOTE_LEAF_LB6)
+ .setIsEdgeRouter(true)
+ .setRouterMac(REMOTE_MAC.toString());
+ SegmentRoutingDeviceConfig localLeafConfig = new SegmentRoutingDeviceConfig();
+ JsonNode localLeafTree = mapper.createObjectNode();
+ localLeafConfig.init(LOCAL_LEAF, "icmp-handler-test", localLeafTree, mapper, delegate);
+ localLeafConfig.setNodeSidIPv4(LOCAL_LEAF_SID4)
+ .setRouterIpv4(LOCAL_LEAF_LB4)
+ .setNodeSidIPv6(LOCAL_LEAF_SID6)
+ .setRouterIpv6(LOCAL_LEAF_LB6)
+ .setIsEdgeRouter(true)
+ .setRouterMac(LOCAL_MAC.toString());
+ SegmentRoutingDeviceConfig localLeaf1Config = new SegmentRoutingDeviceConfig();
+ JsonNode localLeaf1Tree = mapper.createObjectNode();
+ localLeaf1Config.init(LOCAL_LEAF1, "icmp-handler-test", localLeaf1Tree, mapper, delegate);
+ localLeaf1Config.setNodeSidIPv4(LOCAL_LEAF1_SID4)
+ .setRouterIpv4(LOCAL_LEAF1_LB4)
+ .setNodeSidIPv6(LOCAL_LEAF1_SID6)
+ .setRouterIpv6(LOCAL_LEAF1_LB6)
+ .setIsEdgeRouter(true)
+ .setRouterMac(LOCAL_MAC1.toString())
+ .setPairDeviceId(LOCAL_LEAF2)
+ .setPairLocalPort(P3);
+ SegmentRoutingDeviceConfig localLeaf2Config = new SegmentRoutingDeviceConfig();
+ JsonNode localLeaf2Tree = mapper.createObjectNode();
+ localLeaf2Config.init(LOCAL_LEAF2, "icmp-handler-test", localLeaf2Tree, mapper, delegate);
+ localLeaf2Config.setNodeSidIPv4(LOCAL_LEAF2_SID4)
+ .setRouterIpv4(LOCAL_LEAF2_LB4)
+ .setNodeSidIPv6(LOCAL_LEAF2_SID6)
+ .setRouterIpv6(LOCAL_LEAF2_LB6)
+ .setIsEdgeRouter(true)
+ .setRouterMac(LOCAL_MAC2.toString())
+ .setPairDeviceId(LOCAL_LEAF1)
+ .setPairLocalPort(P3);
+
+ // Setup configuration for ports
+ InterfaceConfig remoteLeafPorts1Config = new InterfaceConfig();
+ ArrayNode remoteLeafPorts1Tree = mapper.createArrayNode();
+ remoteLeafPorts1Config.init(CP12, "icmp-handler-test", remoteLeafPorts1Tree, mapper, delegate);
+ remoteLeafPorts1Config.addInterface(INTF1);
+ InterfaceConfig remoteLeafPorts2Config = new InterfaceConfig();
+ ArrayNode remoteLeafPorts2Tree = mapper.createArrayNode();
+ remoteLeafPorts2Config.init(CP13, "icmp-handler-test", remoteLeafPorts2Tree, mapper, delegate);
+ remoteLeafPorts2Config.addInterface(INTF2);
+ InterfaceConfig localLeafPortsConfig = new InterfaceConfig();
+ ArrayNode localLeafPortsTree = mapper.createArrayNode();
+ localLeafPortsConfig.init(CP1011, "icmp-handler-test", localLeafPortsTree, mapper, delegate);
+ localLeafPortsConfig.addInterface(INTF111);
+ InterfaceConfig localLeaf1PortsConfig = new InterfaceConfig();
+ ArrayNode localLeaf1PortsTree = mapper.createArrayNode();
+ localLeaf1PortsConfig.init(CP2011, "icmp-handler-test", localLeaf1PortsTree, mapper, delegate);
+ localLeaf1PortsConfig.addInterface(INTF211);
+ InterfaceConfig localLeaf2Ports1Config = new InterfaceConfig();
+ ArrayNode localLeaf2Ports1Tree = mapper.createArrayNode();
+ localLeaf2Ports1Config.init(CP2021, "icmp-handler-test", localLeaf2Ports1Tree, mapper, delegate);
+ localLeaf2Ports1Config.addInterface(INTF212);
+ InterfaceConfig localLeaf2Ports2Config = new InterfaceConfig();
+ ArrayNode localLeaf2Ports2Tree = mapper.createArrayNode();
+ localLeaf2Ports2Config.init(CP2024, "icmp-handler-test", localLeaf2Ports2Tree, mapper, delegate);
+ localLeaf2Ports2Config.addInterface(INTF213);
+
+ // Apply config
+ MockNetworkConfigRegistry mockNetworkConfigRegistry = new MockNetworkConfigRegistry();
+ mockNetworkConfigRegistry.applyConfig(remoteLeafConfig);
+ mockNetworkConfigRegistry.applyConfig(remoteLeafPorts1Config);
+ mockNetworkConfigRegistry.applyConfig(remoteLeafPorts2Config);
+ mockNetworkConfigRegistry.applyConfig(localLeafConfig);
+ mockNetworkConfigRegistry.applyConfig(localLeafPortsConfig);
+ mockNetworkConfigRegistry.applyConfig(localLeaf1Config);
+ mockNetworkConfigRegistry.applyConfig(localLeaf1PortsConfig);
+ mockNetworkConfigRegistry.applyConfig(localLeaf2Config);
+ mockNetworkConfigRegistry.applyConfig(localLeaf2Ports1Config);
+ mockNetworkConfigRegistry.applyConfig(localLeaf2Ports2Config);
+
+ segmentRoutingManager = new SegmentRoutingManager();
+ segmentRoutingManager.appId = testApplicationId;
+ packetService = new MockPacketService();
+ segmentRoutingManager.packetService = packetService;
+ segmentRoutingManager.cfgService = mockNetworkConfigRegistry;
+ segmentRoutingManager.neighbourResolutionService = new MockNeighbourResolutionService();
+ segmentRoutingManager.interfaceService = new MockInterfaceService(ImmutableSet.of(
+ INTF1, INTF2, INTF111, INTF211, INTF212, INTF213));
+ segmentRoutingManager.deviceConfiguration = new DeviceConfiguration(segmentRoutingManager);
+ segmentRoutingManager.ipHandler = new IpHandler(segmentRoutingManager);
+ segmentRoutingManager.deviceService = createMock(DeviceService.class);
+ segmentRoutingManager.routeService = new MockRouteService(ROUTE_STORE);
+ segmentRoutingManager.hostService = new MockHostService(Collections.emptySet());
+ icmpHandler = new IcmpHandler(segmentRoutingManager);
+ }
+
+ // Ping to our gateway
+ @Test
+ public void testPing4MyGateway() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmp(ETH_REQ_IPV4_MY, CP12);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_MY.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_MY.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_MY.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv4);
+ IPv4 ip = (IPv4) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV4.toInt()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV4_MY.toInt()));
+ assertTrue(ip.getPayload() instanceof ICMP);
+ ICMP icmp = (ICMP) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+ assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 to our gateway
+ @Test
+ public void testPing6MyGateway() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV6_MY, CP12);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_MY.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_MY.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_MY.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv6);
+ IPv6 ip = (IPv6) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV6.toOctets()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV6_MY.toOctets()));
+ assertTrue(ip.getPayload() instanceof ICMP6);
+ ICMP6 icmp = (ICMP6) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping to a gateway attached to our leaf
+ @Test
+ public void testPing4LocalGateway() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmp(ETH_REQ_IPV4_LOCAL, CP12);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_LOCAL.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_LOCAL.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_LOCAL.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv4);
+ IPv4 ip = (IPv4) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV4_LOCAL.toInt()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV4_MY.toInt()));
+ assertTrue(ip.getPayload() instanceof ICMP);
+ ICMP icmp = (ICMP) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+ assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 to a gateway attached to our leaf
+ @Test
+ public void testPing6LocalGateway() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV6_LOCAL, CP12);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LOCAL.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LOCAL.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LOCAL.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv6);
+ IPv6 ip = (IPv6) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV6_LOCAL.toOctets()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV6_MY.toOctets()));
+ assertTrue(ip.getPayload() instanceof ICMP6);
+ ICMP6 icmp = (ICMP6) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping to a gateway attached only to the pair leaf (routing through spine)
+ @Test
+ public void testPing4RemoteGatewaySamePair() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(true)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmp(ETH_REQ_IPV4_SAME, CP2025);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_SAME.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_SAME.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_SAME.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof MPLS);
+ MPLS mpls = (MPLS) ethernet.getPayload();
+ assertThat(mpls.getLabel(), is(LOCAL_LEAF1_SID4));
+ assertTrue(mpls.getPayload() instanceof IPv4);
+ IPv4 ip = (IPv4) mpls.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV4_SAME.toInt()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+ assertTrue(ip.getPayload() instanceof ICMP);
+ ICMP icmp = (ICMP) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+ assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 to a gateway attached only to the pair leaf (routing through spine)
+ @Test
+ public void testPing6RemoteGatewaySamePair() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(true)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV6_SAME, CP2025);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_SAME.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_SAME.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_SAME.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof MPLS);
+ MPLS mpls = (MPLS) ethernet.getPayload();
+ assertThat(mpls.getLabel(), is(LOCAL_LEAF1_SID6));
+ assertTrue(mpls.getPayload() instanceof IPv6);
+ IPv6 ip = (IPv6) mpls.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV6_SAME.toOctets()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+ assertTrue(ip.getPayload() instanceof ICMP6);
+ ICMP6 icmp = (ICMP6) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping to a gateway but destination leaf is down
+ @Test
+ public void testPing4RemoteGatewayLeafDown() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF))
+ .andReturn(false)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmp(ETH_REQ_IPV4, CP11);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4.getSourceMAC());
+ assertNull(ethernet);
+
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 to a gateway but destination leaf is down
+ @Test
+ public void testPing6RemoteGatewayLeafDown() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF))
+ .andReturn(false)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV6, CP11);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6.getSourceMAC());
+ assertNull(ethernet);
+
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping to a gateway but one of the destination leaf is down
+ @Test
+ public void testPing4RemoteGatewayLeaf1Down() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(false)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmp(ETH_REQ_IPV41, CP11);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV41.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV41.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV41.getSourceMAC()));
+ assertThat(ethernet.getEtherType(), is(Ethernet.MPLS_UNICAST));
+ assertTrue(ethernet.getPayload() instanceof MPLS);
+ MPLS mpls = (MPLS) ethernet.getPayload();
+ assertThat(mpls.getLabel(), is(LOCAL_LEAF2_SID4));
+ assertTrue(mpls.getPayload() instanceof IPv4);
+ IPv4 ip = (IPv4) mpls.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV4.toInt()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+ assertTrue(ip.getPayload() instanceof ICMP);
+ ICMP icmp = (ICMP) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+ assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 to a gateway but one of the destination leaf is down
+ @Test
+ public void testPing6RemoteGatewayLeaf2Down() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(true)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(false)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV61, CP11);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV61.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV61.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV61.getSourceMAC()));
+ assertThat(ethernet.getEtherType(), is(Ethernet.MPLS_UNICAST));
+ assertTrue(ethernet.getPayload() instanceof MPLS);
+ MPLS mpls = (MPLS) ethernet.getPayload();
+ assertThat(mpls.getLabel(), is(LOCAL_LEAF1_SID6));
+ assertTrue(mpls.getPayload() instanceof IPv6);
+ IPv6 ip = (IPv6) mpls.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV6.toOctets()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+ assertTrue(ip.getPayload() instanceof ICMP6);
+ ICMP6 icmp = (ICMP6) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 to a link local address
+ @Test
+ public void testPing6LinkLocalAddress() {
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV6_LL, CP12);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LL.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LL.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LL.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv6);
+ IPv6 ip = (IPv6) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV6_LL.toOctets()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV6_LL.toOctets()));
+ assertTrue(ip.getPayload() instanceof ICMP6);
+ ICMP6 icmp = (ICMP6) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+ }
+
+ // Ping to the looback of our leaf
+ @Test
+ public void testPing4Loopback() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmp(ETH_REQ_IPV4_LOOPBACK, CP12);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_LOOPBACK.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_LOOPBACK.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_LOOPBACK.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv4);
+ IPv4 ip = (IPv4) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV4_LOOPBACK.toInt()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV4_MY.toInt()));
+ assertTrue(ip.getPayload() instanceof ICMP);
+ ICMP icmp = (ICMP) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+ assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 to the looback of our leaf
+ @Test
+ public void testPing6Loopback() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(REMOTE_LEAF))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV6_LOOPBACK, CP12);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LOOPBACK.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LOOPBACK.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LOOPBACK.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv6);
+ IPv6 ip = (IPv6) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV6_LOOPBACK.toOctets()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV6_MY.toOctets()));
+ assertTrue(ip.getPayload() instanceof ICMP6);
+ ICMP6 icmp = (ICMP6) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping to the looback of our leaf (pair)
+ @Test
+ public void testPing4LoopbackPair() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(true)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmp(ETH_REQ_IPV4_LOOPBACK_PAIR, CP2011);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv4);
+ IPv4 ip = (IPv4) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV4_LOOPBACK_PAIR.toInt()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+ assertTrue(ip.getPayload() instanceof ICMP);
+ ICMP icmp = (ICMP) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+ assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 to the looback of our leaf (pair)
+ @Test
+ public void testPing6LoopbackPair() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(true)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV6_LOOPBACK_PAIR, CP2021);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv6);
+ IPv6 ip = (IPv6) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV6_LOOPBACK_PAIR.toOctets()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+ assertTrue(ip.getPayload() instanceof ICMP6);
+ ICMP6 icmp = (ICMP6) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping to the loopback of the leaf but hashing of the bond interfaces sends to wrong leaf
+ @Test
+ public void testPing4LoopbackPairDifferentLeaf() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(true)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmp(ETH_REQ_IPV4_LOOPBACK_PAIR, CP2021);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv4);
+ IPv4 ip = (IPv4) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV4_LOOPBACK_PAIR.toInt()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+ assertTrue(ip.getPayload() instanceof ICMP);
+ ICMP icmp = (ICMP) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+ assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 to the loopback of the leaf but hashing of the bond interfaces sends to wrong leaf
+ @Test
+ public void testPing6LoopbackPairDifferentLeaf() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(true)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV6_LOOPBACK_PAIR, CP2011);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv6);
+ IPv6 ip = (IPv6) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV6_LOOPBACK_PAIR.toOctets()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+ assertTrue(ip.getPayload() instanceof ICMP6);
+ ICMP6 icmp = (ICMP6) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping loopback of a destination that is down but
+ // hashing of the bond interfaces sends to other leaf
+ @Test
+ public void testPing4LoopbackPairDifferentLeafDown() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(false)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmp(ETH_REQ_IPV4_LOOPBACK_PAIR, CP2021);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_LOOPBACK_PAIR.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv4);
+ IPv4 ip = (IPv4) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV4_LOOPBACK_PAIR.toInt()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+ assertTrue(ip.getPayload() instanceof ICMP);
+ ICMP icmp = (ICMP) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+ assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 loopback of a destination that is down but
+ // hashing of the bond interfaces sends to other leaf
+ @Test
+ public void testPing6LoopbackPairDifferentLeafDown() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(true)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(false)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV6_LOOPBACK_PAIR, CP2011);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_LOOPBACK_PAIR.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv6);
+ IPv6 ip = (IPv6) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV6_LOOPBACK_PAIR.toOctets()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+ assertTrue(ip.getPayload() instanceof ICMP6);
+ ICMP6 icmp = (ICMP6) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping to a dh gateway
+ @Test
+ public void testPing4GatewayPair() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(true)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmp(ETH_REQ_IPV4_GATEWAY_PAIR, CP2011);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV4_GATEWAY_PAIR.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV4_GATEWAY_PAIR.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV4_GATEWAY_PAIR.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv4);
+ IPv4 ip = (IPv4) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV4_GATEWAY_PAIR.toInt()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV41.toInt()));
+ assertTrue(ip.getPayload() instanceof ICMP);
+ ICMP icmp = (ICMP) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REPLY));
+ assertThat(icmp.getIcmpCode(), is(CODE_ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+ // Ping6 to a dh gateway
+ @Test
+ public void testPing6GatewayPair() {
+ // Expected behavior
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF1))
+ .andReturn(true)
+ .times(1);
+ expect(segmentRoutingManager.deviceService.isAvailable(LOCAL_LEAF2))
+ .andReturn(true)
+ .times(1);
+ replay(segmentRoutingManager.deviceService);
+
+ // Process
+ icmpHandler.processIcmpv6(ETH_REQ_IPV6_GATEWAY_PAIR, CP2021);
+
+ // Verify packet-out
+ Ethernet ethernet = packetService.getEthernetPacket(ETH_REQ_IPV6_GATEWAY_PAIR.getSourceMAC());
+ assertNotNull(ethernet);
+ assertThat(ethernet.getSourceMAC(), is(ETH_REQ_IPV6_GATEWAY_PAIR.getDestinationMAC()));
+ assertThat(ethernet.getDestinationMAC(), is(ETH_REQ_IPV6_GATEWAY_PAIR.getSourceMAC()));
+ assertTrue(ethernet.getPayload() instanceof IPv6);
+ IPv6 ip = (IPv6) ethernet.getPayload();
+ assertThat(ip.getSourceAddress(), is(DST_IPV6_GATEWAY_PAIR.toOctets()));
+ assertThat(ip.getDestinationAddress(), is(SRC_IPV61.toOctets()));
+ assertTrue(ip.getPayload() instanceof ICMP6);
+ ICMP6 icmp = (ICMP6) ip.getPayload();
+ assertThat(icmp.getIcmpType(), is(ECHO_REPLY));
+ // Verify behavior
+ verify(segmentRoutingManager.deviceService);
+ }
+
+}