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 {
63b037911SMaciej Fijalkowski 	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
73b037911SMaciej Fijalkowski 	__uint(max_entries, 2);
83b037911SMaciej Fijalkowski 	__uint(key_size, sizeof(__u32));
93b037911SMaciej Fijalkowski 	__uint(value_size, sizeof(__u32));
103b037911SMaciej Fijalkowski } jmp_table SEC(".maps");
113b037911SMaciej Fijalkowski 
123b037911SMaciej Fijalkowski #define TAIL_FUNC(x) 				\
13*c22bdd28SAndrii Nakryiko 	SEC("tc")				\
14*c22bdd28SAndrii Nakryiko 	int classifier_##x(struct __sk_buff *skb)	\
153b037911SMaciej Fijalkowski 	{					\
163b037911SMaciej Fijalkowski 		return x;			\
173b037911SMaciej Fijalkowski 	}
183b037911SMaciej Fijalkowski TAIL_FUNC(0)
193b037911SMaciej Fijalkowski TAIL_FUNC(1)
203b037911SMaciej Fijalkowski 
213b037911SMaciej Fijalkowski static __noinline
subprog_tail(struct __sk_buff * skb)223b037911SMaciej Fijalkowski int subprog_tail(struct __sk_buff *skb)
233b037911SMaciej Fijalkowski {
24faef26faSDaniel Borkmann 	bpf_tail_call_static(skb, &jmp_table, 0);
253b037911SMaciej Fijalkowski 
263b037911SMaciej Fijalkowski 	return skb->len * 2;
273b037911SMaciej Fijalkowski }
283b037911SMaciej Fijalkowski 
29*c22bdd28SAndrii Nakryiko SEC("tc")
entry(struct __sk_buff * skb)303b037911SMaciej Fijalkowski int entry(struct __sk_buff *skb)
313b037911SMaciej Fijalkowski {
32faef26faSDaniel Borkmann 	bpf_tail_call_static(skb, &jmp_table, 1);
333b037911SMaciej Fijalkowski 
343b037911SMaciej Fijalkowski 	return subprog_tail(skb);
353b037911SMaciej Fijalkowski }
363b037911SMaciej Fijalkowski 
373b037911SMaciej Fijalkowski char __license[] SEC("license") = "GPL";
38