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