net/pcap: add snaplen argument

Message ID 20220313092659.219452-1-laitianli@tom.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series net/pcap: add snaplen argument |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation warning apply issues
ci/iol-testing warning apply patch failure

Commit Message

Tianli Lai March 13, 2022, 9:26 a.m. UTC
  snaplen argument would set the length of each packet
that will save to pcap file.

Signed-off-by: Tianli Lai <laitianli@tom.com>
---
 doc/guides/nics/pcap_ring.rst  | 16 ++++++-
 drivers/net/pcap/pcap_ethdev.c | 79 ++++++++++++++++------------------
 2 files changed, 52 insertions(+), 43 deletions(-)
  

Patch

diff --git a/doc/guides/nics/pcap_ring.rst b/doc/guides/nics/pcap_ring.rst
index acb1f00e30..8fb309212f 100644
--- a/doc/guides/nics/pcap_ring.rst
+++ b/doc/guides/nics/pcap_ring.rst
@@ -94,6 +94,13 @@  The different stream types are:
 
         iface=eth0
 
+*   snaplen: Defines the length of one packet that will save pcap file.
+    the length of each packets can be snap by set this value.
+    this value between 64 and 65535.
+
+        snaplen=<packet len>
+
+
 Runtime Config Options
 ^^^^^^^^^^^^^^^^^^^^^^
 
@@ -132,6 +139,13 @@  Runtime Config Options
 
 In this case, one dummy rx queue is created for each tx queue argument passed
 
+ - Receive packets on Tx and set the length of packet, for example::
+
+    --vdev 'net_pcap0,tx_pcap=file_tx.pcap,snaplen=100'
+
+In this case, one dummy rx queue is created for each tx queue argument passed and the length of each packet would not over 100 byte.
+
+
 Examples of Usage
 ^^^^^^^^^^^^^^^^^
 
@@ -140,7 +154,7 @@  Read packets from one pcap file and write them to another:
 .. code-block:: console
 
     ./<build_dir>/app/dpdk-testpmd -l 0-3 -n 4 \
-        --vdev 'net_pcap0,rx_pcap=file_rx.pcap,tx_pcap=file_tx.pcap' \
+        --vdev 'net_pcap0,rx_pcap=file_rx.pcap,tx_pcap=file_tx.pcap,snaplen=100' \
         -- --port-topology=chained
 
 Read packets from a network interface and write them to a pcap file:
diff --git a/drivers/net/pcap/pcap_ethdev.c b/drivers/net/pcap/pcap_ethdev.c
index 8aea6d66ee..6e111518e7 100644
--- a/drivers/net/pcap/pcap_ethdev.c
+++ b/drivers/net/pcap/pcap_ethdev.c
@@ -95,13 +95,13 @@  struct pmd_internals {
 	int single_iface;
 	int phy_mac;
 	unsigned int infinite_rx;
+	int snaplen;
 };
 
 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];
