public inbox for passt-dev@passt.top
 help / color / mirror / code / Atom feed
From: David Gibson <david@gibson.dropbear.id.au>
To: passt-dev@passt.top, Stefano Brivio <sbrivio@redhat.com>
Cc: lvivier@redhat.com, David Gibson <david@gibson.dropbear.id.au>
Subject: [PATCH v2 3/9] checksum: add csum_iov()
Date: Wed,  6 Mar 2024 16:58:32 +1100	[thread overview]
Message-ID: <20240306055838.1180477-4-david@gibson.dropbear.id.au> (raw)
In-Reply-To: <20240306055838.1180477-1-david@gibson.dropbear.id.au>

From: Laurent Vivier <lvivier@redhat.com>

Introduce the function csum_unfolded() that computes the unfolded
32-bit checksum of a data buffer, and call it from csum() that returns
the folded value.

Introduce csum_iov() that computes the checksum using csum_folded() on
all vectors of the iovec array and returns the folded result.

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
Message-ID: <20240303135114.1023026-4-lvivier@redhat.com>
[dwg: Fixed trivial cppcheck & clang-tidy regressions]
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
---
 checksum.c | 59 ++++++++++++++++++++++++++++++++++++++++++------------
 checksum.h |  4 +++-
 2 files changed, 49 insertions(+), 14 deletions(-)

diff --git a/checksum.c b/checksum.c
index 65486b46..643957b5 100644
--- a/checksum.c
+++ b/checksum.c
@@ -57,6 +57,7 @@
 #include <linux/icmpv6.h>
 
 #include "util.h"
+#include "checksum.h"
 
 /* Checksums are optional for UDP over IPv4, so we usually just set
  * them to 0.  Change this to 1 to calculate real UDP over IPv4
@@ -112,8 +113,6 @@ uint16_t csum_fold(uint32_t sum)
 	return sum;
 }
 
-uint16_t csum(const void *buf, size_t len, uint32_t init);
-
 /**
  * csum_ip4_header() - Calculate and set IPv4 header checksum
  * @ip4h:	IPv4 header
@@ -385,16 +384,17 @@ less_than_128_bytes:
 }
 
 /**
- * csum() - Compute TCP/IP-style checksum
- * @buf:	Input buffer
- * @len:	Input length
- * @init:	Initial 32-bit checksum, 0 for no pre-computed checksum
+ * csum_unfolded - Calculate the unfolded checksum of a data buffer.
  *
- * Return: 16-bit folded, complemented checksum
+ * @buf:   Input buffer
+ * @len:   Input length
+ * @init:  Initial 32-bit checksum, 0 for no pre-computed checksum
+ *
+ * Return: 32-bit unfolded
  */
 /* NOLINTNEXTLINE(clang-diagnostic-unknown-attributes) */
 __attribute__((optimize("-fno-strict-aliasing")))	/* See csum_16b() */
-uint16_t csum(const void *buf, size_t len, uint32_t init)
+uint32_t csum_unfolded(const void *buf, size_t len, uint32_t init)
 {
 	intptr_t align = ROUND_UP((intptr_t)buf, sizeof(__m256i));
 	unsigned int pad = align - (intptr_t)buf;
@@ -408,16 +408,31 @@ uint16_t csum(const void *buf, size_t len, uint32_t init)
 	if (len > pad)
 		init = csum_avx2((void *)align, len - pad, init);
 
-	return (uint16_t)~csum_fold(init);
+	return init;
 }
-
 #else /* __AVX2__ */
+/**
+ * csum_unfolded - Calculate the unfolded checksum of a data buffer.
+ *
+ * @buf:   Input buffer
+ * @len:   Input length
+ * @init:  Initial 32-bit checksum, 0 for no pre-computed checksum
+ *
+ * Return: 32-bit unfolded checksum
+ */
+/* NOLINTNEXTLINE(clang-diagnostic-unknown-attributes) */
+__attribute__((optimize("-fno-strict-aliasing")))	/* See csum_16b() */
+uint32_t csum_unfolded(const void *buf, size_t len, uint32_t init)
+{
+	return sum_16b(buf, len) + init;
+}
+#endif /* !__AVX2__ */
 
 /**
  * csum() - Compute TCP/IP-style checksum
  * @buf:	Input buffer
  * @len:	Input length
- * @sum:	Initial 32-bit checksum, 0 for no pre-computed checksum
+ * @init:	Initial 32-bit checksum, 0 for no pre-computed checksum
  *
  * Return: 16-bit folded, complemented checksum
  */
@@ -425,7 +440,25 @@ uint16_t csum(const void *buf, size_t len, uint32_t init)
 __attribute__((optimize("-fno-strict-aliasing")))	/* See csum_16b() */
 uint16_t csum(const void *buf, size_t len, uint32_t init)
 {
-	return (uint16_t)~csum_fold(sum_16b(buf, len) + init);
+	return (uint16_t)~csum_fold(csum_unfolded(buf, len, init));
 }
 
