From: Stephen Hemminger <stephen@networkplumber.org>
To: dev@dpdk.org
Cc: Stephen Hemminger <stephen@networkplumber.org>,
Reshma Pattan <reshma.pattan@intel.com>
Subject: [PATCH v2 1/4] pcapng: extend interface statistics
Date: Mon, 27 Jul 2026 15:42:44 -0700 [thread overview]
Message-ID: <20260727224417.1419663-2-stephen@networkplumber.org> (raw)
In-Reply-To: <20260727224417.1419663-1-stephen@networkplumber.org>
The number of packets filtered was not implemented in original
code but useful for analysis.
Modify the API for writing pcapng statistics.
Use a structure and make it extensible in future.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/dumpcap/main.c | 16 ++++-----
app/test/test_pcapng.c | 10 +++---
doc/guides/rel_notes/release_26_11.rst | 9 +++++
lib/pcapng/rte_pcapng.c | 50 +++++++++++++++++++-------
lib/pcapng/rte_pcapng.h | 33 ++++++++++++-----
5 files changed, 85 insertions(+), 33 deletions(-)
diff --git a/app/dumpcap/main.c b/app/dumpcap/main.c
index 46a6cb251e..baec68b0b9 100644
--- a/app/dumpcap/main.c
+++ b/app/dumpcap/main.c
@@ -574,8 +574,8 @@ static void
report_packet_stats(dumpcap_out_t out)
{
struct rte_pdump_stats pdump_stats;
+ struct rte_pcapng_interface_stats isb;
struct interface *intf;
- uint64_t ifrecv, ifdrop;
double percent;
fputc('\n', stderr);
@@ -584,22 +584,22 @@ report_packet_stats(dumpcap_out_t out)
continue;
/* do what Wiretap does */
- ifrecv = pdump_stats.accepted + pdump_stats.filtered;
- ifdrop = pdump_stats.nombuf + pdump_stats.ringfull;
+ isb.ifrecv = pdump_stats.accepted + pdump_stats.filtered;
+ isb.ifdrop = pdump_stats.nombuf + pdump_stats.ringfull;
+ isb.filteraccept = pdump_stats.accepted;
if (use_pcapng)
- rte_pcapng_write_stats(out.pcapng, intf->port,
- ifrecv, ifdrop, NULL);
+ rte_pcapng_write_stats(out.pcapng, intf->port, &isb, sizeof(isb), NULL);
- if (ifrecv == 0)
+ if (isb.ifrecv == 0)
percent = 0;
else
- percent = 100. * ifrecv / (ifrecv + ifdrop);
+ percent = 100. * isb.ifrecv / (isb.ifrecv + isb.ifdrop);
fprintf(stderr,
"Packets received/dropped on interface '%s': "
"%"PRIu64 "/%" PRIu64 " (%.1f)\n",
- intf->name, ifrecv, ifdrop, percent);
+ intf->name, isb.ifrecv, isb.ifdrop, percent);
}
}
diff --git a/app/test/test_pcapng.c b/app/test/test_pcapng.c
index d14ea84f0d..c62fdc1458 100644
--- a/app/test/test_pcapng.c
+++ b/app/test/test_pcapng.c
@@ -558,8 +558,9 @@ test_write_packets(void)
goto fail;
}
- /* write a statistics block */
- ret = rte_pcapng_write_stats(pcapng, port_id, 0, 0, NULL);
+ /* write an initial statistics block */
+ struct rte_pcapng_interface_stats isb = { };
+ ret = rte_pcapng_write_stats(pcapng, port_id, &isb, sizeof(isb), NULL);
if (ret <= 0) {
printf("Write of statistics failed\n");
goto fail;
@@ -569,9 +570,10 @@ test_write_packets(void)
if (count < 0)
goto fail;
- /* write a statistics block */
+ /* write a final statistics block with comment */
+ isb.ifrecv = count;
ret = rte_pcapng_write_stats(pcapng, port_id,
- count, 0, "end of test");
+ &isb, sizeof(isb), "end of test");
if (ret <= 0) {
printf("Write of statistics failed\n");
goto fail;
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index c8cc86295d..cdc3c99f64 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -93,6 +93,11 @@ API Changes
Also, make sure to start the actual text at the margin.
=======================================================
+* **pcapng: add packet filtering statistic.**
+
+ The API for ``rte_pcapng_write_stats`` was changed to include
+ recording the number of filtered packets.
+
ABI Changes
-----------
@@ -109,6 +114,10 @@ ABI Changes
Also, make sure to start the actual text at the margin.
=======================================================
+* **pcapng: add packet filtering statistic.**
+
+ The ABI for ``rte_pcapng_write_stats`` now takes pointer to statistics.
+
Known Issues
------------
diff --git a/lib/pcapng/rte_pcapng.c b/lib/pcapng/rte_pcapng.c
index b5d1026891..fed1581772 100644
--- a/lib/pcapng/rte_pcapng.c
+++ b/lib/pcapng/rte_pcapng.c
@@ -277,6 +277,9 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
uint64_t speed = 0;
int ret;
+ if (self == NULL)
+ return -EINVAL;
+
ret = rte_eth_dev_info_get(port, &dev_info);
if (ret < 0)
return -1; /* should be ret */
@@ -394,29 +397,43 @@ rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port, uint16_t link_type,
RTE_EXPORT_SYMBOL(rte_pcapng_write_stats)
ssize_t
rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
- uint64_t ifrecv, uint64_t ifdrop,
- const char *comment)
+ const struct rte_pcapng_interface_stats *stats,
+ size_t stats_sz, const char *comment)
{
+ struct rte_pcapng_interface_stats isb;
struct pcapng_statistics *hdr;
struct pcapng_option *opt;
- uint64_t start_time = self->clock.ns_base;
- uint64_t sample_time;
+ uint64_t start_time, sample_time;
uint32_t optlen, len;
uint32_t *buf;
ssize_t ret;
+ if (self == NULL)
+ return -EINVAL;
+
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -EINVAL);
+ if (stats == NULL || stats_sz == 0 || stats_sz > sizeof(*stats))
+ return -EINVAL;
+
if (comment && strlen(comment) > PCAPNG_STR_MAX)
return -EINVAL;
+ /* Future proof for more/less stats - all UINT64_MAX */
+ memset(&isb, 0xff, sizeof(isb));
+ memcpy(&isb, stats, stats_sz);
+
optlen = 0;
- if (ifrecv != UINT64_MAX)
- optlen += pcapng_optlen(sizeof(ifrecv));
- if (ifdrop != UINT64_MAX)
- optlen += pcapng_optlen(sizeof(ifdrop));
+ /* compute how many stats will be added. */
+ if (isb.ifrecv != UINT64_MAX)
+ optlen += pcapng_optlen(sizeof(isb.ifrecv));
+ if (isb.ifdrop != UINT64_MAX)
+ optlen += pcapng_optlen(sizeof(isb.ifdrop));
+ if (isb.filteraccept != UINT64_MAX)
+ optlen += pcapng_optlen(sizeof(isb.filteraccept));
+ start_time = self->clock.ns_base;
if (start_time != 0)
optlen += pcapng_optlen(sizeof(start_time));
@@ -439,12 +456,16 @@ rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port_id,
if (start_time != 0)
opt = pcapng_add_option(opt, PCAPNG_ISB_STARTTIME,
&start_time, sizeof(start_time));
- if (ifrecv != UINT64_MAX)
+ if (isb.ifrecv != UINT64_MAX)
opt = pcapng_add_option(opt, PCAPNG_ISB_IFRECV,
- &ifrecv, sizeof(ifrecv));
- if (ifdrop != UINT64_MAX)
+ &isb.ifrecv, sizeof(uint64_t));
+ if (isb.ifdrop != UINT64_MAX)
opt = pcapng_add_option(opt, PCAPNG_ISB_IFDROP,
- &ifdrop, sizeof(ifdrop));
+ &isb.ifdrop, sizeof(uint64_t));
+ if (isb.filteraccept != UINT64_MAX)
+ opt = pcapng_add_option(opt, PCAPNG_ISB_FILTERACCEPT,
+ &isb.filteraccept, sizeof(uint64_t));
+
if (optlen != 0)
opt = pcapng_add_option(opt, PCAPNG_OPT_END, NULL, 0);
@@ -717,6 +738,11 @@ rte_pcapng_write_packets(rte_pcapng_t *self,
unsigned int i, cnt = 0;
ssize_t ret, total = 0;
+ if (self == NULL) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
for (i = 0; i < nb_pkts; i++) {
struct rte_mbuf *m = pkts[i];
struct pcapng_enhance_packet_block *epb;
diff --git a/lib/pcapng/rte_pcapng.h b/lib/pcapng/rte_pcapng.h
index d8d328f710..495b6d3204 100644
--- a/lib/pcapng/rte_pcapng.h
+++ b/lib/pcapng/rte_pcapng.h
@@ -178,21 +178,36 @@ ssize_t
rte_pcapng_write_packets(rte_pcapng_t *self,
struct rte_mbuf *pkts[], uint16_t nb_pkts);
+/**
+ * A structure to store interface statistics in pcapng
+ * Interface statistics block.
+ * If the statistic is unavailable or unknown, use UINT64_MAX.
+ *
+ * Subset of definitions come from IETF pcapng standard.
+ * The osdrop and usrdeliv statistics are not included because
+ * DPDK does not use OS and does not deliver to application over sockets.
+ */
+struct rte_pcapng_interface_stats {
+ uint64_t ifrecv; /**< Packets received on interface during capture. */
+ uint64_t ifdrop; /**< Packets dropped by interface due to lack of resources. */
+ uint64_t filteraccept; /**< Packets accepted by filter. */
+};
+
/**
* Write an Interface statistics block.
- * For statistics, use 0 if don't know or care to report it.
* Should be called before closing capture to report results.
*
* @param self
* The handle to the packet capture file
* @param port
* The Ethernet port to report stats on.
- * @param ifrecv
- * The number of packets received by capture.
- * Optional: use UINT64_MAX if not known.
- * @param ifdrop
- * The number of packets missed by the capture process.
- * Optional: use UINT64_MAX if not known.
+ * @param stats
+ * The statistics to write.
+ * @param stats_sz
+ * The sizeof statistics structure.
+ * Must be greater than 0 and not more than sizeof(*stats).
+ * This allows for future expansion of interface statistics but
+ * with ABI compatibility.
* @param comment
* Optional comment to add to statistics.
* @return
@@ -203,8 +218,8 @@ rte_pcapng_write_packets(rte_pcapng_t *self,
*/
ssize_t
rte_pcapng_write_stats(rte_pcapng_t *self, uint16_t port,
- uint64_t ifrecv, uint64_t ifdrop,
- const char *comment);
+ const struct rte_pcapng_interface_stats *stats,
+ size_t stats_sz, const char *comment);
#ifdef __cplusplus
}
--
2.53.0
next prev parent reply other threads:[~2026-07-27 22:44 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-24 21:11 [PATCH v6 0/5] Wireshark external capture for DPDK Stephen Hemminger
2026-07-24 21:11 ` [PATCH 1/5] pcapng: extend interface statistics Stephen Hemminger
2026-07-24 21:11 ` [PATCH 2/5] capture: infrastructure wireshark packet capture Stephen Hemminger
2026-07-24 21:11 ` [PATCH 3/5] test: add test for capture hooks Stephen Hemminger
2026-07-24 21:11 ` [PATCH 4/5] usertools/dpdk-wireshark-extcap.py: script for external capture Stephen Hemminger
2026-07-24 21:11 ` [PATCH 5/5] usertools/dpdk-dumpcap: add script for file capture Stephen Hemminger
2026-07-27 22:42 ` [PATCH v2 0/4] Wireshark external capture interface Stephen Hemminger
2026-07-27 22:42 ` Stephen Hemminger [this message]
2026-07-27 22:42 ` [PATCH v2 2/4] capture: infrastructure wireshark packet capture Stephen Hemminger
2026-07-27 22:42 ` [PATCH v2 3/4] test: add test for capture hooks Stephen Hemminger
2026-07-27 22:42 ` [PATCH v2 4/4] usertools: add script for wireshark capture Stephen Hemminger
2026-07-29 23:28 ` 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=20260727224417.1419663-2-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=dev@dpdk.org \
--cc=reshma.pattan@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.