1 // SPDX-License-Identifier: GPL-2.0
7 #include <sys/socket.h>
8 #include <netinet/in.h>
10 #include <linux/filter.h>
12 #include <bpf/libbpf.h>
14 #include "bpf_rlimit.h"
16 #include "cgroup_helpers.h"
18 #define CG_PATH "/sockopt"
20 #define SOL_CUSTOM 0xdeadbeef
22 static int getsetsockopt(void)
31 fd
= socket(AF_INET
, SOCK_STREAM
, 0);
33 log_err("Failed to create socket");
37 /* IP_TOS - BPF bypass */
40 err
= setsockopt(fd
, SOL_IP
, IP_TOS
, &buf
, 1);
42 log_err("Failed to call setsockopt(IP_TOS)");
48 err
= getsockopt(fd
, SOL_IP
, IP_TOS
, &buf
, &optlen
);
50 log_err("Failed to call getsockopt(IP_TOS)");
54 if (buf
.u8
[0] != 0x08) {
55 log_err("Unexpected getsockopt(IP_TOS) buf[0] 0x%02x != 0x08",
63 err
= setsockopt(fd
, SOL_IP
, IP_TTL
, &buf
, 1);
64 if (!err
|| errno
!= EPERM
) {
65 log_err("Unexpected success from setsockopt(IP_TTL)");
69 /* SOL_CUSTOM - handled by BPF */
72 err
= setsockopt(fd
, SOL_CUSTOM
, 0, &buf
, 1);
74 log_err("Failed to call setsockopt");
80 err
= getsockopt(fd
, SOL_CUSTOM
, 0, &buf
, &optlen
);
82 log_err("Failed to call getsockopt");
87 log_err("Unexpected optlen %d != 1", optlen
);
90 if (buf
.u8
[0] != 0x01) {
91 log_err("Unexpected buf[0] 0x%02x != 0x01", buf
.u8
[0]);
95 /* SO_SNDBUF is overwritten */
98 err
= setsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &buf
, 4);
100 log_err("Failed to call setsockopt(SO_SNDBUF)");
106 err
= getsockopt(fd
, SOL_SOCKET
, SO_SNDBUF
, &buf
, &optlen
);
108 log_err("Failed to call getsockopt(SO_SNDBUF)");
112 if (buf
.u32
!= 0x55AA*2) {
113 log_err("Unexpected getsockopt(SO_SNDBUF) 0x%x != 0x55AA*2",
125 static int prog_attach(struct bpf_object
*obj
, int cgroup_fd
, const char *title
)
127 enum bpf_attach_type attach_type
;
128 enum bpf_prog_type prog_type
;
129 struct bpf_program
*prog
;
132 err
= libbpf_prog_type_by_name(title
, &prog_type
, &attach_type
);
134 log_err("Failed to deduct types for %s BPF program", title
);
138 prog
= bpf_object__find_program_by_title(obj
, title
);
140 log_err("Failed to find %s BPF program", title
);
144 err
= bpf_prog_attach(bpf_program__fd(prog
), cgroup_fd
,
147 log_err("Failed to attach %s BPF program", title
);
154 static int run_test(int cgroup_fd
)
156 struct bpf_prog_load_attr attr
= {
157 .file
= "./sockopt_sk.o",
159 struct bpf_object
*obj
;
163 err
= bpf_prog_load_xattr(&attr
, &obj
, &ignored
);
165 log_err("Failed to load BPF object");
169 err
= prog_attach(obj
, cgroup_fd
, "cgroup/getsockopt");
171 goto close_bpf_object
;
173 err
= prog_attach(obj
, cgroup_fd
, "cgroup/setsockopt");
175 goto close_bpf_object
;
177 err
= getsetsockopt();
180 bpf_object__close(obj
);
184 int main(int args
, char **argv
)
187 int err
= EXIT_SUCCESS
;
189 if (setup_cgroup_environment())
192 cgroup_fd
= create_and_get_cgroup(CG_PATH
);
194 goto cleanup_cgroup_env
;
196 if (join_cgroup(CG_PATH
))
199 if (run_test(cgroup_fd
))
202 printf("test_sockopt_sk: %s\n",
203 err
== EXIT_SUCCESS
? "PASSED" : "FAILED");
208 cleanup_cgroup_environment();