BPF is used quite intensively inside Linux (and BSD) kernels for various different purposes and proved to be extremely useful.
In theory, BPF inside DPDK might also be used in a lot of places for a lot of similar things. As an example to: - packet filtering/tracing (aka tcpdump) - packet classification - statistics collection - HW/PMD live-system debugging/prototyping - trace HW descriptors, internal PMD SW state, etc. ... All of that in a dynamic, user-defined and extensible manner. So these series introduce new library - librte_bpf. librte_bpf provides API to load and execute BPF bytecode within user-space dpdk app. It supported basic set of features from eBPF spec. Also it introduces basic framework to load/unload BPF-based filters on eth devices (right now via SW RX/TX callbacks). How to try it: =============== 1) run testpmd as usual and start your favorite forwarding case. 2) build bpf program you'd like to load (you'll need clang v3.7 or above): $ cd test/bpf $ clang -O2 -target bpf -c t1.c 3) load bpf program(s): testpmd> bpf-load rx|tx <portid> <queueid> <load-flags> <bpf-prog-filename> <load-flags>: [-][J][M] J - use JIT generated native code, otherwise BPF interpreter will be used. M - assume input parameter is a pointer to rte_mbuf, otherwise assume it is a pointer to first segment's data. Few examples: # to load (not JITed) dummy.o at TX queue 0, port 0: testpmd> bpf-load tx 0 0 - ./dpdk.org/test/bpf/dummy.o #to load (and JIT compile) t1.o at RX queue 0, port 1: testpmd> bpf-load rx 1 0 J ./dpdk.org/test/bpf/t1.o #to load and JIT t2.o (note that it expects mbuf as an input): testpmd> bpf-load rx 2 0 JM ./dpdk.org/test/bpf/t2.o 4) observe changed traffic behavior Let say with the examples above - dummy.o does literally nothing, so no changes should be here, except some possible slowdown - t1.o - should force to drop all packets that doesn.t' match: 'dst 1.2.3.4 && udp && dst port 5000' filter. 5) unload some or all bpf programs: testpmd> bpf-unload tx 0 0 6) continue with step 3) or exit TODO list: ========= - meson build - UT for it - implement proper validate() - allow JIT to generate bulk version Not currently supported features: ================================= - cBPF - tail-pointer call - eBPF MAP - skb Konstantin Ananyev (5): bpf: add BPF loading and execution framework bpf: add JIT compilation for x86_64 ISA. bpf: introduce basic RX/TX BPF filters testpmd: new commands to load/unload BPF filters test: add few eBPF samples app/test-pmd/cmdline.c | 144 +++++ config/common_base | 5 + config/common_linuxapp | 1 + lib/Makefile | 2 + lib/librte_bpf/Makefile | 35 ++ lib/librte_bpf/bpf.c | 52 ++ lib/librte_bpf/bpf_exec.c | 453 ++++++++++++++ lib/librte_bpf/bpf_impl.h | 37 ++ lib/librte_bpf/bpf_jit_x86.c | 1155 ++++++++++++++++++++++++++++++++++++ lib/librte_bpf/bpf_load.c | 344 +++++++++++ lib/librte_bpf/bpf_pkt.c | 524 ++++++++++++++++ lib/librte_bpf/bpf_validate.c | 55 ++ lib/librte_bpf/rte_bpf.h | 154 +++++ lib/librte_bpf/rte_bpf_ethdev.h | 50 ++ lib/librte_bpf/rte_bpf_version.map | 16 + mk/rte.app.mk | 2 + test/bpf/dummy.c | 20 + test/bpf/mbuf.h | 556 +++++++++++++++++ test/bpf/t1.c | 54 ++ test/bpf/t2.c | 31 + 20 files changed, 3690 insertions(+) create mode 100644 lib/librte_bpf/Makefile create mode 100644 lib/librte_bpf/bpf.c create mode 100644 lib/librte_bpf/bpf_exec.c create mode 100644 lib/librte_bpf/bpf_impl.h create mode 100644 lib/librte_bpf/bpf_jit_x86.c create mode 100644 lib/librte_bpf/bpf_load.c create mode 100644 lib/librte_bpf/bpf_pkt.c create mode 100644 lib/librte_bpf/bpf_validate.c create mode 100644 lib/librte_bpf/rte_bpf.h create mode 100644 lib/librte_bpf/rte_bpf_ethdev.h create mode 100644 lib/librte_bpf/rte_bpf_version.map create mode 100644 test/bpf/dummy.c create mode 100644 test/bpf/mbuf.h create mode 100644 test/bpf/t1.c create mode 100644 test/bpf/t2.c -- 2.13.6