[PATCH v4 5/7] test: vary size of packets in pcapng test

Stephen Hemminger
2026-01-13T00:52:32Z

In order to exercise more logic in pcapng, vary the size
of the packets.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_pcapng.c | 94 +++++++++++++++++++++++++++++-------------
1 file changed, 65 insertions(+), 29 deletions(-)

diff --git a/app/test/test_pcapng.c b/app/test/test_pcapng.c
index 09a963c676..f1405cfa7c 100644
--- a/app/test/test_pcapng.c
+++ b/app/test/test_pcapng.c
@@ -28,10 +28,9 @@
#define TOTAL_PACKETS 4096
#define MAX_BURST 64
#define MAX_GAP_US 100000
-#define DUMMY_MBUF_NUM 3
+#define DUMMY_MBUF_NUM 2

static struct rte_mempool *mp;
-static const uint32_t pkt_len = 200;
static uint16_t port_id;
static const char null_dev[] = "net_null0";

@@ -41,13 +40,36 @@ struct dummy_mbuf {
uint8_t buf[DUMMY_MBUF_NUM][RTE_MBUF_DEFAULT_BUF_SIZE];
};

+#define MAX_DATA_SIZE (RTE_MBUF_DEFAULT_BUF_SIZE - RTE_PKTMBUF_HEADROOM)
+
+/* RFC 864 chargen pattern used for comment testing */
+#define FILL_LINE_LENGTH 72
+#define FILL_START 0x21 /* ! */
+#define FILL_END 0x7e /* ~ */
+#define FILL_RANGE (FILL_END - FILL_START)
+
static void
-dummy_mbuf_prep(struct rte_mbuf *mb, uint8_t buf[], uint32_t buf_len,
- uint32_t data_len)
+fill_mbuf(struct rte_mbuf *mb)
{
- uint32_t i;
- uint8_t *db;
+ unsigned int len = rte_pktmbuf_tailroom(mb);
+ char *buf = rte_pktmbuf_append(mb, len);
+ unsigned int n = 0;
+
+ while (n < len - 1) {
+ char ch = FILL_START + (n % FILL_LINE_LENGTH) % FILL_RANGE;
+ for (unsigned int i = 0; i < FILL_LINE_LENGTH && n < len - 1; i++) {
+ buf[n++] = ch;
+ if (++ch == FILL_END)
+ ch = FILL_START;
+ }
+ if (n < len - 1)
+ buf[n++] = '\n';
+ }
+}

+static void
+dummy_mbuf_prep(struct rte_mbuf *mb, uint8_t buf[], uint32_t buf_len)
+{
mb->buf_addr = buf;
rte_mbuf_iova_set(mb, (uintptr_t)buf);
mb->buf_len = buf_len;
@@ -57,15 +79,11 @@ dummy_mbuf_prep(struct rte_mbuf *mb, uint8_t buf[], uint32_t buf_len,
mb->pool = (void *)buf;

rte_pktmbuf_reset(mb);
- db = (uint8_t *)rte_pktmbuf_append(mb, data_len);
-
- for (i = 0; i != data_len; i++)
- db[i] = i;
}

/* Make an IP packet consisting of chain of one packets */
static void
-mbuf1_prepare(struct dummy_mbuf *dm, uint32_t plen)
+mbuf1_prepare(struct dummy_mbuf *dm)
{
struct {
struct rte_ether_hdr eth;
@@ -84,32 +102,47 @@ mbuf1_prepare(struct dummy_mbuf *dm, uint32_t plen)
.dst_addr = rte_cpu_to_be_32(RTE_IPV4_BROADCAST),
},
.udp = {
+ .src_port = rte_cpu_to_be_16(19), /* Chargen port */
.dst_port = rte_cpu_to_be_16(9), /* Discard port */
},
};

memset(dm, 0, sizeof(*dm));
- dummy_mbuf_prep(&dm->mb[0], dm->buf[0], sizeof(dm->buf[0]), plen);
+ dummy_mbuf_prep(&dm->mb[0], dm->buf[0], sizeof(dm->buf[0]));
+ dummy_mbuf_prep(&dm->mb[1], dm->buf[1], sizeof(dm->buf[1]));

rte_eth_random_addr(pkt.eth.src_addr.addr_bytes);
- plen -= sizeof(struct rte_ether_hdr);
+ memcpy(rte_pktmbuf_append(&dm->mb[0], sizeof(pkt)), &pkt, sizeof(pkt));
+
+ fill_mbuf(&dm->mb[1]);
+ rte_pktmbuf_chain(&dm->mb[0], &dm->mb[1]);
+
+ rte_mbuf_sanity_check(&dm->mb[0], 1);
+ rte_mbuf_sanity_check(&dm->mb[1], 0);
+}

