xref: /linux/tools/testing/selftests/bpf/progs/tailcall_bpf2bpf_hierarchy3.c (revision 07fdad3a93756b872da7b53647715c48d0f4a2d0)
1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/bpf.h>
3 #include <bpf/bpf_helpers.h>
4 #include "bpf_misc.h"
5 #include "bpf_test_utils.h"
6 
7 int classifier_0(struct __sk_buff *skb);
8 
9 struct {
10 	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
11 	__uint(max_entries, 1);
12 	__uint(key_size, sizeof(__u32));
13 	__array(values, void (void));
14 } jmp_table0 SEC(".maps") = {
15 	.values = {
16 		[0] = (void *) &classifier_0,
17 	},
18 };
19 
20 struct {
21 	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
22 	__uint(max_entries, 1);
23 	__uint(key_size, sizeof(__u32));
24 	__array(values, void (void));
25 } jmp_table1 SEC(".maps") = {
26 	.values = {
27 		[0] = (void *) &classifier_0,
28 	},
29 };
30 
31 int count = 0;
32 
33 static __noinline
34 int subprog_tail(struct __sk_buff *skb, void *jmp_table)
35 {
36 	bpf_tail_call_static(skb, jmp_table, 0);
37 	return 0;
38 }
39 
40 __auxiliary
41 SEC("tc")
42 int classifier_0(struct __sk_buff *skb)
43 {
44 	count++;
45 	subprog_tail(skb, &jmp_table0);
46 	subprog_tail(skb, &jmp_table1);
47 	return count;
48 }
49 
50 __success
51 __retval(33)
52 SEC("tc")
53 int tailcall_bpf2bpf_hierarchy_3(struct __sk_buff *skb)
54 {
55 	int ret = 0;
56 
57 	clobber_regs_stack();
58 
59 	bpf_tail_call_static(skb, &jmp_table0, 0);
60 
61 	__sink(ret);
62 	return ret;
63 }
64 
65 char __license[] SEC("license") = "GPL";
66