From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>
Subject: [PATCH v8 3/7] test: add test for packet dissector
Date: Mon, 16 Sep 2024 20:28:00 -0700 [thread overview]
Message-ID: <20240917033117.66346-4-stephen@networkplumber.org> (raw)
In-Reply-To: <20240917033117.66346-1-stephen@networkplumber.org>
Add some tests for new packet dissector.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/meson.build | 1 +
app/test/test_dissect.c | 302 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 303 insertions(+)
create mode 100644 app/test/test_dissect.c
diff --git a/app/test/meson.build b/app/test/meson.build
index e29258e6ec..9cd2051320 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -62,6 +62,7 @@ source_file_deps = {
'test_debug.c': [],
'test_devargs.c': ['kvargs'],
'test_dispatcher.c': ['dispatcher'],
+ 'test_dissect.c': ['net'],
'test_distributor.c': ['distributor'],
'test_distributor_perf.c': ['distributor'],
'test_dmadev.c': ['dmadev', 'bus_vdev'],
diff --git a/app/test/test_dissect.c b/app/test/test_dissect.c
new file mode 100644
index 0000000000..08734134d5
--- /dev/null
+++ b/app/test/test_dissect.c
@@ -0,0 +1,302 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2024 Stephen Hemminger <stephen@networkplumber.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <unistd.h>
+
+#include <rte_bus_vdev.h>
+#include <rte_dissect.h>
+#include <rte_ethdev.h>
+#include <rte_ether.h>
+#include <rte_ip.h>
+#include <rte_mbuf.h>
+#include <rte_net.h>
+#include <rte_random.h>
+#include <rte_udp.h>
+#include <rte_vxlan.h>
+
+#include "test.h"
+
+#ifndef LINE_MAX
+#define LINE_MAX 2048
+#endif
+
+#define TOTAL_PACKETS 100
+#define PACKET_LEN 1000
+#define ETH_IP_UDP_VXLAN_SIZE (sizeof(struct rte_ether_hdr) + \
+ sizeof(struct rte_ipv4_hdr) + \
+ sizeof(struct rte_udp_hdr) + \
+ sizeof(struct rte_vxlan_hdr))
+
+
+static uint16_t port_id;
+static const char null_dev[] = "net_null0";
+
+static void
+add_header(struct rte_mbuf *mb, uint32_t plen,
+ rte_be16_t src_port, rte_be16_t dst_port)
+{
+ struct {
+ struct rte_ether_hdr eth;
+ struct rte_ipv4_hdr ip;
+ struct rte_udp_hdr udp;
+ } pkt = {
+ .eth = {
+ .dst_addr.addr_bytes = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
+ .ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4),
+ },
+ .ip = {
+ .version_ihl = RTE_IPV4_VHL_DEF,
+ .time_to_live = 1,
+ .next_proto_id = IPPROTO_UDP,
+ .src_addr = rte_cpu_to_be_32(RTE_IPV4_LOOPBACK),
+ .dst_addr = rte_cpu_to_be_32(RTE_IPV4_BROADCAST),
+ },
+ .udp = {
+ .dst_port = dst_port,
+ .src_port = src_port,
+ },
+ };
+
+ rte_eth_random_addr(pkt.eth.src_addr.addr_bytes);
+
+ plen -= sizeof(struct rte_ether_hdr);
+ pkt.ip.total_length = rte_cpu_to_be_16(plen);
+ pkt.ip.hdr_checksum = rte_ipv4_cksum(&pkt.ip);
+
+ plen -= sizeof(struct rte_ipv4_hdr);
+ pkt.udp.dgram_len = rte_cpu_to_be_16(plen);
+
+ /* Copy header into mbuf */
+ memcpy(rte_pktmbuf_append(mb, sizeof(pkt)), &pkt, sizeof(pkt));
+}
+
+static void
+add_vxlan(struct rte_mbuf *mb, rte_be32_t vni)
+{
+ struct rte_vxlan_hdr *vxlan;
+
+ vxlan = (struct rte_vxlan_hdr *)rte_pktmbuf_append(mb, sizeof(*vxlan));
+ memset(vxlan, 0, sizeof(*vxlan));
+ vxlan->flag_i = 1;
+ vxlan->vx_vni = vni;
+}
+
+
+static void
+fill_data(struct rte_mbuf *mb, uint32_t len)
+{
+ uint32_t i;
+ char *ptr = rte_pktmbuf_append(mb, len);
+ char c = '!';
+
+ /* traditional barber pole pattern */
+ for (i = 0; i < len; i++) {
+ ptr[i] = c++;
+ if (c == 0x7f)
+ c = '!';
+ }
+}
+
+static void
+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;
+ rte_mbuf_refcnt_set(mb, 1);
+
+ /* set pool pointer to dummy value, test doesn't use it */
+ mb->pool = (void *)buf;
+
+ rte_pktmbuf_reset(mb);
+}
+
+static int
+test_setup(void)
+{
+ port_id = rte_eth_dev_count_avail();
+
+ /* Make a dummy null device to snoop on */
+ if (rte_vdev_init(null_dev, NULL) != 0) {
+ fprintf(stderr, "Failed to create vdev '%s'\n", null_dev);
+ goto fail;
+ }
+ return 0;
+
+fail:
+ rte_vdev_uninit(null_dev);
+ return -1;
+}
+
+static void
+test_cleanup(void)
+{
+ rte_vdev_uninit(null_dev);
+}
+
+
+static int
+test_simple(void)
+{
+ struct rte_mbuf mb;
+ uint8_t buf[RTE_MBUF_DEFAULT_BUF_SIZE];
+ uint32_t data_len = PACKET_LEN;
+ rte_be16_t src_port = rte_rand_max(UINT16_MAX);
+ const rte_be16_t dst_port = rte_cpu_to_be_16(9); /* Discard port */
+ char obuf[LINE_MAX] = { };
+ char result[LINE_MAX] = { };
+ int ret;
+
+ /* make a dummy packet */
+ mbuf_prep(&mb, buf, sizeof(buf));
+ add_header(&mb, data_len, src_port, dst_port);
+ fill_data(&mb, data_len - mb.data_off);
+
+ /* construct the expected result */
+ int len = snprintf(result, sizeof(result),
+ "127.0.0.1 → 224.0.0.0 UDP 966 %u → 9",
+ rte_be_to_cpu_16(src_port));
+
+ ret = rte_dissect_mbuf(obuf, sizeof(obuf), &mb, 0);
+ TEST_ASSERT(ret > 0, "Dissect returned: %d", ret);
+
+ TEST_ASSERT_BUFFERS_ARE_EQUAL(obuf, result, len,
+ "Dissect string differs:\nexpect \"%s\"\n got \"%s\"",
+ result, obuf);
+
+ return TEST_SUCCESS;
+}
+
+static int
+test_buffer(void)
+{
+ struct rte_mbuf mb;
+ uint8_t buf[RTE_MBUF_DEFAULT_BUF_SIZE];
+ uint32_t data_len = PACKET_LEN;
+ rte_be16_t src_port = rte_rand_max(UINT16_MAX);
+ const rte_be16_t dst_port = rte_cpu_to_be_16(9); /* Discard port */
+ char *obuf = NULL;
+ char result[LINE_MAX] = { };
+ int ret;
+
+ /* make a dummy packet */
+ mbuf_prep(&mb, buf, sizeof(buf));
+ add_header(&mb, data_len, src_port, dst_port);
+ fill_data(&mb, data_len - mb.data_off);
+
+ /* construct the expected result */
+ int len = snprintf(result, sizeof(result),
+ "127.0.0.1 → 224.0.0.0 UDP 966 %u → 9",
+ rte_be_to_cpu_16(src_port));
+
+ /* call rte_dissect first to determine buffer length needed. */
+ ret = rte_dissect_mbuf(obuf, 0, &mb, 0);
+ TEST_ASSERT(ret == len, "Dissect with NULL returned %d not %d", ret, len);
+
+ size_t size = (size_t) ret + 1; /* One extra byte for '\0' */
+ obuf = malloc(size);
+ TEST_ASSERT_NOT_NULL(obuf, "Malloc for buf failed");
+
+ ret = rte_dissect_mbuf(obuf, size, &mb, 0);
+ TEST_ASSERT(ret == len, "Dissect with buffer returned %d not %d", ret, len);
+
+ TEST_ASSERT_BUFFERS_ARE_EQUAL(obuf, result, len,
+ "Dissect string differs:\nexpect \"%s\"\n got \"%s\"",
+ result, obuf);
+ free(obuf);
+ return TEST_SUCCESS;
+}
+
+static int
+test_truncated(void)
+{
+ struct rte_mbuf mb;
+ uint8_t buf[RTE_MBUF_DEFAULT_BUF_SIZE];
+ uint32_t pkt_len, data_len = PACKET_LEN;
+ rte_be16_t dst_port = rte_cpu_to_be_16(RTE_VXLAN_DEFAULT_PORT);
+ char obuf[LINE_MAX];
+ int ret;
+
+ /* make a really nested vxlan packet */
+ mbuf_prep(&mb, buf, sizeof(buf));
+ pkt_len = data_len;
+ do {
+ rte_be16_t src_port = rte_rand_max(UINT16_MAX);
+ uint32_t vni = rte_rand_max(1ul << 24);
+
+ add_header(&mb, data_len, src_port, dst_port);
+ add_vxlan(&mb, vni);
+ pkt_len -= ETH_IP_UDP_VXLAN_SIZE;
+ } while (pkt_len > ETH_IP_UDP_VXLAN_SIZE);
+
+ fill_data(&mb, pkt_len);
+
+ /* dissect it but snip off some amount of data */
+ for (unsigned int i = 0; i < TOTAL_PACKETS; i++) {
+ uint32_t snaplen = rte_rand_max(pkt_len);
+
+ ret = rte_dissect_mbuf(obuf, sizeof(obuf), &mb, snaplen);
+ TEST_ASSERT(ret > 0, "Truncated len %u failed: %d",
+ snaplen, ret);
+ }
+
+ return TEST_SUCCESS;
+}
+
+static int
+test_fuzz(void)
+{
+ struct rte_mbuf mb;
+ uint8_t buf[RTE_MBUF_DEFAULT_BUF_SIZE];
+ uint32_t data_len = PACKET_LEN;
+ const rte_be16_t dst_port = rte_cpu_to_be_16(rte_rand_max(1024));
+ const rte_be16_t src_port = rte_rand_max(UINT16_MAX);
+ char obuf[LINE_MAX];
+ int ret;
+
+ /* make a dummy packet */
+ mbuf_prep(&mb, buf, sizeof(buf));
+ add_header(&mb, data_len, src_port, dst_port);
+ fill_data(&mb, data_len - mb.data_off);
+
+ /* randomly flip bits in it */
+ for (unsigned int i = 0; i < TOTAL_PACKETS; i++) {
+ uint32_t bit = rte_rand_max(data_len) * 8;
+ uint8_t *bp = buf + bit / 8;
+ uint8_t mask = 1u << (bit % 8);
+
+ /* twiddle one bit */
+ *bp ^= mask;
+ ret = rte_dissect_mbuf(obuf, sizeof(obuf), &mb, 0);
+ TEST_ASSERT(ret > 0, "Fuzz bit %u failed", bit);
+ *bp ^= mask;
+ }
+
+ return TEST_SUCCESS;
+}
+
+static struct
+unit_test_suite test_dissect_suite = {
+ .setup = test_setup,
+ .teardown = test_cleanup,
+ .suite_name = "Test Dissect Unit Test Suite",
+ .unit_test_cases = {
+ TEST_CASE(test_simple),
+ TEST_CASE(test_buffer),
+ TEST_CASE(test_truncated),
+ TEST_CASE(test_fuzz),
+ TEST_CASES_END()
+ }
+};
+
+static int
+test_dissect(void)
+{
+ return unit_test_suite_runner(&test_dissect_suite);
+}
+
+REGISTER_FAST_TEST(dissect_autotest, true, true, test_dissect);
--
2.45.2
next prev parent reply other threads:[~2024-09-17 3:31 UTC|newest]
Thread overview: 63+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-12 22:01 [PATCH] test-pmd: add more packet decode options (verbose) Stephen Hemminger
2024-03-13 21:49 ` Stephen Hemminger
2024-07-05 7:13 ` David Marchand
2024-07-23 2:44 ` [PATCH v2 0/3] Add packet dissector Stephen Hemminger
2024-07-23 2:44 ` [PATCH v2 1/3] net: add new " Stephen Hemminger
2024-07-23 2:44 ` [PATCH v2 2/3] test: add test for " Stephen Hemminger
2024-07-23 2:44 ` [PATCH v2 3/3] test-pmd: add more packet verbose decode options Stephen Hemminger
2024-07-23 20:33 ` [PATCH v3 0/3] add packet dissector function Stephen Hemminger
2024-07-23 20:33 ` [PATCH v3 1/3] net: add new packet dissector Stephen Hemminger
2024-07-23 20:33 ` [PATCH v3 2/3] test: add test for " Stephen Hemminger
2024-07-23 20:33 ` [PATCH v3 3/3] test-pmd: add more packet verbose decode options Stephen Hemminger
2024-07-24 18:46 ` [PATCH v4 0/3] Add packet dissector Stephen Hemminger
2024-07-24 18:46 ` [PATCH v4 1/3] net: add new " Stephen Hemminger
2024-07-24 18:46 ` [PATCH v4 2/3] test: add test for " Stephen Hemminger
2024-07-24 18:46 ` [PATCH v4 3/3] test-pmd: add more packet verbose decode options Stephen Hemminger
2024-08-01 19:04 ` [PATCH v5 0/4] Add network packet dissector Stephen Hemminger
2024-08-01 19:04 ` [PATCH v5 1/4] net: add more icmp types Stephen Hemminger
2024-08-01 19:04 ` [PATCH v5 2/4] net: add new packet dissector Stephen Hemminger
2024-08-01 19:04 ` [PATCH v5 3/4] test: add test for " Stephen Hemminger
2024-08-02 8:38 ` Bruce Richardson
2024-08-02 15:31 ` Stephen Hemminger
2024-08-02 18:06 ` Stephen Hemminger
2024-08-01 19:04 ` [PATCH v5 4/4] test-pmd: add more packet verbose decode options Stephen Hemminger
2024-08-02 18:07 ` [PATCH v6 0/4] Add network packet dissector Stephen Hemminger
2024-08-02 18:07 ` [PATCH v6 1/4] net: add more icmp types Stephen Hemminger
2024-08-02 18:07 ` [PATCH v6 2/4] net: add new packet dissector Stephen Hemminger
2024-08-02 18:07 ` [PATCH v6 3/4] test: add test for " Stephen Hemminger
2024-08-02 18:07 ` [PATCH v6 4/4] test-pmd: add more packet verbose decode options Stephen Hemminger
2024-08-02 19:56 ` [PATCH v7 0/4] Add network packet dissector Stephen Hemminger
2024-08-02 19:56 ` [PATCH v7 1/4] net: add more icmp types Stephen Hemminger
2024-08-02 19:56 ` [PATCH v7 2/4] net: add new packet dissector Stephen Hemminger
2024-08-02 19:56 ` [PATCH v7 3/4] test: add test for " Stephen Hemminger
2024-08-02 19:56 ` [PATCH v7 4/4] test-pmd: add more packet verbose decode options Stephen Hemminger
2024-08-20 13:42 ` Alex Chapman
2024-08-20 15:54 ` Stephen Hemminger
2024-08-22 9:04 ` Paul Szczepanek
2024-09-28 18:36 ` Stephen Hemminger
2024-09-17 3:27 ` [PATCH v8 0/7] Test-pmd packet decode enhancements Stephen Hemminger
2024-09-17 3:27 ` [PATCH v8 1/7] net: add more icmp types Stephen Hemminger
2024-09-17 3:27 ` [PATCH v8 2/7] net: add new packet dissector Stephen Hemminger
2024-09-17 3:28 ` Stephen Hemminger [this message]
2024-09-17 3:28 ` [PATCH v8 4/7] test-pmd: add option to redirect packet log Stephen Hemminger
2024-09-17 3:28 ` [PATCH v8 5/7] test-pmd: add hex decode Stephen Hemminger
2024-09-17 3:28 ` [PATCH v8 6/7] test-pmd: add packet dissect format Stephen Hemminger
2024-09-17 3:28 ` [PATCH v8 7/7] test-pmd: add a JSON packet output Stephen Hemminger
2024-09-28 16:18 ` [PATCH v9 0/8] test-pmd packet decoding enhancements Stephen Hemminger
2024-09-28 16:18 ` [PATCH v9 1/8] net: add more icmp types Stephen Hemminger
2024-09-28 16:18 ` [PATCH v9 2/8] net: add new packet dissector Stephen Hemminger
2024-09-28 16:18 ` [PATCH v9 3/8] mbuf: decode the hash and fdir info in rte_pktmbuf_dump Stephen Hemminger
2024-09-28 16:18 ` [PATCH v9 4/8] test: add test for packet dissector Stephen Hemminger
2024-09-28 16:18 ` [PATCH v9 5/8] test-pmd: add option to redirect packet log Stephen Hemminger
2024-09-28 16:18 ` [PATCH v9 6/8] test-pmd: add hex decode Stephen Hemminger
2024-09-28 16:18 ` [PATCH v9 7/8] test-pmd: add packet dissect format Stephen Hemminger
2024-09-28 16:18 ` [PATCH v9 8/8] test-pmd: add a JSON packet output Stephen Hemminger
2024-10-28 2:19 ` [PATCH v10 0/8] test-pmd packet decoding enhancements Stephen Hemminger
2024-10-28 2:19 ` [PATCH v10 1/8] net: add more icmp types Stephen Hemminger
2024-10-28 2:19 ` [PATCH v10 2/8] net: add new packet dissector Stephen Hemminger
2024-10-28 2:19 ` [PATCH v10 3/8] mbuf: decode the hash and fdir info in rte_pktmbuf_dump Stephen Hemminger
2024-10-28 2:19 ` [PATCH v10 4/8] test: add test for packet dissector Stephen Hemminger
2024-10-28 2:19 ` [PATCH v10 5/8] test-pmd: add option to redirect packet log Stephen Hemminger
2024-10-28 2:19 ` [PATCH v10 6/8] test-pmd: add hex decode Stephen Hemminger
2024-10-28 2:19 ` [PATCH v10 7/8] test-pmd: add packet dissect format Stephen Hemminger
2024-10-28 2:19 ` [PATCH v10 8/8] test-pmd: add a JSON packet output 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=20240917033117.66346-4-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=dev@dpdk.org \
/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;
as well as URLs for NNTP newsgroup(s).