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

