1
2#include <stddef.h>
3#include <linux/bpf.h>
4#include <bpf/bpf_helpers.h>
5
6struct S {
7 int x;
8};
9
10struct C {
11 int x;
12 int y;
13};
14
15struct {
16 __uint(type, BPF_MAP_TYPE_ARRAY);
17 __uint(max_entries, 1);
18 __type(key, __u32);
19 __type(value, struct S);
20} map SEC(".maps");
21
22enum E {
23 E_ITEM
24};
25
26static int global_data_x = 100;
27static int volatile global_data_y = 500;
28
29__noinline int foo(const struct S *s)
30{
31 if (s)
32 return bpf_get_prandom_u32() < s->x;
33
34 return 0;
35}
36
37__noinline int bar(int *x)
38{
39 if (x)
40 *x &= bpf_get_prandom_u32();
41
42 return 0;
43}
44__noinline int baz(volatile int *x)
45{
46 if (x)
47 *x &= bpf_get_prandom_u32();
48
49 return 0;
50}
51
52__noinline int qux(enum E *e)
53{
54 if (e)
55 return *e;
56
57 return 0;
58}
59
60__noinline int quux(int (*arr)[10])
61{
62 if (arr)
63 return (*arr)[9];
64
65 return 0;
66}
67
68__noinline int quuz(int **p)
69{
70 if (p)
71 *p = NULL;
72
73 return 0;
74}
75
76SEC("cgroup_skb/ingress")
77int test_cls(struct __sk_buff *skb)
78{
79 int result = 0;
80
81 {
82 const struct S s = {.x = skb->len };
83
84 result |= foo(&s);
85 }
86
87 {
88 const __u32 key = 1;
89 const struct S *s = bpf_map_lookup_elem(&map, &key);
90
91 result |= foo(s);
92 }
93
94 {
95 const struct C c = {.x = skb->len, .y = skb->family };
96
97 result |= foo((const struct S *)&c);
98 }
99
100 {
101 result |= foo(NULL);
102 }
103
104 {
105 bar(&result);
106 bar(&global_data_x);
107 }
108
109 {
110 result |= baz(&global_data_y);
111 }
112
113 {
114 enum E e = E_ITEM;
115
116 result |= qux(&e);
117 }
118
119 {
120 int array[10] = {0};
121
122 result |= quux(&array);
123 }
124
125 {
126 int *p;
127
128 result |= quuz(&p);
129 }
130
131 return result ? 1 : 0;
132}
133