From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga04.intel.com (mga04.intel.com [192.55.52.120]) by dpdk.org (Postfix) with ESMTP id 89BF14C7C for ; Fri, 30 Mar 2018 19:32:59 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga104.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 30 Mar 2018 10:32:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.48,382,1517904000"; d="scan'208";a="46664494" Received: from sivswdev02.ir.intel.com (HELO localhost.localdomain) ([10.237.217.46]) by orsmga002.jf.intel.com with ESMTP; 30 Mar 2018 10:32:56 -0700 From: Konstantin Ananyev To: dev@dpdk.org Cc: Konstantin Ananyev Date: Fri, 30 Mar 2018 18:32:36 +0100 Message-Id: <1522431163-25621-1-git-send-email-konstantin.ananyev@intel.com> X-Mailer: git-send-email 1.7.0.7 In-Reply-To: <1520613725-9176-1-git-send-email-konstantin.ananyev@intel.com> References: <1520613725-9176-1-git-send-email-konstantin.ananyev@intel.com> Subject: [dpdk-dev] [PATCH v2 0/7] add framework to load and execute BPF code X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 30 Mar 2018 17:33:01 -0000 BPF is used quite intensively inside Linux (and BSD) kernels for various different purposes and proved to be extremely useful. 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. - Comeup with your own idea 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 supports 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 : [-][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 t3.o (note that it expects mbuf as an input): testpmd> bpf-load rx 2 0 JM ./dpdk.org/test/bpf/t3.o If you are curious to check JIT generated native code: gdb -p `pgrep testpmd` (gdb) disas 0x7fd173c5f000,+76 Dump of assembler code from 0x7fd173c5f000 to 0x7fd173c5f04c: 0x00007fd173c5f000: mov %rdi,%rsi 0x00007fd173c5f003: movzwq 0x10(%rsi),%rdi 0x00007fd173c5f008: mov 0x0(%rsi),%rdx 0x00007fd173c5f00c: add %rdi,%rdx 0x00007fd173c5f00f: movzbq 0xc(%rdx),%rdi 0x00007fd173c5f014: movzbq 0xd(%rdx),%rdx 0x00007fd173c5f019: shl $0x8,%rdx 0x00007fd173c5f01d: or %rdi,%rdx 0x00007fd173c5f020: cmp $0x608,%rdx 0x00007fd173c5f027: jne 0x7fd173c5f044 0x00007fd173c5f029: mov $0xb712e8,%rdi 0x00007fd173c5f030: mov 0x0(%rdi),%rdi 0x00007fd173c5f034: mov $0x40,%rdx 0x00007fd173c5f03b: mov $0x4db2f0,%rax 0x00007fd173c5f042: callq *%rax 0x00007fd173c5f044: mov $0x1,%rax 0x00007fd173c5f04b: retq End of assembler dump. 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. - t3.o - should dump to stdout ARP packets. 5) unload some or all bpf programs: testpmd> bpf-unload tx 0 0 6) continue with step 3) or exit TODO list: ========== - UT for it - allow JIT to generate bulk version Not currently supported features: ================================= - cBPF - tail-pointer call - eBPF MAP - JIT for non X86_64 targets - skb v2: - add meson build - add freebsd build - use new logging API - using rte_malloc() for cbi allocation - add extra logic into bpf_validate() Konstantin Ananyev (7): net: move BPF related definitions into librte_net bpf: add BPF loading and execution framework bpf: add more logic into bpf_validate() 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/bpf_sup.h | 25 + app/test-pmd/cmdline.c | 146 ++++ app/test-pmd/meson.build | 2 +- config/common_base | 5 + drivers/net/tap/tap_bpf.h | 80 +-- lib/Makefile | 2 + lib/librte_bpf/Makefile | 35 + lib/librte_bpf/bpf.c | 64 ++ lib/librte_bpf/bpf_exec.c | 452 ++++++++++++ lib/librte_bpf/bpf_impl.h | 41 ++ lib/librte_bpf/bpf_jit_x86.c | 1329 ++++++++++++++++++++++++++++++++++++ lib/librte_bpf/bpf_load.c | 385 +++++++++++ lib/librte_bpf/bpf_pkt.c | 607 ++++++++++++++++ lib/librte_bpf/bpf_validate.c | 1166 +++++++++++++++++++++++++++++++ lib/librte_bpf/meson.build | 24 + lib/librte_bpf/rte_bpf.h | 160 +++++ lib/librte_bpf/rte_bpf_ethdev.h | 100 +++ lib/librte_bpf/rte_bpf_version.map | 16 + lib/librte_net/Makefile | 1 + lib/librte_net/meson.build | 3 +- lib/librte_net/rte_bpf_def.h | 370 ++++++++++ lib/meson.build | 2 +- mk/rte.app.mk | 2 + test/bpf/dummy.c | 20 + test/bpf/mbuf.h | 578 ++++++++++++++++ test/bpf/t1.c | 52 ++ test/bpf/t2.c | 31 + test/bpf/t3.c | 36 + 28 files changed, 5652 insertions(+), 82 deletions(-) create mode 100644 app/test-pmd/bpf_sup.h 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/meson.build 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 lib/librte_net/rte_bpf_def.h 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 create mode 100644 test/bpf/t3.c -- 2.13.6