kern/145737: Wrong UDP checksum not ignored as expected in UDP encapsuladed ESP packet

Peter Molnar peter at molnar.cc
Thu Apr 15 23:50:02 UTC 2010


>Number:         145737
>Category:       kern
>Synopsis:       Wrong UDP checksum not ignored as expected in UDP encapsuladed ESP packet
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Apr 15 23:50:01 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Peter Molnar
>Release:        RELENG_7_0_0_RELEASE
>Organization:
>Environment:
>Description:
Test setup:

A FreeBSD machine acts as VPN client (ESP-Transport, L2TP, NAT-T) to an OpenSWAN based VPN concentrator.

Problem description:

The L2TP (UDP) packets originating from the concentrator are rejected because of a wrong UDP checksum.

Detailed problem description:

[RFC 3948, 3.1.2] states: 

   When a transport mode has been used to transmit packets, contained
   TCP or UDP headers will have incorrect checksums due to the change of
   parts of the IP header during transit.  This procedure defines how to
   fix these checksums [...]

   Depending on local policy, one of the following MUST be done:

   [...]

   3.  If the protocol header after the ESP header is a UDP header, set
       the checksum field to zero in the UDP header. [...]
>How-To-Repeat:

>Fix:


Patch attached with submission follows:

diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index cbb13b6..bbe80f6 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -372,6 +372,25 @@ udp_input(struct mbuf *m, int off)
 	else
 		memset(&save_ip, 0, sizeof(save_ip));
 
+#ifdef IPSEC_NAT_T
+	/* 
+	 * RFC 3948
+	 * 
+	 * 3.1.2. Transport Mode Decapsulation NAT Procedure
+	 * 
+	 * Depending on local policy, one of the following MUST be done:
+	 * 
+	 * [...]
+	 * 
+	 * 3.  If the protocol header after the ESP header is a UDP header, set
+	 *     the checksum field to zero in the UDP header. [...]
+	 */
+	
+	if (m_tag_find(m, PACKET_TAG_IPSEC_NAT_T_PORTS, NULL) != NULL) {
+		uh->uh_sum = 0;
+	}
+#endif
+
 	/*
 	 * Checksum extended UDP header and data.
 	 */


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list