Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 6 Jun 2018 13:01:53 +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: r334709 - head/sys/netinet
Message-ID:  <201806061301.w56D1rex093625@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ae
Date: Wed Jun  6 13:01:53 2018
New Revision: 334709
URL: https://svnweb.freebsd.org/changeset/base/334709

Log:
  Make in_delayed_cksum() be similar to IPv6 implementation.
  
  Use m_copyback() function to write checksum when it isn't located
  in the first mbuf of the chain. Handmade analog doesn't handle the
  case when parts of checksum are located in different mbufs.
  Also in case when mbuf is too short, m_copyback() will allocate new
  mbuf in the chain instead of making out of bounds write.
  
  Also wrap long line and remove now useless KASSERTs.
  
  X-MFC after:	r334705

Modified:
  head/sys/netinet/ip_output.c

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c	Wed Jun  6 12:57:11 2018	(r334708)
+++ head/sys/netinet/ip_output.c	Wed Jun  6 13:01:53 2018	(r334709)
@@ -933,10 +933,10 @@ in_delayed_cksum(struct mbuf *m)
 	if (m->m_pkthdr.csum_flags & CSUM_UDP) {
 		/* if udp header is not in the first mbuf copy udplen */
 		if (offset + sizeof(struct udphdr) > m->m_len)
-			m_copydata(m, offset + offsetof(struct udphdr, uh_ulen),
-				2, (caddr_t)&cklen);
+			m_copydata(m, offset + offsetof(struct udphdr,
+			    uh_ulen), sizeof(cklen), (caddr_t)&cklen);
 		else {
-			uh = (struct udphdr *)((caddr_t)ip + offset);
+			uh = (struct udphdr *)mtodo(m, offset);
 			cklen = ntohs(uh->uh_ulen);
 		}
 		csum = in_cksum_skip(m, cklen + offset, offset);
@@ -948,14 +948,10 @@ in_delayed_cksum(struct mbuf *m)
 	}
 	offset += m->m_pkthdr.csum_data;	/* checksum offset */
 
-	/* find the mbuf in the chain where the checksum starts*/
-	while ((m != NULL) && (offset >= m->m_len)) {
-		offset -= m->m_len;
-		m = m->m_next;
-	}
-	KASSERT(m != NULL, ("in_delayed_cksum: checksum outside mbuf chain."));
-	KASSERT(offset + sizeof(u_short) <= m->m_len, ("in_delayed_cksum: checksum split between mbufs."));
-	*(u_short *)(m->m_data + offset) = csum;
+	if (offset + sizeof(csum) > m->m_len)
+		m_copyback(m, offset, sizeof(csum), (caddr_t)&csum);
+	else
+		*(u_short *)mtodo(m, offset) = csum;
 }
 
 /*



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