[PATCH net-next v2 00/14] skb extension for BPF metadata
From: Jakub Sitnicki <jakub@cloudflare.com>
Date: 2026-09-10 14:02:44
Also in:
bpf
This is the second spin of the per-packet metadata for BPF. See the RFC cover letter for the full overview and motivation [1]. Since v1 the focus has been on getting skb scrubbing and extension sharing right, driven by Sashiko's review: 1) skb scrubbing now simply deactivates all the extensions but the BPF metadata. Made possible due to recent change in skb_ext_del semantics [2] that already landed in net-next. Thanks to Florian and Paolo for guidance on this. 2) Clones made by bpf_clone_redirect() share the extension block. A write through a previously acquired writable dynptr would land in the shared block and become visible to the clone, so v2 makes such writes fail until the program re-acquires the dynptr with BPF_SKB_EXT_F_CREATE, which COWs the block into a private writable copy. 3) Re-acquiring the extension with BPF_SKB_EXT_F_CREATE can COW and free the old block, so a dynptr slice taken before that re-acquire would be left pointing into freed memory. bpf_dynptr_from_skb_ext() is therefore marked packet-changing, making the verifier invalidate such slices and forcing the program to re-take them after the re-acquire. 4) Tracing and LSM programs can run on a shared skb concurrently on another CPU, so creating the extension there would mutate skb->extensions without synchronization. v2 rejects BPF_SKB_EXT_F_CREATE in these program types at load time; read-only access remains available. Regarding performance compared to consume_skb+kfree_skb tracepoints, I have not yet re-run the experiment measuring the overhead when attaching metadata to 5% instead of 1% of skbs in flight; happy to do so if it is a blocker. That said, as things stand we have already established in v1 [3] that for our existing use case - attaching metadata to <1% of skbs - the tracepoint-based approach is prohibitively expensive (+5% of CPU time), as Jesper noted. The skb-extension-based solution, in contrast, shows comparable-or-lower overhead, making it a viable drop-in replacement that enables new use cases for us and potentially offers a performance win. Thanks, -jkbs [1] https://patch.msgid.link/20260714-bpf-meta-inside-skb-ext-v1-0-5871c07a8dd6@cloudflare.com [2] https://lore.kernel.org/all/20260831-skb-ext-prep-work-v1-0-ecc2a8542fd9@cloudflare.com/ (local) [3] https://patch.msgid.link/20260814-bpf-meta-inside-skb-ext-v1-0-767edd862656@cloudflare.com Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com> --- Changes in v2: - Rework skb_ext_scrub() to simply delete all extensions but bpf_skb_ext now that the delete operation is idempotent. (Florian, sashiko) - Fail writes through a dynptr while the extension block is shared with clones: bpf_dynptr_write() now returns -EBUSY and bpf_dynptr_slice_rdwr() returns NULL; re-acquiring the dynptr with BPF_SKB_EXT_F_CREATE COWs the block and restores write access. (sashiko) - Mark bpf_dynptr_from_skb_ext() as packet-changing so the verifier invalidates slices from an earlier dynptr when a re-open with F_CREATE can COW the block and leave them dangling (use-after-free). (sashiko) - Reject bpf_dynptr_from_skb_ext(BPF_SKB_EXT_F_CREATE) in tracing and LSM programs, which can run on a shared skb concurrently on another CPU; require a constant flags argument without F_CREATE at load time, keeping read-only access. (sashiko) - selftests: Add verifier negative tests for the new tracing/LSM restrictions (F_CREATE and non-constant flags rejected). (sashiko) - selftests: Add clone_redirect coverage into the cloned-skbs test (clone_redir_ext_write_after / clone_redir_ext_slice_write_after), queueing the clone on a netem-delayed loopback; enable CONFIG_NET_SCH_NETEM. - selftests: Fix if_nametoindex() assertions to use ASSERT_GT(..., 0) so a lookup failure is not silently accepted as ifindex 0. (sashiko) - selftests: Use int (not __be16) for get_socket_local_port() so a negative error is not truncated and masked. (sashiko) - selftests: Validate send()/recv() return values and switch the sk_skb stream test to recv_timeout() to avoid a hang when the data path regresses. (Jack Wang, sashiko) - selftests: Split the LWT test cleanup so bpf_tc_hook_destroy() does not delete the base-namespace clsact qdisc on the error path. (sashiko) - selftests: Unify multi-line function comments to the "/*" on its own line style. (sashiko) - Link to v1: https://patch.msgid.link/20260814-bpf-meta-inside-skb-ext-v1-0-767edd862656@cloudflare.com Changes in v1: - Don't scrub BPF skb extension. Remove F_NO_SCRUB flag. (Stan) - Allow calling bpf_dynptr_from_skb_ext from NETFILTER, LWT_*, SK_SKB progs. - Reorg tests into smaller commits. Add missing coverage. - Link to RFC: https://patch.msgid.link/20260714-bpf-meta-inside-skb-ext-v1-0-5871c07a8dd6@cloudflare.com --- Jakub Sitnicki (14): bpf: Introduce per-packet metadata storage for BPF programs bpf: Allow access to bpf_sock_ops_kern->skb bpf: Make BPF skb extension survive packet scrubbing selftests/bpf: Add tests for bpf_dynptr_from_skb_ext selftests/bpf: Test skb_ext on cloned skbs selftests/bpf: Test skb_ext survival across veth and GRE selftests/bpf: Test skb_ext read from cgroup_skb and sk_filter hooks selftests/bpf: Test skb_ext read from sock_ops and LSM hooks selftests/bpf: Test skb_ext read from kfree_skb tracepoint selftests/bpf: Test skb_ext read from netfilter hook selftests/bpf: Test skb_ext from LWT in, out, and xmit hooks selftests/bpf: Test skb_ext read from seg6local End.BPF hook selftests/bpf: Test skb_ext read from sk_skb stream verdict hook selftests/bpf: Use non-trivial test payload in xdp_context tests include/linux/bpf.h | 10 + include/linux/filter.h | 27 + include/linux/skbuff.h | 13 + include/uapi/linux/bpf.h | 5 + kernel/bpf/helpers.c | 21 +- kernel/bpf/log.c | 2 + kernel/bpf/verifier.c | 25 +- net/Kconfig | 20 + net/core/filter.c | 149 +++ net/core/skbuff.c | 27 +- net/ipv4/udp.c | 6 +- tools/testing/selftests/bpf/config | 2 + .../selftests/bpf/prog_tests/socket_helpers.h | 1 + tools/testing/selftests/bpf/prog_tests/verifier.c | 2 + .../bpf/prog_tests/xdp_context_test_run.c | 1117 +++++++++++++++++++- tools/testing/selftests/bpf/progs/test_xdp_meta.c | 569 +++++++++- .../testing/selftests/bpf/progs/verifier_skb_ext.c | 122 +++ 17 files changed, 2094 insertions(+), 24 deletions(-)