1 /*
2 * Copyright (c) 2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/posix/fcntl.h>
8 #include <zephyr/logging/log.h>
9 #include <zephyr/net/dummy.h>
10 #include <zephyr/net/net_if.h>
11 #include <zephyr/net/offloaded_netdev.h>
12 #include <zephyr/net/socket.h>
13 #include <sockets_internal.h>
14 #include <zephyr/sys/fdtable.h>
15 #include <zephyr/ztest.h>
16
17
18 LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);
19
20 /* Generic test offload API */
21
22 #define OFFLOAD_1 0
23 #define OFFLOAD_2 1
24 #define OFFLOAD_COUNT 2
25
26 static struct test_socket_calls {
27 bool socket_called;
28 bool close_called;
29 bool ioctl_called;
30 bool shutdown_called;
31 bool bind_called;
32 bool connect_called;
33 bool listen_called;
34 bool accept_called;
35 bool sendto_called;
36 bool recvfrom_called;
37 bool getsockopt_called;
38 bool setsockopt_called;
39 bool sendmsg_called;
40 bool getsockname_called;
41 bool getpeername_called;
42 } test_socket_ctx[OFFLOAD_COUNT];
43
44 static int test_sock = -1;
45
offload_read(void * obj,void * buffer,size_t count)46 static ssize_t offload_read(void *obj, void *buffer, size_t count)
47 {
48 ARG_UNUSED(obj);
49 ARG_UNUSED(buffer);
50 ARG_UNUSED(count);
51
52 return 0;
53 }
54
offload_write(void * obj,const void * buffer,size_t count)55 static ssize_t offload_write(void *obj, const void *buffer, size_t count)
56 {
57 ARG_UNUSED(obj);
58 ARG_UNUSED(buffer);
59 ARG_UNUSED(count);
60
61 return 0;
62 }
63
offload_close(void * obj)64 static int offload_close(void *obj)
65 {
66 struct test_socket_calls *ctx = obj;
67
68 ctx->close_called = true;
69
70 return 0;
71 }
72
offload_ioctl(void * obj,unsigned int request,va_list args)73 static int offload_ioctl(void *obj, unsigned int request, va_list args)
74 {
75 struct test_socket_calls *ctx = obj;
76
77 ARG_UNUSED(request);
78 ARG_UNUSED(args);
79
80 ctx->ioctl_called = true;
81
82 return 0;
83 }
84
offload_shutdown(void * obj,int how)85 static int offload_shutdown(void *obj, int how)
86 {
87 struct test_socket_calls *ctx = obj;
88
89 ARG_UNUSED(how);
90
91 ctx->shutdown_called = true;
92
93 return 0;
94 }
95
offload_bind(void * obj,const struct sockaddr * addr,socklen_t addrlen)96 static int offload_bind(void *obj, const struct sockaddr *addr,
97 socklen_t addrlen)
98 {
99 struct test_socket_calls *ctx = obj;
100
101 ARG_UNUSED(addr);
102 ARG_UNUSED(addrlen);
103
104 ctx->bind_called = true;
105
106 return 0;
107 }
108
offload_connect(void * obj,const struct sockaddr * addr,socklen_t addrlen)109 static int offload_connect(void *obj, const struct sockaddr *addr,
110 socklen_t addrlen)
111 {
112 struct test_socket_calls *ctx = obj;
113
114 ARG_UNUSED(addr);
115 ARG_UNUSED(addrlen);
116
117 ctx->connect_called = true;
118
119 return 0;
120 }
121
offload_listen(void * obj,int backlog)122 static int offload_listen(void *obj, int backlog)
123 {
124 struct test_socket_calls *ctx = obj;
125
126 ARG_UNUSED(backlog);
127
128 ctx->listen_called = true;
129
130 return 0;
131 }
132
offload_accept(void * obj,struct sockaddr * addr,socklen_t * addrlen)133 static int offload_accept(void *obj, struct sockaddr *addr, socklen_t *addrlen)
134 {
135 struct test_socket_calls *ctx = obj;
136
137 ARG_UNUSED(addr);
138 ARG_UNUSED(addrlen);
139
140 ctx->accept_called = true;
141
142 return 0;
143 }
144
offload_sendto(void * obj,const void * buf,size_t len,int flags,const struct sockaddr * dest_addr,socklen_t addrlen)145 static ssize_t offload_sendto(void *obj, const void *buf, size_t len,
146 int flags, const struct sockaddr *dest_addr,
147 socklen_t addrlen)
148 {
149 struct test_socket_calls *ctx = obj;
150
151 ARG_UNUSED(buf);
152 ARG_UNUSED(len);
153 ARG_UNUSED(flags);
154 ARG_UNUSED(dest_addr);
155 ARG_UNUSED(addrlen);
156
157 ctx->sendto_called = true;
158
159 return len;
160 }
161
offload_sendmsg(void * obj,const struct msghdr * msg,int flags)162 static ssize_t offload_sendmsg(void *obj, const struct msghdr *msg, int flags)
163 {
164 struct test_socket_calls *ctx = obj;
165
166 ARG_UNUSED(msg);
167 ARG_UNUSED(flags);
168
169 ctx->sendmsg_called = true;
170
171 return 0;
172 }
173
offload_recvfrom(void * obj,void * buf,size_t max_len,int flags,struct sockaddr * src_addr,socklen_t * addrlen)174 static ssize_t offload_recvfrom(void *obj, void *buf, size_t max_len,
175 int flags, struct sockaddr *src_addr,
176 socklen_t *addrlen)
177 {
178 struct test_socket_calls *ctx = obj;
179
180 ARG_UNUSED(buf);
181 ARG_UNUSED(max_len);
182 ARG_UNUSED(flags);
183 ARG_UNUSED(src_addr);
184 ARG_UNUSED(addrlen);
185
186 ctx->recvfrom_called = true;
187
188 return 0;
189 }
190
offload_getsockopt(void * obj,int level,int optname,void * optval,socklen_t * optlen)191 static int offload_getsockopt(void *obj, int level, int optname,
192 void *optval, socklen_t *optlen)
193 {
194 struct test_socket_calls *ctx = obj;
195
196 ARG_UNUSED(level);
197 ARG_UNUSED(optname);
198 ARG_UNUSED(optval);
199 ARG_UNUSED(optlen);
200
201 ctx->getsockopt_called = true;
202
203 return 0;
204 }
205
offload_setsockopt(void * obj,int level,int optname,const void * optval,socklen_t optlen)206 static int offload_setsockopt(void *obj, int level, int optname,
207 const void *optval, socklen_t optlen)
208 {
209 struct test_socket_calls *ctx = obj;
210
211 ARG_UNUSED(level);
212 ARG_UNUSED(optname);
213 ARG_UNUSED(optval);
214 ARG_UNUSED(optlen);
215
216 ctx->setsockopt_called = true;
217
218 return 0;
219 }
220
offload_getpeername(void * obj,struct sockaddr * addr,socklen_t * addrlen)221 static int offload_getpeername(void *obj, struct sockaddr *addr,
222 socklen_t *addrlen)
223 {
224 struct test_socket_calls *ctx = obj;
225
226 ARG_UNUSED(addr);
227 ARG_UNUSED(addrlen);
228
229 ctx->getpeername_called = true;
230
231 return 0;
232 }
233
offload_getsockname(void * obj,struct sockaddr * addr,socklen_t * addrlen)234 static int offload_getsockname(void *obj, struct sockaddr *addr,
235 socklen_t *addrlen)
236 {
237 struct test_socket_calls *ctx = obj;
238
239 ARG_UNUSED(addr);
240 ARG_UNUSED(addrlen);
241
242 ctx->getsockname_called = true;
243
244 return 0;
245 }
246
247 /* Offloaded interface 1 - high priority */
248
249 #define SOCKET_OFFLOAD_PRIO_HIGH 10
250
251 static const struct socket_op_vtable offload_1_socket_fd_op_vtable = {
252 .fd_vtable = {
253 .read = offload_read,
254 .write = offload_write,
255 .close = offload_close,
256 .ioctl = offload_ioctl,
257 },
258 .shutdown = offload_shutdown,
259 .bind = offload_bind,
260 .connect = offload_connect,
261 .listen = offload_listen,
262 .accept = offload_accept,
263 .sendto = offload_sendto,
264 .recvfrom = offload_recvfrom,
265 .getsockopt = offload_getsockopt,
266 .setsockopt = offload_setsockopt,
267 .sendmsg = offload_sendmsg,
268 .getsockname = offload_getsockname,
269 .getpeername = offload_getpeername,
270 };
271
offload_1_socket(int family,int type,int proto)272 int offload_1_socket(int family, int type, int proto)
273 {
274 int fd = zvfs_reserve_fd();
275
276 if (fd < 0) {
277 return -1;
278 }
279
280 zvfs_finalize_typed_fd(fd, &test_socket_ctx[OFFLOAD_1],
281 (const struct fd_op_vtable *)&offload_1_socket_fd_op_vtable,
282 ZVFS_MODE_IFSOCK);
283
284 test_socket_ctx[OFFLOAD_1].socket_called = true;
285
286 return fd;
287 }
288
offload_1_is_supported(int family,int type,int proto)289 static bool offload_1_is_supported(int family, int type, int proto)
290 {
291 return true;
292 }
293
294 NET_SOCKET_OFFLOAD_REGISTER(offloaded_1, SOCKET_OFFLOAD_PRIO_HIGH, AF_UNSPEC,
295 offload_1_is_supported, offload_1_socket);
296
offloaded_1_iface_init(struct net_if * iface)297 static void offloaded_1_iface_init(struct net_if *iface)
298 {
299 net_if_socket_offload_set(iface, offload_1_socket);
300 }
301
302 static struct offloaded_if_api offloaded_1_if_api = {
303 .iface_api.init = offloaded_1_iface_init,
304 };
305
306 NET_DEVICE_OFFLOAD_INIT(offloaded_1, "offloaded_1", NULL, NULL,
307 NULL, NULL, 0, &offloaded_1_if_api, 1500);
308
309 /* Offloaded interface 2 - low priority */
310
311 #define SOCKET_OFFLOAD_PRIO_LOW 20
312
313 static const struct socket_op_vtable offload_2_socket_fd_op_vtable = {
314 .fd_vtable = {
315 .read = offload_read,
316 .write = offload_write,
317 .close = offload_close,
318 .ioctl = offload_ioctl,
319 },
320 .shutdown = offload_shutdown,
321 .bind = offload_bind,
322 .connect = offload_connect,
323 .listen = offload_listen,
324 .accept = offload_accept,
325 .sendto = offload_sendto,
326 .recvfrom = offload_recvfrom,
327 .getsockopt = offload_getsockopt,
328 .setsockopt = offload_setsockopt,
329 .sendmsg = offload_sendmsg,
330 .getsockname = offload_getsockname,
331 .getpeername = offload_getpeername,
332 };
333
offload_2_socket(int family,int type,int proto)334 int offload_2_socket(int family, int type, int proto)
335 {
336 int fd = zvfs_reserve_fd();
337
338 if (fd < 0) {
339 return -1;
340 }
341
342 zvfs_finalize_typed_fd(fd, &test_socket_ctx[OFFLOAD_2],
343 (const struct fd_op_vtable *)&offload_2_socket_fd_op_vtable,
344 ZVFS_MODE_IFSOCK);
345
346 test_socket_ctx[OFFLOAD_2].socket_called = true;
347
348 return fd;
349 }
350
offload_2_is_supported(int family,int type,int proto)351 static bool offload_2_is_supported(int family, int type, int proto)
352 {
353 return true;
354 }
355
356 NET_SOCKET_OFFLOAD_REGISTER(offloaded_2, SOCKET_OFFLOAD_PRIO_HIGH, AF_UNSPEC,
357 offload_2_is_supported, offload_2_socket);
358
offloaded_2_iface_init(struct net_if * iface)359 static void offloaded_2_iface_init(struct net_if *iface)
360 {
361 net_if_socket_offload_set(iface, offload_2_socket);
362 }
363
364 static struct offloaded_if_api offloaded_2_if_api = {
365 .iface_api.init = offloaded_2_iface_init,
366 };
367
368 NET_DEVICE_OFFLOAD_INIT(offloaded_2, "offloaded_2", NULL, NULL,
369 NULL, NULL, 0, &offloaded_2_if_api, 1500);
370
371
372 /* Native dummy interface */
373
374 static uint8_t lladdr[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
375 static struct in_addr in4addr_my = { { { 192, 0, 2, 1 } } };
376 static K_SEM_DEFINE(test_native_send_called, 0, 1);
377
dummy_native_iface_init(struct net_if * iface)378 static void dummy_native_iface_init(struct net_if *iface)
379 {
380 net_if_set_link_addr(iface, lladdr, 6, NET_LINK_DUMMY);
381 net_if_ipv4_addr_add(iface, &in4addr_my, NET_ADDR_MANUAL, 0);
382 }
383
dummy_native_dev_send(const struct device * dev,struct net_pkt * pkt)384 static int dummy_native_dev_send(const struct device *dev, struct net_pkt *pkt)
385 {
386 ARG_UNUSED(dev);
387 ARG_UNUSED(pkt);
388
389 k_sem_give(&test_native_send_called);
390
391 return 0;
392 }
393
394 static const struct dummy_api dummy_native_dev_api = {
395 .iface_api.init = dummy_native_iface_init,
396 .send = dummy_native_dev_send,
397 };
398
399 NET_DEVICE_INIT(dummy_native, "dummy_native", NULL, NULL, NULL,
400 NULL, 0, &dummy_native_dev_api, DUMMY_L2,
401 NET_L2_GET_CTX_TYPE(DUMMY_L2), 1500);
402
403 /* Actual tests */
404
405 static const struct sockaddr_in test_peer_addr = {
406 .sin_family = AF_INET,
407 .sin_addr = { { { 192, 0, 0, 2 } } },
408 .sin_port = 1234
409 };
410
test_result_reset(void)411 static void test_result_reset(void)
412 {
413 memset(test_socket_ctx, 0, sizeof(test_socket_ctx));
414 k_sem_reset(&test_native_send_called);
415 }
416
test_socket_setup_udp(void * dummy)417 static void test_socket_setup_udp(void *dummy)
418 {
419 ARG_UNUSED(dummy);
420 test_result_reset();
421
422 test_sock = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
423
424 zassert_true(test_sock >= 0, "Failed to create socket");
425 zassert_false(test_socket_ctx[OFFLOAD_1].socket_called,
426 "Socket should'nt have been dispatched yet");
427 }
428
test_socket_setup_tls(void * dummy)429 static void test_socket_setup_tls(void *dummy)
430 {
431 ARG_UNUSED(dummy);
432 test_result_reset();
433
434 test_sock = zsock_socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2);
435 zassert_true(test_sock >= 0, "Failed to create socket");
436 zassert_false(test_socket_ctx[OFFLOAD_1].socket_called,
437 "Socket should'nt have been dispatched yet");
438 }
439
test_socket_teardown(void * dummy)440 static void test_socket_teardown(void *dummy)
441 {
442 ARG_UNUSED(dummy);
443
444 int ret = zsock_close(test_sock);
445
446 test_sock = -1;
447
448 zassert_equal(0, ret, "close() failed");
449 }
450
451 /* Verify that socket is not dispatched when close() is called immediately after
452 * creating dispatcher socket.
453 */
ZTEST(net_socket_offload_close,test_close_not_bound)454 ZTEST(net_socket_offload_close, test_close_not_bound)
455 {
456 int ret = zsock_close(test_sock);
457
458 test_sock = -1;
459
460 zassert_equal(0, ret, "close() failed");
461 zassert_false(test_socket_ctx[OFFLOAD_1].socket_called,
462 "Socket should'nt have been dispatched");
463 zassert_false(test_socket_ctx[OFFLOAD_1].close_called,
464 "close() should'nt have been dispatched");
465 }
466
467 /* Verify that socket is automatically dispatched to a default socket
468 * implementation on ioctl() call, if not bound.
469 */
ZTEST(net_socket_offload_udp,test_fcntl_not_bound)470 ZTEST(net_socket_offload_udp, test_fcntl_not_bound)
471 {
472 int ret;
473
474 ret = zsock_fcntl(test_sock, F_SETFL, 0);
475 zassert_equal(0, ret, "fcntl() failed");
476 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
477 "Socket should've been dispatched");
478 zassert_true(test_socket_ctx[OFFLOAD_1].ioctl_called,
479 "fcntl() should've been dispatched");
480 }
481
482 /* Verify that socket is automatically dispatched to a default socket
483 * implementation on shutdown() call, if not bound.
484 */
485
ZTEST(net_socket_offload_udp,test_shutdown_not_bound)486 ZTEST(net_socket_offload_udp, test_shutdown_not_bound)
487 {
488 int ret;
489
490 ret = zsock_shutdown(test_sock, ZSOCK_SHUT_RD);
491 zassert_equal(0, ret, "shutdown() failed");
492 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
493 "Socket should've been dispatched");
494 zassert_true(test_socket_ctx[OFFLOAD_1].shutdown_called,
495 "shutdown() should've been dispatched");
496 }
497
498 /* Verify that socket is automatically dispatched to a default socket
499 * implementation on bind() call, if not bound.
500 */
ZTEST(net_socket_offload_udp,test_bind_not_bound)501 ZTEST(net_socket_offload_udp, test_bind_not_bound)
502 {
503 int ret;
504 struct sockaddr_in addr = {
505 .sin_family = AF_INET
506 };
507
508 ret = zsock_bind(test_sock, (struct sockaddr *)&addr, sizeof(addr));
509 zassert_equal(0, ret, "bind() failed");
510 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
511 "Socket should've been dispatched");
512 zassert_true(test_socket_ctx[OFFLOAD_1].bind_called,
513 "bind() should've been dispatched");
514 }
515
516 /* Verify that socket is automatically dispatched to a default socket
517 * implementation on connect() call, if not bound.
518 */
ZTEST(net_socket_offload_udp,test_connect_not_bound)519 ZTEST(net_socket_offload_udp, test_connect_not_bound)
520 {
521 int ret;
522 struct sockaddr_in addr = test_peer_addr;
523
524 ret = zsock_connect(test_sock, (struct sockaddr *)&addr, sizeof(addr));
525 zassert_equal(0, ret, "connect() failed");
526 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
527 "Socket should've been dispatched");
528 zassert_true(test_socket_ctx[OFFLOAD_1].connect_called,
529 "connect() should've been dispatched");
530 }
531
532 /* Verify that socket is automatically dispatched to a default socket
533 * implementation on listen() call, if not bound.
534 */
ZTEST(net_socket_offload_udp,test_listen_not_bound)535 ZTEST(net_socket_offload_udp, test_listen_not_bound)
536 {
537 int ret;
538
539 ret = zsock_listen(test_sock, 1);
540 zassert_equal(0, ret, "listen() failed");
541 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
542 "Socket should've been dispatched");
543 zassert_true(test_socket_ctx[OFFLOAD_1].listen_called,
544 "listen() should've been dispatched");
545 }
546
547 /* Verify that socket is automatically dispatched to a default socket
548 * implementation on accept() call, if not bound.
549 */
ZTEST(net_socket_offload_udp,test_accept_not_bound)550 ZTEST(net_socket_offload_udp, test_accept_not_bound)
551 {
552 int ret;
553 struct sockaddr_in addr;
554 socklen_t addrlen = sizeof(addr);
555
556 ret = zsock_accept(test_sock, (struct sockaddr *)&addr, &addrlen);
557 zassert_equal(0, ret, "accept() failed");
558 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
559 "Socket should've been dispatched");
560 zassert_true(test_socket_ctx[OFFLOAD_1].accept_called,
561 "accept() should've been dispatched");
562 }
563
564 /* Verify that socket is automatically dispatched to a default socket
565 * implementation on sendto() call, if not bound.
566 */
ZTEST(net_socket_offload_udp,test_sendto_not_bound)567 ZTEST(net_socket_offload_udp, test_sendto_not_bound)
568 {
569 int ret;
570 uint8_t dummy_data = 0;
571 struct sockaddr_in addr = test_peer_addr;
572
573 ret = zsock_sendto(test_sock, &dummy_data, 1, 0,
574 (struct sockaddr *)&addr, sizeof(addr));
575 zassert_equal(1, ret, "sendto() failed");
576 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
577 "Socket should've been dispatched");
578 zassert_true(test_socket_ctx[OFFLOAD_1].sendto_called,
579 "sendto() should've been dispatched");
580 }
581
582 /* Verify that socket is automatically dispatched to a default socket
583 * implementation on recvfrom() call, if not bound.
584 */
ZTEST(net_socket_offload_udp,test_recvfrom_not_bound)585 ZTEST(net_socket_offload_udp, test_recvfrom_not_bound)
586 {
587 int ret;
588 uint8_t dummy_data = 0;
589
590 ret = zsock_recvfrom(test_sock, &dummy_data, 1, 0, NULL, 0);
591 zassert_equal(0, ret, "recvfrom() failed");
592 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
593 "Socket should've been dispatched");
594 zassert_true(test_socket_ctx[OFFLOAD_1].recvfrom_called,
595 "recvfrom() should've been dispatched");
596 }
597
598 /* Verify that socket is automatically dispatched to a default socket
599 * implementation on getsockopt() call, if not bound.
600 */
ZTEST(net_socket_offload_udp,test_getsockopt_not_bound)601 ZTEST(net_socket_offload_udp, test_getsockopt_not_bound)
602 {
603 int ret;
604 struct timeval optval = { 0 };
605 socklen_t optlen = sizeof(optval);
606
607 ret = zsock_getsockopt(test_sock, SOL_SOCKET, SO_RCVTIMEO,
608 &optval, &optlen);
609 zassert_equal(0, ret, "getsockopt() failed");
610 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
611 "Socket should've been dispatched");
612 zassert_true(test_socket_ctx[OFFLOAD_1].getsockopt_called,
613 "getsockopt() should've been dispatched");
614 }
615
616 /* Verify that socket is automatically dispatched to a default socket
617 * implementation on setsockopt() call, if not bound.
618 */
ZTEST(net_socket_offload_udp,test_setsockopt_not_bound)619 ZTEST(net_socket_offload_udp, test_setsockopt_not_bound)
620 {
621 int ret;
622 struct timeval optval = { 0 };
623
624 ret = zsock_setsockopt(test_sock, SOL_SOCKET, SO_RCVTIMEO,
625 &optval, sizeof(optval));
626 zassert_equal(0, ret, "setsockopt() failed");
627 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
628 "Socket should've been dispatched");
629 zassert_true(test_socket_ctx[OFFLOAD_1].setsockopt_called,
630 "setsockopt() should've been dispatched");
631 }
632
633 /* Verify that socket is automatically dispatched to a default socket
634 * implementation on sendmsg() call, if not bound.
635 */
ZTEST(net_socket_offload_udp,test_sendmsg_not_bound)636 ZTEST(net_socket_offload_udp, test_sendmsg_not_bound)
637 {
638 int ret;
639 struct msghdr dummy_msg = { 0 };
640
641 ret = zsock_sendmsg(test_sock, &dummy_msg, 0);
642 zassert_equal(0, ret, "sendmsg() failed");
643 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
644 "Socket should've been dispatched");
645 zassert_true(test_socket_ctx[OFFLOAD_1].sendmsg_called,
646 "sendmsg() should've been dispatched");
647 }
648
649 /* Verify that socket is automatically dispatched to a default socket
650 * implementation on getpeername() call, if not bound.
651 */
ZTEST(net_socket_offload_udp,test_getpeername_not_bound)652 ZTEST(net_socket_offload_udp, test_getpeername_not_bound)
653 {
654 int ret;
655 struct sockaddr_in addr;
656 socklen_t addrlen = sizeof(addr);
657
658 ret = zsock_getpeername(test_sock, (struct sockaddr *)&addr, &addrlen);
659 zassert_equal(0, ret, "getpeername() failed");
660 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
661 "Socket should've been dispatched");
662 zassert_true(test_socket_ctx[OFFLOAD_1].getpeername_called,
663 "getpeername() should've been dispatched");
664 }
665
666 /* Verify that socket is automatically dispatched to a default socket
667 * implementation on getsockname() call, if not bound.
668 */
ZTEST(net_socket_offload_udp,test_getsockname_not_bound)669 ZTEST(net_socket_offload_udp, test_getsockname_not_bound)
670 {
671 int ret;
672 struct sockaddr_in addr;
673 socklen_t addrlen = sizeof(addr);
674
675 ret = zsock_getsockname(test_sock, (struct sockaddr *)&addr, &addrlen);
676 zassert_equal(0, ret, "getsockname() failed");
677 zassert_true(test_socket_ctx[OFFLOAD_1].socket_called,
678 "Socket should've been dispatched");
679 zassert_true(test_socket_ctx[OFFLOAD_1].getsockname_called,
680 "getsockname() should've been dispatched");
681 }
682
683 /* Verify that socket is dispatched to a proper offloaded socket implementation
684 * if the socket is bound to an offloaded interface.
685 */
ZTEST(net_socket_offload_udp,test_so_bindtodevice_iface_offloaded)686 ZTEST(net_socket_offload_udp, test_so_bindtodevice_iface_offloaded)
687 {
688 int ret;
689 uint8_t dummy_data = 0;
690 struct ifreq ifreq = {
691 #if defined(CONFIG_NET_INTERFACE_NAME)
692 .ifr_name = "net1"
693 #else
694 .ifr_name = "offloaded_2"
695 #endif
696 };
697 struct sockaddr_in addr = {
698 .sin_family = AF_INET
699 };
700
701 ret = zsock_setsockopt(test_sock, SOL_SOCKET, SO_BINDTODEVICE,
702 &ifreq, sizeof(ifreq));
703 zassert_equal(0, ret, "setsockopt() failed");
704 zassert_false(test_socket_ctx[OFFLOAD_1].socket_called,
705 "Socket dispatched to wrong iface");
706 zassert_true(test_socket_ctx[OFFLOAD_2].socket_called,
707 "Socket should've been dispatched to offloaded iface 2");
708 zassert_true(test_socket_ctx[OFFLOAD_2].setsockopt_called,
709 "setsockopt() should've been dispatched");
710
711 ret = zsock_sendto(test_sock, &dummy_data, 1, 0,
712 (struct sockaddr *)&addr, sizeof(addr));
713 zassert_equal(1, ret, "sendto() failed");
714 zassert_true(test_socket_ctx[OFFLOAD_2].sendto_called,
715 "sendto() should've been dispatched");
716 }
717
718 /* Verify that socket is dispatched to a native socket implementation
719 * if the socket is bound to a native interface.
720 */
ZTEST(net_socket_offload_udp,test_so_bindtodevice_iface_native)721 ZTEST(net_socket_offload_udp, test_so_bindtodevice_iface_native)
722 {
723 int ret;
724 uint8_t dummy_data = 0;
725 struct ifreq ifreq = {
726 #if defined(CONFIG_NET_INTERFACE_NAME)
727 .ifr_name = "dummy0"
728 #else
729 .ifr_name = "dummy_native"
730 #endif
731 };
732 struct sockaddr_in addr = test_peer_addr;
733
734 ret = zsock_setsockopt(test_sock, SOL_SOCKET, SO_BINDTODEVICE,
735 &ifreq, sizeof(ifreq));
736
737 zassert_equal(0, ret, "setsockopt() failed");
738 zassert_false(test_socket_ctx[OFFLOAD_1].socket_called,
739 "Socket dispatched to wrong iface");
740 zassert_false(test_socket_ctx[OFFLOAD_2].socket_called,
741 "Socket dispatched to wrong iface");
742
743 ret = zsock_sendto(test_sock, &dummy_data, 1, 0,
744 (struct sockaddr *)&addr, sizeof(addr));
745 zassert_equal(1, ret, "sendto() failed %d", errno);
746
747 ret = k_sem_take(&test_native_send_called, K_MSEC(200));
748 zassert_equal(0, ret, "sendto() should've been dispatched to native iface");
749 }
750
751 /* Verify that the underlying socket is dispatched to a proper offloaded socket
752 * implementation if native TLS is used and the socket is bound to an offloaded
753 * interface.
754 */
ZTEST(net_socket_offload_tls,test_tls_native_iface_offloaded)755 ZTEST(net_socket_offload_tls, test_tls_native_iface_offloaded)
756 {
757 int ret;
758 const struct fd_op_vtable *vtable;
759 void *obj;
760 struct ifreq ifreq = {
761 #if defined(CONFIG_NET_INTERFACE_NAME)
762 .ifr_name = "net1"
763 #else
764 .ifr_name = "offloaded_2"
765 #endif
766 };
767 int tls_native = 1;
768 struct sockaddr_in addr = test_peer_addr;
769
770 ret = zsock_setsockopt(test_sock, SOL_TLS, TLS_NATIVE,
771 &tls_native, sizeof(tls_native));
772 zassert_equal(0, ret, "setsockopt() failed");
773 zassert_false(test_socket_ctx[OFFLOAD_1].socket_called,
774 "TLS socket dispatched to wrong iface");
775 zassert_false(test_socket_ctx[OFFLOAD_2].socket_called,
776 "TLS socket dispatched to wrong iface");
777
778 obj = zvfs_get_fd_obj_and_vtable(test_sock, &vtable, NULL);
779 zassert_not_null(obj, "No obj found");
780 zassert_true(net_socket_is_tls(obj), "Socket is not a native TLS sock");
781
782 ret = zsock_setsockopt(test_sock, SOL_SOCKET, SO_BINDTODEVICE,
783 &ifreq, sizeof(ifreq));
784 zassert_equal(0, ret, "setsockopt() failed");
785 zassert_false(test_socket_ctx[OFFLOAD_1].socket_called,
786 "Underlying socket dispatched to wrong iface");
787 zassert_true(test_socket_ctx[OFFLOAD_2].socket_called,
788 "Underlying socket dispatched to wrong iface");
789
790 /* Ignore connect result as it will fail anyway. Just verify the
791 * call/packets were forwarded to a valid iface.
792 */
793 ret = zsock_connect(test_sock, (struct sockaddr *)&addr, sizeof(addr));
794 zassert_true(test_socket_ctx[OFFLOAD_2].connect_called,
795 "connect() should've been dispatched to offloaded_2 iface");
796 }
797
798 /* Verify that the underlying socket is dispatched to a native socket
799 * implementation if native TLS is used and the socket is bound to a native
800 * interface.
801 */
ZTEST(net_socket_offload_tls,test_tls_native_iface_native)802 ZTEST(net_socket_offload_tls, test_tls_native_iface_native)
803 {
804 int ret;
805 const struct fd_op_vtable *vtable;
806 void *obj;
807 struct ifreq ifreq = {
808 #if defined(CONFIG_NET_INTERFACE_NAME)
809 .ifr_name = "dummy0"
810 #else
811 .ifr_name = "dummy_native"
812 #endif
813 };
814 int tls_native = 1;
815 struct sockaddr_in addr = test_peer_addr;
816
817 ret = zsock_setsockopt(test_sock, SOL_TLS, TLS_NATIVE,
818 &tls_native, sizeof(tls_native));
819 zassert_equal(0, ret, "setsockopt() failed");
820 zassert_false(test_socket_ctx[OFFLOAD_1].socket_called,
821 "TLS socket dispatched to wrong iface");
822 zassert_false(test_socket_ctx[OFFLOAD_2].socket_called,
823 "TLS socket dispatched to wrong iface");
824
825 obj = zvfs_get_fd_obj_and_vtable(test_sock, &vtable, NULL);
826 zassert_not_null(obj, "No obj found");
827 zassert_true(net_socket_is_tls(obj), "Socket is not a native TLS sock");
828
829 ret = zsock_setsockopt(test_sock, SOL_SOCKET, SO_BINDTODEVICE,
830 &ifreq, sizeof(ifreq));
831 zassert_equal(0, ret, "setsockopt() failed");
832 zassert_false(test_socket_ctx[OFFLOAD_1].socket_called,
833 "Underlying socket dispatched to wrong iface");
834 zassert_false(test_socket_ctx[OFFLOAD_2].socket_called,
835 "Underlying socket dispatched to wrong iface");
836
837 /* Ignore connect result as it will fail anyway. Just verify the
838 * call/packets were forwarded to a valid iface.
839 */
840 (void)zsock_connect(test_sock, (struct sockaddr *)&addr, sizeof(addr));
841
842 ret = k_sem_take(&test_native_send_called, K_MSEC(200));
843 zassert_equal(0, ret, "sendto() should've been dispatched to native iface");
844 }
845
846 ZTEST_SUITE(net_socket_offload_udp, NULL, NULL, test_socket_setup_udp,
847 test_socket_teardown, NULL);
848 ZTEST_SUITE(net_socket_offload_tls, NULL, NULL, test_socket_setup_tls,
849 test_socket_teardown, NULL);
850 ZTEST_SUITE(net_socket_offload_close, NULL, NULL, test_socket_setup_udp,
851 NULL, NULL);
852