git: 422456ae27f5 - stable/13 - sctp: Use m_apply() to calcuate a checksum for an mbuf chain

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Tue, 30 Nov 2021 01:35:38 UTC
The branch stable/13 has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=422456ae27f5f79dee3969de9190fbe9b9301c3c

commit 422456ae27f5f79dee3969de9190fbe9b9301c3c
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2021-11-16 18:36:30 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2021-11-30 01:35:08 +0000

    sctp: Use m_apply() to calcuate a checksum for an mbuf chain
    
    m_apply() works on unmapped mbufs, so this will let us elide
    mb_unmapped_to_ext() calls preceding sctp_calculate_cksum() calls in
    the network stack.
    
    Modify sctp_calculate_cksum() to assume it's passed an mbuf header.
    This assumption appears to be true in practice, and we need to know the
    full length of the chain.
    
    No functional change intended.
    
    Reviewed by:    tuexen, jhb
    Sponsored by:   The FreeBSD Foundation
    
    (cherry picked from commit b4d758a0cc54d991d2bdf7f697ec0b6b3fd6230d)
---
 sys/netinet/sctp_crc32.c | 45 +++++++++++++++++++++------------------------
 1 file changed, 21 insertions(+), 24 deletions(-)

diff --git a/sys/netinet/sctp_crc32.c b/sys/netinet/sctp_crc32.c
index a36d36dc4861..97b881bb5062 100644
--- a/sys/netinet/sctp_crc32.c
+++ b/sys/netinet/sctp_crc32.c
@@ -80,6 +80,16 @@ sctp_finalize_crc32c(uint32_t crc32c)
 	return (crc32c);
 }
 
+static int
+sctp_calculate_cksum_cb(void *arg, void *data, u_int len)
+{
+	uint32_t *basep;
+
+	basep = arg;
+	*basep = calculate_crc32c(*basep, data, len);
+	return (0);
+}
+
 /*
  * Compute the SCTP checksum in network byte order for a given mbuf chain m
  * which contains an SCTP packet starting at offset.
@@ -89,30 +99,17 @@ sctp_finalize_crc32c(uint32_t crc32c)
 uint32_t
 sctp_calculate_cksum(struct mbuf *m, uint32_t offset)
 {
-	uint32_t base = 0xffffffff;
-
-	while (offset > 0) {
-		KASSERT(m != NULL, ("sctp_calculate_cksum, offset > length of mbuf chain"));
-		if (offset < (uint32_t)m->m_len) {
-			break;
-		}
-		offset -= m->m_len;
-		m = m->m_next;
-	}
-	if (offset > 0) {
-		base = calculate_crc32c(base,
-		    (unsigned char *)(m->m_data + offset),
-		    (unsigned int)(m->m_len - offset));
-		m = m->m_next;
-	}
-	while (m != NULL) {
-		base = calculate_crc32c(base,
-		    (unsigned char *)m->m_data,
-		    (unsigned int)m->m_len);
-		m = m->m_next;
-	}
-	base = sctp_finalize_crc32c(base);
-	return (base);
+	uint32_t base;
+	int len;
+
+	M_ASSERTPKTHDR(m);
+	KASSERT(offset < m->m_pkthdr.len,
+	    ("%s: invalid offset %u into mbuf %p", __func__, offset, m));
+
+	base = 0xffffffff;
+	len = m->m_pkthdr.len - offset;
+	(void)m_apply(m, offset, len, sctp_calculate_cksum_cb, &base);
+	return (sctp_finalize_crc32c(base));
 }
 
 #if defined(SCTP) || defined(SCTP_SUPPORT)