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