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