1102782Skan// SPDX-License-Identifier: GPL-2.0
2102782Skan#include <vmlinux.h>
3102782Skan#include <bpf/bpf_helpers.h>
4102782Skan
5102782Skan#include "bpf_misc.h"
6102782Skan
7102782Skanstruct hmap_elem {
8102782Skan	struct bpf_timer timer;
9102782Skan};
10102782Skan
11102782Skanstruct {
12102782Skan	__uint(type, BPF_MAP_TYPE_HASH);
13102782Skan	__uint(max_entries, 64);
14102782Skan	__type(key, int);
15102782Skan	__type(value, struct hmap_elem);
16102782Skan} hmap SEC(".maps");
17102782Skan
18169691Skan__attribute__((noinline))
19102782Skanstatic int timer_cb(void *map, int *key, struct bpf_timer *timer)
20102782Skan{
21102782Skan	volatile char buf[256] = {};
22102782Skan	return buf[69];
23102782Skan}
24102782Skan
25102782Skan__attribute__((noinline))
26102782Skanstatic int bad_timer_cb(void *map, int *key, struct bpf_timer *timer)
27102782Skan{
28102782Skan	volatile char buf[300] = {};
29102782Skan	return buf[255] + timer_cb(NULL, NULL, NULL);
30132720Skan}
31132720Skan
32102782SkanSEC("tc")
33102782Skan__failure __msg("combined stack size of 2 calls is")
34132720Skanint pseudo_call_check(struct __sk_buff *ctx)
35102782Skan{
36102782Skan	struct hmap_elem *elem;
37102782Skan	volatile char buf[256] = {};
38102782Skan
39102782Skan	elem = bpf_map_lookup_elem(&hmap, &(int){0});
40102782Skan	if (!elem)
41102782Skan		return 0;
42102782Skan
43102782Skan	timer_cb(NULL, NULL, NULL);
44102782Skan	return bpf_timer_set_callback(&elem->timer, timer_cb) + buf[0];
45102782Skan}
46102782Skan
47102782SkanSEC("tc")
48102782Skan__failure __msg("combined stack size of 2 calls is")
49102782Skanint async_call_root_check(struct __sk_buff *ctx)
50102782Skan{
51102782Skan	struct hmap_elem *elem;
52102782Skan	volatile char buf[256] = {};
53102782Skan
54102782Skan	elem = bpf_map_lookup_elem(&hmap, &(int){0});
55102782Skan	if (!elem)
56102782Skan		return 0;
57102782Skan
58102782Skan	return bpf_timer_set_callback(&elem->timer, bad_timer_cb) + buf[0];
59102782Skan}
60102782Skan
61char _license[] SEC("license") = "GPL";
62