We have run into some trouble with third-party devices whose traceroute implementation sends UDP packets with empty checksums. Since the checksum is optional for UDP inside an IPv4 packet, this is perfectly legal, even if slightly strange. However, we found that such a packet ends up getting silently ignored by our switch instead of eliciting the expected ICMP response. The reason is that we handle UDP traceroute packets are with the iptables rule -A INPUT -p udp -m udp --dport 33434:33636 -j REJECT --reject-with icmp-port-unreachable Such packets therefore get an iptables reject normally eliciting the desired ICMP_DEST_UNREACH response from nf_send_unreach(). However, it seems that before sending the ICMP response, this function determines whether it needs to verify the checksum on the incoming packet by checking if skb->ip_summed == CHECKSUM_UNNECESSARY or skb->csum_valid. If this is not the case, then it proceeds to verify the checksum. However, no provision is made here for an empty checksum, which of course will fail to verify. In this case, netfilter declines to send the ICMP response on the assumption that the packet is garbage and the source address cannot be trusted. As our front panel ports do not perform layer 4 hardware checksum verification before sending packets to the kernel, the struct skb passed to netif_recieve_skb by the driver are unconditionally marked CHECKSUM_NONE. The udp_error function makes accommodation for UDP packets with empty checksum by declining to run nf_checksum on them and instead indicating the packet acceptable. Since nf_checksum already alters the skb->ip_summed member by marking it as CHECKSUM_COMPLETE when there is a checksum to verify, it seems reasonable that udp_error similarly mark it as CHECKSUM_UNNECESSARY when it determines there is no checksum. This is supported by the note in skbuff.h that explicitly suggests such a value for packets with empty checksum. It seems that this issue was almost fixed by 7fc38225363d ("netfilter: reject: skip csum verification for protocols that don't support it"), which addressed protocols other than UDP. I considered adding a IPPROTO_UDP branch to the nf_reject_verify_csum switch statement, however it would necessarily be more complex than all of the existing cases since it would require extracting the UDP header and checking the checksum value. I'm open to doing that as well if requested, but it doesn't appear to be necessary from what I can tell with the simpler one-liner I have proposed here. Finally, I have made no attempt to distinguish between IPv4 and IPv6 in spite of the fact that empty checksums are not strictly allowed for UDP inside IPv6. However, this decision to be more permissive appears to have already been made since udp_error already declared such packets error free. The aforementioned skbuff.h comment also explicitly mentions setting empty checksum UDP in IPv6 as CHECKSUM_UNNECESSARY.