From: Alexander Bluhm Subject: UDP tunnel clear checksum out flag To: tech@openbsd.org Date: Sun, 3 Nov 2024 12:20:51 +0100 Hi, Some network interfaces, like lo(4) or vio(4), set the M_UDP_CSUM_OUT flag on incoming packets. For optimization they produce packets with M_UDP_CSUM_IN_OK, but the actual checksum field in the packet is wrong. If such a packet is forwared, the checksum must be calculated. So they also set M_UDP_CSUM_OUT. For protocols tunneled in UDP, udp_input() removes the header, but the mbuf flag stayed. This means later processing of the packet may insert an UDP checksum, althoug it is not UDP anymore. I have seen this when forwarding ping packets between two vxlan(4) interfaces. Then an UDP checksum was inserted into the ICMP packet. This packet was later dropped due to wrong checksum. Fix is easy. Clear the M_UDP_CSUM_OUT flag when the UDP header is stripped. ok? bluhm Index: netinet/udp_usrreq.c =================================================================== RCS file: /data/mirror/openbsd/cvs/src/sys/netinet/udp_usrreq.c,v diff -u -p -r1.324 udp_usrreq.c --- netinet/udp_usrreq.c 6 Aug 2024 20:15:53 -0000 1.324 +++ netinet/udp_usrreq.c 3 Nov 2024 11:08:10 -0000 @@ -298,6 +298,7 @@ udp_input(struct mbuf **mp, int *offp, i } } } + CLR(m->m_pkthdr.csum_flags, M_UDP_CSUM_OUT); #ifdef IPSEC if (udpencap_enable && udpencap_port && esp_enable &&