1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2015 Intel Corporation
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(net_test, CONFIG_NET_CONTEXT_LOG_LEVEL);
11 
12 #include <zephyr/types.h>
13 #include <zephyr/ztest.h>
14 #include <stdbool.h>
15 #include <stddef.h>
16 #include <string.h>
17 #include <errno.h>
18 #include <zephyr/sys/printk.h>
19 #include <zephyr/linker/sections.h>
20 #include <zephyr/random/random.h>
21 
22 #include <zephyr/tc_util.h>
23 
24 #include <zephyr/net/ethernet.h>
25 #include <zephyr/net/dummy.h>
26 #include <zephyr/net_buf.h>
27 #include <zephyr/net/net_ip.h>
28 #include <zephyr/net/net_if.h>
29 #include <zephyr/net/net_context.h>
30 #include <zephyr/net/udp.h>
31 
32 #include "net_private.h"
33 
34 #if defined(CONFIG_NET_CONTEXT_LOG_LEVEL_DBG)
35 #define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
36 #else
37 #define DBG(fmt, ...)
38 #endif
39 
40 static struct net_context *udp_v6_ctx;
41 static struct net_context *udp_v4_ctx;
42 static struct net_context *mcast_v6_ctx;
43 
44 #if defined(CONFIG_NET_TCP)
45 static struct net_context *tcp_v6_ctx;
46 static struct net_context *tcp_v4_ctx;
47 #endif
48 
49 static struct in6_addr in6addr_my = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
50 					  0, 0, 0, 0, 0, 0, 0, 0x1 } } };
51 static struct in6_addr in6addr_mcast = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
52 					     0, 0, 0, 0, 0, 0, 0, 0x1 } } };
53 
54 static struct in_addr in4addr_my = { { { 192, 0, 2, 1 } } };
55 
56 static char *test_data = "Test data to be sent";
57 
58 static bool test_failed;
59 static bool cb_failure;
60 static bool expecting_cb_failure;
61 static bool data_failure;
62 static bool recv_cb_called;
63 static bool recv_cb_reconfig_called;
64 static bool recv_cb_timeout_called;
65 static bool test_sending;
66 
67 static struct k_sem wait_data;
68 
69 #define WAIT_TIME K_MSEC(250)
70 #define WAIT_TIME_LONG MSEC_PER_SEC
71 #define SENDING 93244
72 #define MY_PORT 1969
73 #define PEER_PORT 16233
74 
ZTEST(net_context,test_net_ctx_get_fail)75 ZTEST(net_context, test_net_ctx_get_fail)
76 {
77 	struct net_context *context;
78 	int ret;
79 
80 	ret = net_context_get(AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP, &context);
81 	zassert_equal(ret, -EAFNOSUPPORT,
82 		      "Invalid family test failed");
83 
84 	ret = net_context_get(AF_INET6, 10, IPPROTO_UDP, &context);
85 	zassert_equal(ret, -EPROTOTYPE,
86 		      "Invalid context type test failed ");
87 
88 	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6, &context);
89 	zassert_equal(ret, -EPROTONOSUPPORT,
90 		      "Invalid context protocol test failed");
91 
92 	ret = net_context_get(99, SOCK_DGRAM, IPPROTO_UDP, &context);
93 	zassert_equal(ret, -EAFNOSUPPORT,
94 		      "Invalid context family test failed");
95 
96 	ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP, &context);
97 	zassert_equal(ret, -EPROTOTYPE,
98 		      "Invalid context proto type test failed");
99 
100 	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_TCP, &context);
101 	zassert_equal(ret, -EPROTONOSUPPORT,
102 		      "Invalid context proto value test failed");
103 
104 	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, NULL);
105 	zassert_equal(ret, -EINVAL,
106 		      "Invalid context value test failed ");
107 }
108 
ZTEST(net_context,test_net_ctx_get_success)109 ZTEST(net_context, test_net_ctx_get_success)
110 {
111 	struct net_context *context = NULL;
112 	int ret;
113 
114 	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &context);
115 	zassert_equal(ret, 0,
116 		      "Context get test failed");
117 	zassert_not_null(context, "Got NULL context");
118 
119 	ret = net_context_put(context);
120 	zassert_equal(ret, 0,
121 		      "Context put test failed");
122 
123 	zassert_false(net_context_is_used(context),
124 		      "Context put check test failed");
125 }
126 
ZTEST(net_context,test_net_ctx_get_all)127 ZTEST(net_context, test_net_ctx_get_all)
128 {
129 	struct net_context *contexts[CONFIG_NET_MAX_CONTEXTS];
130 	struct net_context *context;
131 	int ret, i;
132 
133 	for (i = 0; i < ARRAY_SIZE(contexts); i++) {
134 		ret = net_context_get(AF_INET6, SOCK_DGRAM,
135 				      IPPROTO_UDP, &contexts[i]);
136 		zassert_equal(ret, 0,
137 			      "context get test failed");
138 	}
139 
140 	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &context);
141 	zassert_equal(ret, -ENOENT,
142 		      "Context get extra test failed");
143 
144 	for (i = 0; i < ARRAY_SIZE(contexts); i++) {
145 		ret = net_context_put(contexts[i]);
146 		zassert_equal(ret, 0,
147 			      "Context put test failed");
148 	}
149 }
150 
net_ctx_create(void)151 static void net_ctx_create(void)
152 {
153 	int ret;
154 
155 	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP,
156 			      &udp_v6_ctx);
157 	zassert_equal(ret, 0,
158 		      "Context create IPv6 UDP test failed");
159 
160 	ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP,
161 			      &mcast_v6_ctx);
162 	zassert_equal(ret, 0,
163 		      "Context create IPv6 mcast test failed ");
164 
165 	ret = net_context_get(AF_INET, SOCK_DGRAM, IPPROTO_UDP,
166 			      &udp_v4_ctx);
167 	zassert_equal(ret, 0,
168 		      "Context create IPv4 UDP test failed");
169 
170 #if defined(CONFIG_NET_TCP)
171 	ret = net_context_get(AF_INET6, SOCK_STREAM, IPPROTO_TCP,
172 			      &tcp_v6_ctx);
173 	zassert_equal(ret, 0,
174 		      "Context create IPv6 TCP test failed");
175 
176 	ret = net_context_get(AF_INET, SOCK_STREAM, IPPROTO_TCP,
177 			      &tcp_v4_ctx);
178 	zassert_equal(ret, 0,
179 		      "Context create IPv4 TCP test failed");
180 #endif /* CONFIG_NET_TCP */
181 }
182 
net_ctx_bind_fail(void)183 static void net_ctx_bind_fail(void)
184 {
185 	struct sockaddr_in6 addr = {
186 		.sin6_family = AF_INET6,
187 		.sin6_port = 0,
188 		.sin6_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
189 				   0, 0, 0, 0, 0, 0, 0, 0x2 } } },
190 	};
191 	int ret;
192 
193 	ret = net_context_bind(udp_v6_ctx, (struct sockaddr *)&addr,
194 			       sizeof(struct sockaddr_in6));
195 	zassert_equal(ret, -ENOENT,
196 		      "Context bind failure test failed");
197 }
198 
net_ctx_bind_uni_success_v6(void)199 static void net_ctx_bind_uni_success_v6(void)
200 {
201 	struct sockaddr_in6 addr = {
202 		.sin6_family = AF_INET6,
203 		.sin6_port = htons(MY_PORT),
204 		.sin6_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
205 				   0, 0, 0, 0, 0, 0, 0, 0x1 } } },
206 	};
207 	int ret;
208 
209 	ret = net_context_bind(udp_v6_ctx, (struct sockaddr *)&addr,
210 			       sizeof(struct sockaddr_in6));
211 	zassert_equal(ret, 0,
212 		      "Context bind IPv6 test failed");
213 }
214 
net_ctx_bind_uni_success_v4(void)215 static void net_ctx_bind_uni_success_v4(void)
216 {
217 	struct sockaddr_in addr = {
218 		.sin_family = AF_INET,
219 		.sin_port = htons(MY_PORT),
220 		.sin_addr = { { { 192, 0, 2, 1 } } },
221 	};
222 	int ret;
223 
224 	ret = net_context_bind(udp_v4_ctx, (struct sockaddr *)&addr,
225 			       sizeof(struct sockaddr_in));
226 	zassert_equal(ret, 0,
227 		      "Context bind IPv4 test failed");
228 }
229 
net_ctx_bind_mcast_success(void)230 static void net_ctx_bind_mcast_success(void)
231 {
232 	int ret;
233 	struct sockaddr_in6 addr = {
234 		.sin6_family = AF_INET6,
235 		.sin6_port = htons(MY_PORT),
236 		.sin6_addr = { { { 0 } } },
237 	};
238 
239 	net_ipv6_addr_create_ll_allnodes_mcast(&addr.sin6_addr);
240 
241 	ret = net_context_bind(mcast_v6_ctx, (struct sockaddr *)&addr,
242 			       sizeof(struct sockaddr_in6));
243 	zassert_equal(ret, 0,
244 		      "Context bind test failed ");
245 }
246 
net_ctx_listen_v6(void)247 static void net_ctx_listen_v6(void)
248 {
249 #if defined(CONFIG_NET_TCP)
250 	zassert_true(net_context_listen(tcp_v6_ctx, 0),
251 		     "Context listen IPv6 TCP test failed");
252 #endif /* CONFIG_NET_TCP */
253 }
254 
net_ctx_listen_v4(void)255 static void net_ctx_listen_v4(void)
256 {
257 #if defined(CONFIG_NET_TCP)
258 	zassert_true(net_context_listen(tcp_v4_ctx, 0),
259 		     "Context listen IPv4 TCP test failed");
260 #endif /* CONFIG_NET_TCP */
261 }
262 
connect_cb(struct net_context * context,int status,void * user_data)263 static void connect_cb(struct net_context *context, int status,
264 		       void *user_data)
265 {
266 	sa_family_t family = POINTER_TO_INT(user_data);
267 
268 	if (net_context_get_family(context) != family) {
269 		TC_ERROR("Connect family mismatch %d should be %d\n",
270 		       net_context_get_family(context), family);
271 		cb_failure = true;
272 		return;
273 	}
274 
275 	cb_failure = false;
276 }
277 
net_ctx_connect_v6(void)278 static void net_ctx_connect_v6(void)
279 {
280 	struct sockaddr_in6 addr = {
281 		.sin6_family = AF_INET6,
282 		.sin6_port = htons(PEER_PORT),
283 		.sin6_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
284 				   0, 0, 0, 0, 0, 0, 0, 0x2 } } },
285 	};
286 	int ret;
287 
288 	ret = net_context_connect(udp_v6_ctx, (struct sockaddr *)&addr,
289 				  sizeof(struct sockaddr_in6), connect_cb,
290 				  K_NO_WAIT, INT_TO_POINTER(AF_INET6));
291 	zassert_false((ret || cb_failure),
292 		      "Context connect IPv6 UDP test failed");
293 
294 #if defined(CONFIG_NET_TCP)
295 	ret = net_context_connect(tcp_v6_ctx, (struct sockaddr *)&addr,
296 				  sizeof(struct sockaddr_in6), connect_cb,
297 				  K_NO_WAIT, INT_TO_POINTER(AF_INET6));
298 	zassert_false((ret || cb_failure),
299 		      "Context connect IPv6 TCP test failed");
300 
301 #endif /* CONFIG_NET_TCP */
302 }
303 
net_ctx_connect_v4(void)304 static void net_ctx_connect_v4(void)
305 {
306 	struct sockaddr_in addr = {
307 		.sin_family = AF_INET,
308 		.sin_port = htons(PEER_PORT),
309 		.sin_addr = { { { 192, 0, 2, 2 } } },
310 	};
311 	int ret;
312 
313 	ret = net_context_connect(udp_v4_ctx, (struct sockaddr *)&addr,
314 				  sizeof(struct sockaddr_in), connect_cb,
315 				  K_NO_WAIT, INT_TO_POINTER(AF_INET));
316 	zassert_false((ret || cb_failure),
317 		      "Context connect IPv6 UDP test failed");
318 
319 #if defined(CONFIG_NET_TCP)
320 	ret = net_context_connect(tcp_v4_ctx, (struct sockaddr *)&addr,
321 				  sizeof(struct sockaddr_in6), connect_cb,
322 				  K_NO_WAIT, INT_TO_POINTER(AF_INET));
323 	zassert_false((ret || cb_failure),
324 		      "Context connect IPv6 TCP test failed");
325 #endif /* CONFIG_NET_TCP */
326 }
327 
328 #if defined(CONFIG_NET_TCP)
accept_cb(struct net_context * context,struct sockaddr * addr,socklen_t addrlen,int status,void * user_data)329 static void accept_cb(struct net_context *context,
330 		      struct sockaddr *addr,
331 		      socklen_t addrlen,
332 		      int status,
333 		      void *user_data)
334 {
335 	sa_family_t family = POINTER_TO_INT(user_data);
336 
337 	if (net_context_get_family(context) != family) {
338 		TC_ERROR("Accept family mismatch %d should be %d\n",
339 		       net_context_get_family(context), family);
340 		cb_failure = true;
341 		return;
342 	}
343 
344 	cb_failure = false;
345 }
346 #endif
net_ctx_accept_v6(void)347 static void net_ctx_accept_v6(void)
348 {
349 #if defined(CONFIG_NET_TCP)
350 	int ret;
351 
352 	ret = net_context_accept(udp_v6_ctx, accept_cb, K_NO_WAIT,
353 				 INT_TO_POINTER(AF_INET6));
354 	zassert_false((ret != -EINVAL || cb_failure),
355 		      "Context accept IPv6 UDP test failed");
356 #endif
357 }
358 
net_ctx_accept_v4(void)359 static void net_ctx_accept_v4(void)
360 {
361 #if defined(CONFIG_NET_TCP)
362 	int ret;
363 
364 	ret = net_context_accept(udp_v4_ctx, accept_cb, K_NO_WAIT,
365 				 INT_TO_POINTER(AF_INET));
366 	zassert_false((ret != -EINVAL || cb_failure),
367 		      "Context accept IPv4 UDP test failed");
368 #endif
369 }
370 
net_ctx_setups_order_dependent(void)371 static void net_ctx_setups_order_dependent(void)
372 {
373 	net_ctx_bind_fail();
374 	net_ctx_bind_uni_success_v6();
375 	net_ctx_bind_uni_success_v4();
376 	net_ctx_bind_mcast_success();
377 	net_ctx_listen_v6();
378 	net_ctx_listen_v4();
379 	net_ctx_connect_v6();
380 	net_ctx_connect_v4();
381 	net_ctx_accept_v6();
382 	net_ctx_accept_v4();
383 }
384 
net_ctx_put(void)385 static void net_ctx_put(void)
386 {
387 	int ret;
388 
389 	ret = net_context_put(udp_v6_ctx);
390 	zassert_equal(ret, 0,
391 		      "Context put IPv6 UDP test failed.");
392 
393 	ret = net_context_put(mcast_v6_ctx);
394 	zassert_equal(ret, 0,
395 		      "Context put IPv6 mcast test failed");
396 
397 	ret = net_context_put(udp_v4_ctx);
398 	zassert_equal(ret, 0,
399 		      "Context put IPv4 UDP test failed");
400 
401 #if defined(CONFIG_NET_TCP)
402 	ret = net_context_put(tcp_v4_ctx);
403 	zassert_equal(ret, 0,
404 		      "Context put IPv4 TCP test failed");
405 
406 	ret = net_context_put(tcp_v6_ctx);
407 	zassert_equal(ret, 0,
408 		      "Context put IPv6 TCP test failed");
409 #endif
410 }
411 
send_cb(struct net_context * context,int status,void * user_data)412 static void send_cb(struct net_context *context, int status, void *user_data)
413 {
414 	sa_family_t family = POINTER_TO_INT(user_data);
415 
416 	if (net_context_get_family(context) != family) {
417 		TC_ERROR("Send family mismatch %d should be %d\n",
418 		       net_context_get_family(context), family);
419 		cb_failure = true;
420 		return;
421 	}
422 
423 	cb_failure = false;
424 }
425 
net_ctx_send_v6(void)426 static void net_ctx_send_v6(void)
427 {
428 	int ret;
429 
430 	test_sending = true;
431 
432 	ret = net_context_send(udp_v6_ctx, test_data, strlen(test_data),
433 			       send_cb, K_FOREVER, INT_TO_POINTER(AF_INET6));
434 	k_yield();
435 
436 	zassert_false(((ret < 0) || cb_failure),
437 		     "Context send IPv6 UDP test failed");
438 }
439 
net_ctx_send_v4(void)440 static void net_ctx_send_v4(void)
441 {
442 	int ret;
443 
444 	test_sending = true;
445 
446 	ret = net_context_send(udp_v4_ctx, test_data, strlen(test_data),
447 			       send_cb, K_FOREVER, INT_TO_POINTER(AF_INET));
448 	k_yield();
449 
450 	zassert_false(((ret < 0) || cb_failure),
451 		      "Context send IPv4 UDP test failed");
452 }
453 
net_ctx_sendto_v6(void)454 static void net_ctx_sendto_v6(void)
455 {
456 	int ret;
457 	struct sockaddr_in6 addr = {
458 		.sin6_family = AF_INET6,
459 		.sin6_port = htons(PEER_PORT),
460 		.sin6_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
461 				   0, 0, 0, 0, 0, 0, 0, 0x2 } } },
462 	};
463 
464 	test_sending = true;
465 
466 	ret = net_context_sendto(udp_v6_ctx, test_data, strlen(test_data),
467 				 (struct sockaddr *)&addr,
468 				 sizeof(struct sockaddr_in6), send_cb,
469 				 K_NO_WAIT, INT_TO_POINTER(AF_INET6));
470 	zassert_false(((ret < 0) || cb_failure),
471 		      "Context send IPv6 UDP test failed");
472 }
473 
net_ctx_sendto_v4(void)474 static void net_ctx_sendto_v4(void)
475 {
476 	int ret;
477 	struct sockaddr_in addr = {
478 		.sin_family = AF_INET,
479 		.sin_port = htons(PEER_PORT),
480 		.sin_addr = { { { 192, 0, 2, 2 } } },
481 	};
482 
483 	test_sending = true;
484 
485 	ret = net_context_sendto(udp_v4_ctx, test_data, strlen(test_data),
486 				 (struct sockaddr *)&addr,
487 				 sizeof(struct sockaddr_in), send_cb,
488 				 K_NO_WAIT, INT_TO_POINTER(AF_INET));
489 	zassert_false(((ret < 0) || cb_failure),
490 		      "Context send IPv4 UDP test failed");
491 }
492 
recv_cb(struct net_context * context,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto_hdr,int status,void * user_data)493 static void recv_cb(struct net_context *context,
494 		    struct net_pkt *pkt,
495 		    union net_ip_header *ip_hdr,
496 		    union net_proto_header *proto_hdr,
497 		    int status,
498 		    void *user_data)
499 {
500 	DBG("Data received.\n");
501 
502 	recv_cb_called = true;
503 	k_sem_give(&wait_data);
504 }
505 
ZTEST(net_context,test_net_ctx_recv_v6)506 ZTEST(net_context, test_net_ctx_recv_v6)
507 {
508 	int ret;
509 
510 	net_ctx_create();
511 	net_ctx_setups_order_dependent();
512 
513 	ret = net_context_recv(udp_v6_ctx, recv_cb, K_NO_WAIT,
514 			       INT_TO_POINTER(AF_INET6));
515 	zassert_false((ret || cb_failure),
516 		      "Context recv IPv6 UDP test failed");
517 
518 	net_ctx_sendto_v6();
519 
520 	k_sem_take(&wait_data, WAIT_TIME);
521 
522 	zassert_true(recv_cb_called, "No data received on time, "
523 				"IPv6 recv test failed");
524 	recv_cb_called = false;
525 
526 	net_ctx_put();
527 }
528 
ZTEST(net_context,test_net_ctx_recv_v4)529 ZTEST(net_context, test_net_ctx_recv_v4)
530 {
531 	int ret;
532 
533 	net_ctx_create();
534 	net_ctx_setups_order_dependent();
535 
536 	ret = net_context_recv(udp_v4_ctx, recv_cb, K_NO_WAIT,
537 			       INT_TO_POINTER(AF_INET));
538 	zassert_false((ret || cb_failure),
539 		      "Context recv IPv4 UDP test failed");
540 
541 	net_ctx_sendto_v4();
542 
543 	k_sem_take(&wait_data, WAIT_TIME);
544 
545 	zassert_true(recv_cb_called, "No data received on time, "
546 				"IPv4 recv test failed");
547 
548 	recv_cb_called = false;
549 
550 	net_ctx_put();
551 }
552 
net_ctx_sendto_v6_wrong_src(void)553 static bool net_ctx_sendto_v6_wrong_src(void)
554 {
555 	int ret;
556 	struct sockaddr_in6 addr = {
557 		.sin6_family = AF_INET6,
558 		.sin6_port = htons(PEER_PORT),
559 		.sin6_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
560 				   0, 0, 0, 0, 0, 0, 0, 0x3 } } },
561 	};
562 
563 	test_sending = true;
564 
565 	ret = net_context_sendto(udp_v6_ctx, test_data, strlen(test_data),
566 				 (struct sockaddr *)&addr,
567 				 sizeof(struct sockaddr_in6), send_cb,
568 				 K_NO_WAIT, INT_TO_POINTER(AF_INET6));
569 	if ((ret < 0) || cb_failure) {
570 		TC_ERROR("Context sendto IPv6 UDP wrong src "
571 			 "test failed (%d)\n", ret);
572 		return false;
573 	}
574 
575 	return true;
576 }
577 
ZTEST(net_context,test_net_ctx_recv_v6_fail)578 ZTEST(net_context, test_net_ctx_recv_v6_fail)
579 {
580 	int ret;
581 
582 	net_ctx_create();
583 	net_ctx_setups_order_dependent();
584 
585 	ret = net_context_recv(udp_v6_ctx, recv_cb, K_NO_WAIT,
586 			       INT_TO_POINTER(AF_INET6));
587 	zassert_false((ret || cb_failure),
588 		      "Context recv IPv6 UDP test failed");
589 
590 	net_ctx_sendto_v6_wrong_src();
591 
592 	zassert_true(k_sem_take(&wait_data, WAIT_TIME),
593 		     "Semaphore triggered but should not");
594 
595 	zassert_false(recv_cb_called, "Data received but should not have, "
596 			     "IPv6 recv test failed");
597 
598 	recv_cb_called = false;
599 
600 	net_ctx_put();
601 }
602 
net_ctx_sendto_v4_wrong_src(void)603 static bool net_ctx_sendto_v4_wrong_src(void)
604 {
605 	int ret;
606 	struct sockaddr_in addr = {
607 		.sin_family = AF_INET,
608 		.sin_port = htons(PEER_PORT),
609 		.sin_addr = { { { 192, 0, 2, 3 } } },
610 	};
611 
612 	test_sending = true;
613 
614 	ret = net_context_sendto(udp_v4_ctx, test_data, strlen(test_data),
615 				 (struct sockaddr *)&addr,
616 				 sizeof(struct sockaddr_in), send_cb,
617 				 K_NO_WAIT, INT_TO_POINTER(AF_INET));
618 	if ((ret < 0) || cb_failure) {
619 		TC_ERROR("Context send IPv4 UDP test failed (%d)\n", ret);
620 		return false;
621 	}
622 
623 	return true;
624 }
625 
ZTEST(net_context,test_net_ctx_recv_v4_fail)626 ZTEST(net_context, test_net_ctx_recv_v4_fail)
627 {
628 	int ret;
629 
630 	net_ctx_create();
631 	net_ctx_setups_order_dependent();
632 
633 	ret = net_context_recv(udp_v4_ctx, recv_cb, K_NO_WAIT,
634 			       INT_TO_POINTER(AF_INET));
635 	zassert_false((ret || cb_failure),
636 		      "Context recv IPv4 UDP test failed");
637 
638 	net_ctx_sendto_v4_wrong_src();
639 
640 	zassert_true(k_sem_take(&wait_data, WAIT_TIME),
641 		     "Semaphore triggered but should not");
642 
643 	zassert_false(recv_cb_called, "Data received but should not have, "
644 		      "IPv4 recv test failed");
645 
646 	recv_cb_called = false;
647 
648 	net_ctx_put();
649 }
650 
ZTEST(net_context,test_net_ctx_recv_v6_again)651 ZTEST(net_context, test_net_ctx_recv_v6_again)
652 {
653 	int ret;
654 
655 	net_ctx_create();
656 	net_ctx_setups_order_dependent();
657 
658 	ret = net_context_recv(udp_v6_ctx, recv_cb, K_NO_WAIT,
659 			       INT_TO_POINTER(AF_INET6));
660 	zassert_false((ret || cb_failure),
661 		      "Context recv IPv6 UDP test failed");
662 
663 	net_ctx_sendto_v6();
664 
665 	k_sem_take(&wait_data, WAIT_TIME);
666 
667 	net_ctx_sendto_v6();
668 
669 	k_sem_take(&wait_data, WAIT_TIME);
670 
671 	zassert_true(recv_cb_called, "No data received on time 2nd time, "
672 		     "IPv6 recv test failed");
673 
674 	recv_cb_called = false;
675 
676 	net_ctx_put();
677 }
678 
ZTEST(net_context,test_net_ctx_recv_v4_again)679 ZTEST(net_context, test_net_ctx_recv_v4_again)
680 {
681 	int ret;
682 
683 	net_ctx_create();
684 	net_ctx_setups_order_dependent();
685 
686 	ret = net_context_recv(udp_v4_ctx, recv_cb, K_NO_WAIT,
687 			       INT_TO_POINTER(AF_INET));
688 	zassert_false((ret || cb_failure),
689 		      "Context recv IPv4 UDP test failed");
690 
691 	net_ctx_sendto_v4();
692 
693 	k_sem_take(&wait_data, WAIT_TIME);
694 
695 	net_ctx_sendto_v4();
696 
697 	k_sem_take(&wait_data, WAIT_TIME);
698 
699 	zassert_true(recv_cb_called,
700 		     "No data received on time 2nd time, "
701 		     "IPv4 recv test failed");
702 
703 	recv_cb_called = false;
704 
705 	net_ctx_put();
706 }
707 
recv_cb_another(struct net_context * context,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto_hdr,int status,void * user_data)708 static void recv_cb_another(struct net_context *context,
709 			    struct net_pkt *pkt,
710 			    union net_ip_header *ip_hdr,
711 			    union net_proto_header *proto_hdr,
712 			    int status,
713 			    void *user_data)
714 {
715 	DBG("Data received in another callback.\n");
716 
717 	recv_cb_reconfig_called = true;
718 	k_sem_give(&wait_data);
719 }
720 
ZTEST(net_context,test_net_ctx_recv_v6_reconfig)721 ZTEST(net_context, test_net_ctx_recv_v6_reconfig)
722 {
723 	int ret;
724 
725 	net_ctx_create();
726 	net_ctx_setups_order_dependent();
727 
728 	ret = net_context_recv(udp_v6_ctx, recv_cb_another, K_NO_WAIT,
729 			       INT_TO_POINTER(AF_INET6));
730 	zassert_false((ret || cb_failure),
731 		      "Context recv reconfig IPv6 UDP test failed");
732 
733 	net_ctx_sendto_v6();
734 
735 	k_sem_take(&wait_data, WAIT_TIME);
736 
737 	zassert_true(recv_cb_reconfig_called,
738 		     "No data received on time, "
739 		     "IPv6 recv reconfig test failed");
740 
741 	recv_cb_reconfig_called = false;
742 
743 	net_ctx_put();
744 }
745 
ZTEST(net_context,test_net_ctx_recv_v4_reconfig)746 ZTEST(net_context, test_net_ctx_recv_v4_reconfig)
747 {
748 	int ret;
749 
750 	net_ctx_create();
751 	net_ctx_setups_order_dependent();
752 
753 	ret = net_context_recv(udp_v4_ctx, recv_cb_another, K_NO_WAIT,
754 			       INT_TO_POINTER(AF_INET));
755 	zassert_false((ret || cb_failure),
756 		      "Context recv reconfig IPv4 UDP test failed");
757 
758 
759 	net_ctx_sendto_v4();
760 
761 	k_sem_take(&wait_data, WAIT_TIME);
762 
763 	zassert_true(recv_cb_reconfig_called, "No data received on time, "
764 		     "IPv4 recv reconfig test failed");
765 
766 	recv_cb_reconfig_called = false;
767 
768 	net_ctx_put();
769 }
770 
771 #define STACKSIZE 1024
772 K_THREAD_STACK_DEFINE(thread_stack, STACKSIZE);
773 static struct k_thread thread_data;
774 
recv_cb_timeout(struct net_context * context,struct net_pkt * pkt,union net_ip_header * ip_hdr,union net_proto_header * proto_hdr,int status,void * user_data)775 static void recv_cb_timeout(struct net_context *context,
776 			    struct net_pkt *pkt,
777 			    union net_ip_header *ip_hdr,
778 			    union net_proto_header *proto_hdr,
779 			    int status,
780 			    void *user_data)
781 {
782 	if (expecting_cb_failure) {
783 		DBG("Data received after a timeout.\n");
784 	}
785 
786 	recv_cb_timeout_called = true;
787 	k_sem_give(&wait_data);
788 
789 	net_pkt_unref(pkt);
790 }
791 
timeout_thread(void * p1,void * p2,void * p3)792 void timeout_thread(void *p1, void *p2, void *p3)
793 {
794 	struct net_context *ctx = p1;
795 	int family = POINTER_TO_INT(p2);
796 	int32_t timeout = POINTER_TO_INT(p3);
797 	int ret;
798 
799 	ret = net_context_recv(ctx, recv_cb_timeout, K_MSEC(timeout),
800 			       INT_TO_POINTER(family));
801 	if (ret != -ETIMEDOUT && expecting_cb_failure) {
802 		zassert_true(expecting_cb_failure,
803 			     "Context recv UDP timeout test failed");
804 		cb_failure = true;
805 		return;
806 	}
807 
808 	if (!recv_cb_timeout_called) {
809 		DBG("Data received on time, recv test failed\n");
810 		cb_failure = true;
811 		return;
812 	}
813 
814 	DBG("Timeout %s\n", family == AF_INET ? "IPv4" : "IPv6");
815 
816 	k_sem_give(&wait_data);
817 }
818 
start_timeout_v6_thread(int32_t timeout)819 static k_tid_t start_timeout_v6_thread(int32_t timeout)
820 {
821 	return k_thread_create(&thread_data, thread_stack, STACKSIZE,
822 			       timeout_thread,
823 			       udp_v6_ctx, INT_TO_POINTER(AF_INET6),
824 			       INT_TO_POINTER(timeout),
825 			       K_PRIO_COOP(7), 0, K_NO_WAIT);
826 }
827 
start_timeout_v4_thread(int32_t timeout)828 static k_tid_t start_timeout_v4_thread(int32_t timeout)
829 {
830 	return k_thread_create(&thread_data, thread_stack, STACKSIZE,
831 			       timeout_thread,
832 			       udp_v4_ctx, INT_TO_POINTER(AF_INET),
833 			       INT_TO_POINTER(timeout),
834 			       K_PRIO_COOP(7), 0, K_NO_WAIT);
835 }
836 
ZTEST(net_context,test_net_ctx_recv_v6_timeout)837 ZTEST(net_context, test_net_ctx_recv_v6_timeout)
838 {
839 	k_tid_t tid;
840 
841 	cb_failure = false;
842 	expecting_cb_failure = true;
843 	recv_cb_timeout_called = false;
844 
845 	net_ctx_create();
846 	net_ctx_setups_order_dependent();
847 
848 	/* Start a thread that will send data to receiver. */
849 	tid = start_timeout_v6_thread(WAIT_TIME_LONG);
850 
851 	k_sem_reset(&wait_data);
852 	k_sem_take(&wait_data, K_MSEC(WAIT_TIME_LONG * 2));
853 
854 	net_ctx_send_v6();
855 
856 	DBG("Sent data\n");
857 
858 	k_sem_take(&wait_data, K_FOREVER);
859 
860 	k_thread_abort(tid);
861 
862 	expecting_cb_failure = false;
863 	recv_cb_timeout_called = false;
864 
865 	zassert_true(!cb_failure);
866 
867 	net_ctx_put();
868 }
869 
ZTEST(net_context,test_net_ctx_recv_v4_timeout)870 ZTEST(net_context, test_net_ctx_recv_v4_timeout)
871 {
872 	k_tid_t tid;
873 
874 	cb_failure = false;
875 	expecting_cb_failure = true;
876 	recv_cb_timeout_called = false;
877 
878 	net_ctx_create();
879 	net_ctx_setups_order_dependent();
880 
881 	/* Start a thread that will send data to receiver. */
882 	tid = start_timeout_v4_thread(WAIT_TIME_LONG);
883 
884 	k_sem_reset(&wait_data);
885 	k_sem_take(&wait_data, K_MSEC(WAIT_TIME_LONG * 2));
886 
887 	net_ctx_send_v4();
888 
889 	DBG("Sent data\n");
890 
891 	k_sem_take(&wait_data, K_FOREVER);
892 
893 	k_thread_abort(tid);
894 
895 	expecting_cb_failure = false;
896 	recv_cb_timeout_called = false;
897 
898 	zassert_true(!cb_failure);
899 
900 	net_ctx_put();
901 }
902 
ZTEST(net_context,test_net_ctx_recv_v6_timeout_forever)903 ZTEST(net_context, test_net_ctx_recv_v6_timeout_forever)
904 {
905 	k_tid_t tid;
906 
907 	cb_failure = false;
908 	expecting_cb_failure = false;
909 	recv_cb_timeout_called = false;
910 
911 	net_ctx_create();
912 	net_ctx_setups_order_dependent();
913 
914 	/* Start a thread that will send data to receiver. */
915 	tid = start_timeout_v6_thread(SYS_FOREVER_MS);
916 
917 	/* Wait a bit so that we see if recv waited or not */
918 	k_sleep(WAIT_TIME);
919 
920 	net_ctx_send_v6();
921 
922 	DBG("Sent data\n");
923 
924 	k_sem_take(&wait_data, K_FOREVER);
925 
926 	k_thread_abort(tid);
927 
928 	expecting_cb_failure = false;
929 	recv_cb_timeout_called = false;
930 
931 	net_ctx_put();
932 }
933 
ZTEST(net_context,test_net_ctx_recv_v4_timeout_forever)934 ZTEST(net_context, test_net_ctx_recv_v4_timeout_forever)
935 {
936 	k_tid_t tid;
937 
938 	cb_failure = false;
939 	expecting_cb_failure = false;
940 	recv_cb_timeout_called = false;
941 
942 	net_ctx_create();
943 	net_ctx_setups_order_dependent();
944 
945 	/* Start a thread that will send data to receiver. */
946 	tid = start_timeout_v4_thread(SYS_FOREVER_MS);
947 
948 	/* Wait a bit so that we see if recv waited or not */
949 	k_sleep(WAIT_TIME);
950 
951 	net_ctx_send_v4();
952 
953 	DBG("Sent data\n");
954 
955 	k_sem_take(&wait_data, K_FOREVER);
956 
957 	k_thread_abort(tid);
958 
959 	expecting_cb_failure = false;
960 	recv_cb_timeout_called = false;
961 
962 	net_ctx_put();
963 }
964 
965 struct net_context_test {
966 	uint8_t mac_addr[sizeof(struct net_eth_addr)];
967 	struct net_linkaddr ll_addr;
968 };
969 
net_context_dev_init(const struct device * dev)970 int net_context_dev_init(const struct device *dev)
971 {
972 	return 0;
973 }
974 
net_context_get_mac(const struct device * dev)975 static uint8_t *net_context_get_mac(const struct device *dev)
976 {
977 	struct net_context_test *context = dev->data;
978 
979 	if (context->mac_addr[2] == 0x00) {
980 		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
981 		context->mac_addr[0] = 0x00;
982 		context->mac_addr[1] = 0x00;
983 		context->mac_addr[2] = 0x5E;
984 		context->mac_addr[3] = 0x00;
985 		context->mac_addr[4] = 0x53;
986 		context->mac_addr[5] = sys_rand8_get();
987 	}
988 
989 	return context->mac_addr;
990 }
991 
net_context_iface_init(struct net_if * iface)992 static void net_context_iface_init(struct net_if *iface)
993 {
994 	uint8_t *mac = net_context_get_mac(net_if_get_device(iface));
995 
996 	net_if_set_link_addr(iface, mac, sizeof(struct net_eth_addr),
997 			     NET_LINK_ETHERNET);
998 }
999 
tester_send(const struct device * dev,struct net_pkt * pkt)1000 static int tester_send(const struct device *dev, struct net_pkt *pkt)
1001 {
1002 	struct net_udp_hdr hdr, *udp_hdr;
1003 
1004 	if (!pkt->buffer) {
1005 		TC_ERROR("No data to send!\n");
1006 		return -ENODATA;
1007 	}
1008 
1009 	if (test_sending) {
1010 		/* We are now about to send data to outside but in this
1011 		 * test we just check what would be sent. In real life
1012 		 * one would not do something like this in the sending
1013 		 * side.
1014 		 */
1015 
1016 		/* In this test we feed the data back to us
1017 		 * in order to test the recv functionality.
1018 		 */
1019 		/* We need to swap the IP addresses because otherwise
1020 		 * the packet will be dropped.
1021 		 */
1022 		uint16_t port;
1023 
1024 		if (net_pkt_family(pkt) == AF_INET6) {
1025 			struct in6_addr addr;
1026 
1027 			net_ipv6_addr_copy_raw((uint8_t *)&addr, NET_IPV6_HDR(pkt)->src);
1028 			net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->src,
1029 					       NET_IPV6_HDR(pkt)->dst);
1030 			net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->dst, (uint8_t *)&addr);
1031 		} else {
1032 			struct in_addr addr;
1033 
1034 			net_ipv4_addr_copy_raw((uint8_t *)&addr, NET_IPV4_HDR(pkt)->src);
1035 			net_ipv4_addr_copy_raw(NET_IPV4_HDR(pkt)->src,
1036 					       NET_IPV4_HDR(pkt)->dst);
1037 			net_ipv4_addr_copy_raw(NET_IPV4_HDR(pkt)->dst, (uint8_t *)&addr);
1038 		}
1039 
1040 		udp_hdr = net_udp_get_hdr(pkt, &hdr);
1041 		if (!udp_hdr) {
1042 			TC_ERROR("UDP data receive failed.");
1043 			goto out;
1044 		}
1045 
1046 		port = udp_hdr->src_port;
1047 		udp_hdr->src_port = udp_hdr->dst_port;
1048 		udp_hdr->dst_port = port;
1049 		net_udp_set_hdr(pkt, udp_hdr);
1050 
1051 		if (net_recv_data(net_pkt_iface(pkt),
1052 				  net_pkt_clone(pkt, K_NO_WAIT)) < 0) {
1053 			TC_ERROR("Data receive failed.");
1054 			goto out;
1055 		}
1056 
1057 		test_sending = false;
1058 
1059 		return 0;
1060 	}
1061 
1062 out:
1063 	if (data_failure) {
1064 		test_failed = true;
1065 	}
1066 
1067 	return 0;
1068 }
1069 
1070 
1071 struct net_context_test net_context_data;
1072 
1073 static struct dummy_api net_context_if_api = {
1074 	.iface_api.init = net_context_iface_init,
1075 	.send = tester_send,
1076 };
1077 
1078 #define _ETH_L2_LAYER DUMMY_L2
1079 #define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
1080 
1081 NET_DEVICE_INIT(net_context_test, "net_context_test",
1082 		net_context_dev_init, NULL,
1083 		&net_context_data, NULL,
1084 		CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
1085 		&net_context_if_api, _ETH_L2_LAYER,
1086 		_ETH_L2_CTX_TYPE, 127);
1087 
iface_add_address(void)1088 static void *iface_add_address(void)
1089 {
1090 	struct net_if_addr *ifaddr;
1091 	struct net_if_mcast_addr *maddr;
1092 	struct net_if *iface;
1093 
1094 	iface = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
1095 	zassert_not_null(iface, "Interface is NULL");
1096 
1097 	ifaddr = net_if_ipv6_addr_add(iface, &in6addr_my,
1098 				      NET_ADDR_MANUAL, 0);
1099 	zassert_not_null(ifaddr, "Cannot add IPv6 address ");
1100 
1101 	ifaddr = net_if_ipv4_addr_add(iface, &in4addr_my,
1102 				      NET_ADDR_MANUAL, 0);
1103 	zassert_not_null(ifaddr, "Cannot add IPv4 address");
1104 
1105 	net_ipv6_addr_create(&in6addr_mcast, 0xff02, 0, 0, 0, 0, 0, 0, 0x0001);
1106 
1107 	maddr = net_if_ipv6_maddr_add(iface, &in6addr_mcast);
1108 	zassert_not_null(maddr, "Cannot add multicast IPv6 address");
1109 
1110 	/* The semaphore is there to wait the data to be received. */
1111 	k_sem_init(&wait_data, 0, UINT_MAX);
1112 
1113 	return NULL;
1114 }
1115 
iface_remove_addr(void * dummy)1116 static void iface_remove_addr(void *dummy)
1117 {
1118 	struct net_if *iface;
1119 
1120 	iface = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
1121 
1122 	net_if_ipv6_addr_rm(iface, &in6addr_my);
1123 	net_if_ipv4_addr_rm(iface, &in4addr_my);
1124 	net_if_ipv6_maddr_rm(iface, &in6addr_mcast);
1125 }
1126 
1127 ZTEST_SUITE(net_context, NULL, iface_add_address, NULL, NULL, iface_remove_addr);
1128