[PATCH v5 2/4] eal: add --no-capture option

Stephen Hemminger stephen at networkplumber.org
Sat Oct 17 00:30:32 CEST 2026


Not every deployment wants packet capture available. The capture library
registers its telemetry commands from a constructor, before EAL has parsed
arguments, so it cannot decline to register; add an EAL option and have the
library refuse at use instead.

Capture is reached over the telemetry socket, so --no-telemetry implies
--no-capture.

The option is per-process like --no-telemetry: a secondary started with it
refuses to attach callbacks, and the primary treats that refusal as a
configured choice rather than an error.

Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
---
 doc/guides/linux_gsg/eal_args.include.rst |  4 ++++
 doc/guides/prog_guide/capture_lib.rst     |  3 +++
 lib/capture/capture.c                     |  5 +++++
 lib/capture/multiproc.c                   | 11 ++++++++---
 lib/eal/common/eal_common_config.c        |  7 +++++++
 lib/eal/common/eal_common_options.c       |  3 +++
 lib/eal/common/eal_internal_cfg.h         |  1 +
 lib/eal/common/eal_option_list.h          |  1 +
 lib/eal/include/rte_eal.h                 |  9 +++++++++
 9 files changed, 41 insertions(+), 3 deletions(-)

diff --git a/doc/guides/linux_gsg/eal_args.include.rst b/doc/guides/linux_gsg/eal_args.include.rst
index 32c24c8e41..7925084c5c 100644
--- a/doc/guides/linux_gsg/eal_args.include.rst
+++ b/doc/guides/linux_gsg/eal_args.include.rst
@@ -293,6 +293,10 @@ Other options
 
     Disable telemetry.
 
+*   ``--no-capture``:
+
+    Disable packet capture. Implied by ``--no-telemetry``.
+
 *   ``--force-max-simd-bitwidth=<val>``:
 
     Specify the maximum SIMD bitwidth size to handle. This limits which vector paths,
diff --git a/doc/guides/prog_guide/capture_lib.rst b/doc/guides/prog_guide/capture_lib.rst
index 43823ffc87..bafa194fd4 100644
--- a/doc/guides/prog_guide/capture_lib.rst
+++ b/doc/guides/prog_guide/capture_lib.rst
@@ -67,6 +67,9 @@ Requirements
   commands if the call does not work at startup, so capture is simply
   unavailable rather than unsafe.
 
+* Capture can be refused at runtime with the ``--no-capture`` EAL option,
+  which is also implied by ``--no-telemetry``.
+
 Telemetry commands
 ------------------
 
diff --git a/lib/capture/capture.c b/lib/capture/capture.c
index 62b95c9de4..af5800017f 100644
--- a/lib/capture/capture.c
+++ b/lib/capture/capture.c
@@ -384,6 +384,11 @@ capture_start_req(const char *cmd, const char *params, struct rte_tel_data *d)
 		return -1;
 	}
 
+	if (!rte_eal_has_capture()) {
+		capture_err(d, "capture disabled by --no-capture");
+		return 0;
+	}
+
 	/* Note: params is const so need non-const copy for parsing
 	 * Alternative would be to change telemetry to allow this.
 	 */
diff --git a/lib/capture/multiproc.c b/lib/capture/multiproc.c
index ab29710210..9de9d8117e 100644
--- a/lib/capture/multiproc.c
+++ b/lib/capture/multiproc.c
@@ -70,6 +70,10 @@ capture_mp_attach(struct capture *cap)
 	struct rte_eth_dev_info dev_info;
 	uint16_t num_queues;
 
+	/* each process decides for itself */
+	if (!rte_eal_has_capture())
+		return -EPERM;
+
 	if (rte_eth_dev_info_get(cap->port_id, &dev_info) < 0)
 		return -EINVAL;
 
@@ -223,10 +227,11 @@ capture_mp_broadcast(struct capture *cap, enum capture_mp_op op)
 			= (const struct capture_mp_response *)mp_reply.msgs[i].param;
 
 		/*
-		 * A secondary that has no callbacks to detach replies ENOENT,
-		 * which happens whenever it was not polling this port.
+		 * ENOENT: nothing to detach, it was not polling this port.
+		 * EPERM: started with --no-capture, which is not an error.
 		 */
