git: dfd5240189ca - stable/13 - netinet: Implement in_cksum_skip() using m_apply()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 01 Dec 2021 12:48:37 UTC
The branch stable/13 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=dfd5240189ca024b268e53df2f0a3076df57b240 commit dfd5240189ca024b268e53df2f0a3076df57b240 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2021-11-24 18:19:54 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2021-12-01 12:43:03 +0000 netinet: Implement in_cksum_skip() using m_apply() This allows it to work with unmapped mbufs. In particular, in_cksum_skip() calls no longer need to be preceded by calls to mb_unmapped_to_ext() to avoid a page fault. PR: 259645 Reviewed by: gallatin, glebius, jhb Sponsored by: The FreeBSD Foundation (cherry picked from commit 0d9c3423f59bb305301f5a5bc7c8f5daf7b7aa52) --- sys/netinet/in_cksum.c | 63 +++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/sys/netinet/in_cksum.c b/sys/netinet/in_cksum.c index 581950c8afa4..98317d4dac4a 100644 --- a/sys/netinet/in_cksum.c +++ b/sys/netinet/in_cksum.c @@ -49,7 +49,9 @@ __FBSDID("$FreeBSD$"); #include <machine/in_cksum.h> /* - * These implementations may be overridden on a per-platform basis. + * These implementations may be overridden on a per-platform basis. On + * platforms with a direct map, the implementation of in_cksum() must handle + * unmapped mbufs. */ #ifndef HAVE_MD_IN_CKSUM @@ -203,44 +205,43 @@ in_pseudo(u_int32_t a, u_int32_t b, u_int32_t c) return (sum); } +struct cksum_skip_partial_args { + uint64_t csum; + int clen; +}; + +static int +in_cksum_skip_partial(void *arg, void *data, u_int len) +{ + struct cksum_skip_partial_args *a; + + a = arg; + if (((uintptr_t)data ^ a->clen) & 1) + a->csum += in_cksumdata(data, len) << 8; + else + a->csum += in_cksumdata(data, len); + a->clen += len; + return (0); +} + u_short in_cksum_skip(struct mbuf *m, int len, int skip) { - u_int64_t sum = 0; - int mlen = 0; - int clen = 0; - caddr_t addr; + struct cksum_skip_partial_args a; union q_util q_util; union l_util l_util; + uint64_t sum; len -= skip; - for (; skip && m; m = m->m_next) { - if (m->m_len > skip) { - mlen = m->m_len - skip; - addr = mtod(m, caddr_t) + skip; - goto skip_start; - } else { - skip -= m->m_len; - } - } - - for (; m && len; m = m->m_next) { - if (m->m_len == 0) - continue; - mlen = m->m_len; - addr = mtod(m, caddr_t); -skip_start: - if (len < mlen) - mlen = len; - - if ((clen ^ (uintptr_t) addr) & 1) - sum += in_cksumdata(addr, mlen) << 8; - else - sum += in_cksumdata(addr, mlen); - clen += mlen; - len -= mlen; - } + /* + * The use of m_apply() allows this routine to operate on unmapped + * mbufs. + */ + a.csum = 0; + a.clen = 0; + (void)m_apply(m, skip, len, in_cksum_skip_partial, &a); + sum = a.csum; REDUCE16; return (~sum & 0xffff); }