Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 13 Apr 2017 17:03:57 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r316770 - in head/sys: netinet netinet6
Message-ID:  <201704131703.v3DH3v4P037561@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Thu Apr 13 17:03:57 2017
New Revision: 316770
URL: https://svnweb.freebsd.org/changeset/base/316770

Log:
  Clear h/w csum flags on mbuf handled by UDP.
  
  When checksums of received IP and UDP header already checked, UDP uses
  sbappendaddr_locked() to pass received data to the socket.
  sbappendaddr_locked() uses given mbuf as is, and if NIC supports checksum
  offloading, mbuf contains csum_data and csum_flags that were calculated
  for already stripped headers. Some NICs support only limited checksums
  offloading and do not use CSUM_PSEUDO_HDR flag, and csum_data contains
  some value that UDP/TCP should use for pseudo header checksum calculation.
  
  When L2TP is used for tunneling with mpd5, ng_ksocket receives mbuf with
  filled csum_flags and csum_data, that were calculated for outer headers.
  When L2TP header is stripped, a packet that was tunneled goes to the IP
  layer and due to presence of csum_flags (without CSUM_PSEUDO_HDR) and
  csum_data, the UDP/TCP checksum check fails for this packet.
  
  Reported by:	Irina Liakh <spell at itl ua>
  Tested by:	Irina Liakh <spell at itl ua>
  MFC after:	1 week

Modified:
  head/sys/netinet/udp_usrreq.c
  head/sys/netinet6/udp6_usrreq.c

Modified: head/sys/netinet/udp_usrreq.c
==============================================================================
--- head/sys/netinet/udp_usrreq.c	Thu Apr 13 16:57:02 2017	(r316769)
+++ head/sys/netinet/udp_usrreq.c	Thu Apr 13 17:03:57 2017	(r316770)
@@ -372,6 +372,9 @@ udp_append(struct inpcb *inp, struct ip 
 		append_sa = (struct sockaddr *)&udp_in[0];
 	m_adj(n, off);
 
+	/* Clear any h/w csum flags as they are no longer valid. */
+	n->m_pkthdr.csum_flags &= ~(CSUM_DATA_VALID | CSUM_IP_VALID);
+
 	so = inp->inp_socket;
 	SOCKBUF_LOCK(&so->so_rcv);
 	if (sbappendaddr_locked(&so->so_rcv, append_sa, n, opts) == 0) {

Modified: head/sys/netinet6/udp6_usrreq.c
==============================================================================
--- head/sys/netinet6/udp6_usrreq.c	Thu Apr 13 16:57:02 2017	(r316769)
+++ head/sys/netinet6/udp6_usrreq.c	Thu Apr 13 17:03:57 2017	(r316770)
@@ -187,6 +187,9 @@ udp6_append(struct inpcb *inp, struct mb
 	}
 	m_adj(n, off + sizeof(struct udphdr));
 
+	/* Clear any h/w csum flags as they are no longer valid. */
+	n->m_pkthdr.csum_flags &= ~CSUM_DATA_VALID;
+
 	so = inp->inp_socket;
 	SOCKBUF_LOCK(&so->so_rcv);
 	if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)&fromsa[0], n,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201704131703.v3DH3v4P037561>