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
11struct 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
24SEC("tc")
25__description("single CO-RE bitfield roundtrip")
26__btf_path("btf__core_reloc_bitfields.bpf.o")
27__success
28__retval(3)
29int 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
38SEC("tc")
39__description("multiple CO-RE bitfield roundtrip")
40__btf_path("btf__core_reloc_bitfields.bpf.o")
41__success
42__retval(0x3FD)
43int 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
59SEC("tc")
60__description("adjacent CO-RE bitfield roundtrip")
61__btf_path("btf__core_reloc_bitfields.bpf.o")
62__success
63__retval(7)
64int 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
79SEC("tc")
80__description("multibyte CO-RE bitfield roundtrip")
81__btf_path("btf__core_reloc_bitfields.bpf.o")
82__success
83__retval(0x21)
84int 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
100char _license[] SEC("license") = "GPL";
101