From: Stephen Hemminger <stephen@networkplumber.org>
To: scott.k.mitch1@gmail.com
Cc: dev@dpdk.org
Subject: Re: [PATCH v4 4/4] net/af_packet: add software checksum offload support
Date: Mon, 2 Feb 2026 10:47:55 -0800 [thread overview]
Message-ID: <20260202104755.05d834b6@phoenix.local> (raw)
In-Reply-To: <20260202081456.4322-5-scott.k.mitch1@gmail.com>
On Mon, 2 Feb 2026 00:14:56 -0800
scott.k.mitch1@gmail.com wrote:
> +/**
> + * Compute IPv4 header and UDP/TCP checksums in software.
> + *
> + * Computes checksums based on mbuf offload flags:
> + * - RTE_MBUF_F_TX_IP_CKSUM: Compute IPv4 header checksum
> + * - RTE_MBUF_F_TX_UDP_CKSUM: Compute UDP checksum (IPv4 or IPv6)
> + * - RTE_MBUF_F_TX_TCP_CKSUM: Compute TCP checksum (IPv4 or IPv6)
> + *
> + * @param mbuf
> + * The packet mbuf. Must have l2_len and l3_len set correctly.
> + * @param copy
> + * If true, copy L2/L3/L4 headers to a new segment before computing
> + * checksums. This is safe for indirect mbufs but has overhead.
> + * If false, compute checksums in place. This is only safe if the
> + * mbuf will be copied afterward (e.g., to a device ring buffer).
> + * @return
> + * - On success: Returns mbuf (new segment if copy=true, original if copy=false)
> + * - On error: Returns NULL (allocation failed or malformed packet)
> + */
> +__rte_experimental
> +static inline struct rte_mbuf *
> +rte_net_ip_udptcp_cksum_mbuf(struct rte_mbuf *mbuf, bool copy)
> +{
> + const uint64_t l4_ol_flags = mbuf->ol_flags & RTE_MBUF_F_TX_L4_MASK;
> + const uint64_t l4_offset = mbuf->l2_len + mbuf->l3_len;
> + uint32_t hdrlens = l4_offset;
> + void *l3_hdr = NULL;
> +
> + /* Determine total header length needed */
> + if (l4_ol_flags == RTE_MBUF_F_TX_UDP_CKSUM)
> + hdrlens += sizeof(struct rte_udp_hdr);
> + else if (l4_ol_flags == RTE_MBUF_F_TX_TCP_CKSUM)
> + hdrlens += sizeof(struct rte_tcp_hdr);
> + else if (l4_ol_flags != RTE_MBUF_F_TX_L4_NO_CKSUM)
> + return NULL; /* Unsupported L4 checksum type */
> + else if (!(mbuf->ol_flags & RTE_MBUF_F_TX_IP_CKSUM))
> + return mbuf; /* Nothing to do */
> +
> + /* Validate we at least have L2+L3 headers before doing any work */
> + if (unlikely(rte_pktmbuf_data_len(mbuf) < l4_offset))
> + return NULL;
> +
> + if (copy) {
> + /*
> + * Copy headers to new segment to handle indirect mbufs.
> + * This ensures we can safely modify checksums without
> + * corrupting shared/read-only data.
> + */
> + struct rte_mbuf *seg = rte_pktmbuf_copy(mbuf, mbuf->pool, 0, hdrlens);
> + if (!seg)
> + return NULL;
> +
> + rte_pktmbuf_adj(mbuf, hdrlens);
> + rte_pktmbuf_chain(seg, mbuf);
> + mbuf = seg;
> + } else if (unlikely(!RTE_MBUF_DIRECT(mbuf) || rte_mbuf_refcnt_read(mbuf) > 1))
> + return NULL;
> +
> + l3_hdr = rte_pktmbuf_mtod_offset(mbuf, void *, mbuf->l2_len);
> +
> + /* IPv4 header checksum */
> + if (mbuf->ol_flags & RTE_MBUF_F_TX_IP_CKSUM) {
> + struct rte_ipv4_hdr *iph = (struct rte_ipv4_hdr *)l3_hdr;
> + iph->hdr_checksum = 0;
> + iph->hdr_checksum = rte_ipv4_cksum(iph);
> + }
> +
> + /* L4 checksum (UDP or TCP) - skip if headers not in first segment */
> + if (l4_ol_flags == RTE_MBUF_F_TX_UDP_CKSUM && rte_pktmbuf_data_len(mbuf) >= hdrlens) {
> + struct rte_udp_hdr *udp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_udp_hdr *,
> + l4_offset);
> + udp_hdr->dgram_cksum = 0;
> + udp_hdr->dgram_cksum = (mbuf->ol_flags & RTE_MBUF_F_TX_IPV4) ?
> + rte_ipv4_udptcp_cksum_mbuf(mbuf, (const struct rte_ipv4_hdr *)l3_hdr,
> + l4_offset) :
> + rte_ipv6_udptcp_cksum_mbuf(mbuf, (const struct rte_ipv6_hdr *)l3_hdr,
> + l4_offset);
> + } else if (l4_ol_flags == RTE_MBUF_F_TX_TCP_CKSUM &&
> + rte_pktmbuf_data_len(mbuf) >= hdrlens) {
> + struct rte_tcp_hdr *tcp_hdr = rte_pktmbuf_mtod_offset(mbuf, struct rte_tcp_hdr *,
> + l4_offset);
> + tcp_hdr->cksum = 0;
> + tcp_hdr->cksum = (mbuf->ol_flags & RTE_MBUF_F_TX_IPV4) ?
> + rte_ipv4_udptcp_cksum_mbuf(mbuf, (const struct rte_ipv4_hdr *)l3_hdr,
> + l4_offset) :
> + rte_ipv6_udptcp_cksum_mbuf(mbuf, (const struct rte_ipv6_hdr *)l3_hdr,
> + l4_offset);
> + }
> +
> + return mbuf;
> +}
> +
This is getting a little large to be inline.
Maybe split into inline that checks offload flags, and non-inline
that does the checksum if necessary.
The code could use rte_pktmbuf_linearize() if necessary.
There is code duplication in multiple arms of the if statement
Can the code just "do the right thing" based on the mbufs it is given.
If the mbuf is indirect or has ref count > 1 then copy headers, otherwise
do in place.
next prev parent reply other threads:[~2026-02-02 18:48 UTC|newest]
Thread overview: 65+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-27 18:13 [PATCH v1 0/3] net/af_packet: correctness fixes and improvements scott.k.mitch1
2026-01-27 18:13 ` [PATCH v1 1/3] net/af_packet: fix thread safety and frame calculations scott.k.mitch1
2026-01-27 18:39 ` Stephen Hemminger
2026-01-28 1:35 ` Scott Mitchell
2026-01-27 18:13 ` [PATCH v1 2/3] net/af_packet: RX/TX rte_memcpy, bulk free, prefetch scott.k.mitch1
2026-01-27 18:54 ` Stephen Hemminger
2026-01-28 1:23 ` Scott Mitchell
2026-01-28 9:49 ` Morten Brørup
2026-01-28 15:37 ` Scott Mitchell
2026-01-28 16:57 ` Stephen Hemminger
2026-01-27 18:13 ` [PATCH v1 3/3] net/af_packet: software checksum and tx poll control scott.k.mitch1
2026-01-27 18:57 ` Stephen Hemminger
2026-01-28 7:05 ` Scott Mitchell
2026-01-28 17:36 ` Stephen Hemminger
2026-01-28 18:59 ` Scott Mitchell
2026-01-27 20:45 ` [REVIEW] " Stephen Hemminger
2026-01-28 9:36 ` [PATCH v2 0/4] af_packet correctness, performance, cksum scott.k.mitch1
2026-01-28 9:36 ` [PATCH v2 1/4] net/af_packet: fix thread safety and frame calculations scott.k.mitch1
2026-01-28 16:59 ` Stephen Hemminger
2026-01-28 18:00 ` Scott Mitchell
2026-01-28 18:28 ` Stephen Hemminger
2026-01-28 9:36 ` [PATCH v2 2/4] net/af_packet: RX/TX unlikely, bulk free, prefetch scott.k.mitch1
2026-01-28 9:36 ` [PATCH v2 3/4] net/af_packet: tx poll control scott.k.mitch1
2026-01-28 9:36 ` [PATCH v2 4/4] net/af_packet: software checksum scott.k.mitch1
2026-01-28 18:27 ` Stephen Hemminger
2026-01-28 19:08 ` Scott Mitchell
2026-01-28 19:10 ` [PATCH v3 0/4] af_packet correctness, performance, cksum scott.k.mitch1
2026-01-28 19:10 ` [PATCH v3 1/4] net/af_packet: fix thread safety and frame calculations scott.k.mitch1
2026-01-28 19:10 ` [PATCH v3 2/4] net/af_packet: RX/TX unlikely, bulk free, prefetch scott.k.mitch1
2026-01-29 1:07 ` Stephen Hemminger
2026-02-02 5:29 ` Scott Mitchell
2026-01-28 19:10 ` [PATCH v3 3/4] net/af_packet: tx poll control scott.k.mitch1
2026-01-28 19:10 ` [PATCH v3 4/4] net/af_packet: software checksum scott.k.mitch1
2026-01-28 21:57 ` [REVIEW] " Stephen Hemminger
2026-02-02 7:55 ` Scott Mitchell
2026-02-02 16:58 ` Stephen Hemminger
2026-02-02 8:14 ` [PATCH v4 0/4] af_packet correctness, performance, cksum scott.k.mitch1
2026-02-02 8:14 ` [PATCH v4 1/4] net/af_packet: fix thread safety and frame calculations scott.k.mitch1
2026-02-02 8:14 ` [PATCH v4 2/4] net/af_packet: RX/TX bulk free, unlikely hint scott.k.mitch1
2026-02-02 8:14 ` [PATCH v4 3/4] net/af_packet: tx poll control scott.k.mitch1
2026-02-02 8:14 ` [PATCH v4 4/4] net/af_packet: add software checksum offload support scott.k.mitch1
2026-02-02 17:00 ` Stephen Hemminger
2026-02-02 18:47 ` Stephen Hemminger [this message]
2026-02-03 6:41 ` Scott Mitchell
2026-02-02 18:53 ` [PATCH v4 0/4] af_packet correctness, performance, cksum Stephen Hemminger
2026-02-03 7:07 ` [PATCH v5 " scott.k.mitch1
2026-02-03 7:07 ` [PATCH v5 1/4] net/af_packet: fix thread safety and frame calculations scott.k.mitch1
2026-02-03 7:07 ` [PATCH v5 2/4] net/af_packet: RX/TX bulk free, unlikely hint scott.k.mitch1
2026-02-03 7:07 ` [PATCH v5 3/4] net/af_packet: tx poll control scott.k.mitch1
2026-02-03 7:07 ` [PATCH v5 4/4] net/af_packet: add software checksum offload support scott.k.mitch1
2026-02-03 8:20 ` Scott Mitchell
2026-02-03 14:12 ` Stephen Hemminger
2026-02-04 2:59 ` Scott Mitchell
2026-02-03 14:13 ` Stephen Hemminger
2026-02-04 1:39 ` Scott Mitchell
2026-02-05 21:27 ` Stephen Hemminger
2026-02-06 1:11 ` [PATCH v6 0/4] af_packet correctness, performance, cksum scott.k.mitch1
2026-02-06 1:11 ` [PATCH v6 1/4] net/af_packet: fix thread safety and frame calculations scott.k.mitch1
2026-02-06 1:11 ` [PATCH v6 2/4] net/af_packet: RX/TX bulk free, unlikely hint scott.k.mitch1
2026-02-06 1:11 ` [PATCH v6 3/4] net/af_packet: tx poll control scott.k.mitch1
2026-02-06 1:11 ` [PATCH v6 4/4] net/af_packet: add software checksum offload support scott.k.mitch1
2026-02-06 1:49 ` [PATCH v6 0/4] af_packet correctness, performance, cksum Stephen Hemminger
2026-02-06 4:45 ` Scott Mitchell
2026-02-06 14:36 ` Morten Brørup
2026-02-06 16:11 ` Stephen Hemminger
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=20260202104755.05d834b6@phoenix.local \
--to=stephen@networkplumber.org \
--cc=dev@dpdk.org \
--cc=scott.k.mitch1@gmail.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.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox