0001
0002 #include <linux/bpf.h>
0003 #include <bpf/bpf_helpers.h>
0004
0005 struct {
0006 __uint(type, BPF_MAP_TYPE_ARRAY);
0007 __uint(max_entries, 1);
0008 __uint(key_size, sizeof(__u32));
0009 __uint(value_size, sizeof(__u32));
0010 } nop_table SEC(".maps");
0011
0012 struct {
0013 __uint(type, BPF_MAP_TYPE_PROG_ARRAY);
0014 __uint(max_entries, 3);
0015 __uint(key_size, sizeof(__u32));
0016 __uint(value_size, sizeof(__u32));
0017 } jmp_table SEC(".maps");
0018
0019 int count = 0;
0020 int noise = 0;
0021
0022 __always_inline int subprog_noise(void)
0023 {
0024 __u32 key = 0;
0025
0026 bpf_map_lookup_elem(&nop_table, &key);
0027 return 0;
0028 }
0029
0030 __noinline
0031 int subprog_tail_2(struct __sk_buff *skb)
0032 {
0033 if (noise)
0034 subprog_noise();
0035 bpf_tail_call_static(skb, &jmp_table, 2);
0036 return skb->len * 3;
0037 }
0038
0039 __noinline
0040 int subprog_tail_1(struct __sk_buff *skb)
0041 {
0042 bpf_tail_call_static(skb, &jmp_table, 1);
0043 return skb->len * 2;
0044 }
0045
0046 __noinline
0047 int subprog_tail(struct __sk_buff *skb)
0048 {
0049 bpf_tail_call_static(skb, &jmp_table, 0);
0050 return skb->len;
0051 }
0052
0053 SEC("tc")
0054 int classifier_1(struct __sk_buff *skb)
0055 {
0056 return subprog_tail_2(skb);
0057 }
0058
0059 SEC("tc")
0060 int classifier_2(struct __sk_buff *skb)
0061 {
0062 count++;
0063 return subprog_tail_2(skb);
0064 }
0065
0066 SEC("tc")
0067 int classifier_0(struct __sk_buff *skb)
0068 {
0069 return subprog_tail_1(skb);
0070 }
0071
0072 SEC("tc")
0073 int entry(struct __sk_buff *skb)
0074 {
0075 return subprog_tail(skb);
0076 }
0077
0078 char __license[] SEC("license") = "GPL";