use of org.onlab.packet.IPv6 in project trellis-control by opennetworkinglab.
the class IcmpHandlerTest method testPing6LocalGateway.
// 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);
}
use of org.onlab.packet.IPv6 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.IPv6 in project trellis-control by opennetworkinglab.
the class IcmpHandler method isNdpForGateway.
/**
* Utility to verify if the ND are for the gateway.
*
* @param pkt the ndp packet
* @return true if the ndp is for the gateway. False otherwise
*/
private boolean isNdpForGateway(NeighbourMessageContext pkt) {
DeviceId deviceId = pkt.inPort().deviceId();
Set<IpAddress> gatewayIpAddresses = null;
try {
if (pkt.target().equals(config.getRouterIpv6(deviceId))) {
return true;
}
gatewayIpAddresses = config.getPortIPs(deviceId);
} catch (DeviceConfigNotFoundException e) {
log.warn(e.getMessage() + " Aborting check for router IP in processing ndp");
return false;
}
return gatewayIpAddresses != null && gatewayIpAddresses.stream().filter(IpAddress::isIp6).anyMatch(gatewayIp -> gatewayIp.equals(pkt.target()) || Arrays.equals(IPv6.getSolicitNodeAddress(gatewayIp.toOctets()), pkt.target().toOctets()));
}
use of org.onlab.packet.IPv6 in project trellis-control by opennetworkinglab.
the class IpHandler method forwardPackets.
/**
* Forwards IP packets in the buffer to the destination IP address.
* It is called when the controller finds the destination MAC address
* via NDP replies.
*
* @param deviceId the target device
* @param destIpAddress the destination ip address
*/
public void forwardPackets(DeviceId deviceId, Ip6Address destIpAddress) {
if (ipPacketQueue.get(destIpAddress) == null) {
return;
}
for (IP ipPacket : ipPacketQueue.get(destIpAddress)) {
if (ipPacket.getVersion() == ((byte) 6)) {
IPv6 ipv6Packet = (IPv6) ipPacket;
Ip6Address destAddress = Ip6Address.valueOf(ipv6Packet.getDestinationAddress());
if (config.inSameSubnet(deviceId, destAddress)) {
ipv6Packet.setHopLimit((byte) (ipv6Packet.getHopLimit() - 1));
for (Host dest : srManager.hostService.getHostsByIp(destIpAddress)) {
Ethernet eth = new Ethernet();
eth.setDestinationMACAddress(dest.mac());
try {
eth.setSourceMACAddress(config.getDeviceMac(deviceId));
} catch (DeviceConfigNotFoundException e) {
log.warn(e.getMessage() + " Skipping forwardPackets for this destination.");
continue;
}
eth.setEtherType(Ethernet.TYPE_IPV6);
eth.setPayload(ipv6Packet);
forwardToHost(deviceId, eth, dest);
ipPacketQueue.get(destIpAddress).remove(ipPacket);
}
ipPacketQueue.get(destIpAddress).remove(ipPacket);
}
}
ipPacketQueue.get(destIpAddress).remove(ipPacket);
}
}
Aggregations