18b08807dSDmitrii Banshchikov // SPDX-License-Identifier: GPL-2.0-only
28b08807dSDmitrii Banshchikov #include <stddef.h>
38b08807dSDmitrii Banshchikov #include <linux/bpf.h>
48b08807dSDmitrii Banshchikov #include <bpf/bpf_helpers.h>
5*95ebb376SAndrii Nakryiko #include "bpf_misc.h"
68b08807dSDmitrii Banshchikov 
78b08807dSDmitrii Banshchikov struct S {
88b08807dSDmitrii Banshchikov 	int x;
98b08807dSDmitrii Banshchikov };
108b08807dSDmitrii Banshchikov 
118b08807dSDmitrii Banshchikov struct C {
128b08807dSDmitrii Banshchikov 	int x;
138b08807dSDmitrii Banshchikov 	int y;
148b08807dSDmitrii Banshchikov };
158b08807dSDmitrii Banshchikov 
168b08807dSDmitrii Banshchikov struct {
178b08807dSDmitrii Banshchikov 	__uint(type, BPF_MAP_TYPE_ARRAY);
188b08807dSDmitrii Banshchikov 	__uint(max_entries, 1);
198b08807dSDmitrii Banshchikov 	__type(key, __u32);
208b08807dSDmitrii Banshchikov 	__type(value, struct S);
218b08807dSDmitrii Banshchikov } map SEC(".maps");
228b08807dSDmitrii Banshchikov 
238b08807dSDmitrii Banshchikov enum E {
248b08807dSDmitrii Banshchikov 	E_ITEM
258b08807dSDmitrii Banshchikov };
268b08807dSDmitrii Banshchikov 
278b08807dSDmitrii Banshchikov static int global_data_x = 100;
288b08807dSDmitrii Banshchikov static int volatile global_data_y = 500;
298b08807dSDmitrii Banshchikov 
foo(const struct S * s)308b08807dSDmitrii Banshchikov __noinline int foo(const struct S *s)
318b08807dSDmitrii Banshchikov {
328b08807dSDmitrii Banshchikov 	if (s)
338b08807dSDmitrii Banshchikov 		return bpf_get_prandom_u32() < s->x;
348b08807dSDmitrii Banshchikov 
358b08807dSDmitrii Banshchikov 	return 0;
368b08807dSDmitrii Banshchikov }
378b08807dSDmitrii Banshchikov 
bar(int * x)388b08807dSDmitrii Banshchikov __noinline int bar(int *x)
398b08807dSDmitrii Banshchikov {
408b08807dSDmitrii Banshchikov 	if (x)
418b08807dSDmitrii Banshchikov 		*x &= bpf_get_prandom_u32();
428b08807dSDmitrii Banshchikov 
438b08807dSDmitrii Banshchikov 	return 0;
448b08807dSDmitrii Banshchikov }
baz(volatile int * x)458b08807dSDmitrii Banshchikov __noinline int baz(volatile int *x)
468b08807dSDmitrii Banshchikov {
478b08807dSDmitrii Banshchikov 	if (x)
488b08807dSDmitrii Banshchikov 		*x &= bpf_get_prandom_u32();
498b08807dSDmitrii Banshchikov 
508b08807dSDmitrii Banshchikov 	return 0;
518b08807dSDmitrii Banshchikov }
528b08807dSDmitrii Banshchikov 
qux(enum E * e)538b08807dSDmitrii Banshchikov __noinline int qux(enum E *e)
548b08807dSDmitrii Banshchikov {
558b08807dSDmitrii Banshchikov 	if (e)
568b08807dSDmitrii Banshchikov 		return *e;
578b08807dSDmitrii Banshchikov 
588b08807dSDmitrii Banshchikov 	return 0;
598b08807dSDmitrii Banshchikov }
608b08807dSDmitrii Banshchikov 
quux(int (* arr)[10])618b08807dSDmitrii Banshchikov __noinline int quux(int (*arr)[10])
628b08807dSDmitrii Banshchikov {
638b08807dSDmitrii Banshchikov 	if (arr)
648b08807dSDmitrii Banshchikov 		return (*arr)[9];
658b08807dSDmitrii Banshchikov 
668b08807dSDmitrii Banshchikov 	return 0;
678b08807dSDmitrii Banshchikov }
688b08807dSDmitrii Banshchikov 
quuz(int ** p)698b08807dSDmitrii Banshchikov __noinline int quuz(int **p)
708b08807dSDmitrii Banshchikov {
718b08807dSDmitrii Banshchikov 	if (p)
728b08807dSDmitrii Banshchikov 		*p = NULL;
738b08807dSDmitrii Banshchikov 
748b08807dSDmitrii Banshchikov 	return 0;
758b08807dSDmitrii Banshchikov }
768b08807dSDmitrii Banshchikov 
778b08807dSDmitrii Banshchikov SEC("cgroup_skb/ingress")
78*95ebb376SAndrii Nakryiko __success
global_func9(struct __sk_buff * skb)79*95ebb376SAndrii Nakryiko int global_func9(struct __sk_buff *skb)
808b08807dSDmitrii Banshchikov {
818b08807dSDmitrii Banshchikov 	int result = 0;
828b08807dSDmitrii Banshchikov 
838b08807dSDmitrii Banshchikov 	{
848b08807dSDmitrii Banshchikov 		const struct S s = {.x = skb->len };
858b08807dSDmitrii Banshchikov 
868b08807dSDmitrii Banshchikov 		result |= foo(&s);
878b08807dSDmitrii Banshchikov 	}
888b08807dSDmitrii Banshchikov 
898b08807dSDmitrii Banshchikov 	{
908b08807dSDmitrii Banshchikov 		const __u32 key = 1;
918b08807dSDmitrii Banshchikov 		const struct S *s = bpf_map_lookup_elem(&map, &key);
928b08807dSDmitrii Banshchikov 
938b08807dSDmitrii Banshchikov 		result |= foo(s);
948b08807dSDmitrii Banshchikov 	}
958b08807dSDmitrii Banshchikov 
968b08807dSDmitrii Banshchikov 	{
978b08807dSDmitrii Banshchikov 		const struct C c = {.x = skb->len, .y = skb->family };
988b08807dSDmitrii Banshchikov 
998b08807dSDmitrii Banshchikov 		result |= foo((const struct S *)&c);
1008b08807dSDmitrii Banshchikov 	}
1018b08807dSDmitrii Banshchikov 
1028b08807dSDmitrii Banshchikov 	{
1038b08807dSDmitrii Banshchikov 		result |= foo(NULL);
1048b08807dSDmitrii Banshchikov 	}
1058b08807dSDmitrii Banshchikov 
1068b08807dSDmitrii Banshchikov 	{
1078b08807dSDmitrii Banshchikov 		bar(&result);
1088b08807dSDmitrii Banshchikov 		bar(&global_data_x);
1098b08807dSDmitrii Banshchikov 	}
1108b08807dSDmitrii Banshchikov 
1118b08807dSDmitrii Banshchikov 	{
1128b08807dSDmitrii Banshchikov 		result |= baz(&global_data_y);
1138b08807dSDmitrii Banshchikov 	}
1148b08807dSDmitrii Banshchikov 
1158b08807dSDmitrii Banshchikov 	{
1168b08807dSDmitrii Banshchikov 		enum E e = E_ITEM;
1178b08807dSDmitrii Banshchikov 
1188b08807dSDmitrii Banshchikov 		result |= qux(&e);
1198b08807dSDmitrii Banshchikov 	}
1208b08807dSDmitrii Banshchikov 
1218b08807dSDmitrii Banshchikov 	{
1228b08807dSDmitrii Banshchikov 		int array[10] = {0};
1238b08807dSDmitrii Banshchikov 
1248b08807dSDmitrii Banshchikov 		result |= quux(&array);
1258b08807dSDmitrii Banshchikov 	}
1268b08807dSDmitrii Banshchikov 
1278b08807dSDmitrii Banshchikov 	{
1288b08807dSDmitrii Banshchikov 		int *p;
1298b08807dSDmitrii Banshchikov 
1308b08807dSDmitrii Banshchikov 		result |= quuz(&p);
1318b08807dSDmitrii Banshchikov 	}
1328b08807dSDmitrii Banshchikov 
1338b08807dSDmitrii Banshchikov 	return result ? 1 : 0;
1348b08807dSDmitrii Banshchikov }
135