-		if (resp->err != 0 && resp->err != -ENOENT) {
+		if (resp->err != 0 && resp->err != -ENOENT &&
+		    resp->err != -EPERM) {
 			CAPTURE_LOG(ERR, "Secondary could not %s capture: %s",
 				    op == CAPTURE_MP_START ? "start" : "stop",
 				    rte_strerror(-resp->err));
diff --git a/lib/eal/common/eal_common_config.c b/lib/eal/common/eal_common_config.c
index e2e69a75fb..953a5f7ef8 100644
--- a/lib/eal/common/eal_common_config.c
+++ b/lib/eal/common/eal_common_config.c
@@ -109,3 +109,10 @@ rte_eal_has_pci(void)
 {
 	return !internal_config.no_pci;
 }
+
+RTE_EXPORT_SYMBOL(rte_eal_has_capture)
+int
+rte_eal_has_capture(void)
+{
+	return !internal_config.no_capture;
+}
diff --git a/lib/eal/common/eal_common_options.c b/lib/eal/common/eal_common_options.c
index b2c0744447..3c347e1a01 100644
--- a/lib/eal/common/eal_common_options.c
+++ b/lib/eal/common/eal_common_options.c
@@ -2350,6 +2350,9 @@ eal_parse_args(void)
 		int_cfg->no_shconf = 1;
 	if (args.no_telemetry)
 		int_cfg->no_telemetry = 1;
+	/* capture is reached over the telemetry socket, so it goes with it */
+	if (args.no_capture || args.no_telemetry)
+		int_cfg->no_capture = 1;
 	if (args.match_allocations)
 		int_cfg->match_allocations = 1;
 	if (args.create_uio_dev)
diff --git a/lib/eal/common/eal_internal_cfg.h b/lib/eal/common/eal_internal_cfg.h
index 07cd35167d..27e3a7990f 100644
--- a/lib/eal/common/eal_internal_cfg.h
+++ b/lib/eal/common/eal_internal_cfg.h
@@ -109,6 +109,7 @@ struct internal_config {
 	volatile unsigned int init_complete;
 	/**< indicates whether EAL has completed initialization */
 	unsigned int no_telemetry; /**< true to disable Telemetry */
+	unsigned int no_capture; /**< true to disable packet capture */
 	struct simd_bitwidth max_simd_bitwidth;
 	/**< max simd bitwidth path to use */
 	size_t huge_worker_stack_size; /**< worker thread stack size */
diff --git a/lib/eal/common/eal_option_list.h b/lib/eal/common/eal_option_list.h
index b72f243cc6..c8a1665d44 100644
--- a/lib/eal/common/eal_option_list.h
+++ b/lib/eal/common/eal_option_list.h
@@ -53,6 +53,7 @@ STR_ARG("--memory-channels", "-n", "Number of memory channels per socket", memor
 STR_ARG("--memory-ranks", "-r", "Force number of memory ranks (don't detect)", memory_ranks)
 STR_ARG("--memory-size", "-m", "Total size of memory to allocate initially", memory_size)
 BOOL_ARG("--no-auto-probing", "-A", "Do not probe any devices unless some -a option is set", no_auto_probing)
+BOOL_ARG("--no-capture", NULL, "Disable packet capture", no_capture)
 BOOL_ARG("--no-hpet", NULL, "Disable HPET timer", no_hpet)
 BOOL_ARG("--no-huge", NULL, "Disable hugetlbfs support", no_huge)
 BOOL_ARG("--no-pci", NULL, "Disable all PCI devices", no_pci)
diff --git a/lib/eal/include/rte_eal.h b/lib/eal/include/rte_eal.h
index 7241f3be5d..ded7be9196 100644
--- a/lib/eal/include/rte_eal.h
+++ b/lib/eal/include/rte_eal.h
@@ -392,6 +392,15 @@ int rte_eal_has_hugepages(void);
  */
 int rte_eal_has_pci(void);
 
+/**
+ * Whether packet capture is allowed.
+ * Disabled by the --no-capture and --no-telemetry options.
+ *
+ * @return
+ *   Nonzero if capture is enabled.
+ */
+int rte_eal_has_capture(void);
+
 /**
  * Whether the EAL was asked to create UIO device.
  *
-- 
2.53.0



More information about the dev mailing list