Skip to content

Commit 6caab6f

Browse files
r41k0uclaude
andcommitted
Tests: Rank the ctx-field case on a scalar field, not the packet pointer
xdp_md.data is a u32 in C, but the verifier tracks it as a packet pointer and rejects 32-bit arithmetic on it: "R0 32-bit pointer arithmetic prohibited", the same for a C program, which is why C casts it through (void *)(long) first. The u32 ranking the test pins is the correct one; it just has to be pinned on a field that is a scalar to the verifier too. ingress_ifindex is. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 6b19bf6 commit 6caab6f

1 file changed

Lines changed: 9 additions & 4 deletions

File tree

‎tests/passing_tests/vmlinux/ctx_field_rank.py‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
# A sub-register context field is loaded widened to i64, but C ranks it by
2-
# its declared width: xdp_md.data is a u32, so data - k with a c_int32 k is
3-
# a u32 subtraction (the result is cut to 32 bits and zero-extended), not a
4-
# 64-bit one.
2+
# its declared width: xdp_md.ingress_ifindex is a u32, so ifindex - k with a
3+
# c_int32 k is a u32 subtraction (the result is cut to 32 bits and
4+
# zero-extended), not a 64-bit one.
5+
#
6+
# Not xdp_md.data: it is a u32 in C too, but the verifier tracks it as a
7+
# packet pointer and rejects 32-bit arithmetic on it ("R0 32-bit pointer
8+
# arithmetic prohibited"), for C programs as much as for this one. That is
9+
# why C casts it through (void *)(long) before doing anything with it.
510
from ctypes import c_int32, c_int64
611
from pythonbpf import bpf, section, bpfglobal, compile
712
from vmlinux import struct_xdp_md
@@ -11,7 +16,7 @@
1116
@section("xdp")
1217
def prog(ctx: struct_xdp_md) -> c_int64:
1318
k = c_int32(1)
14-
d = ctx.data - k
19+
d = ctx.ingress_ifindex - k
1520
return c_int64(d)
1621

1722

0 commit comments

Comments
 (0)