- pkt.ip.total_length = rte_cpu_to_be_16(plen);
- pkt.ip.hdr_checksum = rte_ipv4_cksum(&pkt.ip);
+static void
+mbuf1_resize(struct dummy_mbuf *dm, uint16_t len)
+{
+ struct {
+ struct rte_ether_hdr eth;
+ struct rte_ipv4_hdr ip;
+ struct rte_udp_hdr udp;
+ } *pkt = rte_pktmbuf_mtod(&dm->mb[0], void *);

- plen -= sizeof(struct rte_ipv4_hdr);
- pkt.udp.src_port = rte_rand();
- pkt.udp.dgram_len = rte_cpu_to_be_16(plen);
+ dm->mb[1].data_len = len;
+ dm->mb[0].pkt_len = dm->mb[0].data_len + dm->mb[1].data_len;

- memcpy(rte_pktmbuf_mtod(dm->mb, void *), &pkt, sizeof(pkt));
+ len += sizeof(struct rte_udp_hdr);
+ pkt->udp.dgram_len = rte_cpu_to_be_16(len);

- /* Idea here is to create mbuf chain big enough that after mbuf deep copy they won't be
- * compressed into single mbuf to properly test store of chained mbufs
- */
- dummy_mbuf_prep(&dm->mb[1], dm->buf[1], sizeof(dm->buf[1]), pkt_len);
- dummy_mbuf_prep(&dm->mb[2], dm->buf[2], sizeof(dm->buf[2]), pkt_len);
- rte_pktmbuf_chain(&dm->mb[0], &dm->mb[1]);
- rte_pktmbuf_chain(&dm->mb[0], &dm->mb[2]);
+ len += sizeof(struct rte_ipv4_hdr);
+ pkt->ip.total_length = rte_cpu_to_be_16(len);
+ pkt->ip.hdr_checksum = 0;
+ pkt->ip.hdr_checksum = rte_ipv4_cksum(&pkt->ip);
+
+ rte_mbuf_sanity_check(&dm->mb[0], 1);
+ rte_mbuf_sanity_check(&dm->mb[1], 0);
}

static int
@@ -125,7 +158,8 @@ test_setup(void)

/* Make a pool for cloned packets */
mp = rte_pktmbuf_pool_create_by_ops("pcapng_test_pool",
- MAX_BURST * 32, 0, 0, rte_pcapng_mbuf_size(pkt_len),
+ MAX_BURST * 32, 0, 0,
+ rte_pcapng_mbuf_size(MAX_DATA_SIZE),
SOCKET_ID_ANY, "ring_mp_sc");
if (mp == NULL) {
fprintf(stderr, "Cannot create mempool\n");
@@ -165,8 +199,7 @@ fill_pcapng_file(rte_pcapng_t *pcapng, unsigned int num_packets)
"nobody remembers why. Trust the process."),
};

- /* make a dummy packet */
- mbuf1_prepare(&mbfs, pkt_len);
+ mbuf1_prepare(&mbfs);
orig = &mbfs.mb[0];

for (count = 0; count < num_packets; count += burst_size) {
@@ -183,6 +216,9 @@ fill_pcapng_file(rte_pcapng_t *pcapng, unsigned int num_packets)
if ((count + i) % 41 == 0)
comment = examples[rte_rand_max(RTE_DIM(examples))];

+ /* Vary the size of the packets */
+ mbuf1_resize(&mbfs, rte_rand_max(MAX_DATA_SIZE));
+
mc = rte_pcapng_copy(port_id, 0, orig, mp, rte_pktmbuf_pkt_len(orig),
RTE_PCAPNG_DIRECTION_IN, comment);
if (mc == NULL) {
--
2.51.0