1 // SPDX-License-Identifier: GPL-2.0
2 #include <netinet/in.h>
4 #include "bpf_helpers.h"
6 char _license
[] SEC("license") = "GPL";
7 __u32 _version
SEC("version") = 1;
9 #define SOL_CUSTOM 0xdeadbeef
15 struct bpf_map_def
SEC("maps") socket_storage_map
= {
16 .type
= BPF_MAP_TYPE_SK_STORAGE
,
17 .key_size
= sizeof(int),
18 .value_size
= sizeof(struct sockopt_sk
),
19 .map_flags
= BPF_F_NO_PREALLOC
,
21 BPF_ANNOTATE_KV_PAIR(socket_storage_map
, int, struct sockopt_sk
);
23 SEC("cgroup/getsockopt")
24 int _getsockopt(struct bpf_sockopt
*ctx
)
26 __u8
*optval_end
= ctx
->optval_end
;
27 __u8
*optval
= ctx
->optval
;
28 struct sockopt_sk
*storage
;
30 if (ctx
->level
== SOL_IP
&& ctx
->optname
== IP_TOS
)
31 /* Not interested in SOL_IP:IP_TOS;
32 * let next BPF program in the cgroup chain or kernel
37 if (ctx
->level
== SOL_SOCKET
&& ctx
->optname
== SO_SNDBUF
) {
38 /* Not interested in SOL_SOCKET:SO_SNDBUF;
39 * let next BPF program in the cgroup chain or kernel
45 if (ctx
->level
!= SOL_CUSTOM
)
46 return 0; /* EPERM, deny everything except custom level */
48 if (optval
+ 1 > optval_end
)
49 return 0; /* EPERM, bounds check */
51 storage
= bpf_sk_storage_get(&socket_storage_map
, ctx
->sk
, 0,
52 BPF_SK_STORAGE_GET_F_CREATE
);
54 return 0; /* EPERM, couldn't get sk storage */
57 return 0; /* EPERM, kernel should not have handled
58 * SOL_CUSTOM, something is wrong!
60 ctx
->retval
= 0; /* Reset system call return value to zero */
62 optval
[0] = storage
->val
;
68 SEC("cgroup/setsockopt")
69 int _setsockopt(struct bpf_sockopt
*ctx
)
71 __u8
*optval_end
= ctx
->optval_end
;
72 __u8
*optval
= ctx
->optval
;
73 struct sockopt_sk
*storage
;
75 if (ctx
->level
== SOL_IP
&& ctx
->optname
== IP_TOS
)
76 /* Not interested in SOL_IP:IP_TOS;
77 * let next BPF program in the cgroup chain or kernel
82 if (ctx
->level
== SOL_SOCKET
&& ctx
->optname
== SO_SNDBUF
) {
83 /* Overwrite SO_SNDBUF value */
85 if (optval
+ sizeof(__u32
) > optval_end
)
86 return 0; /* EPERM, bounds check */
88 *(__u32
*)optval
= 0x55AA;
94 if (ctx
->level
!= SOL_CUSTOM
)
95 return 0; /* EPERM, deny everything except custom level */
97 if (optval
+ 1 > optval_end
)
98 return 0; /* EPERM, bounds check */
100 storage
= bpf_sk_storage_get(&socket_storage_map
, ctx
->sk
, 0,
101 BPF_SK_STORAGE_GET_F_CREATE
);
103 return 0; /* EPERM, couldn't get sk storage */
105 storage
->val
= optval
[0];
106 ctx
->optlen
= -1; /* BPF has consumed this option, don't call kernel
107 * setsockopt handler.