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