From: Stephen Hemminger <stephen@networkplumber.org>
To: Ben Magistro <koncept1@gmail.com>
Cc: dev@dpdk.org, Stephen Hemminger <stephen@networkplumber.org>
Subject: [PATCH v2 5/6] pcapng: require per-interface information
Date: Tue, 3 Jan 2023 19:38:14 -0800 [thread overview]
Message-ID: <20230104033815.35496-6-stephen@networkplumber.org> (raw)
In-Reply-To: <20230104033815.35496-1-stephen@networkplumber.org>
This changes the API for how pcapng is used.
Before each interface was automatically added to the capture
file. Now the application must add each interface.
Note: API changes are allowed because this is an experimental
interface.
This allows application to specify extra meta data like
interface name, description and packet filter.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
app/test/test_pcapng.c | 7 ++++
lib/pcapng/rte_pcapng.c | 79 ++++++++++++++++++++++++++---------------
lib/pcapng/rte_pcapng.h | 25 +++++++++++++
lib/pcapng/version.map | 1 +
4 files changed, 84 insertions(+), 28 deletions(-)
diff --git a/app/test/test_pcapng.c b/app/test/test_pcapng.c
index a7acbdc0586d..edba46d1fe0f 100644
--- a/app/test/test_pcapng.c
+++ b/app/test/test_pcapng.c
@@ -109,6 +109,13 @@ test_setup(void)
return -1;
}
+ /* Add interface to the file */
+ if (rte_pcapng_add_interface(pcapng, port_id,
+ NULL, NULL, NULL) != 0) {
+ fprintf(stderr, "can not add port %u\n", port_id);
+ return -1;
+ }
+
/* Make a pool for cloned packets */
mp = rte_pktmbuf_pool_create_by_ops("pcapng_test_pool", IOV_MAX + NUM_PACKETS,
0, 0,
diff --git a/lib/pcapng/rte_pcapng.c b/lib/pcapng/rte_pcapng.c
index 80d08e1a3bde..ea004939e63e 100644
--- a/lib/pcapng/rte_pcapng.c
+++ b/lib/pcapng/rte_pcapng.c
@@ -32,6 +32,9 @@
/* Format of the capture file handle */
struct rte_pcapng {
int outfd; /* output file */
+
+ unsigned int ports; /* number of interfaces added */
+
/* DPDK port id to interface index in file */
uint32_t port_index[RTE_MAX_ETHPORTS];
};
@@ -185,8 +188,10 @@ pcapng_section_block(rte_pcapng_t *self,
}
/* Write an interface block for a DPDK port */
-static int
-pcapng_add_interface(rte_pcapng_t *self, uint16_t port)
+int
+rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port,
+ const char *ifname, const char *ifdescr,
+ const char *filter)
{
struct pcapng_interface_block *hdr;
struct rte_eth_dev_info dev_info;
@@ -197,7 +202,7 @@ pcapng_add_interface(rte_pcapng_t *self, uint16_t port)
const uint8_t tsresol = 9; /* nanosecond resolution */
uint32_t len;
void *buf;
- char ifname[IF_NAMESIZE];
+ char ifname_buf[IF_NAMESIZE];
char ifhw[256];
uint64_t speed = 0;
@@ -205,8 +210,14 @@ pcapng_add_interface(rte_pcapng_t *self, uint16_t port)
return -1;
/* make something like an interface name */
- if (if_indextoname(dev_info.if_index, ifname) == NULL)
- snprintf(ifname, IF_NAMESIZE, "dpdk:%u", port);
+ if (ifname == NULL) {
+ /* Use kernel name if available */
+ ifname = if_indextoname(dev_info.if_index, ifname_buf);
+ if (ifname == NULL) {
+ snprintf(ifname_buf, IF_NAMESIZE, "dpdk:%u", port);
+ ifname = ifname_buf;
+ }
+ }
/* make a useful device hardware string */
dev = dev_info.device;
@@ -230,10 +241,14 @@ pcapng_add_interface(rte_pcapng_t *self, uint16_t port)
len += pcapng_optlen(sizeof(tsresol)); /* timestamp */
len += pcapng_optlen(strlen(ifname)); /* ifname */
+ if (ifdescr)
+ len += pcapng_optlen(strlen(ifdescr));
if (ea)
len += pcapng_optlen(RTE_ETHER_ADDR_LEN); /* macaddr */
if (speed != 0)
len += pcapng_optlen(sizeof(uint64_t));
+ if (filter)
+ len += pcapng_optlen(strlen(filter) + 1);
if (dev)
len += pcapng_optlen(strlen(ifhw));
@@ -256,6 +271,9 @@ pcapng_add_interface(rte_pcapng_t *self, uint16_t port)
&tsresol, sizeof(tsresol));
opt = pcapng_add_option(opt, PCAPNG_IFB_NAME,
ifname, strlen(ifname));
+ if (ifdescr)
+ opt = pcapng_add_option(opt, PCAPNG_IFB_DESCRIPTION,
+ ifdescr, strlen(ifdescr));
if (ea)
opt = pcapng_add_option(opt, PCAPNG_IFB_MACADDR,
ea, RTE_ETHER_ADDR_LEN);
@@ -265,31 +283,29 @@ pcapng_add_interface(rte_pcapng_t *self, uint16_t port)
if (dev)
opt = pcapng_add_option(opt, PCAPNG_IFB_HARDWARE,
ifhw, strlen(ifhw));
+ if (filter) {
+ /* Encoding is that the first octet indicates string vs BPF */
+ size_t len;
+ char *buf;
+
+ len = strlen(filter) + 1;
+ buf = alloca(len);
+ *buf = '\0';
+ memcpy(buf + 1, filter, len);
+
+ opt = pcapng_add_option(opt, PCAPNG_IFB_FILTER,
+ buf, len);
+ }
+
opt = pcapng_add_option(opt, PCAPNG_OPT_END, NULL, 0);
/* clone block_length after optionsa */
memcpy(opt, &hdr->block_length, sizeof(uint32_t));
- return write(self->outfd, buf, len);
-}
-
-/*
- * Write the list of possible interfaces at the start
- * of the file.
- */
-static int
-pcapng_interfaces(rte_pcapng_t *self)
-{
- uint16_t port_id;
- uint16_t index = 0;
+ /* remember the file index */
+ self->port_index[port] = self->ports++;
- RTE_ETH_FOREACH_DEV(port_id) {
- /* The list if ports in pcapng needs to be contiguous */
- self->port_index[port_id] = index++;
- if (pcapng_add_interface(self, port_id) < 0)
- return -1;
- }
- return 0;
+ return write(self->outfd, buf, len);
}
/*
@@ -598,6 +614,13 @@ rte_pcapng_write_packets(rte_pcapng_t *self,
return -1;
}
+ /* check that this interface was added. */
+ epb->interface_id = self->port_index[m->port];
+ if (unlikely(epb->interface_id > RTE_MAX_ETHPORTS)) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
/*
* Handle case of highly fragmented and large burst size
* Note: this assumes that max segments per mbuf < IOV_MAX
@@ -616,7 +639,6 @@ rte_pcapng_write_packets(rte_pcapng_t *self,
* The DPDK port is recorded during pcapng_copy.
* Map that to PCAPNG interface in file.
*/
- epb->interface_id = self->port_index[m->port];
do {
iov[cnt].iov_base = rte_pktmbuf_mtod(m, void *);
iov[cnt].iov_len = rte_pktmbuf_data_len(m);
@@ -638,6 +660,7 @@ rte_pcapng_fdopen(int fd,
const char *osname, const char *hardware,
const char *appname, const char *comment)
{
+ unsigned int i;
rte_pcapng_t *self;
self = malloc(sizeof(*self));
@@ -647,13 +670,13 @@ rte_pcapng_fdopen(int fd,
}
self->outfd = fd;
+ self->ports = 0;
+ for (i = 0; i < RTE_MAX_ETHPORTS; i++)
+ self->port_index[i] = UINT32_MAX;
if (pcapng_section_block(self, osname, hardware, appname, comment) < 0)
goto fail;
- if (pcapng_interfaces(self) < 0)
- goto fail;
-
return self;
fail:
free(self);
diff --git a/lib/pcapng/rte_pcapng.h b/lib/pcapng/rte_pcapng.h
index 7d2697c647ef..86b7996e291e 100644
--- a/lib/pcapng/rte_pcapng.h
+++ b/lib/pcapng/rte_pcapng.h
@@ -70,6 +70,31 @@ __rte_experimental
void
rte_pcapng_close(rte_pcapng_t *self);
+/**
+ * Add interface information to the capture file
+ *
+ * @param self
+ * The handle to the packet capture file
+ * @param port
+ * The Ethernet port to report stats on.
+ * @param ifname (optional)
+ * Interface name to record in the file.
+ * If not specified, name will be constructed from port
+ * @param ifdescr (optional)
+ * Interface description to record in the file.
+ * @param filter
+ * Capture filter to record in the file.
+ *
+ * Interfaces must be added to the output file after opening
+ * and before any packet record. All ports used in packet capture
+ * must be added.
+ */
+__rte_experimental
+int
+rte_pcapng_add_interface(rte_pcapng_t *self, uint16_t port,
+ const char *ifname, const char *ifdescr,
+ const char *filter);
+
/**
* Direction flag
* These should match Enhanced Packet Block flag bits
diff --git a/lib/pcapng/version.map b/lib/pcapng/version.map
index 05a9c86a7d91..e98e71038ee6 100644
--- a/lib/pcapng/version.map
+++ b/lib/pcapng/version.map
@@ -7,6 +7,7 @@ EXPERIMENTAL {
rte_pcapng_mbuf_size;
rte_pcapng_write_packets;
rte_pcapng_write_stats;
+ rte_pcapng_add_interface;
local: *;
};
--
2.39.0
next prev parent reply other threads:[~2023-01-04 3:38 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-01-02 16:24 [PATCH 1/6] app/dumpcap: add additional dump info Ben Magistro
2023-01-02 16:24 ` [PATCH 2/6] app/dumpcap: fix storing port identifier Ben Magistro
2023-01-02 16:58 ` Stephen Hemminger
2023-01-04 3:04 ` Stephen Hemminger
2023-01-02 16:24 ` [PATCH 3/6] app/dumpcap: fix preserving promiscuous mode Ben Magistro
2023-01-02 16:58 ` Stephen Hemminger
2023-01-04 3:04 ` Stephen Hemminger
2023-01-02 16:24 ` [PATCH 4/6] app/dumpcap: fix capturing on multiple interfaces Ben Magistro
2023-01-04 3:01 ` Stephen Hemminger
2023-01-02 16:24 ` [PATCH 5/6] app/dumpcap: improve per interface arg parsing Ben Magistro
2023-01-04 3:04 ` Stephen Hemminger
2023-01-02 16:24 ` [PATCH 6/6] app/dumpcap: refactor add all and default Ben Magistro
2023-01-02 16:57 ` [PATCH 1/6] app/dumpcap: add additional dump info Stephen Hemminger
2023-01-02 17:01 ` [RFT] dumpcap: fix multiple interface and promiscious handling Stephen Hemminger
2023-01-04 2:58 ` [PATCH 1/6] app/dumpcap: add additional dump info Stephen Hemminger
2023-01-04 3:38 ` [PATCH v2 0/6] dumpcap support multiple interfaces Stephen Hemminger
2023-01-04 3:38 ` [PATCH v2 1/6] app/dumpcap: fix storing port identifier Stephen Hemminger
2023-01-04 3:38 ` [PATCH v2 2/6] app/dumpcap: remove unused variable Stephen Hemminger
2023-01-04 3:38 ` [PATCH v2 3/6] app/dumpcap: check for invalid interface name Stephen Hemminger
2023-01-04 3:38 ` [PATCH v2 4/6] app/dumpcap: support multiple interfaces Stephen Hemminger
2023-01-04 3:38 ` Stephen Hemminger [this message]
2023-01-04 3:38 ` [PATCH v2 6/6] app/dumpcap: support interface name and description Stephen Hemminger
2023-02-06 11:18 ` [PATCH v2 0/6] dumpcap support multiple interfaces Thomas Monjalon
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=20230104033815.35496-6-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=dev@dpdk.org \
--cc=koncept1@gmail.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).