1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2021 Facebook */
3#include "vmlinux.h"
4#include <bpf/bpf_helpers.h>
5
6char _license[] SEC("license") = "GPL";
7
8struct {
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
15struct {
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
22struct callback_ctx {
23	int output;
24};
25
26const volatile int bypass_unused = 1;
27
28static __u64
29unused_subprog(struct bpf_map *map, __u32 *key, __u64 *val,
30	       struct callback_ctx *data)
31{
32	data->output = 0;
33	return 1;
34}
35
36static __u64
37check_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
49static __u64
50check_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
58u32 arraymap_output = 0;
59
60SEC("tc")
61int 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