71 lines · c
1// SPDX-License-Identifier: GPL-2.02#include <linux/bpf.h>3#include <bpf/bpf_helpers.h>4#include "bpf_misc.h"5 6int classifier_0(struct __sk_buff *skb);7int classifier_1(struct __sk_buff *skb);8 9struct {10 __uint(type, BPF_MAP_TYPE_PROG_ARRAY);11 __uint(max_entries, 2);12 __uint(key_size, sizeof(__u32));13 __array(values, void (void));14} jmp_table SEC(".maps") = {15 .values = {16 [0] = (void *) &classifier_0,17 [1] = (void *) &classifier_1,18 },19};20 21int count0 = 0;22int count1 = 0;23 24static __noinline25int subprog_tail0(struct __sk_buff *skb)26{27 bpf_tail_call_static(skb, &jmp_table, 0);28 return 0;29}30 31__auxiliary32SEC("tc")33int classifier_0(struct __sk_buff *skb)34{35 count0++;36 subprog_tail0(skb);37 return 0;38}39 40static __noinline41int subprog_tail1(struct __sk_buff *skb)42{43 bpf_tail_call_static(skb, &jmp_table, 1);44 return 0;45}46 47__auxiliary48SEC("tc")49int classifier_1(struct __sk_buff *skb)50{51 count1++;52 subprog_tail1(skb);53 return 0;54}55 56__success57__retval(33)58SEC("tc")59int tailcall_bpf2bpf_hierarchy_2(struct __sk_buff *skb)60{61 int ret = 0;62 63 subprog_tail0(skb);64 subprog_tail1(skb);65 66 __sink(ret);67 return (count1 << 16) | count0;68}69 70char __license[] SEC("license") = "GPL";71