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