-#endif /* !__AVX2__ */
+/**
+ * csum_iov() - Calculates the unfolded checksum over an array of IO vectors
+ *
+ * @iov		Pointer to the array of IO vectors
+ * @n		Length of the array
+ * @init	Initial 32-bit checksum, 0 for no pre-computed checksum
+ *
+ * Return: 16-bit folded, complemented checksum
+ */
+/* cppcheck-suppress unusedFunction */
+uint16_t csum_iov(const struct iovec *iov, size_t n, uint32_t init)
+{
+	unsigned int i;
+
+	for (i = 0; i < n; i++)
+		init = csum_unfolded(iov[i].iov_base, iov[i].iov_len, init);
+
+	return (uint16_t)~csum_fold(init);
+}
diff --git a/checksum.h b/checksum.h
index 21c0310d..cb80ab38 100644
--- a/checksum.h
+++ b/checksum.h
@@ -17,13 +17,15 @@ void csum_ip4_header(struct iphdr *ip4h);
 void csum_udp4(struct udphdr *udp4hr,
 	       struct in_addr saddr, struct in_addr daddr,
 	       const void *payload, size_t len);
-void csum_icmp4(struct icmphdr *ih, const void *payload, size_t len);
+void csum_icmp4(struct icmphdr *icmp4hr, const void *payload, size_t len);
 void csum_udp6(struct udphdr *udp6hr,
 	       const struct in6_addr *saddr, const struct in6_addr *daddr,
 	       const void *payload, size_t len);
 void csum_icmp6(struct icmp6hdr *icmp6hr,
 		const struct in6_addr *saddr, const struct in6_addr *daddr,
 		const void *payload, size_t len);
+uint32_t csum_unfolded(const void *buf, size_t len, uint32_t init);
 uint16_t csum(const void *buf, size_t len, uint32_t init);
+uint16_t csum_iov(const struct iovec *iov, size_t n, uint32_t init);
 
 #endif /* CHECKSUM_H */
-- 
@@ -17,13 +17,15 @@ void csum_ip4_header(struct iphdr *ip4h);
 void csum_udp4(struct udphdr *udp4hr,
 	       struct in_addr saddr, struct in_addr daddr,
 	       const void *payload, size_t len);
-void csum_icmp4(struct icmphdr *ih, const void *payload, size_t len);
+void csum_icmp4(struct icmphdr *icmp4hr, const void *payload, size_t len);
 void csum_udp6(struct udphdr *udp6hr,
 	       const struct in6_addr *saddr, const struct in6_addr *daddr,
 	       const void *payload, size_t len);
 void csum_icmp6(struct icmp6hdr *icmp6hr,
 		const struct in6_addr *saddr, const struct in6_addr *daddr,
 		const void *payload, size_t len);
+uint32_t csum_unfolded(const void *buf, size_t len, uint32_t init);
 uint16_t csum(const void *buf, size_t len, uint32_t init);
+uint16_t csum_iov(const struct iovec *iov, size_t n, uint32_t init);
 
 #endif /* CHECKSUM_H */
-- 
2.44.0


  parent reply	other threads:[~2024-03-06  5:58 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-06  5:58 [PATCH v2 0/9] vhost-user part 1, v6 David Gibson
2024-03-06  5:58 ` [PATCH v2 1/9] pcap: add pcap_iov() David Gibson
2024-03-06  5:58 ` [PATCH v2 2/9] checksum: align buffers David Gibson
2024-03-06  5:58 ` David Gibson [this message]
2024-03-06  5:58 ` [PATCH v2 4/9] util: move IP stuff from util.[ch] to ip.[ch] David Gibson
2024-03-06  5:58 ` [PATCH v2 5/9] udp: little cleanup in udp_update_hdrX() to prepare future changes David Gibson
2024-03-06  5:58 ` [PATCH v2 6/9] checksum: use csum_ip4_header() in udp.c and tcp.c David Gibson
2024-03-06  5:58 ` [PATCH v2 7/9] checksum: introduce functions to compute the header part checksum for TCP/UDP David Gibson
2024-03-06  5:58 ` [PATCH v2 8/9] tap: make tap_update_mac() generic David Gibson
2024-03-06  5:58 ` [PATCH v2 9/9] tcp: Introduce tcp_fill_headers4()/tcp_fill_headers6() David Gibson
2024-03-06  7:04 ` [PATCH v2 0/9] vhost-user part 1, v6 Stefano Brivio

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240306055838.1180477-4-david@gibson.dropbear.id.au \
    --to=david@gibson.dropbear.id.au \
    --cc=lvivier@redhat.com \
    --cc=passt-dev@passt.top \
    --cc=sbrivio@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://passt.top/passt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).