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_HASH);
10	__uint(max_entries, 3);
11	__type(key, __u32);
12	__type(value, __u64);
13} hashmap SEC(".maps");
14
15struct {
16	__uint(type, BPF_MAP_TYPE_PERCPU_HASH);
17	__uint(max_entries, 1);
18	__type(key, __u32);
19	__type(value, __u64);
20} percpu_map SEC(".maps");
21
22struct callback_ctx {
23	struct __sk_buff *ctx;
24	int input;
25	int output;
26};
27
28static __u64
29check_hash_elem(struct bpf_map *map, __u32 *key, __u64 *val,
30		struct callback_ctx *data)
31{
32	struct __sk_buff *skb = data->ctx;
33	__u32 k;
34	__u64 v;
35
36	if (skb) {
37		k = *key;
38		v = *val;
39		if (skb->len == 10000 && k == 10 && v == 10)
40			data->output = 3; /* impossible path */
41		else
42			data->output = 4;
43	} else {
44		data->output = data->input;
45		bpf_map_delete_elem(map, key);
46	}
47
48	return 0;
49}
50
51__u32 cpu = 0;
52__u32 percpu_called = 0;
53__u32 percpu_key = 0;
54__u64 percpu_val = 0;
55int percpu_output = 0;
56
57static __u64
58check_percpu_elem(struct bpf_map *map, __u32 *key, __u64 *val,
59		  struct callback_ctx *unused)
60{
61	struct callback_ctx data;
62
63	percpu_called++;
64	cpu = bpf_get_smp_processor_id();
65	percpu_key = *key;
66	percpu_val = *val;
67
68	data.ctx = 0;
69	data.input = 100;
70	data.output = 0;
71	bpf_for_each_map_elem(&hashmap, check_hash_elem, &data, 0);
72	percpu_output = data.output;
73
74	return 0;
75}
76
77int hashmap_output = 0;
78int hashmap_elems = 0;
79int percpu_map_elems = 0;
80
81SEC("tc")
82int test_pkt_access(struct __sk_buff *skb)
83{
84	struct callback_ctx data;
85
86	data.ctx = skb;
87	data.input = 10;
88	data.output = 0;
89	hashmap_elems = bpf_for_each_map_elem(&hashmap, check_hash_elem, &data, 0);
90	hashmap_output = data.output;
91
92	percpu_map_elems = bpf_for_each_map_elem(&percpu_map, check_percpu_elem,
93						 (void *)0, 0);
94	return 0;
95}
96