]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests/bpf: Cover skb metadata access after vlan push/pop helper
authorJakub Sitnicki <jakub@cloudflare.com>
Wed, 5 Nov 2025 20:19:50 +0000 (21:19 +0100)
committerMartin KaFai Lau <martin.lau@kernel.org>
Mon, 10 Nov 2025 18:52:32 +0000 (10:52 -0800)
Add a test to verify that skb metadata remains accessible after calling
bpf_skb_vlan_push() and bpf_skb_vlan_pop(), which modify the packet
headroom.

Signed-off-by: Jakub Sitnicki <jakub@cloudflare.com>
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>
Link: https://patch.msgid.link/20251105-skb-meta-rx-path-v4-13-5ceb08a9b37b@cloudflare.com
tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c
tools/testing/selftests/bpf/progs/test_xdp_meta.c

index a129c3057202b5cf0e8aaf54da58ee377ad42d08..97c8f876f673b66cfd144f4e36ece1f069d2be2e 100644 (file)
@@ -478,6 +478,12 @@ void test_xdp_context_tuntap(void)
                test_tuntap_mirred(skel->progs.ing_xdp,
                                   skel->progs.clone_meta_dynptr_rw_before_meta_dynptr_write,
                                   &skel->bss->test_pass);
+       /* Tests for BPF helpers which touch headroom */
+       if (test__start_subtest("helper_skb_vlan_push_pop"))
+               test_tuntap(skel->progs.ing_xdp,
+                           skel->progs.helper_skb_vlan_push_pop,
+                           NULL, /* tc prio 2 */
+                           &skel->bss->test_pass);
 
        test_xdp_meta__destroy(skel);
 }
index a70de55c6997f30cd78c350f84567561d41f5c2e..04c7487bb350e3887af70fe5042ec10093be63b7 100644 (file)
@@ -44,6 +44,16 @@ static bool check_metadata(const char *file, int line, __u8 *meta_have)
 
 #define check_metadata(meta_have) check_metadata(__FILE__, __LINE__, meta_have)
 
+static bool check_skb_metadata(const char *file, int line, struct __sk_buff *skb)
+{
+       __u8 *data_meta = ctx_ptr(skb, data_meta);
+       __u8 *data = ctx_ptr(skb, data);
+
+       return data_meta + META_SIZE <= data && (check_metadata)(file, line, data_meta);
+}
+
+#define check_skb_metadata(skb) check_skb_metadata(__FILE__, __LINE__, skb)
+
 SEC("tc")
 int ing_cls(struct __sk_buff *ctx)
 {
@@ -525,4 +535,37 @@ out:
        return TC_ACT_SHOT;
 }
 
+SEC("tc")
+int helper_skb_vlan_push_pop(struct __sk_buff *ctx)
+{
+       int err;
+
+       /* bpf_skb_vlan_push assumes HW offload for primary VLAN tag. Only
+        * secondary tag push triggers an actual MAC header modification.
+        */
+       err = bpf_skb_vlan_push(ctx, 0, 42);
+       if (err)
+               goto out;
+       err = bpf_skb_vlan_push(ctx, 0, 207);
+       if (err)
+               goto out;
+
+       if (!check_skb_metadata(ctx))
+               goto out;
+
+       err = bpf_skb_vlan_pop(ctx);
+       if (err)
+               goto out;
+       err = bpf_skb_vlan_pop(ctx);
+       if (err)
+               goto out;
+
+       if (!check_skb_metadata(ctx))
+               goto out;
+
+       test_pass = true;
+out:
+       return TC_ACT_SHOT;
+}
+
 char _license[] SEC("license") = "GPL";