]> Git Repo - J-linux.git/blob - tools/testing/selftests/bpf/prog_tests/sockopt_inherit.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.git] / tools / testing / selftests / bpf / prog_tests / sockopt_inherit.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <test_progs.h>
3 #include "cgroup_helpers.h"
4 #include "network_helpers.h"
5
6 #include "sockopt_inherit.skel.h"
7
8 #define SOL_CUSTOM                      0xdeadbeef
9 #define CUSTOM_INHERIT1                 0
10 #define CUSTOM_INHERIT2                 1
11 #define CUSTOM_LISTENER                 2
12
13 static int verify_sockopt(int fd, int optname, const char *msg, char expected)
14 {
15         socklen_t optlen = 1;
16         char buf = 0;
17         int err;
18
19         err = getsockopt(fd, SOL_CUSTOM, optname, &buf, &optlen);
20         if (err) {
21                 log_err("%s: failed to call getsockopt", msg);
22                 return 1;
23         }
24
25         printf("%s %d: got=0x%x ? expected=0x%x\n", msg, optname, buf, expected);
26
27         if (buf != expected) {
28                 log_err("%s: unexpected getsockopt value %d != %d", msg,
29                         buf, expected);
30                 return 1;
31         }
32
33         return 0;
34 }
35
36 static pthread_mutex_t server_started_mtx = PTHREAD_MUTEX_INITIALIZER;
37 static pthread_cond_t server_started = PTHREAD_COND_INITIALIZER;
38
39 static void *server_thread(void *arg)
40 {
41         struct sockaddr_storage addr;
42         socklen_t len = sizeof(addr);
43         int fd = *(int *)arg;
44         int client_fd;
45         int err = 0;
46
47         err = listen(fd, 1);
48
49         pthread_mutex_lock(&server_started_mtx);
50         pthread_cond_signal(&server_started);
51         pthread_mutex_unlock(&server_started_mtx);
52
53         if (!ASSERT_GE(err, 0, "listed on socket"))
54                 return NULL;
55
56         err += verify_sockopt(fd, CUSTOM_INHERIT1, "listen", 1);
57         err += verify_sockopt(fd, CUSTOM_INHERIT2, "listen", 1);
58         err += verify_sockopt(fd, CUSTOM_LISTENER, "listen", 1);
59
60         client_fd = accept(fd, (struct sockaddr *)&addr, &len);
61         if (!ASSERT_GE(client_fd, 0, "accept client"))
62                 return NULL;
63
64         err += verify_sockopt(client_fd, CUSTOM_INHERIT1, "accept", 1);
65         err += verify_sockopt(client_fd, CUSTOM_INHERIT2, "accept", 1);
66         err += verify_sockopt(client_fd, CUSTOM_LISTENER, "accept", 0);
67
68         close(client_fd);
69
70         return (void *)(long)err;
71 }
72
73 static int custom_cb(int fd, void *opts)
74 {
75         char buf;
76         int err;
77         int i;
78
79         for (i = CUSTOM_INHERIT1; i <= CUSTOM_LISTENER; i++) {
80                 buf = 0x01;
81                 err = setsockopt(fd, SOL_CUSTOM, i, &buf, 1);
82                 if (err) {
83                         log_err("Failed to call setsockopt(%d)", i);
84                         return -1;
85                 }
86         }
87
88         return 0;
89 }
90
91 static void run_test(int cgroup_fd)
92 {
93         struct bpf_link *link_getsockopt = NULL;
94         struct bpf_link *link_setsockopt = NULL;
95         struct network_helper_opts opts = {
96                 .post_socket_cb = custom_cb,
97         };
98         int server_fd = -1, client_fd;
99         struct sockaddr_in addr = {
100                 .sin_family = AF_INET,
101                 .sin_addr.s_addr = htonl(INADDR_LOOPBACK),
102         };
103         struct sockopt_inherit *obj;
104         void *server_err;
105         pthread_t tid;
106         int err;
107
108         obj = sockopt_inherit__open_and_load();
109         if (!ASSERT_OK_PTR(obj, "skel-load"))
110                 return;
111
112         obj->bss->page_size = sysconf(_SC_PAGESIZE);
113
114         link_getsockopt = bpf_program__attach_cgroup(obj->progs._getsockopt,
115                                                      cgroup_fd);
116         if (!ASSERT_OK_PTR(link_getsockopt, "cg-attach-getsockopt"))
117                 goto close_bpf_object;
118
119         link_setsockopt = bpf_program__attach_cgroup(obj->progs._setsockopt,
120                                                      cgroup_fd);
121         if (!ASSERT_OK_PTR(link_setsockopt, "cg-attach-setsockopt"))
122                 goto close_bpf_object;
123
124         server_fd = start_server_addr(SOCK_STREAM, (struct sockaddr_storage *)&addr,
125                                       sizeof(addr), &opts);
126         if (!ASSERT_GE(server_fd, 0, "start_server"))
127                 goto close_bpf_object;
128
129         pthread_mutex_lock(&server_started_mtx);
130         if (!ASSERT_OK(pthread_create(&tid, NULL, server_thread,
131                                       (void *)&server_fd), "pthread_create")) {
132                 pthread_mutex_unlock(&server_started_mtx);
133                 goto close_server_fd;
134         }
135         pthread_cond_wait(&server_started, &server_started_mtx);
136         pthread_mutex_unlock(&server_started_mtx);
137
138         client_fd = connect_to_fd(server_fd, 0);
139         if (!ASSERT_GE(client_fd, 0, "connect_to_server"))
140                 goto close_server_fd;
141
142         ASSERT_OK(verify_sockopt(client_fd, CUSTOM_INHERIT1, "connect", 0), "verify_sockopt1");
143         ASSERT_OK(verify_sockopt(client_fd, CUSTOM_INHERIT2, "connect", 0), "verify_sockopt2");
144         ASSERT_OK(verify_sockopt(client_fd, CUSTOM_LISTENER, "connect", 0), "verify_sockopt ener");
145
146         pthread_join(tid, &server_err);
147
148         err = (int)(long)server_err;
149         ASSERT_OK(err, "pthread_join retval");
150
151         close(client_fd);
152
153 close_server_fd:
154         close(server_fd);
155 close_bpf_object:
156         bpf_link__destroy(link_getsockopt);
157         bpf_link__destroy(link_setsockopt);
158
159         sockopt_inherit__destroy(obj);
160 }
161
162 void test_sockopt_inherit(void)
163 {
164         int cgroup_fd;
165
166         cgroup_fd = test__join_cgroup("/sockopt_inherit");
167         if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup"))
168                 return;
169
170         run_test(cgroup_fd);
171         close(cgroup_fd);
172 }
This page took 0.03646 seconds and 4 git commands to generate.