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 <[email protected]>
---
 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

Reply via email to