13b037911SMaciej Fijalkowski // SPDX-License-Identifier: GPL-2.0
23b037911SMaciej Fijalkowski #include <linux/bpf.h>
33b037911SMaciej Fijalkowski #include <bpf/bpf_helpers.h>
43b037911SMaciej Fijalkowski #include "bpf_legacy.h"
5*c8ed6685SAndrii Nakryiko #include "bpf_misc.h"
63b037911SMaciej Fijalkowski 
73b037911SMaciej Fijalkowski struct {
83b037911SMaciej Fijalkowski 	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
93b037911SMaciej Fijalkowski 	__uint(max_entries, 2);
103b037911SMaciej Fijalkowski 	__uint(key_size, sizeof(__u32));
113b037911SMaciej Fijalkowski 	__uint(value_size, sizeof(__u32));
123b037911SMaciej Fijalkowski } jmp_table SEC(".maps");
133b037911SMaciej Fijalkowski 
143b037911SMaciej Fijalkowski __noinline
subprog_tail2(struct __sk_buff * skb)153b037911SMaciej Fijalkowski int subprog_tail2(struct __sk_buff *skb)
163b037911SMaciej Fijalkowski {
173b037911SMaciej Fijalkowski 	volatile char arr[64] = {};
183b037911SMaciej Fijalkowski 
193b037911SMaciej Fijalkowski 	if (load_word(skb, 0) || load_half(skb, 0))
20faef26faSDaniel Borkmann 		bpf_tail_call_static(skb, &jmp_table, 10);
213b037911SMaciej Fijalkowski 	else
22faef26faSDaniel Borkmann 		bpf_tail_call_static(skb, &jmp_table, 1);
233b037911SMaciej Fijalkowski 
24*c8ed6685SAndrii Nakryiko 	__sink(arr[sizeof(arr) - 1]);
25*c8ed6685SAndrii Nakryiko 
263b037911SMaciej Fijalkowski 	return skb->len;
273b037911SMaciej Fijalkowski }
283b037911SMaciej Fijalkowski 
293b037911SMaciej Fijalkowski static __noinline
subprog_tail(struct __sk_buff * skb)303b037911SMaciej Fijalkowski int subprog_tail(struct __sk_buff *skb)
313b037911SMaciej Fijalkowski {
323b037911SMaciej Fijalkowski 	volatile char arr[64] = {};
333b037911SMaciej Fijalkowski 
34faef26faSDaniel Borkmann 	bpf_tail_call_static(skb, &jmp_table, 0);
353b037911SMaciej Fijalkowski 
36*c8ed6685SAndrii Nakryiko 	__sink(arr[sizeof(arr) - 1]);
37*c8ed6685SAndrii Nakryiko 
383b037911SMaciej Fijalkowski 	return skb->len * 2;
393b037911SMaciej Fijalkowski }
403b037911SMaciej Fijalkowski 
41c22bdd28SAndrii Nakryiko SEC("tc")
classifier_0(struct __sk_buff * skb)42c22bdd28SAndrii Nakryiko int classifier_0(struct __sk_buff *skb)
433b037911SMaciej Fijalkowski {
443b037911SMaciej Fijalkowski 	volatile char arr[128] = {};
453b037911SMaciej Fijalkowski 
46*c8ed6685SAndrii Nakryiko 	__sink(arr[sizeof(arr) - 1]);
47*c8ed6685SAndrii Nakryiko 
483b037911SMaciej Fijalkowski 	return subprog_tail2(skb);
493b037911SMaciej Fijalkowski }
503b037911SMaciej Fijalkowski 
51c22bdd28SAndrii Nakryiko SEC("tc")
classifier_1(struct __sk_buff * skb)52c22bdd28SAndrii Nakryiko int classifier_1(struct __sk_buff *skb)
533b037911SMaciej Fijalkowski {
543b037911SMaciej Fijalkowski 	volatile char arr[128] = {};
553b037911SMaciej Fijalkowski 
56*c8ed6685SAndrii Nakryiko 	__sink(arr[sizeof(arr) - 1]);
57*c8ed6685SAndrii Nakryiko 
583b037911SMaciej Fijalkowski 	return skb->len * 3;
593b037911SMaciej Fijalkowski }
603b037911SMaciej Fijalkowski 
61c22bdd28SAndrii Nakryiko SEC("tc")
entry(struct __sk_buff * skb)623b037911SMaciej Fijalkowski int entry(struct __sk_buff *skb)
633b037911SMaciej Fijalkowski {
643b037911SMaciej Fijalkowski 	volatile char arr[128] = {};
653b037911SMaciej Fijalkowski 
66*c8ed6685SAndrii Nakryiko 	__sink(arr[sizeof(arr) - 1]);
67*c8ed6685SAndrii Nakryiko 
683b037911SMaciej Fijalkowski 	return subprog_tail(skb);
693b037911SMaciej Fijalkowski }
703b037911SMaciej Fijalkowski 
713b037911SMaciej Fijalkowski char __license[] SEC("license") = "GPL";
72