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>
17c8ed6685SAndrii Nakryiko #include "bpf_misc.h"
18991e35eeSJohn Fastabend 
19991e35eeSJohn Fastabend /* Sockmap sample program connects a client and a backend together
20991e35eeSJohn Fastabend  * using cgroups.
21991e35eeSJohn Fastabend  *
22991e35eeSJohn Fastabend  *    client:X <---> frontend:80 client:X <---> backend:80
23991e35eeSJohn Fastabend  *
24991e35eeSJohn Fastabend  * For simplicity we hard code values here and bind 1:1. The hard
25991e35eeSJohn Fastabend  * coded values are part of the setup in sockmap.sh script that
26991e35eeSJohn Fastabend  * is associated with this BPF program.
27991e35eeSJohn Fastabend  *
28991e35eeSJohn Fastabend  * The bpf_printk is verbose and prints information as connections
29991e35eeSJohn Fastabend  * are established and verdicts are decided.
30991e35eeSJohn Fastabend  */
31991e35eeSJohn Fastabend 
32991e35eeSJohn Fastabend struct {
33991e35eeSJohn Fastabend 	__uint(type, TEST_MAP_TYPE);
34991e35eeSJohn Fastabend 	__uint(max_entries, 20);
35991e35eeSJohn Fastabend 	__uint(key_size, sizeof(int));
36991e35eeSJohn Fastabend 	__uint(value_size, sizeof(int));
37991e35eeSJohn Fastabend } sock_map SEC(".maps");
38991e35eeSJohn Fastabend 
39991e35eeSJohn Fastabend struct {
40991e35eeSJohn Fastabend 	__uint(type, TEST_MAP_TYPE);
41991e35eeSJohn Fastabend 	__uint(max_entries, 20);
42991e35eeSJohn Fastabend 	__uint(key_size, sizeof(int));
43991e35eeSJohn Fastabend 	__uint(value_size, sizeof(int));
44991e35eeSJohn Fastabend } sock_map_txmsg SEC(".maps");
45991e35eeSJohn Fastabend 
46991e35eeSJohn Fastabend struct {
47991e35eeSJohn Fastabend 	__uint(type, TEST_MAP_TYPE);
48991e35eeSJohn Fastabend 	__uint(max_entries, 20);
49991e35eeSJohn Fastabend 	__uint(key_size, sizeof(int));
50991e35eeSJohn Fastabend 	__uint(value_size, sizeof(int));
51991e35eeSJohn Fastabend } sock_map_redir SEC(".maps");
52991e35eeSJohn Fastabend 
53991e35eeSJohn Fastabend struct {
54991e35eeSJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
55991e35eeSJohn Fastabend 	__uint(max_entries, 1);
56991e35eeSJohn Fastabend 	__type(key, int);
57991e35eeSJohn Fastabend 	__type(value, int);
58991e35eeSJohn Fastabend } sock_apply_bytes SEC(".maps");
59991e35eeSJohn Fastabend 
60991e35eeSJohn Fastabend struct {
61991e35eeSJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
62991e35eeSJohn Fastabend 	__uint(max_entries, 1);
63991e35eeSJohn Fastabend 	__type(key, int);
64991e35eeSJohn Fastabend 	__type(value, int);
65991e35eeSJohn Fastabend } sock_cork_bytes SEC(".maps");
66991e35eeSJohn Fastabend 
67991e35eeSJohn Fastabend struct {
68991e35eeSJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
69991e35eeSJohn Fastabend 	__uint(max_entries, 6);
70991e35eeSJohn Fastabend 	__type(key, int);
71991e35eeSJohn Fastabend 	__type(value, int);
72991e35eeSJohn Fastabend } sock_bytes SEC(".maps");
73991e35eeSJohn Fastabend 
74991e35eeSJohn Fastabend struct {
75991e35eeSJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
76991e35eeSJohn Fastabend 	__uint(max_entries, 1);
77991e35eeSJohn Fastabend 	__type(key, int);
78991e35eeSJohn Fastabend 	__type(value, int);
79991e35eeSJohn Fastabend } sock_redir_flags SEC(".maps");
80991e35eeSJohn Fastabend 
81991e35eeSJohn Fastabend struct {
82991e35eeSJohn Fastabend 	__uint(type, BPF_MAP_TYPE_ARRAY);
8353792fa4SJohn Fastabend 	__uint(max_entries, 3);
84991e35eeSJohn Fastabend 	__type(key, int);
85991e35eeSJohn Fastabend 	__type(value, int);
86991e35eeSJohn Fastabend } sock_skb_opts SEC(".maps");
87991e35eeSJohn Fastabend 
88463bac5fSJohn Fastabend struct {
89463bac5fSJohn Fastabend 	__uint(type, TEST_MAP_TYPE);
90463bac5fSJohn Fastabend 	__uint(max_entries, 20);
91463bac5fSJohn Fastabend 	__uint(key_size, sizeof(int));
92463bac5fSJohn Fastabend 	__uint(value_size, sizeof(int));
93463bac5fSJohn Fastabend } tls_sock_map SEC(".maps");
94463bac5fSJohn Fastabend 
95991e35eeSJohn Fastabend SEC("sk_skb1")
bpf_prog1(struct __sk_buff * skb)96991e35eeSJohn Fastabend int bpf_prog1(struct __sk_buff *skb)
97991e35eeSJohn Fastabend {
9853792fa4SJohn Fastabend 	int *f, two = 2;
9953792fa4SJohn Fastabend 
10053792fa4SJohn Fastabend 	f = bpf_map_lookup_elem(&sock_skb_opts, &two);
10153792fa4SJohn Fastabend 	if (f && *f) {
10253792fa4SJohn Fastabend 		return *f;
10353792fa4SJohn Fastabend 	}
104991e35eeSJohn Fastabend 	return skb->len;
105991e35eeSJohn Fastabend }
106991e35eeSJohn Fastabend 
107991e35eeSJohn Fastabend SEC("sk_skb2")
bpf_prog2(struct __sk_buff * skb)108991e35eeSJohn Fastabend int bpf_prog2(struct __sk_buff *skb)
109991e35eeSJohn Fastabend {
110991e35eeSJohn Fastabend 	__u32 lport = skb->local_port;
111991e35eeSJohn Fastabend 	__u32 rport = skb->remote_port;
112991e35eeSJohn Fastabend 	int len, *f, ret, zero = 0;
113991e35eeSJohn Fastabend 	__u64 flags = 0;
114991e35eeSJohn Fastabend 
115c8ed6685SAndrii Nakryiko 	__sink(rport);
116991e35eeSJohn Fastabend 	if (lport == 10000)
117991e35eeSJohn Fastabend 		ret = 10;
118991e35eeSJohn Fastabend 	else
119991e35eeSJohn Fastabend 		ret = 1;
120991e35eeSJohn Fastabend 
121991e35eeSJohn Fastabend 	len = (__u32)skb->data_end - (__u32)skb->data;
122c8ed6685SAndrii Nakryiko 	__sink(len);
123c8ed6685SAndrii Nakryiko 
124991e35eeSJohn Fastabend 	f = bpf_map_lookup_elem(&sock_skb_opts, &zero);
125991e35eeSJohn Fastabend 	if (f && *f) {
126991e35eeSJohn Fastabend 		ret = 3;
127991e35eeSJohn Fastabend 		flags = *f;
128991e35eeSJohn Fastabend 	}
129991e35eeSJohn Fastabend 
130991e35eeSJohn Fastabend #ifdef SOCKMAP
131991e35eeSJohn Fastabend 	return bpf_sk_redirect_map(skb, &sock_map, ret, flags);
132991e35eeSJohn Fastabend #else
133991e35eeSJohn Fastabend 	return bpf_sk_redirect_hash(skb, &sock_map, &ret, flags);
134991e35eeSJohn Fastabend #endif
135991e35eeSJohn Fastabend 
136991e35eeSJohn Fastabend }
137991e35eeSJohn Fastabend 
bpf_write_pass(struct __sk_buff * skb,int offset)13891274ca5SJohn Fastabend static inline void bpf_write_pass(struct __sk_buff *skb, int offset)
139463bac5fSJohn Fastabend {
14091274ca5SJohn Fastabend 	int err = bpf_skb_pull_data(skb, 6 + offset);
141463bac5fSJohn Fastabend 	void *data_end;
142463bac5fSJohn Fastabend 	char *c;
143463bac5fSJohn Fastabend 
144463bac5fSJohn Fastabend 	if (err)
14591274ca5SJohn Fastabend 		return;
146463bac5fSJohn Fastabend 
147463bac5fSJohn Fastabend 	c = (char *)(long)skb->data;
148463bac5fSJohn Fastabend 	data_end = (void *)(long)skb->data_end;
149463bac5fSJohn Fastabend 
15091274ca5SJohn Fastabend 	if (c + 5 + offset < data_end)
15191274ca5SJohn Fastabend 		memcpy(c + offset, "PASS", 4);
15291274ca5SJohn Fastabend }
15391274ca5SJohn Fastabend 
15491274ca5SJohn Fastabend SEC("sk_skb3")
bpf_prog3(struct __sk_buff * skb)15591274ca5SJohn Fastabend int bpf_prog3(struct __sk_buff *skb)
15691274ca5SJohn Fastabend {
15791274ca5SJohn Fastabend 	int err, *f, ret = SK_PASS;
15891274ca5SJohn Fastabend 	const int one = 1;
15991274ca5SJohn Fastabend 
160463bac5fSJohn Fastabend 	f = bpf_map_lookup_elem(&sock_skb_opts, &one);
161463bac5fSJohn Fastabend 	if (f && *f) {
162463bac5fSJohn Fastabend 		__u64 flags = 0;
163463bac5fSJohn Fastabend 
164463bac5fSJohn Fastabend 		ret = 0;
165463bac5fSJohn Fastabend 		flags = *f;
16691274ca5SJohn Fastabend 
16791274ca5SJohn Fastabend 		err = bpf_skb_adjust_room(skb, -13, 0, 0);
16891274ca5SJohn Fastabend 		if (err)
16991274ca5SJohn Fastabend 			return SK_DROP;
17091274ca5SJohn Fastabend 		err = bpf_skb_adjust_room(skb, 4, 0, 0);
17191274ca5SJohn Fastabend 		if (err)
17291274ca5SJohn Fastabend 			return SK_DROP;
17391274ca5SJohn Fastabend 		bpf_write_pass(skb, 0);
174463bac5fSJohn Fastabend #ifdef SOCKMAP
175463bac5fSJohn Fastabend 		return bpf_sk_redirect_map(skb, &tls_sock_map, ret, flags);
176463bac5fSJohn Fastabend #else
177463bac5fSJohn Fastabend 		return bpf_sk_redirect_hash(skb, &tls_sock_map, &ret, flags);
178463bac5fSJohn Fastabend #endif
179463bac5fSJohn Fastabend 	}
180463bac5fSJohn Fastabend 	f = bpf_map_lookup_elem(&sock_skb_opts, &one);
181463bac5fSJohn Fastabend 	if (f && *f)
182463bac5fSJohn Fastabend 		ret = SK_DROP;
18391274ca5SJohn Fastabend 	err = bpf_skb_adjust_room(skb, 4, 0, 0);
18491274ca5SJohn Fastabend 	if (err)
18591274ca5SJohn Fastabend 		return SK_DROP;
18691274ca5SJohn Fastabend 	bpf_write_pass(skb, 13);
187463bac5fSJohn Fastabend 	return ret;
188463bac5fSJohn Fastabend }
189463bac5fSJohn Fastabend 
190991e35eeSJohn Fastabend SEC("sockops")
bpf_sockmap(struct bpf_sock_ops * skops)191991e35eeSJohn Fastabend int bpf_sockmap(struct bpf_sock_ops *skops)
192991e35eeSJohn Fastabend {
193991e35eeSJohn Fastabend 	__u32 lport, rport;
194*f726e035SJohn Fastabend 	int op, ret;
195991e35eeSJohn Fastabend 
196991e35eeSJohn Fastabend 	op = (int) skops->op;
197991e35eeSJohn Fastabend 
198991e35eeSJohn Fastabend 	switch (op) {
199991e35eeSJohn Fastabend 	case BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB:
200991e35eeSJohn Fastabend 		lport = skops->local_port;
201991e35eeSJohn Fastabend 		rport = skops->remote_port;
202991e35eeSJohn Fastabend 
203991e35eeSJohn Fastabend 		if (lport == 10000) {
204991e35eeSJohn Fastabend 			ret = 1;
205991e35eeSJohn Fastabend #ifdef SOCKMAP
206*f726e035SJohn Fastabend 			bpf_sock_map_update(skops, &sock_map, &ret,
207991e35eeSJohn Fastabend 						  BPF_NOEXIST);
208991e35eeSJohn Fastabend #else
209*f726e035SJohn Fastabend 			bpf_sock_hash_update(skops, &sock_map, &ret,
210991e35eeSJohn Fastabend 						   BPF_NOEXIST);
211991e35eeSJohn Fastabend #endif
212991e35eeSJohn Fastabend 		}
213991e35eeSJohn Fastabend 		break;
214991e35eeSJohn Fastabend 	case BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB:
215991e35eeSJohn Fastabend 		lport = skops->local_port;
216991e35eeSJohn Fastabend 		rport = skops->remote_port;
217991e35eeSJohn Fastabend 
218991e35eeSJohn Fastabend 		if (bpf_ntohl(rport) == 10001) {
219991e35eeSJohn Fastabend 			ret = 10;
220991e35eeSJohn Fastabend #ifdef SOCKMAP
221*f726e035SJohn Fastabend 			bpf_sock_map_update(skops, &sock_map, &ret,
222991e35eeSJohn Fastabend 						  BPF_NOEXIST);
223991e35eeSJohn Fastabend #else
224*f726e035SJohn Fastabend 			bpf_sock_hash_update(skops, &sock_map, &ret,
225991e35eeSJohn Fastabend 						   BPF_NOEXIST);
226991e35eeSJohn Fastabend #endif
227991e35eeSJohn Fastabend 		}
228991e35eeSJohn Fastabend 		break;
229991e35eeSJohn Fastabend 	default:
230991e35eeSJohn Fastabend 		break;
231991e35eeSJohn Fastabend 	}
232991e35eeSJohn Fastabend 
233991e35eeSJohn Fastabend 	return 0;
234991e35eeSJohn Fastabend }
235991e35eeSJohn Fastabend 
236991e35eeSJohn Fastabend SEC("sk_msg1")
bpf_prog4(struct sk_msg_md * msg)237991e35eeSJohn Fastabend int bpf_prog4(struct sk_msg_md *msg)
238991e35eeSJohn Fastabend {
239991e35eeSJohn Fastabend 	int *bytes, zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5;
24061d06f01SFelix Maurer 	int *start, *end, *start_push, *end_push, *start_pop, *pop, err = 0;
241991e35eeSJohn Fastabend 
242991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
243991e35eeSJohn Fastabend 	if (bytes)
244991e35eeSJohn Fastabend 		bpf_msg_apply_bytes(msg, *bytes);
245991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
246991e35eeSJohn Fastabend 	if (bytes)
247991e35eeSJohn Fastabend 		bpf_msg_cork_bytes(msg, *bytes);
248991e35eeSJohn Fastabend 	start = bpf_map_lookup_elem(&sock_bytes, &zero);
249991e35eeSJohn Fastabend 	end = bpf_map_lookup_elem(&sock_bytes, &one);
250991e35eeSJohn Fastabend 	if (start && end)
251991e35eeSJohn Fastabend 		bpf_msg_pull_data(msg, *start, *end, 0);
252991e35eeSJohn Fastabend 	start_push = bpf_map_lookup_elem(&sock_bytes, &two);
253991e35eeSJohn Fastabend 	end_push = bpf_map_lookup_elem(&sock_bytes, &three);
25461d06f01SFelix Maurer 	if (start_push && end_push) {
25561d06f01SFelix Maurer 		err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
25661d06f01SFelix Maurer 		if (err)
25761d06f01SFelix Maurer 			return SK_DROP;
25861d06f01SFelix Maurer 	}
259991e35eeSJohn Fastabend 	start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
260991e35eeSJohn Fastabend 	pop = bpf_map_lookup_elem(&sock_bytes, &five);
261991e35eeSJohn Fastabend 	if (start_pop && pop)
262991e35eeSJohn Fastabend 		bpf_msg_pop_data(msg, *start_pop, *pop, 0);
263991e35eeSJohn Fastabend 	return SK_PASS;
264991e35eeSJohn Fastabend }
265991e35eeSJohn Fastabend 
266991e35eeSJohn Fastabend SEC("sk_msg2")
bpf_prog6(struct sk_msg_md * msg)267991e35eeSJohn Fastabend int bpf_prog6(struct sk_msg_md *msg)
268991e35eeSJohn Fastabend {
269991e35eeSJohn Fastabend 	int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5, key = 0;
270991e35eeSJohn Fastabend 	int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop, *f;
27161d06f01SFelix Maurer 	int err = 0;
272991e35eeSJohn Fastabend 	__u64 flags = 0;
273991e35eeSJohn Fastabend 
274991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
275991e35eeSJohn Fastabend 	if (bytes)
276991e35eeSJohn Fastabend 		bpf_msg_apply_bytes(msg, *bytes);
277991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
278991e35eeSJohn Fastabend 	if (bytes)
279991e35eeSJohn Fastabend 		bpf_msg_cork_bytes(msg, *bytes);
280991e35eeSJohn Fastabend 
281991e35eeSJohn Fastabend 	start = bpf_map_lookup_elem(&sock_bytes, &zero);
282991e35eeSJohn Fastabend 	end = bpf_map_lookup_elem(&sock_bytes, &one);
283991e35eeSJohn Fastabend 	if (start && end)
284991e35eeSJohn Fastabend 		bpf_msg_pull_data(msg, *start, *end, 0);
285991e35eeSJohn Fastabend 
286991e35eeSJohn Fastabend 	start_push = bpf_map_lookup_elem(&sock_bytes, &two);
287991e35eeSJohn Fastabend 	end_push = bpf_map_lookup_elem(&sock_bytes, &three);
28861d06f01SFelix Maurer 	if (start_push && end_push) {
28961d06f01SFelix Maurer 		err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
29061d06f01SFelix Maurer 		if (err)
29161d06f01SFelix Maurer 			return SK_DROP;
29261d06f01SFelix Maurer 	}
293991e35eeSJohn Fastabend 
294991e35eeSJohn Fastabend 	start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
295991e35eeSJohn Fastabend 	pop = bpf_map_lookup_elem(&sock_bytes, &five);
296991e35eeSJohn Fastabend 	if (start_pop && pop)
297991e35eeSJohn Fastabend 		bpf_msg_pop_data(msg, *start_pop, *pop, 0);
298991e35eeSJohn Fastabend 
299991e35eeSJohn Fastabend 	f = bpf_map_lookup_elem(&sock_redir_flags, &zero);
300991e35eeSJohn Fastabend 	if (f && *f) {
301991e35eeSJohn Fastabend 		key = 2;
302991e35eeSJohn Fastabend 		flags = *f;
303991e35eeSJohn Fastabend 	}
304991e35eeSJohn Fastabend #ifdef SOCKMAP
305991e35eeSJohn Fastabend 	return bpf_msg_redirect_map(msg, &sock_map_redir, key, flags);
306991e35eeSJohn Fastabend #else
307991e35eeSJohn Fastabend 	return bpf_msg_redirect_hash(msg, &sock_map_redir, &key, flags);
308991e35eeSJohn Fastabend #endif
309991e35eeSJohn Fastabend }
310991e35eeSJohn Fastabend 
311d79a3212SJohn Fastabend SEC("sk_msg3")
bpf_prog8(struct sk_msg_md * msg)312991e35eeSJohn Fastabend int bpf_prog8(struct sk_msg_md *msg)
313991e35eeSJohn Fastabend {
314991e35eeSJohn Fastabend 	void *data_end = (void *)(long) msg->data_end;
315991e35eeSJohn Fastabend 	void *data = (void *)(long) msg->data;
316991e35eeSJohn Fastabend 	int ret = 0, *bytes, zero = 0;
317991e35eeSJohn Fastabend 
318991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
319991e35eeSJohn Fastabend 	if (bytes) {
320991e35eeSJohn Fastabend 		ret = bpf_msg_apply_bytes(msg, *bytes);
321991e35eeSJohn Fastabend 		if (ret)
322991e35eeSJohn Fastabend 			return SK_DROP;
323991e35eeSJohn Fastabend 	} else {
324991e35eeSJohn Fastabend 		return SK_DROP;
325991e35eeSJohn Fastabend 	}
326c8ed6685SAndrii Nakryiko 
327c8ed6685SAndrii Nakryiko 	__sink(data_end);
328c8ed6685SAndrii Nakryiko 	__sink(data);
329c8ed6685SAndrii Nakryiko 
330991e35eeSJohn Fastabend 	return SK_PASS;
331991e35eeSJohn Fastabend }
332d79a3212SJohn Fastabend SEC("sk_msg4")
bpf_prog9(struct sk_msg_md * msg)333991e35eeSJohn Fastabend int bpf_prog9(struct sk_msg_md *msg)
334991e35eeSJohn Fastabend {
335991e35eeSJohn Fastabend 	void *data_end = (void *)(long) msg->data_end;
336991e35eeSJohn Fastabend 	void *data = (void *)(long) msg->data;
337991e35eeSJohn Fastabend 	int ret = 0, *bytes, zero = 0;
338991e35eeSJohn Fastabend 
339991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
340991e35eeSJohn Fastabend 	if (bytes) {
341991e35eeSJohn Fastabend 		if (((__u64)data_end - (__u64)data) >= *bytes)
342991e35eeSJohn Fastabend 			return SK_PASS;
343991e35eeSJohn Fastabend 		ret = bpf_msg_cork_bytes(msg, *bytes);
344991e35eeSJohn Fastabend 		if (ret)
345991e35eeSJohn Fastabend 			return SK_DROP;
346991e35eeSJohn Fastabend 	}
347991e35eeSJohn Fastabend 	return SK_PASS;
348991e35eeSJohn Fastabend }
349991e35eeSJohn Fastabend 
350d79a3212SJohn Fastabend SEC("sk_msg5")
bpf_prog10(struct sk_msg_md * msg)351991e35eeSJohn Fastabend int bpf_prog10(struct sk_msg_md *msg)
352991e35eeSJohn Fastabend {
353991e35eeSJohn Fastabend 	int *bytes, *start, *end, *start_push, *end_push, *start_pop, *pop;
35461d06f01SFelix Maurer 	int zero = 0, one = 1, two = 2, three = 3, four = 4, five = 5, err = 0;
355991e35eeSJohn Fastabend 
356991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_apply_bytes, &zero);
357991e35eeSJohn Fastabend 	if (bytes)
358991e35eeSJohn Fastabend 		bpf_msg_apply_bytes(msg, *bytes);
359991e35eeSJohn Fastabend 	bytes = bpf_map_lookup_elem(&sock_cork_bytes, &zero);
360991e35eeSJohn Fastabend 	if (bytes)
361991e35eeSJohn Fastabend 		bpf_msg_cork_bytes(msg, *bytes);
362991e35eeSJohn Fastabend 	start = bpf_map_lookup_elem(&sock_bytes, &zero);
363991e35eeSJohn Fastabend 	end = bpf_map_lookup_elem(&sock_bytes, &one);
364991e35eeSJohn Fastabend 	if (start && end)
365991e35eeSJohn Fastabend 		bpf_msg_pull_data(msg, *start, *end, 0);
366991e35eeSJohn Fastabend 	start_push = bpf_map_lookup_elem(&sock_bytes, &two);
367991e35eeSJohn Fastabend 	end_push = bpf_map_lookup_elem(&sock_bytes, &three);
36861d06f01SFelix Maurer 	if (start_push && end_push) {
36961d06f01SFelix Maurer 		err = bpf_msg_push_data(msg, *start_push, *end_push, 0);
37061d06f01SFelix Maurer 		if (err)
37161d06f01SFelix Maurer 			return SK_PASS;
37261d06f01SFelix Maurer 	}
373991e35eeSJohn Fastabend 	start_pop = bpf_map_lookup_elem(&sock_bytes, &four);
374991e35eeSJohn Fastabend 	pop = bpf_map_lookup_elem(&sock_bytes, &five);
375991e35eeSJohn Fastabend 	if (start_pop && pop)
376991e35eeSJohn Fastabend 		bpf_msg_pop_data(msg, *start_pop, *pop, 0);
377991e35eeSJohn Fastabend 	return SK_DROP;
378991e35eeSJohn Fastabend }
379991e35eeSJohn Fastabend 
380991e35eeSJohn Fastabend char _license[] SEC("license") = "GPL";
381