use of org.onlab.packet.ICMP in project trellis-control by opennetworkinglab.
the class IcmpHandlerTest method testPing4RemoteGatewayLeaf1Down.
// 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);
}
use of org.onlab.packet.ICMP in project trellis-control by opennetworkinglab.
the class IcmpHandler method sendIcmpv6Response.
/**
* Sends an ICMPv6 reply message.
*
* @param ethRequest the original ICMP request
* @param outport the output port where the ICMP reply should be sent to
*/
private void sendIcmpv6Response(Ethernet ethRequest, ConnectPoint outport) {
int destSid = -1;
Ethernet ethReply = ICMP6.buildIcmp6Reply(ethRequest);
IPv6 icmpRequestIpv6 = (IPv6) ethRequest.getPayload();
IPv6 icmpReplyIpv6 = (IPv6) ethRequest.getPayload();
// Source IP of the echo "reply"
Ip6Address srcIpAddress = Ip6Address.valueOf(icmpRequestIpv6.getDestinationAddress());
// Destination IP of the echo "reply"
Ip6Address destIpAddress = Ip6Address.valueOf(icmpRequestIpv6.getSourceAddress());
Optional<Ip6Address> linkLocalIp = getLinkLocalIp(outport);
// Fast path if the echo request targets the link-local address of switch interface
if (linkLocalIp.isPresent() && srcIpAddress.equals(linkLocalIp.get())) {
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);
// Lookup the route store for the nexthop instead.
if (destRouterAddress == null) {
Optional<DeviceId> deviceId = srManager.routeService.longestPrefixLookup(destIpAddress).map(srManager::nextHopLocations).flatMap(locations -> locations.stream().findFirst()).map(ConnectPoint::deviceId);
if (deviceId.isPresent()) {
try {
destRouterAddress = config.getRouterIpv6(deviceId.get());
} catch (DeviceConfigNotFoundException e) {
log.warn("Device config for {} not found. Abort ICMPv6 processing", deviceId);
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, destSid, destIpAddress, icmpReplyIpv6.getHopLimit());
}
use of org.onlab.packet.ICMP in project trellis-control by opennetworkinglab.
the class IcmpHandler method sendIcmpResponse.
/**
* Sends an ICMP reply message.
*
* @param icmpRequest the original ICMP request
* @param outport the output port where the ICMP reply should be sent to
*/
private void sendIcmpResponse(Ethernet icmpRequest, ConnectPoint outport) {
Ethernet icmpReplyEth = ICMP.buildIcmpReply(icmpRequest);
IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload();
IPv4 icmpReplyIpv4 = (IPv4) icmpReplyEth.getPayload();
Ip4Address destIpAddress = Ip4Address.valueOf(icmpRequestIpv4.getSourceAddress());
// Get the available connect points
Set<ConnectPoint> destConnectPoints = config.getConnectPointsForASubnetHost(destIpAddress);
// Select a router
Ip4Address destRouterAddress = selectRouterIp4Address(destIpAddress, outport, destConnectPoints);
// Lookup the route store for the nexthop instead.
if (destRouterAddress == null) {
Optional<DeviceId> deviceId = srManager.routeService.longestPrefixLookup(destIpAddress).map(srManager::nextHopLocations).flatMap(locations -> locations.stream().findFirst()).map(ConnectPoint::deviceId);
if (deviceId.isPresent()) {
try {
destRouterAddress = config.getRouterIpv4(deviceId.get());
} catch (DeviceConfigNotFoundException e) {
log.warn("Device config for {} not found. Abort ICMP processing", deviceId);
return;
}
}
}
int destSid = config.getIPv4SegmentId(destRouterAddress);
if (destSid < 0) {
log.warn("Failed to lookup SID of the switch that {} attaches to. " + "Unable to process ICMP request.", destIpAddress);
return;
}
sendPacketOut(outport, icmpReplyEth, destSid, destIpAddress, icmpReplyIpv4.getTtl());
}
Aggregations