|
|
Log in / Subscribe / Register

Make TC BPF helpers preserve skb metadata

From:  Jakub Sitnicki <jakub-AT-cloudflare.com>
To:  bpf-AT-vger.kernel.org
Subject:  [PATCH bpf-next v2 00/15] Make TC BPF helpers preserve skb metadata
Date:  Sun, 19 Oct 2025 14:45:24 +0200
Message-ID:  <20251019-skb-meta-rx-path-v2-0-f9a58f3eb6d6@cloudflare.com>
Cc:  "David S. Miller" <davem-AT-davemloft.net>, Eric Dumazet <edumazet-AT-google.com>, Jakub Kicinski <kuba-AT-kernel.org>, Paolo Abeni <pabeni-AT-redhat.com>, Simon Horman <horms-AT-kernel.org>, Martin KaFai Lau <martin.lau-AT-linux.dev>, Daniel Borkmann <daniel-AT-iogearbox.net>, John Fastabend <john.fastabend-AT-gmail.com>, Stanislav Fomichev <sdf-AT-fomichev.me>, Alexei Starovoitov <ast-AT-kernel.org>, Andrii Nakryiko <andrii-AT-kernel.org>, Eduard Zingerman <eddyz87-AT-gmail.com>, Song Liu <song-AT-kernel.org>, Yonghong Song <yonghong.song-AT-linux.dev>, KP Singh <kpsingh-AT-kernel.org>, Hao Luo <haoluo-AT-google.com>, Jiri Olsa <jolsa-AT-kernel.org>, Arthur Fabre <arthur-AT-arthurfabre.com>, netdev-AT-vger.kernel.org, kernel-team-AT-cloudflare.com
Archive-link:  Article

This patch set continues our work [1] to allow BPF programs and user-space
applications to attach multiple bytes of metadata to packets via the
XDP/skb metadata area.

The focus of this patch set it to ensure that skb metadata remains intact
when packets pass through a chain of TC BPF programs that call helpers
which operate on skb head.

Currently, several helpers that either adjust the skb->data pointer or
reallocate skb->head do not preserve metadata at its expected location,
that is immediately in front of the MAC header. These are:

- bpf_skb_adjust_room
- bpf_skb_change_head
- bpf_skb_change_proto
- bpf_skb_change_tail
- bpf_skb_vlan_pop
- bpf_skb_vlan_push

In TC BPF context, metadata must be moved whenever skb->data changes to
keep the skb->data_meta pointer valid. I don't see any way around
it. Creative ideas how to avoid that would be very welcome.

We can patch the helpers in at least two different ways:

1. Integrate metadata move into header move

   Replace the existing memmove, which follows skb_push/pull, with a helper
   that moves both headers and metadata in a single call. This avoids an
   extra memmove but reduces transparency.

        skb_pull(skb, len);
-       memmove(skb->data, skb->data - len, n);
+       skb_postpull_data_move(skb, len, n);
        skb->mac_header += len;

        skb_push(skb, len)
-       memmove(skb->data, skb->data + len, n);
+       skb_postpush_data_move(skb, len, n);
        skb->mac_header -= len;

2. Move metadata separately

   Add a dedicated metadata move after the header move. This is more
   explicit but costs an additional memmove.

        skb_pull(skb, len);
        memmove(skb->data, skb->data - len, n);
+       skb_metadata_postpull_move(skb, len);
        skb->mac_header += len;

        skb_push(skb, len)
+       skb_metadata_postpush_move(skb, len);
        memmove(skb->data, skb->data + len, n);
        skb->mac_header -= len;

This patch set implements option (1), expecting that "you can have just one
memmove" will be the most obvious feedback, while readability is a,
somewhat subjective, matter of taste, which I don't claim to have ;-)

The structure of the patch set is as follows:

- patches 1-3 prepare ground for safe-proofing the BPF helpers
- patches 4-8 modify the BPF helpers to preserve skb metadata
- patches 9-10 prepare ground for verifying metadata after BPF helper calls
- patches 11-15 adapt and expand tests to cover the made changes

Thanks,
-jkbs

[1] https://lore.kernel.org/all/20250814-skb-metadata-thru-dy...

---
Changes in v2:
- Tweak WARN_ON_ONCE check in skb_data_move() (patch 2)
- Convert all tests to verify skb metadata in BPF (patches 9-10)
- Add test coverage for modified BPF helpers (patches 12-15)
- Link to RFCv1: https://lore.kernel.org/r/20250929-skb-meta-rx-path-v1-0-...

---
Jakub Sitnicki (15):
      net: Preserve metadata on pskb_expand_head
      net: Helper to move packet data and metadata after skb_push/pull
      vlan: Make vlan_remove_tag return nothing
      bpf: Make bpf_skb_vlan_pop helper metadata-safe
      bpf: Make bpf_skb_vlan_push helper metadata-safe
      bpf: Make bpf_skb_adjust_room metadata-safe
      bpf: Make bpf_skb_change_proto helper metadata-safe
      bpf: Make bpf_skb_change_head helper metadata-safe
      selftests/bpf: Verify skb metadata in BPF instead of userspace
      selftests/bpf: Dump skb metadata on verification failure
      selftests/bpf: Expect unclone to preserve skb metadata
      selftests/bpf: Cover skb metadata access after vlan push/pop helper
      selftests/bpf: Cover skb metadata access after bpf_skb_adjust_room
      selftests/bpf: Cover skb metadata access after change_head/tail helper
      selftests/bpf: Cover skb metadata access after bpf_skb_change_proto

 include/linux/if_vlan.h                            |  13 +-
 include/linux/skbuff.h                             |  74 +++++
 net/core/filter.c                                  |  16 +-
 net/core/skbuff.c                                  |   2 -
 .../bpf/prog_tests/xdp_context_test_run.c          | 127 +++++---
 tools/testing/selftests/bpf/progs/test_xdp_meta.c  | 358 +++++++++++++++------
 6 files changed, 434 insertions(+), 156 deletions(-)




Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds