From: Stephen Hemminger <stephen@networkplumber.org>
To: Xingui Yang <yangxingui@huawei.com>
Cc: <dev@dpdk.org>, <david.marchand@redhat.com>,
<aman.deep.singh@intel.com>, <fengchengwen@huawei.com>,
<yangshuaisong@h-partners.com>, <lihuisong@huawei.com>,
<liuyonglong@huawei.com>, <kangfenglong@huawei.com>
Subject: Re: [PATCH v2] app/testpmd: add padding mode to txonly engine
Date: Fri, 12 Jun 2026 09:13:43 -0700 [thread overview]
Message-ID: <20260612091343.14344ef7@phoenix.local> (raw)
In-Reply-To: <20260612091217.2899755-1-yangxingui@huawei.com>
On Fri, 12 Jun 2026 17:12:17 +0800
Xingui Yang <yangxingui@huawei.com> wrote:
> Add a new padding mode to the txonly forwarding engine, which allows
> sending packets with configurable small sizes without standard L2/L3
> headers. This is useful for testing NIC padding logic.
>
> When padding mode is enabled via --tx-pkt-pad-mode flag:
> - l2_len and l3_len are set to 0 instead of standard header lengths
> - Packet data is filled with a static pattern instead of
> Ethernet/IP/UDP headers
> - Minimum packet length validation is bypassed to allow small
> packet sizes (e.g., set txpkts 14)
>
> Signed-off-by: Xingui Yang <yangxingui@huawei.com>
> Signed-off-by: Huisong Li <lihuisong@huawei.com>
> ---
> v2: Fix compilation exception of unterminated-string-initialization
> ---
What about something like this (*not tested*) patch.
From 84ff35849f9881a93eed65ccd43a5cd1197cecb8 Mon Sep 17 00:00:00 2001
From: Stephen Hemminger <stephen@networkplumber.org>
Date: Fri, 12 Jun 2026 09:10:17 -0700
Subject: [PATCH] testpnd: allow configuring runt frames
Allow setting transmit size to be a small value which has
ethernet header but no IP or UDP header.
---
app/test-pmd/config.c | 12 +++----
app/test-pmd/txonly.c | 35 +++++++++++++++++++--
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 13 ++++++++
3 files changed, 51 insertions(+), 9 deletions(-)
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 9d457ca88e..46ff678b9f 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -6327,9 +6327,6 @@ set_tx_pkt_segments(unsigned int *seg_lengths, unsigned int nb_segs)
/*
* Check that each segment length is greater or equal than
* the mbuf data size.
- * Check also that the total packet length is greater or equal than the
- * size of an empty UDP/IP packet (sizeof(struct rte_ether_hdr) +
- * 20 + 8).
*/
tx_pkt_len = 0;
for (i = 0; i < nb_segs; i++) {
@@ -6341,10 +6338,11 @@ set_tx_pkt_segments(unsigned int *seg_lengths, unsigned int nb_segs)
}
tx_pkt_len = (uint16_t)(tx_pkt_len + seg_lengths[i]);
}
- if (tx_pkt_len < (sizeof(struct rte_ether_hdr) + 20 + 8)) {
- fprintf(stderr, "total packet length=%u < %d - give up\n",
- (unsigned) tx_pkt_len,
- (int)(sizeof(struct rte_ether_hdr) + 20 + 8));
+
+ /* Allow runt packets this is a test tool. */
+ if (tx_pkt_len < (sizeof(struct rte_ether_hdr))) {
+ fprintf(stderr, "total packet length=%u < %zu - give up\n",
+ tx_pkt_len, sizeof(struct rte_ether_hdr));
return;
}
diff --git a/app/test-pmd/txonly.c b/app/test-pmd/txonly.c
index 64893fa205..2e0abe361e 100644
--- a/app/test-pmd/txonly.c
+++ b/app/test-pmd/txonly.c
@@ -76,6 +76,12 @@ copy_buf_to_pkt_segs(void* buf, unsigned len, struct rte_mbuf *pkt,
while (offset >= seg->data_len) {
offset -= seg->data_len;
seg = seg->next;
+ /*
+ * The packet may be shorter than the header stack when
+ * generating runt frames; stop once it runs out of segments.
+ */
+ if (seg == NULL)
+ return;
}
copy_len = seg->data_len - offset;
seg_buf = rte_pktmbuf_mtod_offset(seg, char *, offset);
@@ -84,6 +90,8 @@ copy_buf_to_pkt_segs(void* buf, unsigned len, struct rte_mbuf *pkt,
len -= copy_len;
buf = ((char*) buf + copy_len);
seg = seg->next;
+ if (seg == NULL)
+ return;
seg_buf = rte_pktmbuf_mtod(seg, char *);
copy_len = seg->data_len;
}
@@ -193,7 +201,6 @@ pkt_burst_prepare(struct rte_mbuf *pkt, struct rte_mempool *mbp,
pkt->vlan_tci = vlan_tci;
pkt->vlan_tci_outer = vlan_tci_outer;
pkt->l2_len = sizeof(struct rte_ether_hdr);
- pkt->l3_len = sizeof(struct rte_ipv4_hdr);
pkt_len = pkt->data_len;
pkt_seg = pkt;
@@ -204,6 +211,24 @@ pkt_burst_prepare(struct rte_mbuf *pkt, struct rte_mempool *mbp,
pkt_len += pkt_seg->data_len;
}
pkt_seg->next = NULL; /* Last segment of packet. */
+
+ /*
+ * A runt frame may be too short to carry a full IPv4/UDP header.
+ * Clamp l3_len and drop any checksum offload whose header is not
+ * fully present, so the PMD is never asked to checksum bytes that
+ * are not in the frame. pkt_len is at least sizeof(rte_ether_hdr),
+ * so the subtraction below cannot underflow.
+ */
+ pkt->l3_len = RTE_MIN(sizeof(struct rte_ipv4_hdr),
+ pkt_len - sizeof(struct rte_ether_hdr));
+ if (pkt_len < sizeof(struct rte_ether_hdr) +
+ sizeof(struct rte_ipv4_hdr))
+ pkt->ol_flags &= ~(RTE_MBUF_F_TX_IP_CKSUM |
+ RTE_MBUF_F_TX_L4_MASK);
+ else if (pkt_len < sizeof(struct rte_ether_hdr) +
+ sizeof(struct rte_ipv4_hdr) +
+ sizeof(struct rte_udp_hdr))
+ pkt->ol_flags &= ~RTE_MBUF_F_TX_L4_MASK;
/*
* Copy headers in first packet segment(s).
*/
@@ -405,7 +430,13 @@ tx_only_begin(portid_t pi)
pkt_hdr_len = (uint16_t)(sizeof(struct rte_ether_hdr) +
sizeof(struct rte_ipv4_hdr) +
sizeof(struct rte_udp_hdr));
- pkt_data_len = tx_pkt_length - pkt_hdr_len;
+ /*
+ * tx_pkt_length may be smaller than the full header stack when
+ * generating runt frames; clamp the payload length to zero in that
+ * case so the IP/UDP length fields stay sane.
+ */
+ pkt_data_len = tx_pkt_length > pkt_hdr_len ?
+ tx_pkt_length - pkt_hdr_len : 0;
if ((tx_pkt_split == TX_PKT_SPLIT_RND || txonly_multi_flow) &&
tx_pkt_seg_lengths[0] < pkt_hdr_len) {
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index f0f2b0758b..d2e5b63586 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -876,6 +876,19 @@ Set the length of each segment of the TX-ONLY packets or length of packet for FL
Where x[,y]* represents a CSV list of values, without white space.
+The total packet length may be set as small as the Ethernet header
+(``sizeof(struct rte_ether_hdr)``), which is below the size of an empty
+UDP/IPv4 packet. This generates runt frames with a truncated (or absent)
+IPv4/UDP header, which is useful for testing how a driver handles
+undersized frames. Any header bytes that do not fit in the requested
+length are simply not emitted. Checksum offloads are automatically
+dropped for a frame too short to contain the corresponding header.
+
+Note that random split (``set txsplit rand``) and multi-flow
+(``set txonly-flows``) still require the first segment to hold the full
+Ethernet/IPv4/UDP header stack, so they cannot be combined with runt
+lengths.
+
set txtimes
~~~~~~~~~~~
--
2.53.0
prev parent reply other threads:[~2026-06-12 16:13 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-12 9:12 [PATCH v2] app/testpmd: add padding mode to txonly engine Xingui Yang
2026-06-12 16:13 ` Stephen Hemminger [this message]
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=20260612091343.14344ef7@phoenix.local \
--to=stephen@networkplumber.org \
--cc=aman.deep.singh@intel.com \
--cc=david.marchand@redhat.com \
--cc=dev@dpdk.org \
--cc=fengchengwen@huawei.com \
--cc=kangfenglong@huawei.com \
--cc=lihuisong@huawei.com \
--cc=liuyonglong@huawei.com \
--cc=yangshuaisong@h-partners.com \
--cc=yangxingui@huawei.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