1// SPDX-License-Identifier: GPL-2.0
2#include <vmlinux.h>
3#include <bpf/bpf_tracing.h>
4#include <bpf/bpf_helpers.h>
5#include <bpf/bpf_core_read.h>
6
7struct nf_conn;
8
9struct bpf_ct_opts___local {
10	s32 netns_id;
11	s32 error;
12	u8 l4proto;
13	u8 reserved[3];
14} __attribute__((preserve_access_index));
15
16struct nf_conn *bpf_skb_ct_alloc(struct __sk_buff *, struct bpf_sock_tuple *, u32,
17				 struct bpf_ct_opts___local *, u32) __ksym;
18struct nf_conn *bpf_skb_ct_lookup(struct __sk_buff *, struct bpf_sock_tuple *, u32,
19				  struct bpf_ct_opts___local *, u32) __ksym;
20struct nf_conn *bpf_ct_insert_entry(struct nf_conn *) __ksym;
21void bpf_ct_release(struct nf_conn *) __ksym;
22void bpf_ct_set_timeout(struct nf_conn *, u32) __ksym;
23int bpf_ct_change_timeout(struct nf_conn *, u32) __ksym;
24int bpf_ct_set_status(struct nf_conn *, u32) __ksym;
25int bpf_ct_change_status(struct nf_conn *, u32) __ksym;
26
27SEC("?tc")
28int alloc_release(struct __sk_buff *ctx)
29{
30	struct bpf_ct_opts___local opts = {};
31	struct bpf_sock_tuple tup = {};
32	struct nf_conn *ct;
33
34	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
35	if (!ct)
36		return 0;
37	bpf_ct_release(ct);
38	return 0;
39}
40
41SEC("?tc")
42int insert_insert(struct __sk_buff *ctx)
43{
44	struct bpf_ct_opts___local opts = {};
45	struct bpf_sock_tuple tup = {};
46	struct nf_conn *ct;
47
48	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
49	if (!ct)
50		return 0;
51	ct = bpf_ct_insert_entry(ct);
52	if (!ct)
53		return 0;
54	ct = bpf_ct_insert_entry(ct);
55	return 0;
56}
57
58SEC("?tc")
59int lookup_insert(struct __sk_buff *ctx)
60{
61	struct bpf_ct_opts___local opts = {};
62	struct bpf_sock_tuple tup = {};
63	struct nf_conn *ct;
64
65	ct = bpf_skb_ct_lookup(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
66	if (!ct)
67		return 0;
68	bpf_ct_insert_entry(ct);
69	return 0;
70}
71
72SEC("?tc")
73int write_not_allowlisted_field(struct __sk_buff *ctx)
74{
75	struct bpf_ct_opts___local opts = {};
76	struct bpf_sock_tuple tup = {};
77	struct nf_conn *ct;
78
79	ct = bpf_skb_ct_lookup(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
80	if (!ct)
81		return 0;
82	ct->status = 0xF00;
83	return 0;
84}
85
86SEC("?tc")
87int set_timeout_after_insert(struct __sk_buff *ctx)
88{
89	struct bpf_ct_opts___local opts = {};
90	struct bpf_sock_tuple tup = {};
91	struct nf_conn *ct;
92
93	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
94	if (!ct)
95		return 0;
96	ct = bpf_ct_insert_entry(ct);
97	if (!ct)
98		return 0;
99	bpf_ct_set_timeout(ct, 0);
100	return 0;
101}
102
103SEC("?tc")
104int set_status_after_insert(struct __sk_buff *ctx)
105{
106	struct bpf_ct_opts___local opts = {};
107	struct bpf_sock_tuple tup = {};
108	struct nf_conn *ct;
109
110	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
111	if (!ct)
112		return 0;
113	ct = bpf_ct_insert_entry(ct);
114	if (!ct)
115		return 0;
116	bpf_ct_set_status(ct, 0);
117	return 0;
118}
119
120SEC("?tc")
121int change_timeout_after_alloc(struct __sk_buff *ctx)
122{
123	struct bpf_ct_opts___local opts = {};
124	struct bpf_sock_tuple tup = {};
125	struct nf_conn *ct;
126
127	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
128	if (!ct)
129		return 0;
130	bpf_ct_change_timeout(ct, 0);
131	return 0;
132}
133
134SEC("?tc")
135int change_status_after_alloc(struct __sk_buff *ctx)
136{
137	struct bpf_ct_opts___local opts = {};
138	struct bpf_sock_tuple tup = {};
139	struct nf_conn *ct;
140
141	ct = bpf_skb_ct_alloc(ctx, &tup, sizeof(tup.ipv4), &opts, sizeof(opts));
142	if (!ct)
143		return 0;
144	bpf_ct_change_status(ct, 0);
145	return 0;
146}
147
148char _license[] SEC("license") = "GPL";
149