1 // SPDX-License-Identifier: GPL-2.0
2
3 #include <linux/bpf.h>
4 #include <stdint.h>
5
6 #include <bpf/bpf_helpers.h>
7 #include <bpf/bpf_core_read.h>
8
9 #include "bpf_misc.h"
10
11 struct core_reloc_bitfields {
12 /* unsigned bitfields */
13 uint8_t ub1: 1;
14 uint8_t ub2: 2;
15 uint32_t ub7: 7;
16 /* signed bitfields */
17 int8_t sb4: 4;
18 int32_t sb20: 20;
19 /* non-bitfields */
20 uint32_t u32;
21 int32_t s32;
22 } __attribute__((preserve_access_index));
23
24 SEC("tc")
25 __description("single CO-RE bitfield roundtrip")
26 __btf_path("btf__core_reloc_bitfields.bpf.o")
27 __success
28 __retval(3)
single_field_roundtrip(struct __sk_buff * ctx)29 int single_field_roundtrip(struct __sk_buff *ctx)
30 {
31 struct core_reloc_bitfields bitfields;
32
33 __builtin_memset(&bitfields, 0, sizeof(bitfields));
34 BPF_CORE_WRITE_BITFIELD(&bitfields, ub2, 3);
35 return BPF_CORE_READ_BITFIELD(&bitfields, ub2);
36 }
37
38 SEC("tc")
39 __description("multiple CO-RE bitfield roundtrip")
40 __btf_path("btf__core_reloc_bitfields.bpf.o")
41 __success
42 __retval(0x3FD)
multiple_field_roundtrip(struct __sk_buff * ctx)43 int multiple_field_roundtrip(struct __sk_buff *ctx)
44 {
45 struct core_reloc_bitfields bitfields;
46 uint8_t ub2;
47 int8_t sb4;
48
49 __builtin_memset(&bitfields, 0, sizeof(bitfields));
50 BPF_CORE_WRITE_BITFIELD(&bitfields, ub2, 1);
51 BPF_CORE_WRITE_BITFIELD(&bitfields, sb4, -1);
52
53 ub2 = BPF_CORE_READ_BITFIELD(&bitfields, ub2);
54 sb4 = BPF_CORE_READ_BITFIELD(&bitfields, sb4);
55
56 return (((uint8_t)sb4) << 2) | ub2;
57 }
58
59 SEC("tc")
60 __description("adjacent CO-RE bitfield roundtrip")
61 __btf_path("btf__core_reloc_bitfields.bpf.o")
62 __success
63 __retval(7)
adjacent_field_roundtrip(struct __sk_buff * ctx)64 int adjacent_field_roundtrip(struct __sk_buff *ctx)
65 {
66 struct core_reloc_bitfields bitfields;
67 uint8_t ub1, ub2;
68
69 __builtin_memset(&bitfields, 0, sizeof(bitfields));
70 BPF_CORE_WRITE_BITFIELD(&bitfields, ub1, 1);
71 BPF_CORE_WRITE_BITFIELD(&bitfields, ub2, 3);
72
73 ub1 = BPF_CORE_READ_BITFIELD(&bitfields, ub1);
74 ub2 = BPF_CORE_READ_BITFIELD(&bitfields, ub2);
75
76 return (ub2 << 1) | ub1;
77 }
78
79 SEC("tc")
80 __description("multibyte CO-RE bitfield roundtrip")
81 __btf_path("btf__core_reloc_bitfields.bpf.o")
82 __success
83 __retval(0x21)
multibyte_field_roundtrip(struct __sk_buff * ctx)84 int multibyte_field_roundtrip(struct __sk_buff *ctx)
85 {
86 struct core_reloc_bitfields bitfields;
87 uint32_t ub7;
88 uint8_t ub1;
89
90 __builtin_memset(&bitfields, 0, sizeof(bitfields));
91 BPF_CORE_WRITE_BITFIELD(&bitfields, ub1, 1);
92 BPF_CORE_WRITE_BITFIELD(&bitfields, ub7, 16);
93
94 ub1 = BPF_CORE_READ_BITFIELD(&bitfields, ub1);
95 ub7 = BPF_CORE_READ_BITFIELD(&bitfields, ub7);
96
97 return (ub7 << 1) | ub1;
98 }
99
100 char _license[] SEC("license") = "GPL";
101