From: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
To: dev@dpdk.org
Cc: Tyler Retzlaff <roretzla@microsoft.com>,
Mike Wells <mike.wells@telchemy.com>,
Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>,
Ferruh Yigit <ferruh.yigit@intel.com>
Subject: [dpdk-dev] [PATCH v2 4/6] net/pcap: add libpcap wrappers
Date: Sun, 14 Feb 2021 05:16:14 +0300 [thread overview]
Message-ID: <20210214021616.26970-5-dmitry.kozliuk@gmail.com> (raw)
In-Reply-To: <20210214021616.26970-1-dmitry.kozliuk@gmail.com>
libpcap headers can expose OS headers. On Windows, system networking
headers are incompatible with DPDK ones, causing multiple name clashes.
API of libpcap itself involves a non-standard u_char type.
Add a limited set of trivial libpcap wrappers, so that libpcap headers
are not included directly by OS-independent PMD code. Use EAL types and
functions for time instead of POSIX ones.
Signed-off-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
---
drivers/net/pcap/meson.build | 1 +
drivers/net/pcap/pcap_ethdev.c | 157 +++++++++++++++++----------------
drivers/net/pcap/pcap_osdep.c | 122 +++++++++++++++++++++++++
drivers/net/pcap/pcap_osdep.h | 50 +++++++++++
4 files changed, 252 insertions(+), 78 deletions(-)
create mode 100644 drivers/net/pcap/pcap_osdep.c
diff --git a/drivers/net/pcap/meson.build b/drivers/net/pcap/meson.build
index 26b606699..9ab95ec3e 100644
--- a/drivers/net/pcap/meson.build
+++ b/drivers/net/pcap/meson.build
@@ -13,6 +13,7 @@ if not dpdk_conf.has('RTE_PORT_PCAP')
endif
sources = files(
'pcap_ethdev.c',
+ 'pcap_osdep.c',
'pcap_osdep_@0@.c'.format(exec_env),
)
ext_deps += pcap_dep
diff --git a/drivers/net/pcap/pcap_ethdev.c b/drivers/net/pcap/pcap_ethdev.c
index a102897e9..6461213e0 100644
--- a/drivers/net/pcap/pcap_ethdev.c
+++ b/drivers/net/pcap/pcap_ethdev.c
@@ -4,17 +4,13 @@
* All rights reserved.
*/
-#include <time.h>
-
-#include <pcap.h>
-
-#include <rte_cycles.h>
#include <ethdev_driver.h>
#include <ethdev_vdev.h>
+#include <rte_bus_vdev.h>
+#include <rte_cycles.h>
#include <rte_kvargs.h>
#include <rte_malloc.h>
#include <rte_mbuf.h>
-#include <rte_bus_vdev.h>
#include "pcap_osdep.h"
@@ -36,8 +32,8 @@
#define RTE_PMD_PCAP_MAX_QUEUES 16
-static char errbuf[PCAP_ERRBUF_SIZE];
-static struct timeval start_time;
+static char errbuf[OSDEP_PCAP_ERRBUF_SIZE];
+static struct rte_time_us start_time;
static uint64_t start_cycles;
static uint64_t hz;
static uint8_t iface_idx;
@@ -83,16 +79,16 @@ struct pmd_internals {
};
struct pmd_process_private {
- pcap_t *rx_pcap[RTE_PMD_PCAP_MAX_QUEUES];
- pcap_t *tx_pcap[RTE_PMD_PCAP_MAX_QUEUES];
- pcap_dumper_t *tx_dumper[RTE_PMD_PCAP_MAX_QUEUES];
+ osdep_pcap * rx_pcap[RTE_PMD_PCAP_MAX_QUEUES];
+ osdep_pcap * tx_pcap[RTE_PMD_PCAP_MAX_QUEUES];
+ osdep_pcap_dumper * tx_dumper[RTE_PMD_PCAP_MAX_QUEUES];
};
struct pmd_devargs {
unsigned int num_of_queue;
struct devargs_queue {
- pcap_dumper_t *dumper;
- pcap_t *pcap;
+ osdep_pcap_dumper *dumper;
+ osdep_pcap *pcap;
const char *name;
const char *type;
} queue[RTE_PMD_PCAP_MAX_QUEUES];
@@ -137,7 +133,7 @@ RTE_LOG_REGISTER(eth_pcap_logtype, pmd.net.pcap, NOTICE);
static int
eth_pcap_rx_jumbo(struct rte_mempool *mb_pool, struct rte_mbuf *mbuf,
- const u_char *data, uint16_t data_len)
+ const uint8_t *data, uint16_t data_len)
{
/* Copy the first segment. */
uint16_t len = rte_pktmbuf_tailroom(mbuf);
@@ -214,14 +210,14 @@ static uint16_t
eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
{
unsigned int i;
- struct pcap_pkthdr header;
+ struct osdep_pcap_pkthdr header;
struct pmd_process_private *pp;
- const u_char *packet;
+ const uint8_t *packet;
struct rte_mbuf *mbuf;
struct pcap_rx_queue *pcap_q = queue;
uint16_t num_rx = 0;
uint32_t rx_bytes = 0;
- pcap_t *pcap;
+ osdep_pcap *pcap;
pp = rte_eth_devices[pcap_q->port_id].process_private;
pcap = pp->rx_pcap[pcap_q->queue_id];
@@ -234,7 +230,7 @@ eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
*/
for (i = 0; i < nb_pkts; i++) {
/* Get the next PCAP packet */
- packet = pcap_next(pcap, &header);
+ packet = osdep_pcap_next(pcap, &header);
if (unlikely(packet == NULL))
break;
@@ -261,8 +257,8 @@ eth_pcap_rx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
mbuf->pkt_len = (uint16_t)header.caplen;
*RTE_MBUF_DYNFIELD(mbuf, timestamp_dynfield_offset,
rte_mbuf_timestamp_t *) =
- (uint64_t)header.ts.tv_sec * 1000000 +
- header.ts.tv_usec;
+ (uint64_t)header.ts.sec * 1000000 +
+ header.ts.usec;
mbuf->ol_flags |= timestamp_rx_dynflag;
mbuf->port = pcap_q->port_id;
bufs[num_rx] = mbuf;
@@ -285,20 +281,24 @@ eth_null_rx(void *queue __rte_unused,
#define NSEC_PER_SEC 1000000000L
+/*
+ * This function stores nanoseconds in "usec" field of struct rte_time_us,
+ * because "ts" goes directly to nanosecond-precision dump.
+ */
static inline void
-calculate_timestamp(struct timeval *ts) {
+calculate_timestamp(struct rte_time_us *ts) {
uint64_t cycles;
- struct timeval cur_time;
+ struct rte_time_us cur_time;
cycles = rte_get_timer_cycles() - start_cycles;
- cur_time.tv_sec = cycles / hz;
- cur_time.tv_usec = (cycles % hz) * NSEC_PER_SEC / hz;
-
- ts->tv_sec = start_time.tv_sec + cur_time.tv_sec;
- ts->tv_usec = start_time.tv_usec + cur_time.tv_usec;
- if (ts->tv_usec >= NSEC_PER_SEC) {
- ts->tv_usec -= NSEC_PER_SEC;
- ts->tv_sec += 1;
+ cur_time.sec = cycles / hz;
+ cur_time.usec = (cycles % hz) * NSEC_PER_SEC / hz;
+
+ ts->sec = start_time.sec + cur_time.sec;
+ ts->usec = start_time.usec + cur_time.usec;
+ if (ts->usec >= NSEC_PER_SEC) {
+ ts->usec -= NSEC_PER_SEC;
+ ts->sec += 1;
}
}
@@ -314,8 +314,8 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
struct pcap_tx_queue *dumper_q = queue;
uint16_t num_tx = 0;
uint32_t tx_bytes = 0;
- struct pcap_pkthdr header;
- pcap_dumper_t *dumper;
+ struct osdep_pcap_pkthdr header;
+ osdep_pcap_dumper *dumper;
unsigned char temp_data[RTE_ETH_PCAP_SNAPLEN];
size_t len, caplen;
@@ -342,7 +342,7 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
* in the mbuf (when the mbuf is contiguous) or, otherwise,
* a pointer to temp_data after copying into it.
*/
- pcap_dump((u_char *)dumper, &header,
+ osdep_pcap_dump((uint8_t *)dumper, &header,
rte_pktmbuf_read(mbuf, 0, caplen, temp_data));
num_tx++;
@@ -355,7 +355,7 @@ eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
* process stops and to make sure the pcap file is actually written,
* we flush the pcap dumper within each burst.
*/
- pcap_dump_flush(dumper);
+ osdep_pcap_dump_flush(dumper);
dumper_q->tx_stat.pkts += num_tx;
dumper_q->tx_stat.bytes += tx_bytes;
dumper_q->tx_stat.err_pkts += nb_pkts - num_tx;
@@ -400,7 +400,7 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
struct pcap_tx_queue *tx_queue = queue;
uint16_t num_tx = 0;
uint32_t tx_bytes = 0;
- pcap_t *pcap;
+ osdep_pcap *pcap;
unsigned char temp_data[RTE_ETH_PCAP_SNAPLEN];
size_t len;
@@ -426,7 +426,7 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
* in the mbuf (when the mbuf is contiguous) or, otherwise,
* a pointer to temp_data after copying into it.
*/
- ret = pcap_sendpacket(pcap,
+ ret = osdep_pcap_sendpacket(pcap,
rte_pktmbuf_read(mbuf, 0, len, temp_data), len);
if (unlikely(ret != 0))
break;
@@ -443,11 +443,11 @@ eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
}
/*
- * pcap_open_live wrapper function
+ * osdep_pcap_open_live wrapper function
*/
static inline int
-open_iface_live(const char *iface, pcap_t **pcap) {
- *pcap = pcap_open_live(iface, RTE_ETH_PCAP_SNAPLEN,
+open_iface_live(const char *iface, osdep_pcap **pcap) {
+ *pcap = osdep_pcap_open_live(iface, RTE_ETH_PCAP_SNAPLEN,
RTE_ETH_PCAP_PROMISC, RTE_ETH_PCAP_TIMEOUT, errbuf);
if (*pcap == NULL) {
@@ -459,7 +459,7 @@ open_iface_live(const char *iface, pcap_t **pcap) {
}
static int
-open_single_iface(const char *iface, pcap_t **pcap)
+open_single_iface(const char *iface, osdep_pcap **pcap)
{
if (open_iface_live(iface, pcap) < 0) {
PMD_LOG(ERR, "Couldn't open interface %s", iface);
@@ -470,39 +470,39 @@ open_single_iface(const char *iface, pcap_t **pcap)
}
static int
-open_single_tx_pcap(const char *pcap_filename, pcap_dumper_t **dumper)
+open_single_tx_pcap(const char *pcap_filename, osdep_pcap_dumper **dumper)
{
- pcap_t *tx_pcap;
+ osdep_pcap *tx_pcap;
/*
- * We need to create a dummy empty pcap_t to use it
- * with pcap_dump_open(). We create big enough an Ethernet
+ * We need to create a dummy empty osdep_pcap to use it
+ * with osdep_pcap_dump_open(). We create big enough an Ethernet
* pcap holder.
*/
- tx_pcap = pcap_open_dead_with_tstamp_precision(DLT_EN10MB,
- RTE_ETH_PCAP_SNAPSHOT_LEN, PCAP_TSTAMP_PRECISION_NANO);
+ tx_pcap = osdep_pcap_open_dead_with_tstamp_precision(OSDEP_DLT_EN10MB,
+ RTE_ETH_PCAP_SNAPSHOT_LEN, OSDEP_PCAP_TSTAMP_PRECISION_NANO);
if (tx_pcap == NULL) {
PMD_LOG(ERR, "Couldn't create dead pcap");
return -1;
}
- /* The dumper is created using the previous pcap_t reference */
- *dumper = pcap_dump_open(tx_pcap, pcap_filename);
+ /* The dumper is created using the previous osdep_pcap reference */
+ *dumper = osdep_pcap_dump_open(tx_pcap, pcap_filename);
if (*dumper == NULL) {
- pcap_close(tx_pcap);
+ osdep_pcap_close(tx_pcap);
PMD_LOG(ERR, "Couldn't open %s for writing.",
pcap_filename);
return -1;
}
- pcap_close(tx_pcap);
+ osdep_pcap_close(tx_pcap);
return 0;
}
static int
-open_single_rx_pcap(const char *pcap_filename, pcap_t **pcap)
+open_single_rx_pcap(const char *pcap_filename, osdep_pcap **pcap)
{
- *pcap = pcap_open_offline(pcap_filename, errbuf);
+ *pcap = osdep_pcap_open_offline(pcap_filename, errbuf);
if (*pcap == NULL) {
PMD_LOG(ERR, "Couldn't open %s: %s", pcap_filename,
errbuf);
@@ -513,17 +513,17 @@ open_single_rx_pcap(const char *pcap_filename, pcap_t **pcap)
}
static uint64_t
-count_packets_in_pcap(pcap_t **pcap, struct pcap_rx_queue *pcap_q)
+count_packets_in_pcap(osdep_pcap **pcap, struct pcap_rx_queue *pcap_q)
{
- const u_char *packet;
- struct pcap_pkthdr header;
+ const uint8_t *packet;
+ struct osdep_pcap_pkthdr header;
uint64_t pcap_pkt_count = 0;
- while ((packet = pcap_next(*pcap, &header)))
+ while ((packet = osdep_pcap_next(*pcap, &header)))
pcap_pkt_count++;
/* The pcap is reopened so it can be used as normal later. */
- pcap_close(*pcap);
+ osdep_pcap_close(*pcap);
*pcap = NULL;
open_single_rx_pcap(pcap_q->name, pcap);
@@ -612,7 +612,7 @@ eth_dev_stop(struct rte_eth_dev *dev)
/* Special iface case. Single pcap is open and shared between tx/rx. */
if (internals->single_iface) {
- pcap_close(pp->tx_pcap[0]);
+ osdep_pcap_close(pp->tx_pcap[0]);
pp->tx_pcap[0] = NULL;
pp->rx_pcap[0] = NULL;
goto status_down;
@@ -620,19 +620,19 @@ eth_dev_stop(struct rte_eth_dev *dev)
for (i = 0; i < dev->data->nb_tx_queues; i++) {
if (pp->tx_dumper[i] != NULL) {
- pcap_dump_close(pp->tx_dumper[i]);
+ osdep_pcap_dump_close(pp->tx_dumper[i]);
pp->tx_dumper[i] = NULL;
}
if (pp->tx_pcap[i] != NULL) {
- pcap_close(pp->tx_pcap[i]);
+ osdep_pcap_close(pp->tx_pcap[i]);
pp->tx_pcap[i] = NULL;
}
}
for (i = 0; i < dev->data->nb_rx_queues; i++) {
if (pp->rx_pcap[i] != NULL) {
- pcap_close(pp->rx_pcap[i]);
+ osdep_pcap_close(pp->rx_pcap[i]);
pp->rx_pcap[i] = NULL;
}
}
@@ -804,11 +804,11 @@ eth_rx_queue_setup(struct rte_eth_dev *dev,
if (internals->infinite_rx) {
struct pmd_process_private *pp;
- char ring_name[NAME_MAX];
+ char ring_name[RTE_RING_NAMESIZE];
static uint32_t ring_number;
uint64_t pcap_pkt_count = 0;
struct rte_mbuf *bufs[1];
- pcap_t **pcap;
+ osdep_pcap **pcap;
pp = rte_eth_devices[pcap_q->port_id].process_private;
pcap = &pp->rx_pcap[pcap_q->queue_id];
@@ -932,7 +932,7 @@ static const struct eth_dev_ops ops = {
static int
add_queue(struct pmd_devargs *pmd, const char *name, const char *type,
- pcap_t *pcap, pcap_dumper_t *dumper)
+ osdep_pcap *pcap, osdep_pcap_dumper *dumper)
{
if (pmd->num_of_queue >= RTE_PMD_PCAP_MAX_QUEUES)
return -1;
@@ -955,13 +955,13 @@ open_rx_pcap(const char *key, const char *value, void *extra_args)
{
const char *pcap_filename = value;
struct pmd_devargs *rx = extra_args;
- pcap_t *pcap = NULL;
+ osdep_pcap *pcap = NULL;
if (open_single_rx_pcap(pcap_filename, &pcap) < 0)
return -1;
if (add_queue(rx, pcap_filename, key, pcap, NULL) < 0) {
- pcap_close(pcap);
+ osdep_pcap_close(pcap);
return -1;
}
@@ -977,13 +977,13 @@ open_tx_pcap(const char *key, const char *value, void *extra_args)
{
const char *pcap_filename = value;
struct pmd_devargs *dumpers = extra_args;
- pcap_dumper_t *dumper;
+ osdep_pcap_dumper *dumper;
if (open_single_tx_pcap(pcap_filename, &dumper) < 0)
return -1;
if (add_queue(dumpers, pcap_filename, key, NULL, dumper) < 0) {
- pcap_dump_close(dumper);
+ osdep_pcap_dump_close(dumper);
return -1;
}
@@ -998,7 +998,7 @@ open_rx_tx_iface(const char *key, const char *value, void *extra_args)
{
const char *iface = value;
struct pmd_devargs *tx = extra_args;
- pcap_t *pcap = NULL;
+ osdep_pcap *pcap = NULL;
if (open_single_iface(iface, &pcap) < 0)
return -1;
@@ -1011,13 +1011,14 @@ open_rx_tx_iface(const char *key, const char *value, void *extra_args)
}
static inline int
-set_iface_direction(const char *iface, pcap_t *pcap,
- pcap_direction_t direction)
+set_iface_direction(const char *iface, osdep_pcap *pcap,
+ enum osdep_pcap_direction direction)
{
- const char *direction_str = (direction == PCAP_D_IN) ? "IN" : "OUT";
- if (pcap_setdirection(pcap, direction) < 0) {
+ const char *direction_str =
+ (direction == OSDEP_PCAP_D_IN) ? "IN" : "OUT";
+ if (osdep_pcap_setdirection(pcap, direction) < 0) {
PMD_LOG(ERR, "Setting %s pcap direction %s failed - %s\n",
- iface, direction_str, pcap_geterr(pcap));
+ iface, direction_str, osdep_pcap_geterr(pcap));
return -1;
}
PMD_LOG(INFO, "Setting %s pcap direction %s\n",
@@ -1030,12 +1031,12 @@ open_iface(const char *key, const char *value, void *extra_args)
{
const char *iface = value;
struct pmd_devargs *pmd = extra_args;
- pcap_t *pcap = NULL;
+ osdep_pcap *pcap = NULL;
if (open_single_iface(iface, &pcap) < 0)
return -1;
if (add_queue(pmd, iface, key, pcap, NULL) < 0) {
- pcap_close(pcap);
+ osdep_pcap_close(pcap);
return -1;
}
@@ -1057,7 +1058,7 @@ open_rx_iface(const char *key, const char *value, void *extra_args)
set_iface_direction(pmd->queue[qid].name,
pmd->queue[qid].pcap,
- PCAP_D_IN);
+ OSDEP_PCAP_D_IN);
}
return 0;
@@ -1311,7 +1312,7 @@ pmd_pcap_probe(struct rte_vdev_device *dev)
name = rte_vdev_device_name(dev);
PMD_LOG(INFO, "Initializing pmd_pcap for %s", name);
- gettimeofday(&start_time, NULL);
+ rte_time_get_us(&start_time);
start_cycles = rte_get_timer_cycles();
hz = rte_get_timer_hz();
diff --git a/drivers/net/pcap/pcap_osdep.c b/drivers/net/pcap/pcap_osdep.c
new file mode 100644
index 000000000..5cac9bb89
--- /dev/null
+++ b/drivers/net/pcap/pcap_osdep.c
@@ -0,0 +1,122 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2021 Dmitry Kozlyuk
+ */
+
+#include <pcap.h>
+
+#include <rte_common.h>
+
+#include "pcap_osdep.h"
+
+static inline void
+to_osdep_header(const struct pcap_pkthdr *in, struct osdep_pcap_pkthdr *out)
+{
+ out->ts.sec = in->ts.tv_sec;
+ out->ts.usec = in->ts.tv_usec;
+ out->caplen = in->caplen;
+ out->len = in->len;
+}
+
+static inline void
+to_pcap_header(const struct osdep_pcap_pkthdr *in, struct pcap_pkthdr *out)
+{
+ out->ts.tv_sec = in->ts.sec;
+ out->ts.tv_usec = in->ts.usec;
+ out->caplen = in->caplen;
+ out->len = in->len;
+}
+
+osdep_pcap *
+osdep_pcap_open_live(const char *device, int snaplen,
+ int promisc, int to_ms, char *errbuf)
+{
+ RTE_BUILD_BUG_ON(OSDEP_PCAP_ERRBUF_SIZE != PCAP_ERRBUF_SIZE);
+
+ return (osdep_pcap *)pcap_open_live(device, snaplen, promisc, to_ms,
+ errbuf);
+}
+
+osdep_pcap *
+osdep_pcap_open_offline(const char *fname, char *errbuf)
+{
+ return (osdep_pcap *)pcap_open_offline(fname, errbuf);
+}
+
+osdep_pcap *
+osdep_pcap_open_dead_with_tstamp_precision(int linktype, int snaplen,
+ unsigned int precision)
+{
+ RTE_BUILD_BUG_ON(OSDEP_DLT_EN10MB != DLT_EN10MB);
+ RTE_BUILD_BUG_ON(OSDEP_PCAP_TSTAMP_PRECISION_NANO !=
+ PCAP_TSTAMP_PRECISION_NANO);
+
+ return (osdep_pcap *)pcap_open_dead_with_tstamp_precision(linktype,
+ snaplen, precision);
+}
+
+const uint8_t *
+osdep_pcap_next(osdep_pcap *pcap, struct osdep_pcap_pkthdr *header)
+{
+ const uint8_t *data;
+ struct pcap_pkthdr pkthdr;
+
+ data = pcap_next((pcap_t *)pcap, &pkthdr);
+ to_osdep_header(&pkthdr, header);
+ return data;
+}
+
+int
+osdep_pcap_sendpacket(osdep_pcap *pcap, const uint8_t *buf, int size)
+{
+ return pcap_sendpacket((pcap_t *)pcap, buf, size);
+}
+
+void
+osdep_pcap_close(osdep_pcap *pcap)
+{
+ pcap_close((pcap_t *)pcap);
+}
+
+osdep_pcap_dumper *
+osdep_pcap_dump_open(osdep_pcap *pcap, const char *fname)
+{
+ return (osdep_pcap_dumper *)pcap_dump_open((pcap_t *)pcap, fname);
+}
+
+void
+osdep_pcap_dump(uint8_t *user, const struct osdep_pcap_pkthdr *header,
+ const uint8_t *sp)
+{
+ struct pcap_pkthdr pkthdr;
+
+ to_pcap_header(header, &pkthdr);
+ pcap_dump(user, &pkthdr, sp);
+}
+
+int
+osdep_pcap_dump_flush(osdep_pcap_dumper *p)
+{
+ return pcap_dump_flush((pcap_dumper_t *)p);
+}
+
+void
+osdep_pcap_dump_close(osdep_pcap_dumper *p)
+{
+ pcap_dump_close((pcap_dumper_t *)p);
+}
+
+int
+osdep_pcap_setdirection(osdep_pcap *pcap, enum osdep_pcap_direction dir)
+{
+ RTE_BUILD_BUG_ON((int)OSDEP_PCAP_D_INOUT != (int)PCAP_D_INOUT);
+ RTE_BUILD_BUG_ON((int)OSDEP_PCAP_D_IN != (int)PCAP_D_IN);
+ RTE_BUILD_BUG_ON((int)OSDEP_PCAP_D_OUT != (int)PCAP_D_OUT);
+
+ return pcap_setdirection((pcap_t *)pcap, (pcap_direction_t)dir);
+}
+
+const char *
+osdep_pcap_geterr(osdep_pcap *pcap)
+{
+ return pcap_geterr((pcap_t *)pcap);
+}
diff --git a/drivers/net/pcap/pcap_osdep.h b/drivers/net/pcap/pcap_osdep.h
index 46810d86f..bd00b728a 100644
--- a/drivers/net/pcap/pcap_osdep.h
+++ b/drivers/net/pcap/pcap_osdep.h
@@ -6,6 +6,7 @@
#define _RTE_PCAP_OSDEP_
#include <rte_ether.h>
+#include <rte_time.h>
/*
* Interface manipulation is always OS-specific.
@@ -14,4 +15,53 @@
int osdep_iface_index_get(const char *name);
int osdep_iface_mac_get(const char *name, struct rte_ether_addr *mac);
+/*
+ * On Windows, libpcap (npcap or WinPcap) exposes Win32 API which clashes
+ * with some DPDK constructs. Trivial libpcap wrappers with "osdep_" prefix
+ * are provided to isolate PMD code from Win32 API.
+ */
+
+#define OSDEP_DLT_EN10MB 1
+
+#define OSDEP_PCAP_ERRBUF_SIZE 256
+
+#define OSDEP_PCAP_TSTAMP_PRECISION_NANO 1
+
+/** Handle for an open packet capture. */
+typedef struct osdep_pcap_type osdep_pcap;
+
+/** Handle for an open packet dump. */
+typedef struct osdep_pcap_dumper_type osdep_pcap_dumper;
+
+struct osdep_pcap_pkthdr {
+ struct rte_time_us ts;
+ uint32_t caplen;
+ uint32_t len;
+};
+
+enum osdep_pcap_direction {
+ OSDEP_PCAP_D_INOUT = 0,
+ OSDEP_PCAP_D_IN,
+ OSDEP_PCAP_D_OUT
+};
+
+osdep_pcap *osdep_pcap_open_live(const char *device, int snaplen,
+ int promisc, int to_ms, char *errbuf);
+osdep_pcap *osdep_pcap_open_offline(const char *fname, char *errbuf);
+osdep_pcap *osdep_pcap_open_dead_with_tstamp_precision(int linktype,
+ int snaplen, unsigned int precision);
+const uint8_t *osdep_pcap_next(osdep_pcap *pcap,
+ struct osdep_pcap_pkthdr *header);
+int osdep_pcap_sendpacket(osdep_pcap *pcap, const uint8_t *buf, int size);
+void osdep_pcap_close(osdep_pcap *pcap);
+
+osdep_pcap_dumper *osdep_pcap_dump_open(osdep_pcap *pcap, const char *fname);
+void osdep_pcap_dump(uint8_t *user, const struct osdep_pcap_pkthdr *header,
+ const uint8_t *sp);
+int osdep_pcap_dump_flush(osdep_pcap_dumper *p);
+void osdep_pcap_dump_close(osdep_pcap_dumper *p);
+
+int osdep_pcap_setdirection(osdep_pcap *pcap, enum osdep_pcap_direction dir);
+const char *osdep_pcap_geterr(osdep_pcap *pcap);
+
#endif
--
2.29.2
next prev parent reply other threads:[~2021-02-14 2:17 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-02-14 1:20 [dpdk-dev] [PATCH 0/6] net/pcap: build on Windows Dmitry Kozlyuk
2021-02-14 1:20 ` [dpdk-dev] [PATCH 1/6] eal: add internal API for current time Dmitry Kozlyuk
2021-03-01 22:31 ` Nick Connolly
2021-03-01 22:36 ` Nick Connolly
2021-02-14 1:20 ` [dpdk-dev] [PATCH 2/6] net/pcap: fix format string Dmitry Kozlyuk
2021-03-01 22:33 ` Nick Connolly
2021-02-14 1:20 ` [dpdk-dev] [PATCH 3/6] net/pcap: move OS-dependent code to separate files Dmitry Kozlyuk
2021-02-14 1:20 ` [dpdk-dev] [PATCH 4/6] net/pcap: add libpcap wrappers Dmitry Kozlyuk
2021-02-14 1:20 ` [dpdk-dev] [PATCH 5/6] config: discover libpcap on Windows Dmitry Kozlyuk
2021-02-14 1:20 ` [dpdk-dev] [PATCH 6/6] net/pcap: build " Dmitry Kozlyuk
2021-02-14 2:16 ` [dpdk-dev] [PATCH v2 0/6] " Dmitry Kozlyuk
2021-02-14 2:16 ` [dpdk-dev] [PATCH v2 1/6] eal: add internal API for current time Dmitry Kozlyuk
2021-03-01 22:39 ` Nick Connolly
2021-03-05 17:50 ` Jie Zhou
2021-03-16 9:18 ` Thomas Monjalon
2021-03-16 18:59 ` Stephen Hemminger
2021-03-16 20:07 ` Dmitry Kozlyuk
2021-03-17 9:50 ` Morten Brørup
2021-02-14 2:16 ` [dpdk-dev] [PATCH v2 2/6] net/pcap: fix format string Dmitry Kozlyuk
2021-02-25 14:45 ` Ferruh Yigit
2021-03-02 11:48 ` [dpdk-dev] [dpdk-stable] " Ferruh Yigit
2021-02-14 2:16 ` [dpdk-dev] [PATCH v2 3/6] net/pcap: move OS-dependent code to separate files Dmitry Kozlyuk
2021-02-25 14:51 ` Ferruh Yigit
2021-02-25 16:05 ` Dmitry Kozlyuk
2021-02-14 2:16 ` Dmitry Kozlyuk [this message]
2021-02-25 14:59 ` [dpdk-dev] [PATCH v2 4/6] net/pcap: add libpcap wrappers Ferruh Yigit
2021-02-25 19:04 ` Dmitry Kozlyuk
2021-02-25 20:31 ` Nick Connolly
2021-02-25 23:10 ` Dmitry Kozlyuk
2021-03-01 21:43 ` Nick Connolly
2021-03-01 23:05 ` Dmitry Kozlyuk
2021-03-01 23:23 ` Dmitry Kozlyuk
2021-03-02 11:22 ` Nick Connolly
2021-03-03 16:32 ` Dmitry Kozlyuk
2021-03-03 16:47 ` Ferruh Yigit
2021-03-03 18:19 ` Dmitry Kozlyuk
2021-03-03 19:30 ` Ferruh Yigit
2021-03-03 23:03 ` Dmitry Kozlyuk
2021-02-14 2:16 ` [dpdk-dev] [PATCH v2 5/6] config: discover libpcap on Windows Dmitry Kozlyuk
2021-02-25 15:02 ` Ferruh Yigit
2021-02-25 16:04 ` Dmitry Kozlyuk
2021-02-25 16:33 ` Bruce Richardson
2021-02-25 17:42 ` Dmitry Kozlyuk
2021-03-16 9:16 ` Thomas Monjalon
2021-03-16 9:37 ` Dmitry Kozlyuk
2021-02-14 2:16 ` [dpdk-dev] [PATCH v2 6/6] net/pcap: build " Dmitry Kozlyuk
2021-03-24 0:50 ` [dpdk-dev] [PATCH v3 0/3] " Dmitry Kozlyuk
2021-03-24 0:50 ` [dpdk-dev] [PATCH v3 1/3] eal/windows: add timespec_get shim for MinGW Dmitry Kozlyuk
2021-03-24 0:50 ` [dpdk-dev] [PATCH v3 2/3] net/pcap: move OS-dependent code to separate files Dmitry Kozlyuk
2021-03-24 0:50 ` [dpdk-dev] [PATCH v3 3/3] net/pcap: build on Windows Dmitry Kozlyuk
2021-04-09 10:51 ` [dpdk-dev] [PATCH v3 0/3] " Ferruh Yigit
2021-04-09 11:03 ` Dmitry Kozlyuk
2021-04-09 11:24 ` Ferruh Yigit
2021-04-15 22:10 ` [dpdk-dev] [PATCH v4 " Dmitry Kozlyuk
2021-04-15 22:10 ` [dpdk-dev] [PATCH v4 1/3] eal/windows: add timespec_get shim for MinGW Dmitry Kozlyuk
2021-04-15 22:10 ` [dpdk-dev] [PATCH v4 2/3] net/pcap: move OS-dependent code to separate files Dmitry Kozlyuk
2021-04-15 22:10 ` [dpdk-dev] [PATCH v4 3/3] net/pcap: build on Windows Dmitry Kozlyuk
2021-04-19 21:05 ` Tyler Retzlaff
2021-04-16 17:22 ` [dpdk-dev] [PATCH v4 0/3] " Ferruh Yigit
2021-04-20 22:20 ` Thomas Monjalon
2021-04-21 14:53 ` Dmitry Kozlyuk
2021-04-21 18:12 ` Thomas Monjalon
2021-04-21 19:33 ` [dpdk-dev] [PATCH v5 " Dmitry Kozlyuk
2021-04-21 19:33 ` [dpdk-dev] [PATCH v5 1/3] eal: add timespec_get shim Dmitry Kozlyuk
2021-04-21 19:33 ` [dpdk-dev] [PATCH v5 2/3] net/pcap: move OS-dependent code to separate files Dmitry Kozlyuk
2021-04-21 19:33 ` [dpdk-dev] [PATCH v5 3/3] net/pcap: build on Windows Dmitry Kozlyuk
2021-04-21 21:54 ` [dpdk-dev] [PATCH v5 0/3] " 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=20210214021616.26970-5-dmitry.kozliuk@gmail.com \
--to=dmitry.kozliuk@gmail.com \
--cc=dev@dpdk.org \
--cc=ferruh.yigit@intel.com \
--cc=mike.wells@telchemy.com \
--cc=roretzla@microsoft.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).