Index | Thread | Search

From:
Alexander Bluhm <bluhm@openbsd.org>
Subject:
UDP tunnel clear checksum out flag
To:
tech@openbsd.org
Date:
Sun, 3 Nov 2024 12:20:51 +0100

Download raw body.

Thread
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 &&