1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) 2021 Facebook */
3 #include "vmlinux.h"
4 #include <bpf/bpf_helpers.h>
5 
6 char _license[] SEC("license") = "GPL";
7 
8 struct {
9 	__uint(type, BPF_MAP_TYPE_ARRAY);
10 	__uint(max_entries, 3);
11 	__type(key, __u32);
12 	__type(value, __u64);
13 } arraymap SEC(".maps");
14 
15 struct {
16 	__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
17 	__uint(max_entries, 1);
18 	__type(key, __u32);
19 	__type(value, __u64);
20 } percpu_map SEC(".maps");
21 
22 struct callback_ctx {
23 	int output;
24 };
25 
26 const volatile int bypass_unused = 1;
27 
28 static __u64
unused_subprog(struct bpf_map * map,__u32 * key,__u64 * val,struct callback_ctx * data)29 unused_subprog(struct bpf_map *map, __u32 *key, __u64 *val,
30 	       struct callback_ctx *data)
31 {
32 	data->output = 0;
33 	return 1;
34 }
35 
36 static __u64
check_array_elem(struct bpf_map * map,__u32 * key,__u64 * val,struct callback_ctx * data)37 check_array_elem(struct bpf_map *map, __u32 *key, __u64 *val,
38 		 struct callback_ctx *data)
39 {
40 	data->output += *val;
41 	if (*key == 1)
42 		return 1; /* stop the iteration */
43 	return 0;
44 }
45 
46 __u32 cpu = 0;
47 __u64 percpu_val = 0;
48 
49 static __u64
check_percpu_elem(struct bpf_map * map,__u32 * key,__u64 * val,struct callback_ctx * data)50 check_percpu_elem(struct bpf_map *map, __u32 *key, __u64 *val,
51 		  struct callback_ctx *data)
52 {
53 	cpu = bpf_get_smp_processor_id();
54 	percpu_val = *val;
55 	return 0;
56 }
57 
58 u32 arraymap_output = 0;
59 
60 SEC("tc")
test_pkt_access(struct __sk_buff * skb)61 int test_pkt_access(struct __sk_buff *skb)
62 {
63 	struct callback_ctx data;
64 
65 	data.output = 0;
66 	bpf_for_each_map_elem(&arraymap, check_array_elem, &data, 0);
67 	if (!bypass_unused)
68 		bpf_for_each_map_elem(&arraymap, unused_subprog, &data, 0);
69 	arraymap_output = data.output;
70 
71 	bpf_for_each_map_elem(&percpu_map, check_percpu_elem, (void *)0, 0);
72 	return 0;
73 }
74