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