~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/bpf/prog_tests/sockopt_sk.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 #include <test_progs.h>
  3 #include "cgroup_helpers.h"
  4 
  5 #include <linux/tcp.h>
  6 #include <linux/netlink.h>
  7 #include "sockopt_sk.skel.h"
  8 
  9 #ifndef SOL_TCP
 10 #define SOL_TCP IPPROTO_TCP
 11 #endif
 12 
 13 #define SOL_CUSTOM                      0xdeadbeef
 14 
 15 static int getsetsockopt(void)
 16 {
 17         int fd, err;
 18         union {
 19                 char u8[4];
 20                 __u32 u32;
 21                 char cc[16]; /* TCP_CA_NAME_MAX */
 22                 struct tcp_zerocopy_receive zc;
 23         } buf = {};
 24         socklen_t optlen;
 25         char *big_buf = NULL;
 26 
 27         fd = socket(AF_INET, SOCK_STREAM, 0);
 28         if (fd < 0) {
 29                 log_err("Failed to create socket");
 30                 return -1;
 31         }
 32 
 33         /* IP_TOS - BPF bypass */
 34 
 35         optlen = getpagesize() * 2;
 36         big_buf = calloc(1, optlen);
 37         if (!big_buf) {
 38                 log_err("Couldn't allocate two pages");
 39                 goto err;
 40         }
 41 
 42         *(int *)big_buf = 0x08;
 43         err = setsockopt(fd, SOL_IP, IP_TOS, big_buf, optlen);
 44         if (err) {
 45                 log_err("Failed to call setsockopt(IP_TOS)");
 46                 goto err;
 47         }
 48 
 49         memset(big_buf, 0, optlen);
 50         optlen = 1;
 51         err = getsockopt(fd, SOL_IP, IP_TOS, big_buf, &optlen);
 52         if (err) {
 53                 log_err("Failed to call getsockopt(IP_TOS)");
 54                 goto err;
 55         }
 56 
 57         if (*big_buf != 0x08) {
 58                 log_err("Unexpected getsockopt(IP_TOS) optval 0x%x != 0x08",
 59                         (int)*big_buf);
 60                 goto err;
 61         }
 62 
 63         /* IP_TTL - EPERM */
 64 
 65         buf.u8[0] = 1;
 66         err = setsockopt(fd, SOL_IP, IP_TTL, &buf, 1);
 67         if (!err || errno != EPERM) {
 68                 log_err("Unexpected success from setsockopt(IP_TTL)");
 69                 goto err;
 70         }
 71 
 72         /* SOL_CUSTOM - handled by BPF */
 73 
 74         buf.u8[0] = 0x01;
 75         err = setsockopt(fd, SOL_CUSTOM, 0, &buf, 1);
 76         if (err) {
 77                 log_err("Failed to call setsockopt");
 78                 goto err;
 79         }
 80 
 81         buf.u32 = 0x00;
 82         optlen = 4;
 83         err = getsockopt(fd, SOL_CUSTOM, 0, &buf, &optlen);
 84         if (err) {
 85                 log_err("Failed to call getsockopt");
 86                 goto err;
 87         }
 88 
 89         if (optlen != 1) {
 90                 log_err("Unexpected optlen %d != 1", optlen);
 91                 goto err;
 92         }
 93         if (buf.u8[0] != 0x01) {
 94                 log_err("Unexpected buf[0] 0x%02x != 0x01", buf.u8[0]);
 95                 goto err;
 96         }
 97 
 98         /* IP_FREEBIND - BPF can't access optval past PAGE_SIZE */
 99 
100         optlen = getpagesize() * 2;
101         memset(big_buf, 0, optlen);
102 
103         err = setsockopt(fd, SOL_IP, IP_FREEBIND, big_buf, optlen);
104         if (err != 0) {
105                 log_err("Failed to call setsockopt, ret=%d", err);
106                 goto err;
107         }
108 
109         err = getsockopt(fd, SOL_IP, IP_FREEBIND, big_buf, &optlen);
110         if (err != 0) {
111                 log_err("Failed to call getsockopt, ret=%d", err);
112                 goto err;
113         }
114 
115         if (optlen != 1 || *(__u8 *)big_buf != 0x55) {
116                 log_err("Unexpected IP_FREEBIND getsockopt, optlen=%d, optval=0x%x",
117                         optlen, *(__u8 *)big_buf);
118         }
119 
120         /* SO_SNDBUF is overwritten */
121 
122         buf.u32 = 0x01010101;
123         err = setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, 4);
124         if (err) {
125                 log_err("Failed to call setsockopt(SO_SNDBUF)");
126                 goto err;
127         }
128 
129         buf.u32 = 0x00;
130         optlen = 4;
131         err = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf, &optlen);
132         if (err) {
133                 log_err("Failed to call getsockopt(SO_SNDBUF)");
134                 goto err;
135         }
136 
137         if (buf.u32 != 0x55AA*2) {
138                 log_err("Unexpected getsockopt(SO_SNDBUF) 0x%x != 0x55AA*2",
139                         buf.u32);
140                 goto err;
141         }
142 
143         /* TCP_CONGESTION can extend the string */
144 
145         strcpy(buf.cc, "nv");
146         err = setsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, strlen("nv"));
147         if (err) {
148                 log_err("Failed to call setsockopt(TCP_CONGESTION)");
149                 goto err;
150         }
151 
152 
153         optlen = sizeof(buf.cc);
154         err = getsockopt(fd, SOL_TCP, TCP_CONGESTION, &buf, &optlen);
155         if (err) {
156                 log_err("Failed to call getsockopt(TCP_CONGESTION)");
157                 goto err;
158         }
159 
160         if (strcmp(buf.cc, "cubic") != 0) {
161                 log_err("Unexpected getsockopt(TCP_CONGESTION) %s != %s",
162                         buf.cc, "cubic");
163                 goto err;
164         }
165 
166         /* TCP_ZEROCOPY_RECEIVE triggers */
167         memset(&buf, 0, sizeof(buf));
168         optlen = sizeof(buf.zc);
169         err = getsockopt(fd, SOL_TCP, TCP_ZEROCOPY_RECEIVE, &buf, &optlen);
170         if (err) {
171                 log_err("Unexpected getsockopt(TCP_ZEROCOPY_RECEIVE) err=%d errno=%d",
172                         err, errno);
173                 goto err;
174         }
175 
176         memset(&buf, 0, sizeof(buf));
177         buf.zc.address = 12345; /* Not page aligned. Rejected by tcp_zerocopy_receive() */
178         optlen = sizeof(buf.zc);
179         errno = 0;
180         err = getsockopt(fd, SOL_TCP, TCP_ZEROCOPY_RECEIVE, &buf, &optlen);
181         if (errno != EINVAL) {
182                 log_err("Unexpected getsockopt(TCP_ZEROCOPY_RECEIVE) err=%d errno=%d",
183                         err, errno);
184                 goto err;
185         }
186 
187         /* optval=NULL case is handled correctly */
188 
189         close(fd);
190         fd = socket(AF_NETLINK, SOCK_RAW, 0);
191         if (fd < 0) {
192                 log_err("Failed to create AF_NETLINK socket");
193                 return -1;
194         }
195 
196         buf.u32 = 1;
197         optlen = sizeof(__u32);
198         err = setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &buf, optlen);
199         if (err) {
200                 log_err("Unexpected getsockopt(NETLINK_ADD_MEMBERSHIP) err=%d errno=%d",
201                         err, errno);
202                 goto err;
203         }
204 
205         optlen = 0;
206         err = getsockopt(fd, SOL_NETLINK, NETLINK_LIST_MEMBERSHIPS, NULL, &optlen);
207         if (err) {
208                 log_err("Unexpected getsockopt(NETLINK_LIST_MEMBERSHIPS) err=%d errno=%d",
209                         err, errno);
210                 goto err;
211         }
212         ASSERT_EQ(optlen, 8, "Unexpected NETLINK_LIST_MEMBERSHIPS value");
213 
214         free(big_buf);
215         close(fd);
216         return 0;
217 err:
218         free(big_buf);
219         close(fd);
220         return -1;
221 }
222 
223 static void run_test(int cgroup_fd)
224 {
225         struct sockopt_sk *skel;
226 
227         skel = sockopt_sk__open_and_load();
228         if (!ASSERT_OK_PTR(skel, "skel_load"))
229                 goto cleanup;
230 
231         skel->bss->page_size = getpagesize();
232 
233         skel->links._setsockopt =
234                 bpf_program__attach_cgroup(skel->progs._setsockopt, cgroup_fd);
235         if (!ASSERT_OK_PTR(skel->links._setsockopt, "setsockopt_link"))
236                 goto cleanup;
237 
238         skel->links._getsockopt =
239                 bpf_program__attach_cgroup(skel->progs._getsockopt, cgroup_fd);
240         if (!ASSERT_OK_PTR(skel->links._getsockopt, "getsockopt_link"))
241                 goto cleanup;
242 
243         ASSERT_OK(getsetsockopt(), "getsetsockopt");
244 
245 cleanup:
246         sockopt_sk__destroy(skel);
247 }
248 
249 void test_sockopt_sk(void)
250 {
251         int cgroup_fd;
252 
253         cgroup_fd = test__join_cgroup("/sockopt_sk");
254         if (!ASSERT_GE(cgroup_fd, 0, "join_cgroup /sockopt_sk"))
255                 return;
256 
257         run_test(cgroup_fd);
258         close(cgroup_fd);
259 }
260 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php