From: Marat Khalili <marat.khalili@huawei.com>
To: Konstantin Ananyev <konstantin.ananyev@huawei.com>
Cc: <dev@dpdk.org>
Subject: [PATCH 04/10] bpf: add cBPF origin to rte_bpf_load_ex
Date: Wed, 6 May 2026 18:22:01 +0100 [thread overview]
Message-ID: <20260506172209.6805-5-marat.khalili@huawei.com> (raw)
In-Reply-To: <20260506172209.6805-1-marat.khalili@huawei.com>
Add cBPF origin to rte_bpf_load_ex to allow loading PCAP filters and
other cBPF code through the unified interface.
Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
lib/bpf/bpf_convert.c | 79 +++++++++++++++++++++++++++++++++++++++++--
lib/bpf/bpf_impl.h | 11 ++++++
lib/bpf/bpf_load.c | 12 ++++++-
lib/bpf/bpf_stub.c | 27 ---------------
lib/bpf/meson.build | 11 +++---
lib/bpf/rte_bpf.h | 8 ++++-
6 files changed, 111 insertions(+), 37 deletions(-)
delete mode 100644 lib/bpf/bpf_stub.c
diff --git a/lib/bpf/bpf_convert.c b/lib/bpf/bpf_convert.c
index 953ca80670c4..c997116c691f 100644
--- a/lib/bpf/bpf_convert.c
+++ b/lib/bpf/bpf_convert.c
@@ -9,6 +9,12 @@
* Copyright (c) 2011 - 2014 PLUMgrid, http://plumgrid.com
*/
+#include "bpf_impl.h"
+#include <eal_export.h>
+#include <rte_errno.h>
+
+#ifdef RTE_HAS_LIBPCAP
+
#include <assert.h>
#include <errno.h>
#include <stdbool.h>
@@ -17,17 +23,14 @@
#include <stdlib.h>
#include <string.h>
-#include <eal_export.h>
#include <rte_common.h>
#include <rte_bpf.h>
#include <rte_log.h>
#include <rte_malloc.h>
-#include <rte_errno.h>
#include <pcap/pcap.h>
#include <pcap/bpf.h>
-#include "bpf_impl.h"
#include "bpf_def.h"
#ifndef BPF_MAXINSNS
@@ -572,3 +575,73 @@ rte_bpf_convert(const struct bpf_program *prog)
return prm;
}
+
+void
+__rte_bpf_convert_cleanup(struct __rte_bpf_load *load)
+{
+ free(load->ins);
+}
+
+int __rte_bpf_convert(struct __rte_bpf_load *load)
+{
+ struct rte_bpf_prm_ex *const prm = &load->prm;
+ uint32_t nb_ins = 0;
+ int ret;
+
+ RTE_ASSERT(prm->origin == RTE_BPF_ORIGIN_CBPF);
+
+ if (prm->cbpf.ins == NULL || prm->cbpf.nb_ins == 0)
+ return -EINVAL;
+
+ /* 1st pass: calculate the eBPF program length */
+ ret = bpf_convert_filter(prm->cbpf.ins, prm->cbpf.nb_ins, NULL, &nb_ins);
+ if (ret < 0) {
+ RTE_BPF_LOG_FUNC_LINE(ERR, "cannot get eBPF length");
+ return ret;
+ }
+
+ RTE_ASSERT(load->ins == NULL);
+ load->ins = malloc(nb_ins * sizeof(load->ins[0]));
+ if (load->ins == NULL)
+ return -ENOMEM;
+
+ /* 2nd pass: remap cBPF to eBPF instructions */
+ ret = bpf_convert_filter(prm->cbpf.ins, prm->cbpf.nb_ins, load->ins, &nb_ins);
+ if (ret < 0) {
+ RTE_BPF_LOG_FUNC_LINE(ERR, "cannot convert cBPF to eBPF");
+ return ret;
+ }
+
+ prm->origin = RTE_BPF_ORIGIN_RAW;
+ prm->raw.ins = load->ins;
+ prm->raw.nb_ins = nb_ins;
+
+ return 0;
+}
+
+#else /* RTE_HAS_LIBPCAP */
+
+RTE_EXPORT_SYMBOL(rte_bpf_convert)
+struct rte_bpf_prm *
+rte_bpf_convert(const struct bpf_program *prog)
+{
+ RTE_SET_USED(prog);
+ RTE_BPF_LOG_FUNC_LINE(ERR, "not supported, rebuild with libpcap installed");
+ rte_errno = ENOTSUP;
+ return NULL;
+}
+
+void
+__rte_bpf_convert_cleanup(struct __rte_bpf_load *load)
+{
+ RTE_ASSERT(load->ins == NULL);
+}
+
+int __rte_bpf_convert(struct __rte_bpf_load *load)
+{
+ RTE_SET_USED(load);
+ RTE_BPF_LOG_FUNC_LINE(ERR, "not supported, rebuild with libpcap installed");
+ return -ENOTSUP;
+}
+
+#endif /* RTE_HAS_LIBPCAP */
diff --git a/lib/bpf/bpf_impl.h b/lib/bpf/bpf_impl.h
index 4a98b3373067..92d03583d977 100644
--- a/lib/bpf/bpf_impl.h
+++ b/lib/bpf/bpf_impl.h
@@ -21,6 +21,9 @@ struct rte_bpf {
struct __rte_bpf_load {
struct rte_bpf_prm_ex prm;
+ /* Conversion from cBPF. */
+ struct ebpf_insn *ins;
+
/* Loading ELF and applying relocations. */
int elf_fd; /* ELF fd, must be negative (not zero) by default. */
void *elf; /* Using void to avoid dependency on libelf. */
@@ -34,6 +37,14 @@ struct __rte_bpf_load {
* to avoid potential name conflict with other libraries.
*/
+/* Free temporary resources created by converting from cBPF to eBPF. */
+void
+__rte_bpf_convert_cleanup(struct __rte_bpf_load *load);
+
+/* Convert program from cBPF to eBPF. */
+int
+__rte_bpf_convert(struct __rte_bpf_load *load);
+
/* Free temporary resources created by opening ELF. */
void
__rte_bpf_load_elf_cleanup(struct __rte_bpf_load *load);
diff --git a/lib/bpf/bpf_load.c b/lib/bpf/bpf_load.c
index c9cbaf6ded7e..c3c49ac49b1b 100644
--- a/lib/bpf/bpf_load.c
+++ b/lib/bpf/bpf_load.c
@@ -230,6 +230,9 @@ load_try(struct __rte_bpf_load *load, const struct rte_bpf_prm_ex *app_prm)
switch (load->prm.origin) {
case RTE_BPF_ORIGIN_RAW:
break;
+ case RTE_BPF_ORIGIN_CBPF:
+ rc = rc < 0 ? rc : __rte_bpf_convert(load);
+ break;
case RTE_BPF_ORIGIN_ELF_FILE:
rc = rc < 0 ? rc : __rte_bpf_load_elf_file(load);
rc = rc < 0 ? rc : __rte_bpf_load_elf_code(load);
@@ -244,6 +247,13 @@ load_try(struct __rte_bpf_load *load, const struct rte_bpf_prm_ex *app_prm)
return rc;
}
+static void
+load_cleanup(struct __rte_bpf_load *load)
+{
+ __rte_bpf_convert_cleanup(load);
+ __rte_bpf_load_elf_cleanup(load);
+}
+
RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_bpf_load_ex, 26.11)
struct rte_bpf *
rte_bpf_load_ex(const struct rte_bpf_prm_ex *prm)
@@ -252,7 +262,7 @@ rte_bpf_load_ex(const struct rte_bpf_prm_ex *prm)
const int rc = load_try(&load, prm);
- __rte_bpf_load_elf_cleanup(&load);
+ load_cleanup(&load);
RTE_ASSERT((rc < 0) == (load.bpf == NULL));
diff --git a/lib/bpf/bpf_stub.c b/lib/bpf/bpf_stub.c
deleted file mode 100644
index 4c329832c264..000000000000
--- a/lib/bpf/bpf_stub.c
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018-2021 Intel Corporation
- */
-
-#include "bpf_impl.h"
-#include <eal_export.h>
-#include <rte_errno.h>
-
-/**
- * Contains stubs for unimplemented public API functions
- */
-
-#ifndef RTE_HAS_LIBPCAP
-RTE_EXPORT_SYMBOL(rte_bpf_convert)
-struct rte_bpf_prm *
-rte_bpf_convert(const struct bpf_program *prog)
-{
- if (prog == NULL) {
- rte_errno = EINVAL;
- return NULL;
- }
-
- RTE_BPF_LOG_FUNC_LINE(ERR, "not supported, rebuild with libpcap installed");
- rte_errno = ENOTSUP;
- return NULL;
-}
-#endif
diff --git a/lib/bpf/meson.build b/lib/bpf/meson.build
index 4901b6ee1463..7e8a300e3f87 100644
--- a/lib/bpf/meson.build
+++ b/lib/bpf/meson.build
@@ -15,14 +15,16 @@ if arch_subdir == 'x86' and dpdk_conf.get('RTE_ARCH_32')
subdir_done()
endif
-sources = files('bpf.c',
+sources = files(
+ 'bpf.c',
+ 'bpf_convert.c',
'bpf_dump.c',
'bpf_exec.c',
'bpf_load.c',
'bpf_load_elf.c',
'bpf_pkt.c',
- 'bpf_stub.c',
- 'bpf_validate.c')
+ 'bpf_validate.c',
+)
if arch_subdir == 'x86' and dpdk_conf.get('RTE_ARCH_64')
sources += files('bpf_jit_x86.c')
@@ -45,8 +47,7 @@ else
endif
if dpdk_conf.has('RTE_HAS_LIBPCAP')
- sources += files('bpf_convert.c')
ext_deps += pcap_dep
else
- warning('libpcap is missing, rte_bpf_convert API will be disabled')
+ warning('libpcap is missing, cBPF API will be disabled')
endif
diff --git a/lib/bpf/rte_bpf.h b/lib/bpf/rte_bpf.h
index 751b879bb7fd..dcb709352e17 100644
--- a/lib/bpf/rte_bpf.h
+++ b/lib/bpf/rte_bpf.h
@@ -95,10 +95,12 @@ struct rte_bpf_xsym {
*/
enum rte_bpf_origin {
RTE_BPF_ORIGIN_RAW, /**< code loaded from raw array */
- RTE_BPF_ORIGIN_RESERVED, /**< reserved for cBPF */
+ RTE_BPF_ORIGIN_CBPF, /**< code converted from cbpf */
RTE_BPF_ORIGIN_ELF_FILE, /**< code loaded from elf_file */
};
+struct bpf_insn;
+
/**
* Input parameters for loading eBPF code, extensible version.
*
@@ -117,6 +119,10 @@ struct rte_bpf_prm_ex {
const struct ebpf_insn *ins; /**< eBPF instructions */
uint32_t nb_ins; /**< number of instructions in ins */
} raw;
+ struct {
+ const struct bpf_insn *ins; /**< cBPF instructions */
+ uint32_t nb_ins; /**< number of instructions in ins */
+ } cbpf;
struct {
const char *path; /**< path to the ELF file */
const char *section; /**< ELF section with the code */
--
2.43.0
next prev parent reply other threads:[~2026-05-06 17:23 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-06 17:21 [PATCH 00/10] bpf: introduce extensible load API Marat Khalili
2026-05-06 17:21 ` [PATCH 01/10] bpf: make logging prefixes more consistent Marat Khalili
2026-05-06 17:21 ` [PATCH 02/10] bpf: introduce extensible load API Marat Khalili
2026-05-06 17:22 ` [PATCH 03/10] bpf: support up to 5 arguments Marat Khalili
2026-05-06 17:22 ` Marat Khalili [this message]
2026-05-06 17:22 ` [PATCH 05/10] bpf: support rte_bpf_prm_ex with port callbacks Marat Khalili
2026-05-06 17:22 ` [PATCH 06/10] bpf: support loading ELF files from memory Marat Khalili
2026-05-06 17:22 ` [PATCH 07/10] test/bpf: test loading cBPF directly Marat Khalili
2026-05-06 17:22 ` [PATCH 08/10] test/bpf: test loading ELF file from memory Marat Khalili
2026-05-06 17:22 ` [PATCH 09/10] doc: add release notes for new extensible BPF API Marat Khalili
2026-05-06 17:22 ` [PATCH 10/10] doc: add load API to BPF programmer's guide Marat Khalili
2026-05-09 12:36 ` [PATCH 00/10] bpf: introduce extensible load API Konstantin Ananyev
2026-05-14 9:37 ` [PATCH v2 " Marat Khalili
2026-05-14 9:37 ` [PATCH v2 01/10] bpf: make logging prefixes more consistent Marat Khalili
2026-05-14 9:37 ` [PATCH v2 02/10] bpf: introduce extensible load API Marat Khalili
2026-05-14 9:37 ` [PATCH v2 03/10] bpf: support up to 5 arguments Marat Khalili
2026-05-14 9:37 ` [PATCH v2 04/10] bpf: add cBPF origin to rte_bpf_load_ex Marat Khalili
2026-05-14 9:37 ` [PATCH v2 05/10] bpf: support rte_bpf_prm_ex with port callbacks Marat Khalili
2026-05-14 9:37 ` [PATCH v2 06/10] bpf: support loading ELF files from memory Marat Khalili
2026-05-14 9:37 ` [PATCH v2 07/10] test/bpf: test loading cBPF directly Marat Khalili
2026-05-14 9:37 ` [PATCH v2 08/10] test/bpf: test loading ELF file from memory Marat Khalili
2026-05-14 9:37 ` [PATCH v2 09/10] doc: add release notes for new extensible BPF API Marat Khalili
2026-05-14 9:37 ` [PATCH v2 10/10] doc: add load API to BPF programmer's guide Marat Khalili
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260506172209.6805-5-marat.khalili@huawei.com \
--to=marat.khalili@huawei.com \
--cc=dev@dpdk.org \
--cc=konstantin.ananyev@huawei.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox