13b037911SMaciej Fijalkowski // SPDX-License-Identifier: GPL-2.0
23b037911SMaciej Fijalkowski #include <linux/bpf.h>
33b037911SMaciej Fijalkowski #include <bpf/bpf_helpers.h>
43b037911SMaciej Fijalkowski 
53b037911SMaciej Fijalkowski struct {
61fb5ba29SJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
71fb5ba29SJohn Fastabend 	__uint(max_entries, 1);
81fb5ba29SJohn Fastabend 	__uint(key_size, sizeof(__u32));
91fb5ba29SJohn Fastabend 	__uint(value_size, sizeof(__u32));
101fb5ba29SJohn Fastabend } nop_table SEC(".maps");
111fb5ba29SJohn Fastabend 
121fb5ba29SJohn Fastabend struct {
133b037911SMaciej Fijalkowski 	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
143b037911SMaciej Fijalkowski 	__uint(max_entries, 3);
153b037911SMaciej Fijalkowski 	__uint(key_size, sizeof(__u32));
163b037911SMaciej Fijalkowski 	__uint(value_size, sizeof(__u32));
173b037911SMaciej Fijalkowski } jmp_table SEC(".maps");
183b037911SMaciej Fijalkowski 
19256eab48SAndrii Nakryiko int count = 0;
201fb5ba29SJohn Fastabend int noise = 0;
211fb5ba29SJohn Fastabend 
subprog_noise(void)22*b05d64efSJames Hilliard static __always_inline int subprog_noise(void)
231fb5ba29SJohn Fastabend {
241fb5ba29SJohn Fastabend 	__u32 key = 0;
251fb5ba29SJohn Fastabend 
261fb5ba29SJohn Fastabend 	bpf_map_lookup_elem(&nop_table, &key);
271fb5ba29SJohn Fastabend 	return 0;
281fb5ba29SJohn Fastabend }
293b037911SMaciej Fijalkowski 
303b037911SMaciej Fijalkowski __noinline
subprog_tail_2(struct __sk_buff * skb)313b037911SMaciej Fijalkowski int subprog_tail_2(struct __sk_buff *skb)
323b037911SMaciej Fijalkowski {
331fb5ba29SJohn Fastabend 	if (noise)
341fb5ba29SJohn Fastabend 		subprog_noise();
35faef26faSDaniel Borkmann 	bpf_tail_call_static(skb, &jmp_table, 2);
363b037911SMaciej Fijalkowski 	return skb->len * 3;
373b037911SMaciej Fijalkowski }
383b037911SMaciej Fijalkowski 
393b037911SMaciej Fijalkowski __noinline
subprog_tail_1(struct __sk_buff * skb)403b037911SMaciej Fijalkowski int subprog_tail_1(struct __sk_buff *skb)
413b037911SMaciej Fijalkowski {
42faef26faSDaniel Borkmann 	bpf_tail_call_static(skb, &jmp_table, 1);
433b037911SMaciej Fijalkowski 	return skb->len * 2;
443b037911SMaciej Fijalkowski }
453b037911SMaciej Fijalkowski 
463b037911SMaciej Fijalkowski __noinline
subprog_tail(struct __sk_buff * skb)473b037911SMaciej Fijalkowski int subprog_tail(struct __sk_buff *skb)
483b037911SMaciej Fijalkowski {
49faef26faSDaniel Borkmann 	bpf_tail_call_static(skb, &jmp_table, 0);
503b037911SMaciej Fijalkowski 	return skb->len;
513b037911SMaciej Fijalkowski }
523b037911SMaciej Fijalkowski 
53c22bdd28SAndrii Nakryiko SEC("tc")
classifier_1(struct __sk_buff * skb)54c22bdd28SAndrii Nakryiko int classifier_1(struct __sk_buff *skb)
553b037911SMaciej Fijalkowski {
563b037911SMaciej Fijalkowski 	return subprog_tail_2(skb);
573b037911SMaciej Fijalkowski }
583b037911SMaciej Fijalkowski 
59c22bdd28SAndrii Nakryiko SEC("tc")
classifier_2(struct __sk_buff * skb)60c22bdd28SAndrii Nakryiko int classifier_2(struct __sk_buff *skb)
613b037911SMaciej Fijalkowski {
623b037911SMaciej Fijalkowski 	count++;
633b037911SMaciej Fijalkowski 	return subprog_tail_2(skb);
643b037911SMaciej Fijalkowski }
653b037911SMaciej Fijalkowski 
66c22bdd28SAndrii Nakryiko SEC("tc")
classifier_0(struct __sk_buff * skb)67c22bdd28SAndrii Nakryiko int classifier_0(struct __sk_buff *skb)
683b037911SMaciej Fijalkowski {
693b037911SMaciej Fijalkowski 	return subprog_tail_1(skb);
703b037911SMaciej Fijalkowski }
713b037911SMaciej Fijalkowski 
72c22bdd28SAndrii Nakryiko SEC("tc")
entry(struct __sk_buff * skb)733b037911SMaciej Fijalkowski int entry(struct __sk_buff *skb)
743b037911SMaciej Fijalkowski {
753b037911SMaciej Fijalkowski 	return subprog_tail(skb);
763b037911SMaciej Fijalkowski }
773b037911SMaciej Fijalkowski 
783b037911SMaciej Fijalkowski char __license[] SEC("license") = "GPL";
79