1991e35eeSJohn Fastabend /* SPDX-License-Identifier: GPL-2.0 */
2991e35eeSJohn Fastabend /* Copyright (c) 2017-2018 Covalent IO, Inc. http://covalent.io */
3991e35eeSJohn Fastabend #include <stddef.h>
4991e35eeSJohn Fastabend #include <string.h>
5991e35eeSJohn Fastabend #include <linux/bpf.h>
6991e35eeSJohn Fastabend #include <linux/if_ether.h>
7991e35eeSJohn Fastabend #include <linux/if_packet.h>
8991e35eeSJohn Fastabend #include <linux/ip.h>
9991e35eeSJohn Fastabend #include <linux/ipv6.h>
10991e35eeSJohn Fastabend #include <linux/in.h>
11991e35eeSJohn Fastabend #include <linux/udp.h>
12991e35eeSJohn Fastabend #include <linux/tcp.h>
13991e35eeSJohn Fastabend #include <linux/pkt_cls.h>
14991e35eeSJohn Fastabend #include <sys/socket.h>
15991e35eeSJohn Fastabend #include <bpf/bpf_helpers.h>
16991e35eeSJohn Fastabend #include <bpf/bpf_endian.h>
17991e35eeSJohn Fastabend 
18991e35eeSJohn Fastabend /* Sockmap sample program connects a client and a backend together
19991e35eeSJohn Fastabend  * using cgroups.
20991e35eeSJohn Fastabend  *
21991e35eeSJohn Fastabend  *    client:X <---> frontend:80 client:X <---> backend:80
22991e35eeSJohn Fastabend  *
23991e35eeSJohn Fastabend  * For simplicity we hard code values here and bind 1:1. The hard
24991e35eeSJohn Fastabend  * coded values are part of the setup in sockmap.sh script that
25991e35eeSJohn Fastabend  * is associated with this BPF program.
26991e35eeSJohn Fastabend  *
27991e35eeSJohn Fastabend  * The bpf_printk is verbose and prints information as connections
28991e35eeSJohn Fastabend  * are established and verdicts are decided.
29991e35eeSJohn Fastabend  */
30991e35eeSJohn Fastabend 
31991e35eeSJohn Fastabend struct {
32991e35eeSJohn Fastabend 	__uint(type, TEST_MAP_TYPE);
33991e35eeSJohn Fastabend 	__uint(max_entries, 20);
34991e35eeSJohn Fastabend 	__uint(key_size, sizeof(int));
35991e35eeSJohn Fastabend 	__uint(value_size, sizeof(int));
36991e35eeSJohn Fastabend } sock_map SEC(".maps");
37991e35eeSJohn Fastabend 
38991e35eeSJohn Fastabend struct {
39991e35eeSJohn Fastabend 	__uint(type, TEST_MAP_TYPE);
40991e35eeSJohn Fastabend 	__uint(max_entries, 20);
41991e35eeSJohn Fastabend 	__uint(key_size, sizeof(int));
42991e35eeSJohn Fastabend 	__uint(value_size, sizeof(int));
43991e35eeSJohn Fastabend } sock_map_txmsg SEC(".maps");
44991e35eeSJohn Fastabend 
45991e35eeSJohn Fastabend struct {
46991e35eeSJohn Fastabend 	__uint(type, TEST_MAP_TYPE);
47991e35eeSJohn Fastabend 	__uint(max_entries, 20);
48991e35eeSJohn Fastabend 	__uint(key_size, sizeof(int));
49991e35eeSJohn Fastabend 	__uint(value_size, sizeof(int));
50991e35eeSJohn Fastabend } sock_map_redir SEC(".maps");
51991e35eeSJohn Fastabend 
52991e35eeSJohn Fastabend struct {
53991e35eeSJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
54991e35eeSJohn Fastabend 	__uint(max_entries, 1);
55991e35eeSJohn Fastabend 	__type(key, int);
56991e35eeSJohn Fastabend 	__type(value, int);
57991e35eeSJohn Fastabend } sock_apply_bytes SEC(".maps");
58991e35eeSJohn Fastabend 
59991e35eeSJohn Fastabend struct {
60991e35eeSJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
61991e35eeSJohn Fastabend 	__uint(max_entries, 1);
62991e35eeSJohn Fastabend 	__type(key, int);
63991e35eeSJohn Fastabend 	__type(value, int);
64991e35eeSJohn Fastabend } sock_cork_bytes SEC(".maps");
65991e35eeSJohn Fastabend 
66991e35eeSJohn Fastabend struct {
67991e35eeSJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
68991e35eeSJohn Fastabend 	__uint(max_entries, 6);
69991e35eeSJohn Fastabend 	__type(key, int);
70991e35eeSJohn Fastabend 	__type(value, int);
71991e35eeSJohn Fastabend } sock_bytes SEC(".maps");
72991e35eeSJohn Fastabend 
73991e35eeSJohn Fastabend struct {
74991e35eeSJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
75991e35eeSJohn Fastabend 	__uint(max_entries, 1);
76991e35eeSJohn Fastabend 	__type(key, int);
77991e35eeSJohn Fastabend 	__type(value, int);
78991e35eeSJohn Fastabend } sock_redir_flags SEC(".maps");
79991e35eeSJohn Fastabend 
80991e35eeSJohn Fastabend struct {
81991e35eeSJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
8253792fa4SJohn Fastabend 	__uint(max_entries, 3);
83991e35eeSJohn Fastabend 	__type(key, int);
84991e35eeSJohn Fastabend 	__type(value, int);
85991e35eeSJohn Fastabend } sock_skb_opts SEC(".maps");
86991e35eeSJohn Fastabend 
87463bac5fSJohn Fastabend struct {
88463bac5fSJohn Fastabend 	__uint(type, TEST_MAP_TYPE);
89463bac5fSJohn Fastabend 	__uint(max_entries, 20);
90463bac5fSJohn Fastabend 	__uint(key_size, sizeof(int));
91463bac5fSJohn Fastabend 	__uint(value_size, sizeof(int));
92463bac5fSJohn Fastabend } tls_sock_map SEC(".maps");
93463bac5fSJohn Fastabend 
94991e35eeSJohn Fastabend SEC("sk_skb1")
95991e35eeSJohn Fastabend int bpf_prog1(struct __sk_buff *skb)
96991e35eeSJohn Fastabend {
9753792fa4SJohn Fastabend 	int *f, two = 2;
9853792fa4SJohn Fastabend 
9953792fa4SJohn Fastabend 	f = bpf_map_lookup_elem(&sock_skb_opts, &two);
10053792fa4SJohn Fastabend 	if (f && *f) {
10153792fa4SJohn Fastabend 		return *f;
10253792fa4SJohn Fastabend 	}
103991e35eeSJohn Fastabend 	return skb->len;
104991e35eeSJohn Fastabend }
105991e35eeSJohn Fastabend 
106991e35eeSJohn Fastabend SEC("sk_skb2")
107991e35eeSJohn Fastabend int bpf_prog2(struct __sk_buff *skb)
108991e35eeSJohn Fastabend {
109991e35eeSJohn Fastabend 	__u32 lport = skb->local_port;
110991e35eeSJohn Fastabend 	__u32 rport = skb->remote_port;
111991e35eeSJohn Fastabend 	int len, *f, ret, zero = 0;
112991e35eeSJohn Fastabend 	__u64 flags = 0;
113991e35eeSJohn Fastabend 
114991e35eeSJohn Fastabend 	if (lport == 10000)
115991e35eeSJohn Fastabend 		ret = 10;
116991e35eeSJohn Fastabend 	else
117991e35eeSJohn Fastabend 		ret = 1;
118991e35eeSJohn Fastabend 
119991e35eeSJohn Fastabend 	len = (__u32)skb->data_end - (__u32)skb->data;
120991e35eeSJohn Fastabend 	f = bpf_map_lookup_elem(&sock_skb_opts, &zero);
121991e35eeSJohn Fastabend 	if (f && *f) {
122991e35eeSJohn Fastabend 		ret = 3;
123991e35eeSJohn Fastabend 		flags = *f;
124991e35eeSJohn Fastabend 	}
125991e35eeSJohn Fastabend 
126991e35eeSJohn Fastabend #ifdef SOCKMAP
127991e35eeSJohn Fastabend 	return bpf_sk_redirect_map(skb, &sock_map, ret, flags);
128991e35eeSJohn Fastabend #else
129991e35eeSJohn Fastabend 	return bpf_sk_redirect_hash(skb, &sock_map, &ret, flags);
130991e35eeSJohn Fastabend #endif
131991e35eeSJohn Fastabend 
132991e35eeSJohn Fastabend }
133991e35eeSJohn Fastabend 
134463bac5fSJohn Fastabend SEC("sk_skb3")
135463bac5fSJohn Fastabend int bpf_prog3(struct __sk_buff *skb)
136463bac5fSJohn Fastabend {
137463bac5fSJohn Fastabend 	const int one = 1;
138463bac5fSJohn Fastabend 	int err, *f, ret = SK_PASS;
139463bac5fSJohn Fastabend 	void *data_end;
140463bac5fSJohn Fastabend 	char *c;
141463bac5fSJohn Fastabend 
142463bac5fSJohn Fastabend 	err = bpf_skb_pull_data(skb, 19);
143463bac5fSJohn Fastabend 	if (err)
144463bac5fSJohn Fastabend 		goto tls_out;
145463bac5fSJohn Fastabend 
146463bac5fSJohn Fastabend 	c = (char *)(long)skb->data;
147463bac5fSJohn Fastabend 	data_end = (void *)(long)skb->data_end;
148463bac5fSJohn Fastabend 
149463bac5fSJohn Fastabend 	if (c + 18 < data_end)
150463bac5fSJohn Fastabend 		memcpy(&c[13], "PASS", 4);
151463bac5fSJohn Fastabend 	f = bpf_map_lookup_elem(&sock_skb_opts, &one);
152463bac5fSJohn Fastabend 	if (f && *f) {
153463bac5fSJohn Fastabend 		__u64 flags = 0;
154463bac5fSJohn Fastabend 
155463bac5fSJohn Fastabend 		ret = 0;
156463bac5fSJohn Fastabend 		flags = *f;
157463bac5fSJohn Fastabend #ifdef SOCKMAP
158463bac5fSJohn Fastabend 		return bpf_sk_redirect_map(skb, &tls_sock_map, ret, flags);
159463bac5fSJohn Fastabend #else
160463bac5fSJohn Fastabend 		return bpf_sk_redirect_hash(skb, &tls_sock_map, &ret, flags);
161463bac5fSJohn Fastabend #endif
162463bac5fSJohn Fastabend 	}
163463bac5fSJohn Fastabend 
164463bac5fSJohn Fastabend 	f = bpf_map_lookup_elem(&sock_skb_opts, &one);
165463bac5fSJohn Fastabend 	if (f && *f)
166463bac5fSJohn Fastabend 		ret = SK_DROP;
167463bac5fSJohn Fastabend tls_out:
168463bac5fSJohn Fastabend 	return ret;
169463bac5fSJohn Fastabend }
170463bac5fSJohn Fastabend 
171991e35eeSJohn Fastabend SEC("sockops")
172991e35eeSJohn Fastabend int bpf_sockmap(struct bpf_sock_ops *skops)
173991e35eeSJohn Fastabend {
174991e35eeSJohn Fastabend 	__u32 lport, rport;
175991e35eeSJohn Fastabend 	int op, err = 0, index, key, ret;
176991e35eeSJohn Fastabend 
177991e35eeSJohn Fastabend 
178991e35eeSJohn Fastabend 	op = (int) skops->op;
179991e35eeSJohn Fastabend 
180991e35eeSJohn Fastabend 	switch (op) {
181991e35eeSJohn Fastabend 	case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
182991e35eeSJohn Fastabend 		lport = skops->local_port;
183991e35eeSJohn Fastabend 		rport = skops->remote_port;
184991e35eeSJohn Fastabend 
185991e35eeSJohn Fastabend 		if (lport == 10000) {
186991e35eeSJohn Fastabend 			ret = 1;
187991e35eeSJohn Fastabend #ifdef SOCKMAP
188991e35eeSJohn Fastabend 			err = bpf_sock_map_update(skops, &sock_map, &ret,
189991e35eeSJohn Fastabend 						  BPF_NOEXIST);
190991e35eeSJohn Fastabend #else
191991e35eeSJohn Fastabend 			err = bpf_sock_hash_update(skops, &sock_map, &ret,
192991e35eeSJohn Fastabend 						   BPF_NOEXIST);
193991e35eeSJohn Fastabend #endif
194991e35eeSJohn Fastabend 		}
195991e35eeSJohn Fastabend 		break;
196991e35eeSJohn Fastabend 	case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
197991e35eeSJohn Fastabend 		lport = skops->local_port;
198991e35eeSJohn Fastabend 		rport = skops->remote_port;
199991e35eeSJohn Fastabend 
200991e35eeSJohn Fastabend 		if (bpf_ntohl(rport) == 10001) {
201991e35eeSJohn Fastabend 			ret = 10;
202991e35eeSJohn Fastabend #ifdef SOCKMAP
203991e35eeSJohn Fastabend 			err = bpf_sock_map_update(skops, &sock_map, &ret,
204991e35eeSJohn Fastabend 						  BPF_NOEXIST);
205991e35eeSJohn Fastabend #else
206991e35eeSJohn Fastabend 			err = bpf_sock_hash_update(skops, &sock_map, &ret,
207991e35eeSJohn Fastabend 						   BPF_NOEXIST);
208991e35eeSJohn Fastabend #endif
209991e35eeSJohn Fastabend 		}
210991e35eeSJohn Fastabend 		break;
211991e35eeSJohn Fastabend 	default:
212991e35eeSJohn Fastabend 		break;
213991e35eeSJohn Fastabend 	}
214991e35eeSJohn Fastabend 
215991e35eeSJohn Fastabend 	return 0;
216991e35eeSJohn Fastabend }
217991e35eeSJohn Fastabend 
218991e35eeSJohn Fastabend SEC("sk_msg1")
219991e35eeSJohn Fastabend int bpf_prog4(struct sk_msg_md *msg)
220991e35eeSJohn Fastabend {
221991e35eeSJohn Fastabend 	int *bytes, zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5;
222991e35eeSJohn Fastabend 	int *start, *end, *start_push, *end_push, *start_pop, *pop;
223991e35eeSJohn Fastabend 
224991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
225991e35eeSJohn Fastabend 	if (bytes)
226991e35eeSJohn Fastabend 		bpf_msg_apply_bytes(msg, *bytes);
227991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
228991e35eeSJohn Fastabend 	if (bytes)
229991e35eeSJohn Fastabend 		bpf_msg_cork_bytes(msg, *bytes);
230991e35eeSJohn Fastabend 	start = bpf_map_lookup_elem(&sock_bytes, &zero);
231991e35eeSJohn Fastabend 	end = bpf_map_lookup_elem(&sock_bytes, &one);
232991e35eeSJohn Fastabend 	if (start && end)
233991e35eeSJohn Fastabend 		bpf_msg_pull_data(msg, *start, *end, 0);
234991e35eeSJohn Fastabend 	start_push = bpf_map_lookup_elem(&sock_bytes, &two);
235991e35eeSJohn Fastabend 	end_push = bpf_map_lookup_elem(&sock_bytes, &three);
236991e35eeSJohn Fastabend 	if (start_push && end_push)
237991e35eeSJohn Fastabend 		bpf_msg_push_data(msg, *start_push, *end_push, 0);
238991e35eeSJohn Fastabend 	start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
239991e35eeSJohn Fastabend 	pop = bpf_map_lookup_elem(&sock_bytes, &five);
240991e35eeSJohn Fastabend 	if (start_pop && pop)
241991e35eeSJohn Fastabend 		bpf_msg_pop_data(msg, *start_pop, *pop, 0);
242991e35eeSJohn Fastabend 	return SK_PASS;
243991e35eeSJohn Fastabend }
244991e35eeSJohn Fastabend 
245991e35eeSJohn Fastabend SEC("sk_msg2")
246991e35eeSJohn Fastabend int bpf_prog6(struct sk_msg_md *msg)
247991e35eeSJohn Fastabend {
248991e35eeSJohn Fastabend 	int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5, key = 0;
249991e35eeSJohn Fastabend 	int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop, *f;
250991e35eeSJohn Fastabend 	__u64 flags = 0;
251991e35eeSJohn Fastabend 
252991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
253991e35eeSJohn Fastabend 	if (bytes)
254991e35eeSJohn Fastabend 		bpf_msg_apply_bytes(msg, *bytes);
255991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
256991e35eeSJohn Fastabend 	if (bytes)
257991e35eeSJohn Fastabend 		bpf_msg_cork_bytes(msg, *bytes);
258991e35eeSJohn Fastabend 
259991e35eeSJohn Fastabend 	start = bpf_map_lookup_elem(&sock_bytes, &zero);
260991e35eeSJohn Fastabend 	end = bpf_map_lookup_elem(&sock_bytes, &one);
261991e35eeSJohn Fastabend 	if (start && end)
262991e35eeSJohn Fastabend 		bpf_msg_pull_data(msg, *start, *end, 0);
263991e35eeSJohn Fastabend 
264991e35eeSJohn Fastabend 	start_push = bpf_map_lookup_elem(&sock_bytes, &two);
265991e35eeSJohn Fastabend 	end_push = bpf_map_lookup_elem(&sock_bytes, &three);
266991e35eeSJohn Fastabend 	if (start_push && end_push)
267991e35eeSJohn Fastabend 		bpf_msg_push_data(msg, *start_push, *end_push, 0);
268991e35eeSJohn Fastabend 
269991e35eeSJohn Fastabend 	start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
270991e35eeSJohn Fastabend 	pop = bpf_map_lookup_elem(&sock_bytes, &five);
271991e35eeSJohn Fastabend 	if (start_pop && pop)
272991e35eeSJohn Fastabend 		bpf_msg_pop_data(msg, *start_pop, *pop, 0);
273991e35eeSJohn Fastabend 
274991e35eeSJohn Fastabend 	f = bpf_map_lookup_elem(&sock_redir_flags, &zero);
275991e35eeSJohn Fastabend 	if (f && *f) {
276991e35eeSJohn Fastabend 		key = 2;
277991e35eeSJohn Fastabend 		flags = *f;
278991e35eeSJohn Fastabend 	}
279991e35eeSJohn Fastabend #ifdef SOCKMAP
280991e35eeSJohn Fastabend 	return bpf_msg_redirect_map(msg, &sock_map_redir, key, flags);
281991e35eeSJohn Fastabend #else
282991e35eeSJohn Fastabend 	return bpf_msg_redirect_hash(msg, &sock_map_redir, &key, flags);
283991e35eeSJohn Fastabend #endif
284991e35eeSJohn Fastabend }
285991e35eeSJohn Fastabend 
286d79a3212SJohn Fastabend SEC("sk_msg3")
287991e35eeSJohn Fastabend int bpf_prog8(struct sk_msg_md *msg)
288991e35eeSJohn Fastabend {
289991e35eeSJohn Fastabend 	void *data_end = (void *)(long) msg->data_end;
290991e35eeSJohn Fastabend 	void *data = (void *)(long) msg->data;
291991e35eeSJohn Fastabend 	int ret = 0, *bytes, zero = 0;
292991e35eeSJohn Fastabend 
293991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
294991e35eeSJohn Fastabend 	if (bytes) {
295991e35eeSJohn Fastabend 		ret = bpf_msg_apply_bytes(msg, *bytes);
296991e35eeSJohn Fastabend 		if (ret)
297991e35eeSJohn Fastabend 			return SK_DROP;
298991e35eeSJohn Fastabend 	} else {
299991e35eeSJohn Fastabend 		return SK_DROP;
300991e35eeSJohn Fastabend 	}
301991e35eeSJohn Fastabend 	return SK_PASS;
302991e35eeSJohn Fastabend }
303d79a3212SJohn Fastabend SEC("sk_msg4")
304991e35eeSJohn Fastabend int bpf_prog9(struct sk_msg_md *msg)
305991e35eeSJohn Fastabend {
306991e35eeSJohn Fastabend 	void *data_end = (void *)(long) msg->data_end;
307991e35eeSJohn Fastabend 	void *data = (void *)(long) msg->data;
308991e35eeSJohn Fastabend 	int ret = 0, *bytes, zero = 0;
309991e35eeSJohn Fastabend 
310991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
311991e35eeSJohn Fastabend 	if (bytes) {
312991e35eeSJohn Fastabend 		if (((__u64)data_end - (__u64)data) >= *bytes)
313991e35eeSJohn Fastabend 			return SK_PASS;
314991e35eeSJohn Fastabend 		ret = bpf_msg_cork_bytes(msg, *bytes);
315991e35eeSJohn Fastabend 		if (ret)
316991e35eeSJohn Fastabend 			return SK_DROP;
317991e35eeSJohn Fastabend 	}
318991e35eeSJohn Fastabend 	return SK_PASS;
319991e35eeSJohn Fastabend }
320991e35eeSJohn Fastabend 
321d79a3212SJohn Fastabend SEC("sk_msg5")
322991e35eeSJohn Fastabend int bpf_prog10(struct sk_msg_md *msg)
323991e35eeSJohn Fastabend {
324991e35eeSJohn Fastabend 	int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop;
325991e35eeSJohn Fastabend 	int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5;
326991e35eeSJohn Fastabend 
327991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
328991e35eeSJohn Fastabend 	if (bytes)
329991e35eeSJohn Fastabend 		bpf_msg_apply_bytes(msg, *bytes);
330991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
331991e35eeSJohn Fastabend 	if (bytes)
332991e35eeSJohn Fastabend 		bpf_msg_cork_bytes(msg, *bytes);
333991e35eeSJohn Fastabend 	start = bpf_map_lookup_elem(&sock_bytes, &zero);
334991e35eeSJohn Fastabend 	end = bpf_map_lookup_elem(&sock_bytes, &one);
335991e35eeSJohn Fastabend 	if (start && end)
336991e35eeSJohn Fastabend 		bpf_msg_pull_data(msg, *start, *end, 0);
337991e35eeSJohn Fastabend 	start_push = bpf_map_lookup_elem(&sock_bytes, &two);
338991e35eeSJohn Fastabend 	end_push = bpf_map_lookup_elem(&sock_bytes, &three);
339991e35eeSJohn Fastabend 	if (start_push && end_push)
340991e35eeSJohn Fastabend 		bpf_msg_push_data(msg, *start_push, *end_push, 0);
341991e35eeSJohn Fastabend 	start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
342991e35eeSJohn Fastabend 	pop = bpf_map_lookup_elem(&sock_bytes, &five);
343991e35eeSJohn Fastabend 	if (start_pop && pop)
344991e35eeSJohn Fastabend 		bpf_msg_pop_data(msg, *start_pop, *pop, 0);
345991e35eeSJohn Fastabend 	return SK_DROP;
346991e35eeSJohn Fastabend }
347991e35eeSJohn Fastabend 
348991e35eeSJohn Fastabend int _version SEC("version") = 1;
349991e35eeSJohn Fastabend char _license[] SEC("license") = "GPL";
350