Bugfix: ping6 to interface IP of remote leaf doesn't work
Instead of early return, simply ignore link-local IP matching if interface MAC is not configured (e.g. spine port)
Piggybacked in this commit:
- Refactor the ICMPv6 handler
Change-Id: I44e4daac067262b63e6726b4b4d7e3426e0f7fdb
diff --git a/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
index 4eec890..8228bb5 100644
--- a/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
+++ b/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
@@ -203,27 +203,31 @@
public void processIcmpv6(Ethernet eth, ConnectPoint inPort) {
DeviceId deviceId = inPort.deviceId();
IPv6 ipv6Packet = (IPv6) eth.getPayload();
+ ICMP6 icmp6 = (ICMP6) ipv6Packet.getPayload();
Ip6Address destinationAddress = Ip6Address.valueOf(ipv6Packet.getDestinationAddress());
Set<IpAddress> gatewayIpAddresses = config.getPortIPs(deviceId);
- MacAddress interfaceMac;
IpAddress routerIp;
+ // Only proceed with echo request
+ if (icmp6.getIcmpType() != ICMP6.ECHO_REQUEST) {
+ return;
+ }
+
try {
routerIp = config.getRouterIpv6(deviceId);
- Optional<MacAddress> macAddress = srManager.interfaceService.getInterfacesByPort(inPort).stream()
- .map(Interface::mac)
- .findFirst();
- if (!macAddress.isPresent()) {
- log.warn("Failed in fetching MAC address of {}. Aborting ICMP6 processing.", inPort);
- return;
- }
- interfaceMac = MacAddress.valueOf(macAddress.get().toBytes());
- // Ensure ICMP to the router IP, gateway IP or link-local EUI-64
- ICMP6 icmp6 = (ICMP6) ipv6Packet.getPayload();
- if (icmp6.getIcmpType() == ICMP6.ECHO_REQUEST && (destinationAddress.equals(routerIp.getIp6Address()) ||
- destinationAddress.equals(Ip6Address.valueOf(IPv6.getLinkLocalAddress(interfaceMac.toBytes()))) ||
- gatewayIpAddresses.contains(destinationAddress))) {
+ Optional<Ip6Address> linkLocalIp = srManager.interfaceService.getInterfacesByPort(inPort)
+ .stream()
+ .map(Interface::mac)
+ .map(MacAddress::toBytes)
+ .map(IPv6::getLinkLocalAddress)
+ .map(Ip6Address::valueOf)
+ .findFirst();
+
+ // 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);
@@ -330,17 +334,16 @@
// Process NDP targets towards EUI-64 address.
try {
DeviceId deviceId = pkt.inPort().deviceId();
- Optional<MacAddress> macAddress = srManager.interfaceService.getInterfacesByPort(pkt.inPort())
+
+ Optional<Ip6Address> linkLocalIp = srManager.interfaceService.getInterfacesByPort(pkt.inPort())
.stream()
.map(Interface::mac)
+ .map(MacAddress::toBytes)
+ .map(IPv6::getLinkLocalAddress)
+ .map(Ip6Address::valueOf)
.findFirst();
- if (!macAddress.isPresent()) {
- log.warn("Failed in fetching MAC address of {}. Aborting NDP processing.", pkt.inPort());
- return;
- }
- MacAddress interfaceMac = MacAddress.valueOf(macAddress.get().toBytes());
- Ip6Address interfaceLinkLocalIP = Ip6Address.valueOf(IPv6.getLinkLocalAddress(interfaceMac.toBytes()));
- if (pkt.target().equals(interfaceLinkLocalIP)) {
+
+ if (linkLocalIp.isPresent() && pkt.target().equals(linkLocalIp.get())) {
MacAddress routerMac = config.getDeviceMac(deviceId);
sendResponse(pkt, routerMac, hostService);
}