-	int snaplen;
 };
 
 struct pmd_devargs {
@@ -113,7 +113,6 @@  struct pmd_devargs {
 		const char *type;
 	} queue[RTE_PMD_PCAP_MAX_QUEUES];
 	int phy_mac;
-	int snaplen;
 };
 
 struct pmd_devargs_all {
@@ -125,6 +124,14 @@  struct pmd_devargs_all {
 	unsigned int is_rx_pcap;
 	unsigned int is_rx_iface;
 	unsigned int infinite_rx;
+	int snaplen;
+};
+struct pmd_devargs_all devargs_all = {
+	.single_iface = 0,
+	.is_tx_pcap = 0,
+	.is_tx_iface = 0,
+	.infinite_rx = 0,
+	.snaplen = RTE_ETH_PCAP_SNAPSHOT_LEN,
 };
 
 static const char *valid_arguments[] = {
@@ -389,8 +396,10 @@  eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 	pcap_dumper_t *dumper;
 	unsigned char temp_data[RTE_ETH_PCAP_SNAPLEN];
 	size_t len, caplen;
-
-	pp = rte_eth_devices[dumper_q->port_id].process_private;
+	struct pmd_internals *internals;
+	struct rte_eth_dev *dev = &rte_eth_devices[dumper_q->port_id];
+	internals = dev->data->dev_private;
+	pp = dev->process_private;
 	dumper = pp->tx_dumper[dumper_q->queue_id];
 
 	if (dumper == NULL || nb_pkts == 0)
@@ -407,14 +416,10 @@  eth_pcap_tx_dumper(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
 		}
 
 		calculate_timestamp(&header.ts);
+		if ((typeof(internals->snaplen))caplen > internals->snaplen)
+			caplen = internals->snaplen;
 		header.len = len;
 		header.caplen = caplen;
-		if (pp->snaplen >= RTE_PCAP_MIN_SNAPLEN) {
-			if ((typeof(pp->snaplen))header.caplen > pp->snaplen) {
-				header.caplen = pp->snaplen;
-				caplen = pp->snaplen;
-			}
-		}
 		/* rte_pktmbuf_read() returns a pointer to the data directly
 		 * in the mbuf (when the mbuf is contiguous) or, otherwise,
 		 * a pointer to temp_data after copying into it.
@@ -523,11 +528,8 @@  eth_pcap_tx(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
  * pcap_open_live wrapper function
  */
 static inline int
-open_iface_live(const char *iface, pcap_t **pcap, int snaplen) {
-	int caplen = RTE_ETH_PCAP_SNAPLEN;
-	if (snaplen >= RTE_PCAP_MIN_SNAPLEN)
-		caplen = snaplen;
-	*pcap = pcap_open_live(iface, caplen,
+open_iface_live(const char *iface, pcap_t **pcap) {
+	*pcap = pcap_open_live(iface, RTE_ETH_PCAP_SNAPLEN,
 			RTE_ETH_PCAP_PROMISC, RTE_ETH_PCAP_TIMEOUT, errbuf);
 
 	if (*pcap == NULL) {
@@ -539,9 +541,9 @@  open_iface_live(const char *iface, pcap_t **pcap, int snaplen) {
 }
 
 static int
-open_single_iface(const char *iface, pcap_t **pcap, int snaplen)
+open_single_iface(const char *iface, pcap_t **pcap)
 {
-	if (open_iface_live(iface, pcap, snaplen) < 0) {
+	if (open_iface_live(iface, pcap) < 0) {
 		PMD_LOG(ERR, "Couldn't open interface %s", iface);
 		return -1;
 	}
@@ -553,16 +555,14 @@  static int
 open_single_tx_pcap(const char *pcap_filename, pcap_dumper_t **dumper, int snaplen)
 {
 	pcap_t *tx_pcap;
-	int caplen = RTE_ETH_PCAP_SNAPSHOT_LEN;
-	if (snaplen >= RTE_PCAP_MIN_SNAPLEN)
-		caplen = snaplen;
+
 	/*
 	 * We need to create a dummy empty pcap_t to use it
 	 * with pcap_dump_open(). We create big enough an Ethernet
 	 * pcap holder.
 	 */
 	tx_pcap = pcap_open_dead_with_tstamp_precision(DLT_EN10MB,
-			caplen, PCAP_TSTAMP_PRECISION_NANO);
+			snaplen, PCAP_TSTAMP_PRECISION_NANO);
 	if (tx_pcap == NULL) {
 		PMD_LOG(ERR, "Couldn't create dead pcap");
 		return -1;
@@ -628,7 +628,7 @@  eth_dev_start(struct rte_eth_dev *dev)
 
 		if (!pp->tx_pcap[0] &&
 			strcmp(tx->type, ETH_PCAP_IFACE_ARG) == 0) {
-			if (open_single_iface(tx->name, &pp->tx_pcap[0], pp->snaplen) < 0)
+			if (open_single_iface(tx->name, &pp->tx_pcap[0]) < 0)
 				return -1;
 			pp->rx_pcap[0] = pp->tx_pcap[0];
 		}
@@ -643,11 +643,11 @@  eth_dev_start(struct rte_eth_dev *dev)
 		if (!pp->tx_dumper[i] &&
 				strcmp(tx->type, ETH_PCAP_TX_PCAP_ARG) == 0) {
 			if (open_single_tx_pcap(tx->name,
-				&pp->tx_dumper[i], pp->snaplen) < 0)
+				&pp->tx_dumper[i], internals->snaplen) < 0)
 				return -1;
 		} else if (!pp->tx_pcap[i] &&
 				strcmp(tx->type, ETH_PCAP_TX_IFACE_ARG) == 0) {
-			if (open_single_iface(tx->name, &pp->tx_pcap[i], pp->snaplen) < 0)
+			if (open_single_iface(tx->name, &pp->tx_pcap[i]) < 0)
 				return -1;
 		}
 	}
@@ -663,7 +663,7 @@  eth_dev_start(struct rte_eth_dev *dev)
 			if (open_single_rx_pcap(rx->name, &pp->rx_pcap[i]) < 0)
 				return -1;
 		} else if (strcmp(rx->type, ETH_PCAP_RX_IFACE_ARG) == 0) {
-			if (open_single_iface(rx->name, &pp->rx_pcap[i], pp->snaplen) < 0)
+			if (open_single_iface(rx->name, &pp->rx_pcap[i]) < 0)
 				return -1;
 		}
 	}
@@ -1071,7 +1071,7 @@  open_tx_pcap(const char *key, const char *value, void *extra_args)
 	struct pmd_devargs *dumpers = extra_args;
 	pcap_dumper_t *dumper;
 
-	if (open_single_tx_pcap(pcap_filename, &dumper, dumpers->snaplen) < 0)
+	if (open_single_tx_pcap(pcap_filename, &dumper, devargs_all.snaplen) < 0)
 		return -1;
 
 	if (add_queue(dumpers, pcap_filename, key, NULL, dumper) < 0) {
@@ -1083,9 +1083,8 @@  open_tx_pcap(const char *key, const char *value, void *extra_args)
 }
 
 static int
-parse_uint_value(const char *key, const char *value, void *extra_args)
+parse_uint_value(const char *key __rte_unused, const char *value, void *extra_args)
 {
-	(void)key;
 	char *end;
 	int *val = extra_args;
 	*val = strtoul(value, &end, 10);
@@ -1102,7 +1101,7 @@  open_rx_tx_iface(const char *key, const char *value, void *extra_args)
 	struct pmd_devargs *tx = extra_args;
 	pcap_t *pcap = NULL;
 
-	if (open_single_iface(iface, &pcap, tx->snaplen) < 0)
+	if (open_single_iface(iface, &pcap) < 0)
 		return -1;
 
 	tx->queue[0].pcap = pcap;
@@ -1134,7 +1133,7 @@  open_iface(const char *key, const char *value, void *extra_args)
 	struct pmd_devargs *pmd = extra_args;
 	pcap_t *pcap = NULL;
 
-	if (open_single_iface(iface, &pcap, pmd->snaplen) < 0)
+	if (open_single_iface(iface, &pcap) < 0)
 		return -1;
 	if (add_queue(pmd, iface, key, pcap, NULL) < 0) {
 		pcap_close(pcap);
@@ -1351,10 +1350,10 @@  eth_from_pcaps(struct rte_vdev_device *vdev,
 	int ret;
 
 	ret = eth_from_pcaps_common(vdev, devargs_all, &internals, &eth_dev);
-
 	if (ret < 0)
 		return ret;
 
+	internals->snaplen = devargs_all->snaplen;
 	/* store weather we are using a single interface for rx/tx or not */
 	internals->single_iface = single_iface;
 
@@ -1429,14 +1428,6 @@  pmd_pcap_probe(struct rte_vdev_device *dev)
 	struct rte_eth_dev *eth_dev =  NULL;
 	struct pmd_internals *internal;
 	int ret = 0;
-	int snaplen = 0;
-
-	struct pmd_devargs_all devargs_all = {
-		.single_iface = 0,
-		.is_tx_pcap = 0,
-		.is_tx_iface = 0,
-		.infinite_rx = 0,
-	};
 
 	name = rte_vdev_device_name(dev);
 	PMD_LOG(INFO, "Initializing pmd_pcap for %s", name);
@@ -1473,8 +1464,12 @@  pmd_pcap_probe(struct rte_vdev_device *dev)
 
 	if (rte_kvargs_count(kvlist, ETH_PCAP_SNAPLEN_ARG) == 1) {
 		ret = rte_kvargs_process(kvlist, ETH_PCAP_SNAPLEN_ARG,
-				&parse_uint_value, &snaplen);
-		dumpers.snaplen = snaplen;
+				&parse_uint_value, &devargs_all.snaplen);
+		if (ret < 0)
+			goto free_kvlist;
+		if (devargs_all.snaplen < RTE_PCAP_MIN_SNAPLEN ||
+			devargs_all.snaplen >= RTE_ETH_PCAP_SNAPSHOT_LEN)
+			devargs_all.snaplen = RTE_PCAP_MIN_SNAPLEN;
 	}
 
 	/*
@@ -1626,7 +1621,7 @@  pmd_pcap_probe(struct rte_vdev_device *dev)
 			pp->tx_dumper[i] = dumpers.queue[i].dumper;
 			pp->tx_pcap[i] = dumpers.queue[i].pcap;
 		}
-		pp->snaplen = snaplen;
+		internal->snaplen = devargs_all.snaplen;
 		eth_dev->process_private = pp;
 		eth_dev->rx_pkt_burst = eth_pcap_rx;
 		if (devargs_all.is_tx_pcap)