xref: /linux/tools/testing/selftests/bpf/progs/test_sockmap_change_tail.c (revision 9c707ba99f1b638e32724691b18fd1429e23b7f4)
1*9ee0c7b8SCong Wang // SPDX-License-Identifier: GPL-2.0
2*9ee0c7b8SCong Wang /* Copyright (c) 2024 ByteDance */
3*9ee0c7b8SCong Wang #include <linux/bpf.h>
4*9ee0c7b8SCong Wang #include <bpf/bpf_helpers.h>
5*9ee0c7b8SCong Wang 
6*9ee0c7b8SCong Wang struct {
7*9ee0c7b8SCong Wang 	__uint(type, BPF_MAP_TYPE_SOCKMAP);
8*9ee0c7b8SCong Wang 	__uint(max_entries, 1);
9*9ee0c7b8SCong Wang 	__type(key, int);
10*9ee0c7b8SCong Wang 	__type(value, int);
11*9ee0c7b8SCong Wang } sock_map_rx SEC(".maps");
12*9ee0c7b8SCong Wang 
13*9ee0c7b8SCong Wang long change_tail_ret = 1;
14*9ee0c7b8SCong Wang 
15*9ee0c7b8SCong Wang SEC("sk_skb")
prog_skb_verdict(struct __sk_buff * skb)16*9ee0c7b8SCong Wang int prog_skb_verdict(struct __sk_buff *skb)
17*9ee0c7b8SCong Wang {
18*9ee0c7b8SCong Wang 	char *data, *data_end;
19*9ee0c7b8SCong Wang 
20*9ee0c7b8SCong Wang 	bpf_skb_pull_data(skb, 1);
21*9ee0c7b8SCong Wang 	data = (char *)(unsigned long)skb->data;
22*9ee0c7b8SCong Wang 	data_end = (char *)(unsigned long)skb->data_end;
23*9ee0c7b8SCong Wang 
24*9ee0c7b8SCong Wang 	if (data + 1 > data_end)
25*9ee0c7b8SCong Wang 		return SK_PASS;
26*9ee0c7b8SCong Wang 
27*9ee0c7b8SCong Wang 	if (data[0] == 'T') { /* Trim the packet */
28*9ee0c7b8SCong Wang 		change_tail_ret = bpf_skb_change_tail(skb, skb->len - 1, 0);
29*9ee0c7b8SCong Wang 		return SK_PASS;
30*9ee0c7b8SCong Wang 	} else if (data[0] == 'G') { /* Grow the packet */
31*9ee0c7b8SCong Wang 		change_tail_ret = bpf_skb_change_tail(skb, skb->len + 1, 0);
32*9ee0c7b8SCong Wang 		return SK_PASS;
33*9ee0c7b8SCong Wang 	} else if (data[0] == 'E') { /* Error */
34*9ee0c7b8SCong Wang 		change_tail_ret = bpf_skb_change_tail(skb, 65535, 0);
35*9ee0c7b8SCong Wang 		return SK_PASS;
36*9ee0c7b8SCong Wang 	}
37*9ee0c7b8SCong Wang 	return SK_PASS;
38*9ee0c7b8SCong Wang }
39*9ee0c7b8SCong Wang 
40*9ee0c7b8SCong Wang char _license[] SEC("license") = "GPL";
41