Introduce new functions to install an already loaded BPF program into RX
or TX port/queue, since previous API was tied to rte_bpf_prm.

Signed-off-by: Marat Khalili <[email protected]>
---
 lib/bpf/bpf_pkt.c        | 65 ++++++++++++++++++++++++++++++----------
 lib/bpf/rte_bpf_ethdev.h | 54 +++++++++++++++++++++++++++++++++
 2 files changed, 104 insertions(+), 15 deletions(-)

diff --git a/lib/bpf/bpf_pkt.c b/lib/bpf/bpf_pkt.c
index 5007f6aef57d..87065e939f31 100644
--- a/lib/bpf/bpf_pkt.c
+++ b/lib/bpf/bpf_pkt.c
@@ -490,13 +490,11 @@ rte_bpf_eth_tx_unload(uint16_t port, uint16_t queue)
 }
 
 static int
-bpf_eth_elf_load(struct bpf_eth_cbh *cbh, uint16_t port, uint16_t queue,
-       const struct rte_bpf_prm *prm, const char *fname, const char *sname,
-       uint32_t flags)
+bpf_eth_elf_install(struct bpf_eth_cbh *cbh, uint16_t port, uint16_t queue,
+       struct rte_bpf *bpf, uint32_t flags)
 {
        int32_t rc;
        struct bpf_eth_cbi *bc;
-       struct rte_bpf *bpf;
        rte_rx_callback_fn frx;
        rte_tx_callback_fn ftx;
        struct rte_bpf_jit jit;
@@ -504,14 +502,17 @@ bpf_eth_elf_load(struct bpf_eth_cbh *cbh, uint16_t port, 
uint16_t queue,
        frx = NULL;
        ftx = NULL;
 
-       if (prm == NULL || rte_eth_dev_is_valid_port(port) == 0 ||
+       if (bpf == NULL || rte_eth_dev_is_valid_port(port) == 0 ||
                        queue >= RTE_MAX_QUEUES_PER_PORT)
                return -EINVAL;
 
+       if (bpf->prm.nb_prog_arg != 1)
+               return -EINVAL;
+
        if (cbh->type == BPF_ETH_RX)
-               frx = select_rx_callback(prm->prog_arg.type, flags);
+               frx = select_rx_callback(bpf->prm.prog_arg[0].type, flags);
        else
-               ftx = select_tx_callback(prm->prog_arg.type, flags);
+               ftx = select_tx_callback(bpf->prm.prog_arg[0].type, flags);
 
        if (frx == NULL && ftx == NULL) {
                RTE_BPF_LOG_LINE(ERR, "%s(%u, %u): no callback selected;",
@@ -519,16 +520,11 @@ bpf_eth_elf_load(struct bpf_eth_cbh *cbh, uint16_t port, 
uint16_t queue,
                return -EINVAL;
        }
 
-       bpf = rte_bpf_elf_load(prm, fname, sname);
-       if (bpf == NULL)
-               return -rte_errno;
-
        rte_bpf_get_jit(bpf, &jit);
 
        if ((flags & RTE_BPF_ETH_F_JIT) != 0 && jit.func == NULL) {
                RTE_BPF_LOG_LINE(ERR, "%s(%u, %u): no JIT generated;",
                        __func__, port, queue);
-               rte_bpf_destroy(bpf);
                return -ENOTSUP;
        }
 
@@ -551,7 +547,6 @@ bpf_eth_elf_load(struct bpf_eth_cbh *cbh, uint16_t port, 
uint16_t queue,
 
        if (bc->cb == NULL) {
                rc = -rte_errno;
-               rte_bpf_destroy(bpf);
                bpf_eth_cbi_cleanup(bc);
        } else
                rc = 0;
@@ -564,13 +559,33 @@ int
 rte_bpf_eth_rx_elf_load(uint16_t port, uint16_t queue,
        const struct rte_bpf_prm *prm, const char *fname, const char *sname,
        uint32_t flags)
+{
+       struct rte_bpf *bpf;
+       int32_t rc;
+
+       bpf = rte_bpf_elf_load(prm, fname, sname);
+       if (bpf == NULL)
+               return -rte_errno;
+
+       rc = rte_bpf_eth_rx_install(port, queue, bpf, flags);
+
+       if (rc < 0)
+               rte_bpf_destroy(bpf);
+
+       return rc;
+}
+
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_bpf_eth_rx_install, 26.11)
+int
+rte_bpf_eth_rx_install(uint16_t port, uint16_t queue, struct rte_bpf *bpf,
+       uint32_t flags)
 {
        int32_t rc;
        struct bpf_eth_cbh *cbh;
 
        cbh = &rx_cbh;
        rte_spinlock_lock(&cbh->lock);
-       rc = bpf_eth_elf_load(cbh, port, queue, prm, fname, sname, flags);
+       rc = bpf_eth_elf_install(cbh, port, queue, bpf, flags);
        rte_spinlock_unlock(&cbh->lock);
 
        return rc;
@@ -581,13 +596,33 @@ int
 rte_bpf_eth_tx_elf_load(uint16_t port, uint16_t queue,
        const struct rte_bpf_prm *prm, const char *fname, const char *sname,
        uint32_t flags)
+{
+       struct rte_bpf *bpf;
+       int32_t rc;
+
+       bpf = rte_bpf_elf_load(prm, fname, sname);
+       if (bpf == NULL)
+               return -rte_errno;
+
+       rc = rte_bpf_eth_tx_install(port, queue, bpf, flags);
+
+       if (rc < 0)
+               rte_bpf_destroy(bpf);
+
+       return rc;
+}
+
+RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_bpf_eth_tx_install, 26.11)
+int
+rte_bpf_eth_tx_install(uint16_t port, uint16_t queue, struct rte_bpf *bpf,
+       uint32_t flags)
 {
        int32_t rc;
        struct bpf_eth_cbh *cbh;
 
        cbh = &tx_cbh;
        rte_spinlock_lock(&cbh->lock);
-       rc = bpf_eth_elf_load(cbh, port, queue, prm, fname, sname, flags);
+       rc = bpf_eth_elf_install(cbh, port, queue, bpf, flags);
        rte_spinlock_unlock(&cbh->lock);
 
        return rc;
diff --git a/lib/bpf/rte_bpf_ethdev.h b/lib/bpf/rte_bpf_ethdev.h
index cab8e9e3887a..e5eaf5b245e3 100644
--- a/lib/bpf/rte_bpf_ethdev.h
+++ b/lib/bpf/rte_bpf_ethdev.h
@@ -109,6 +109,60 @@ rte_bpf_eth_tx_elf_load(uint16_t port, uint16_t queue,
        const struct rte_bpf_prm *prm, const char *fname, const char *sname,
        uint32_t flags);
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: This API may change, or be removed, without prior notice.
+ *
+ * Install callback to execute specified BPF program on given TX port/queue.
+ *
+ * On success the ownership of the program passes to the library,
+ * rte_bpf_eth_unload must be used to unload it, and rte_bpf_destroy must no
+ * longer be called.
+ *
+ * @param port
+ *   The identifier of the ethernet port
+ * @param queue
+ *   The identifier of the TX queue on the given port
+ * @param bpf
+ *   BPF program
+ * @param flags
+ *   Flags that define expected behavior of the loaded filter
+ *   (i.e. jited/non-jited version to use).
+ * @return
+ *   Zero on successful completion or negative error code otherwise.
+ */
+__rte_experimental
+int
+rte_bpf_eth_rx_install(uint16_t port, uint16_t queue, struct rte_bpf *bpf,
+       uint32_t flags);
+
+/**
+ * @warning
+ * @b EXPERIMENTAL: This API may change, or be removed, without prior notice.
+ *
+ * Install callback to execute specified BPF program on given RX port/queue.
+ *
+ * On success the ownership of the program passes to the library,
+ * rte_bpf_eth_unload must be used to unload it, and rte_bpf_destroy must no
+ * longer be called.
+ *
+ * @param port
+ *   The identifier of the ethernet port
+ * @param queue
+ *   The identifier of the RX queue on the given port
+ * @param bpf
+ *   BPF program
+ * @param flags
+ *   Flags that define expected behavior of the loaded filter
+ *   (i.e. jited/non-jited version to use).
+ * @return
+ *   Zero on successful completion or negative error code otherwise.
+ */
+__rte_experimental
+int
+rte_bpf_eth_tx_install(uint16_t port, uint16_t queue, struct rte_bpf *bpf,
+       uint32_t flags);
+
 #ifdef __cplusplus
 }
 #endif
-- 
2.43.0

Reply via email to