Refactoring ICMP handler in Segment Routing
- No longer handle ICMPv6 packets except those target routerIP and gatewayIP
- Remove source IP validation for ICMPv6 since IPv6 hosts often speak with their link local address
Change-Id: If92826c080a4643bad71b0d39fc89b7123dc11d5
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
index a42a806..38293d0 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/IcmpHandler.java
@@ -23,7 +23,6 @@
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
import org.onlab.packet.MPLS;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
@@ -117,10 +116,8 @@
/**
* Process incoming ICMP packet.
- * If it is an ICMP request to router or known host, then sends an ICMP response.
- * If it is an ICMP packet to known host and forward the packet to the host.
- * If it is an ICMP packet to unknown host in a subnet, then sends an ARP request
- * to the subnet.
+ * If it is an ICMP request to router, then sends an ICMP response.
+ * Otherwise ignore the packet.
*
* @param eth inbound ICMP packet
* @param inPort the input port
@@ -142,24 +139,11 @@
(destinationAddress.equals(routerIp.getIp4Address()) ||
gatewayIpAddresses.contains(destinationAddress))) {
sendIcmpResponse(eth, inPort);
- // We remove the packet from the queue
- srManager.ipHandler.dequeuePacket(ipv4Packet, destinationAddress);
-
- // ICMP for any known host
- } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
- // TODO: known host packet should not be coming to controller - resend flows?
- srManager.ipHandler.forwardPackets(deviceId, destinationAddress);
-
- // ICMP for an unknown host in the subnet of the router
- } else if (config.inSameSubnet(deviceId, destinationAddress)) {
- srManager.arpHandler.sendArpRequest(deviceId, destinationAddress, inPort);
-
- // ICMP for an unknown host
} else {
- log.debug("ICMP request for unknown host {} ", destinationAddress);
- // We remove the packet from the queue
- srManager.ipHandler.dequeuePacket(ipv4Packet, destinationAddress);
+ log.trace("Ignore ICMP that targets for {}", destinationAddress);
}
+ // We remove the packet from the queue
+ srManager.ipHandler.dequeuePacket(ipv4Packet, destinationAddress);
}
/**
@@ -192,10 +176,8 @@
/**
* Process incoming ICMPv6 packet.
- * If it is an ICMP request to router or known host, then sends an ICMP response.
- * If it is an ICMP packet to known host and forward the packet to the host.
- * If it is an ICMP packet to unknown host in a subnet, then sends an ARP request
- * to the subnet.
+ * If it is an ICMPv6 request to router, then sends an ICMPv6 response.
+ * Otherwise ignore the packet.
*
* @param eth the incoming ICMPv6 packet
* @param inPort the input port
@@ -218,20 +200,8 @@
(destinationAddress.equals(routerIp.getIp6Address()) ||
gatewayIpAddresses.contains(destinationAddress))) {
sendIcmpv6Response(eth, inPort);
- // We remove the packet from the queue
- srManager.ipHandler.dequeuePacket(ipv6Packet, destinationAddress);
- // ICMP for any known host
- } else if (!srManager.hostService.getHostsByIp(destinationAddress).isEmpty()) {
- // TODO: known host packet should not be coming to controller - resend flows?
- srManager.ipHandler.forwardPackets(deviceId, destinationAddress);
- // ICMP for an unknown host in the subnet of the router
- } else if (config.inSameSubnet(deviceId, destinationAddress)) {
- sendNdpRequest(deviceId, destinationAddress, inPort);
- // ICMP for an unknown host or not configured host
} else {
- log.debug("ICMPv6 request for unknown host or not configured host {} ", destinationAddress);
- // We remove the packet from the queue
- srManager.ipHandler.dequeuePacket(ipv6Packet, destinationAddress);
+ log.trace("Ignore ICMPv6 that targets for {}", destinationAddress);
}
}
@@ -276,9 +246,7 @@
* @param hostService the host service
*/
public void processPacketIn(NeighbourMessageContext pkt, HostService hostService) {
- /*
- * First we validate the ndp packet
- */
+ // First we validate the ndp packet
SegmentRoutingAppConfig appConfig = srManager.cfgService
.getConfig(srManager.appId, SegmentRoutingAppConfig.class);
if (appConfig != null && appConfig.suppressSubnet().contains(pkt.inPort())) {
@@ -286,12 +254,6 @@
pkt.drop();
return;
}
- if (!validateSrcIp(pkt)) {
- log.debug("Ignore NDP packet discovered on {} with unexpected src ip address {}.",
- pkt.inPort(), pkt.sender());
- pkt.drop();
- return;
- }
if (pkt.type() == NeighbourMessageType.REQUEST) {
handleNdpRequest(pkt, hostService);
@@ -302,23 +264,6 @@
}
/**
- * Utility function to verify if the src ip belongs to the same
- * subnet configured on the port it is seen.
- *
- * @param pkt the ndp packet and context information
- * @return true if the src ip is a valid address for the subnet configured
- * for the connect point
- */
- private boolean validateSrcIp(NeighbourMessageContext pkt) {
- ConnectPoint connectPoint = pkt.inPort();
- IpPrefix subnet = config.getPortIPv6Subnet(
- connectPoint.deviceId(),
- connectPoint.port()
- );
- return subnet != null && subnet.contains(pkt.sender());
- }
-
- /**
* Helper method to handle the ndp requests.
*
* @param pkt the ndp packet request and context information
@@ -422,22 +367,15 @@
public void sendNdpRequest(DeviceId deviceId, IpAddress targetAddress, ConnectPoint inPort) {
byte[] senderMacAddress = new byte[MacAddress.MAC_ADDRESS_LENGTH];
byte[] senderIpAddress = new byte[Ip6Address.BYTE_LENGTH];
- /*
- * Retrieves device info.
- */
+ // Retrieves device info.
if (!getSenderInfo(senderMacAddress, senderIpAddress, deviceId, targetAddress)) {
log.warn("Aborting sendNdpRequest, we cannot get all the information needed");
return;
}
- /*
- * We have to compute the dst mac address and dst
- * ip address.
- */
+ // We have to compute the dst mac address and dst ip address.
byte[] dstIp = IPv6.getSolicitNodeAddress(targetAddress.toOctets());
byte[] dstMac = IPv6.getMCastMacAddress(dstIp);
- /*
- * Creates the request.
- */
+ // Creates the request.
Ethernet ndpRequest = NeighborSolicitation.buildNdpSolicit(
targetAddress.toOctets(),
senderIpAddress,