162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <linux/bpf.h>
362306a36Sopenharmony_ci#include <bpf/bpf_helpers.h>
462306a36Sopenharmony_ci#include "bpf_legacy.h"
562306a36Sopenharmony_ci#include "bpf_misc.h"
662306a36Sopenharmony_ci
762306a36Sopenharmony_cistruct {
862306a36Sopenharmony_ci	__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
962306a36Sopenharmony_ci	__uint(max_entries, 2);
1062306a36Sopenharmony_ci	__uint(key_size, sizeof(__u32));
1162306a36Sopenharmony_ci	__uint(value_size, sizeof(__u32));
1262306a36Sopenharmony_ci} jmp_table SEC(".maps");
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci__noinline
1562306a36Sopenharmony_ciint subprog_tail2(struct __sk_buff *skb)
1662306a36Sopenharmony_ci{
1762306a36Sopenharmony_ci	volatile char arr[64] = {};
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci	if (load_word(skb, 0) || load_half(skb, 0))
2062306a36Sopenharmony_ci		bpf_tail_call_static(skb, &jmp_table, 10);
2162306a36Sopenharmony_ci	else
2262306a36Sopenharmony_ci		bpf_tail_call_static(skb, &jmp_table, 1);
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci	__sink(arr[sizeof(arr) - 1]);
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci	return skb->len;
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic __noinline
3062306a36Sopenharmony_ciint subprog_tail(struct __sk_buff *skb)
3162306a36Sopenharmony_ci{
3262306a36Sopenharmony_ci	volatile char arr[64] = {};
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci	bpf_tail_call_static(skb, &jmp_table, 0);
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	__sink(arr[sizeof(arr) - 1]);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	return skb->len * 2;
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ciSEC("tc")
4262306a36Sopenharmony_ciint classifier_0(struct __sk_buff *skb)
4362306a36Sopenharmony_ci{
4462306a36Sopenharmony_ci	volatile char arr[128] = {};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	__sink(arr[sizeof(arr) - 1]);
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	return subprog_tail2(skb);
4962306a36Sopenharmony_ci}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ciSEC("tc")
5262306a36Sopenharmony_ciint classifier_1(struct __sk_buff *skb)
5362306a36Sopenharmony_ci{
5462306a36Sopenharmony_ci	volatile char arr[128] = {};
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	__sink(arr[sizeof(arr) - 1]);
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	return skb->len * 3;
5962306a36Sopenharmony_ci}
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ciSEC("tc")
6262306a36Sopenharmony_ciint entry(struct __sk_buff *skb)
6362306a36Sopenharmony_ci{
6462306a36Sopenharmony_ci	volatile char arr[128] = {};
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci	__sink(arr[sizeof(arr) - 1]);
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci	return subprog_tail(skb);
6962306a36Sopenharmony_ci}
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cichar __license[] SEC("license") = "GPL";
72