From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
Ori Kam <orika@nvidia.com>,
Aman Singh <aman.deep.singh@intel.com>,
Yuying Zhang <yuying.zhang@intel.com>
Subject: [PATCH] test-pmd: add more packet decode options (verbose)
Date: Tue, 12 Mar 2024 15:01:27 -0700 [thread overview]
Message-ID: <20240312220129.70667-1-stephen@networkplumber.org> (raw)
The existing verbose levels 1..3 provide a messy multi-line
output per packet. This is unhelpful when diagnosing many
types of problems like packet flow.
This patch adds two new levels:
4: one line per packet is printed in a format resembling
tshark output. With addresses and protocol info.
5: dump packet in hex.
Useful if the driver is messing up the data.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test-pmd/cmdline_flow.c | 3 +-
app/test-pmd/config.c | 33 +-
app/test-pmd/testpmd.h | 11 +
app/test-pmd/util.c | 355 +++++++++++++++++++-
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 5 +-
5 files changed, 391 insertions(+), 16 deletions(-)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 5f761903c1d1..03141c04cae5 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -14002,7 +14002,8 @@ cmd_set_raw_parsed(const struct buffer *in)
upper_layer = proto;
}
}
- if (verbose_level & 0x1)
+
+ if (verbose_level > 0)
printf("total data size is %zu\n", (*total_size));
RTE_ASSERT((*total_size) <= ACTION_RAW_ENCAP_MAX_DATA);
memmove(data, (data_tail - (*total_size)), *total_size);
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 968d2164ab35..8e83b78721fc 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -6250,26 +6250,37 @@ configure_rxtx_dump_callbacks(uint16_t verbose)
return;
#endif
- RTE_ETH_FOREACH_DEV(portid)
- {
- if (verbose == 1 || verbose > 2)
+ RTE_ETH_FOREACH_DEV(portid) {
+ switch (verbose) {
+ case VERBOSE_OFF:
+ remove_rx_dump_callbacks(portid);
+ remove_tx_dump_callbacks(portid);
+ break;
+ case VERBOSE_RX:
add_rx_dump_callbacks(portid);
- else
+ remove_tx_dump_callbacks(portid);
+ break;
+ case VERBOSE_TX:
+ add_tx_dump_callbacks(portid);
remove_rx_dump_callbacks(portid);
- if (verbose >= 2)
+ break;
+ default:
+ add_rx_dump_callbacks(portid);
add_tx_dump_callbacks(portid);
- else
- remove_tx_dump_callbacks(portid);
+ }
}
}
void
set_verbose_level(uint16_t vb_level)
{
- printf("Change verbose level from %u to %u\n",
- (unsigned int) verbose_level, (unsigned int) vb_level);
- verbose_level = vb_level;
- configure_rxtx_dump_callbacks(verbose_level);
+ if (vb_level < VERBOSE_MAX) {
+ printf("Change verbose level from %u to %u\n", verbose_level, vb_level);
+ verbose_level = vb_level;
+ configure_rxtx_dump_callbacks(verbose_level);
+ } else {
+ fprintf(stderr, "Verbose level %u is out of range\n", vb_level);
+ }
}
void
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 55df12033a39..26801226bb47 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -489,6 +489,17 @@ enum dcb_mode_enable
extern uint8_t xstats_hide_zero; /**< Hide zero values for xstats display */
+enum verbose_mode {
+ VERBOSE_OFF = 0,
+ VERBOSE_RX,
+ VERBOSE_TX,
+ VERBOSE_BOTH,
+ VERBOSE_DISSECT,
+ VERBOSE_HEX,
+ VERBOSE_MAX
+};
+
+
/* globals used for configuration */
extern uint8_t record_core_cycles; /**< Enables measurement of CPU cycles */
extern uint8_t record_burst_stats; /**< Enables display of RX and TX bursts */
diff --git a/app/test-pmd/util.c b/app/test-pmd/util.c
index 5aa69ed545af..f9dfa4d7ec07 100644
--- a/app/test-pmd/util.c
+++ b/app/test-pmd/util.c
@@ -9,6 +9,11 @@
#include <rte_net.h>
#include <rte_mbuf.h>
#include <rte_ether.h>
+#include <rte_arp.h>
+#include <rte_icmp.h>
+#include <rte_ip.h>
+#include <rte_tcp.h>
+#include <rte_udp.h>
#include <rte_vxlan.h>
#include <rte_ethdev.h>
#include <rte_flow.h>
@@ -16,6 +21,7 @@
#include "testpmd.h"
#define MAX_STRING_LEN 8192
+#define MAX_DUMP_LEN 1024
#define MKDUMPSTR(buf, buf_size, cur_len, ...) \
do { \
@@ -67,9 +73,10 @@ get_timestamp(const struct rte_mbuf *mbuf)
timestamp_dynfield_offset, rte_mbuf_timestamp_t *);
}
-static inline void
-dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
- uint16_t nb_pkts, int is_rx)
+/* More verbose older style packet decode */
+static void
+dump_pkt_verbose(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
+ uint16_t nb_pkts, int is_rx)
{
struct rte_mbuf *mb;
const struct rte_ether_hdr *eth_hdr;
@@ -297,6 +304,348 @@ dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
}
}
+static void
+dissect_arp(const struct rte_mbuf *mb, uint16_t offset)
+{
+ const struct rte_arp_hdr *arp;
+ struct rte_arp_hdr _arp;
+ uint16_t ar_op;
+ char buf[128];
+
+ arp = rte_pktmbuf_read(mb, offset, sizeof(*arp), &_arp);
+ if (unlikely(arp == NULL)) {
+ printf("truncated ARP! ");
+ return;
+ }
+
+ ar_op = RTE_BE_TO_CPU_16(arp->arp_opcode);
+ switch (ar_op) {
+ case RTE_ARP_OP_REQUEST:
+ inet_ntop(AF_INET, &arp->arp_data.arp_tip, buf, sizeof(buf));
+ printf("Who has %s? ", buf);
+
+ rte_ether_format_addr(buf, sizeof(buf), &arp->arp_data.arp_sha);
+ printf("Tell %s ", buf);
+ break;
+ case RTE_ARP_OP_REPLY:
+ inet_ntop(AF_INET, &arp->arp_data.arp_sip, buf, sizeof(buf));
+ printf("%s is at", buf);
+
+ rte_ether_format_addr(buf, sizeof(buf), &arp->arp_data.arp_sha);
+ printf("%s ", buf);
+ break;
+ case RTE_ARP_OP_INVREQUEST:
+ rte_ether_format_addr(buf, sizeof(buf), &arp->arp_data.arp_tha);
+ printf("Who is %s? ", buf);
+
+ rte_ether_format_addr(buf, sizeof(buf), &arp->arp_data.arp_sha);
+ printf("Tell %s ", buf);
+ break;
+
+ case RTE_ARP_OP_INVREPLY:
+ rte_ether_format_addr(buf, sizeof(buf), &arp->arp_data.arp_sha);
+ printf("%s is at ", buf);
+
+ inet_ntop(AF_INET, &arp->arp_data.arp_sip, buf, sizeof(buf));
+ printf("%s ", buf);
+ break;
+ default:
+ printf("Unknown ARP %#x ", ar_op);
+ break;
+ }
+}
+
+static void
+dissect_udp(const struct rte_mbuf *mb, uint16_t offset)
+{
+ const struct rte_udp_hdr *udph;
+ struct rte_udp_hdr _udp;
+ uint16_t src_port, dst_port;
+
+ udph = rte_pktmbuf_read(mb, offset, sizeof(*udph), &_udp);
+ if (unlikely(udph == NULL)) {
+ printf("truncated UDP! ");
+ return;
+ }
+
+ src_port = RTE_BE_TO_CPU_16(udph->src_port);
+ dst_port = RTE_BE_TO_CPU_16(udph->dst_port);
+
+ /* TODO handle vxlan */
+
+ printf("UDP %u %u → %u ",
+ RTE_BE_TO_CPU_16(udph->dgram_len),
+ src_port, dst_port);
+
+}
+
+static void
+dissect_tcp(const struct rte_mbuf *mb, uint16_t offset)
+{
+ const struct rte_tcp_hdr *tcph;
+ struct rte_tcp_hdr _tcp;
+ uint16_t src_port, dst_port;
+
+ tcph = rte_pktmbuf_read(mb, offset, sizeof(*tcph), &_tcp);
+ if (unlikely(tcph == NULL)) {
+ printf("truncated TCP! ");
+ return;
+ }
+
+ src_port = RTE_BE_TO_CPU_16(tcph->src_port);
+ dst_port = RTE_BE_TO_CPU_16(tcph->dst_port);
+
+ printf("TCP %u → %u",
+ src_port, dst_port);
+#define PRINT_TCP_FLAG(flag) \
+ if (tcph->tcp_flags & RTE_TCP_ ## flag ## _FLAG) \
+ printf(" [" #flag" ]")
+
+ PRINT_TCP_FLAG(URG);
+ PRINT_TCP_FLAG(ACK);
+ PRINT_TCP_FLAG(RST);
+ PRINT_TCP_FLAG(SYN);
+ PRINT_TCP_FLAG(FIN);
+#undef PRINT_TCP_FLAG
+
+ printf("Seq=%u Ack=%u Win=%u ",
+ RTE_BE_TO_CPU_16(tcph->sent_seq),
+ RTE_BE_TO_CPU_16(tcph->recv_ack),
+ RTE_BE_TO_CPU_16(tcph->rx_win));
+}
+
+static void
+dissect_icmp(const struct rte_mbuf *mb, uint16_t offset)
+{
+ const struct rte_icmp_hdr *icmp;
+ struct rte_icmp_hdr _icmp;
+ static const char * const icmp_types[256] = {
+ [RTE_IP_ICMP_ECHO_REPLY] = "ICMP Reply",
+ [RTE_IP_ICMP_ECHO_REQUEST] = "ICMP Request",
+ [RTE_ICMP6_ECHO_REPLY] = "ICMPv6 Reply",
+ [RTE_ICMP6_ECHO_REQUEST] = "ICMPv6 Request",
+ [133] = "ICMPv6 Router Solicitation",
+ [134] = "ICMPv6 Router Solicitation",
+ };
+
+
+ icmp = rte_pktmbuf_read(mb, offset, sizeof(*icmp), &_icmp);
+ if (unlikely(icmp == NULL)) {
+ printf("truncated ICMP! ");
+ } else {
+ const char *name = icmp_types[icmp->icmp_type];
+
+ if (name != NULL)
+ printf("%s ", name);
+ else
+ printf("ICMP type %u ", icmp->icmp_type);
+ }
+}
+
+static void
+dissect_ipv4(const struct rte_mbuf *mb, uint16_t offset)
+{
+ const struct rte_ipv4_hdr *ip_hdr;
+ struct rte_ipv4_hdr _ip_hdr;
+ char sbuf[INET_ADDRSTRLEN], dbuf[INET_ADDRSTRLEN];
+
+ ip_hdr = rte_pktmbuf_read(mb, offset, sizeof(*ip_hdr), &_ip_hdr);
+ if (unlikely(ip_hdr == NULL)) {
+ printf("truncated IP! ");
+ return;
+ }
+
+ inet_ntop(AF_INET, &ip_hdr->src_addr, sbuf, sizeof(sbuf));
+ inet_ntop(AF_INET, &ip_hdr->dst_addr, dbuf, sizeof(dbuf));
+ printf("%s → %s ", sbuf, dbuf);
+
+ offset += ip_hdr->ihl * 4;
+ switch (ip_hdr->next_proto_id) {
+ case IPPROTO_UDP:
+ return dissect_udp(mb, offset);
+ case IPPROTO_TCP:
+ return dissect_tcp(mb, offset);
+ case IPPROTO_ICMP:
+ return dissect_icmp(mb, offset);
+ default:
+ /* TODO dissect tunnels */
+ printf("IP proto %#x ", ip_hdr->next_proto_id);
+ }
+}
+
+static void
+dissect_ipv6(const struct rte_mbuf *mb, uint16_t offset)
+{
+ const struct rte_ipv6_hdr *ip6_hdr;
+ struct rte_ipv6_hdr _ip6_hdr;
+ char sbuf[INET6_ADDRSTRLEN], dbuf[INET6_ADDRSTRLEN];
+ uint16_t proto;
+ unsigned int i;
+
+ ip6_hdr = rte_pktmbuf_read(mb, offset, sizeof(*ip6_hdr), &_ip6_hdr);
+ if (unlikely(ip6_hdr == NULL)) {
+ printf("truncated IPv6! ");
+ return;
+ }
+ offset += sizeof(*ip6_hdr);
+
+ inet_ntop(AF_INET6, ip6_hdr->src_addr, sbuf, sizeof(sbuf));
+ inet_ntop(AF_INET6, ip6_hdr->dst_addr, dbuf, sizeof(dbuf));
+ printf("%s → %s ", sbuf, dbuf);
+
+#define MAX_EXT_HDRS 5
+ proto = ip6_hdr->proto;
+ for (i = 0; i < MAX_EXT_HDRS; i++) {
+ switch (proto) {
+ case IPPROTO_UDP:
+ return dissect_udp(mb, offset);
+ case IPPROTO_TCP:
+ return dissect_tcp(mb, offset);
+ case IPPROTO_ICMPV6:
+ return dissect_icmp(mb, offset);
+
+ case IPPROTO_HOPOPTS:
+ case IPPROTO_ROUTING:
+ case IPPROTO_DSTOPTS:
+ {
+ const struct rte_ipv6_routing_ext *xh;
+ struct rte_ipv6_routing_ext _xh;
+
+ xh = rte_pktmbuf_read(mb, offset, sizeof(*xh), &_xh);
+ if (unlikely(xh == NULL)) {
+ printf("truncated IPV6 option! ");
+ return;
+ }
+ offset += (xh->hdr_len + 1) * 8;
+ proto = xh->next_hdr;
+ continue;
+ }
+
+ case IPPROTO_FRAGMENT:
+ printf("FRAG ");
+ return;
+
+ case IPPROTO_NONE:
+ printf("NONE ");
+ return;
+
+ default:
+ printf("IPv6 proto %u ", proto);
+ return;
+ }
+ }
+
+ printf("Too many extensions! ");
+}
+
+static void
+dissect_eth(const struct rte_mbuf *mb, uint16_t offset)
+{
+ const struct rte_ether_hdr *eth_hdr;
+ struct rte_ether_hdr _eth_hdr;
+ uint16_t eth_type;
+ char sbuf[RTE_ETHER_ADDR_FMT_SIZE], dbuf[RTE_ETHER_ADDR_FMT_SIZE];
+
+ eth_hdr = rte_pktmbuf_read(mb, offset, sizeof(struct rte_ether_hdr), &_eth_hdr);
+ if (unlikely(eth_hdr == NULL)) {
+ printf("missing Eth header! offset=%u", offset);
+ return;
+ }
+
+ offset += sizeof(*eth_hdr);
+ eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
+ if (eth_type == RTE_ETHER_TYPE_VLAN || eth_type == RTE_ETHER_TYPE_QINQ) {
+ const struct rte_vlan_hdr *vh
+ = (const struct rte_vlan_hdr *)(eth_hdr + 1);
+ eth_type = vh->eth_proto;
+ offset += sizeof(*vh);
+
+ printf("%s %#x ", eth_type == RTE_ETHER_TYPE_VLAN ? "VLAN" : "QINQ",
+ RTE_BE_TO_CPU_16(vh->vlan_tci));
+ }
+
+ switch (eth_type) {
+ case RTE_ETHER_TYPE_ARP:
+ rte_ether_format_addr(sbuf, sizeof(sbuf), ð_hdr->src_addr);
+ rte_ether_format_addr(sbuf, sizeof(dbuf), ð_hdr->dst_addr);
+ printf("%s → %s ARP ", sbuf, dbuf);
+
+ dissect_arp(mb, offset);
+ break;
+ case RTE_ETHER_TYPE_IPV4:
+ dissect_ipv4(mb, offset);
+ break;
+
+ case RTE_ETHER_TYPE_IPV6:
+ dissect_ipv6(mb, offset);
+ break;
+ default:
+ printf("Ethernet proto %#x ", eth_type);
+ }
+}
+
+/* Brief tshark style one line output which is
+ * number time_delta Source Destination Protocol len info
+ */
+static void
+dump_pkt_brief(uint16_t queue, struct rte_mbuf *pkts[], uint16_t nb_pkts)
+{
+ static uint64_t start_cycles;
+ static uint64_t packet_count;
+ uint64_t now;
+ uint64_t count;
+ double interval;
+ uint16_t i;
+
+ if (!nb_pkts)
+ return;
+
+ now = rte_rdtsc();
+ if (start_cycles == 0)
+ start_cycles = now;
+ interval = (double)(now - start_cycles) / (double)rte_get_tsc_hz();
+
+ count = __atomic_fetch_add(&packet_count, nb_pkts, __ATOMIC_RELAXED);
+
+ for (i = 0; i < nb_pkts; i++) {
+ const struct rte_mbuf *mb = pkts[i];
+
+ printf("%6"PRIu64" %11.9f %4u:%-3u ", count + i, interval, mb->port, queue);
+ dissect_eth(mb, 0);
+ putchar('\n');
+ }
+ fflush(stdout);
+}
+
+/* Hex dump of packet data */
+static void
+dump_pkt_hex(struct rte_mbuf *pkts[], uint16_t nb_pkts)
+{
+ uint16_t i;
+
+ for (i = 0; i < nb_pkts; i++)
+ rte_pktmbuf_dump(stdout, pkts[i], MAX_DUMP_LEN);
+
+ fflush(stdout);
+}
+
+static uint16_t
+dump_pkt_burst(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
+ uint16_t nb_pkts, int is_rx)
+{
+ switch (verbose_level) {
+ case VERBOSE_RX ... VERBOSE_BOTH:
+ dump_pkt_verbose(port_id, queue, pkts, nb_pkts, is_rx);
+ break;
+ case VERBOSE_DISSECT:
+ dump_pkt_brief(queue, pkts, nb_pkts);
+ break;
+ case VERBOSE_HEX:
+ dump_pkt_hex(pkts, nb_pkts);
+ }
+ return nb_pkts;
+}
+
uint16_t
dump_rx_pkts(uint16_t port_id, uint16_t queue, struct rte_mbuf *pkts[],
uint16_t nb_pkts, __rte_unused uint16_t max_pkts,
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 2fbf9220d8a9..f8b75b09afd0 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -677,7 +677,10 @@ Available levels are as following:
* ``0`` silent except for error.
* ``1`` fully verbose except for Tx packets.
* ``2`` fully verbose except for Rx packets.
-* ``> 2`` fully verbose.
+* ``3`` fully verbose except for Tx and Rx packets.
+* ``4`` dissected protocol information for Tx and Rx packets.
+* ``5`` hex dump of packets
+
set log
~~~~~~~
--
2.43.0
next reply other threads:[~2024-03-12 22:01 UTC|newest]
Thread overview: 54+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-12 22:01 Stephen Hemminger [this message]
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 ` [PATCH v8 3/7] test: add test for " Stephen Hemminger
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
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=20240312220129.70667-1-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=aman.deep.singh@intel.com \
--cc=dev@dpdk.org \
--cc=orika@nvidia.com \
--cc=yuying.zhang@intel.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;
as well as URLs for NNTP newsgroup(s).