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

source code of linux/tools/testing/selftests/bpf/progs/test_global_func9.c