1 /* main.c - Application main entry point */
2
3 /*
4 * Copyright (c) 2018 Intel Corporation
5 *
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 #define NET_LOG_LEVEL CONFIG_NET_TC_LOG_LEVEL
10
11 #include <zephyr/logging/log.h>
12 LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL);
13
14 #include <zephyr/types.h>
15 #include <stdbool.h>
16 #include <stddef.h>
17 #include <string.h>
18 #include <errno.h>
19 #include <zephyr/sys/printk.h>
20 #include <zephyr/linker/sections.h>
21 #include <zephyr/random/random.h>
22
23 #include <zephyr/ztest.h>
24
25 #include <zephyr/net/ethernet.h>
26 #include <zephyr/net/dummy.h>
27 #include <zephyr/net_buf.h>
28 #include <zephyr/net/net_ip.h>
29 #include <zephyr/net/net_l2.h>
30 #include <zephyr/net/udp.h>
31
32 #include "ipv6.h"
33
34 #define NET_LOG_ENABLED 1
35 #include "net_private.h"
36
37 #if NET_LOG_LEVEL >= LOG_LEVEL_DBG
38 #define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
39 #else
40 #define DBG(fmt, ...)
41 #endif
42
43 /* make this large enough so that we do not overflow the sent pkt array */
44 #define MAX_PKT_TO_SEND 4
45 #define MAX_PKT_TO_RECV 4
46
47 #define MAX_PRIORITIES 8
48 #define MAX_TC 8
49
50 static enum net_priority send_priorities[MAX_TC][MAX_PKT_TO_SEND];
51 static enum net_priority recv_priorities[MAX_TC][MAX_PKT_TO_RECV];
52
53 static enum net_priority tx_tc2prio[NET_TC_TX_COUNT];
54 static enum net_priority rx_tc2prio[NET_TC_RX_COUNT];
55
56 #define TEST_PORT 9999
57
58 static const char *test_data = "Test data to be sent";
59
60 /* Interface 1 addresses */
61 static struct in6_addr my_addr1 = { { { 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0,
62 0, 0, 0, 0, 0, 0, 0, 0x1 } } };
63
64 /* Interface 2 addresses */
65 static struct in6_addr my_addr2 = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
66 0, 0, 0, 0, 0, 0, 0, 0x1 } } };
67
68 /* Interface 3 addresses */
69 static struct in6_addr my_addr3 = { { { 0x20, 0x01, 0x0d, 0xb8, 2, 0, 0, 0,
70 0, 0, 0, 0, 0, 0, 0, 0x1 } } };
71
72 /* Destination address for test packets */
73 static struct in6_addr dst_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 9, 0, 0, 0,
74 0, 0, 0, 0, 0, 0, 0, 0x1 } } };
75
76 /* Extra address is assigned to ll_addr */
77 static struct in6_addr ll_addr = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0,
78 0, 0, 0, 0xf2, 0xaa, 0x29, 0x02,
79 0x04 } } };
80
81 static struct sockaddr_in6 dst_addr6 = {
82 .sin6_family = AF_INET6,
83 .sin6_port = htons(TEST_PORT),
84 };
85
86 static struct {
87 struct net_context *ctx;
88 } net_ctxs_tx[NET_TC_COUNT];
89
90 static struct {
91 struct net_context *ctx;
92 } net_ctxs_rx[NET_TC_COUNT];
93
94 static bool test_started;
95 static bool test_failed;
96 static bool start_receiving;
97 static bool recv_cb_called;
98 static struct k_sem wait_data;
99
100 #define WAIT_TIME K_SECONDS(1)
101
102 struct eth_context {
103 struct net_if *iface;
104 uint8_t mac_addr[6];
105
106 uint16_t expecting_tag;
107 };
108
109 static struct eth_context eth_context;
110
eth_iface_init(struct net_if * iface)111 static void eth_iface_init(struct net_if *iface)
112 {
113 const struct device *dev = net_if_get_device(iface);
114 struct eth_context *context = dev->data;
115
116 net_if_set_link_addr(iface, context->mac_addr,
117 sizeof(context->mac_addr),
118 NET_LINK_ETHERNET);
119 }
120
check_higher_priority_pkt_sent(int tc,struct net_pkt * pkt)121 static bool check_higher_priority_pkt_sent(int tc, struct net_pkt *pkt)
122 {
123 /* If we have sent any higher priority packets, then
124 * this test fails as those packets should have been
125 * sent before this one.
126 */
127 int j, k;
128
129 for (j = tc + 1; j < MAX_TC; j++) {
130 for (k = 0; k < MAX_PKT_TO_SEND; k++) {
131 if (send_priorities[j][k]) {
132 return true;
133 }
134 }
135 }
136
137 return false;
138 }
139
check_higher_priority_pkt_recv(int tc,struct net_pkt * pkt)140 static bool check_higher_priority_pkt_recv(int tc, struct net_pkt *pkt)
141 {
142 /* If we have received any higher priority packets, then
143 * this test fails as those packets should have been
144 * received before this one.
145 */
146 int j, k;
147
148 for (j = tc + 1; j < MAX_TC; j++) {
149 for (k = 0; k < MAX_PKT_TO_SEND; k++) {
150 if (recv_priorities[j][k]) {
151 return true;
152 }
153 }
154 }
155
156 return false;
157 }
158
159 /* The eth_tx() will handle both sent packets or and it will also
160 * simulate the receiving of the packets.
161 */
eth_tx(const struct device * dev,struct net_pkt * pkt)162 static int eth_tx(const struct device *dev, struct net_pkt *pkt)
163 {
164 if (!pkt->buffer) {
165 DBG("No data to send!\n");
166 return -ENODATA;
167 }
168
169 if (start_receiving) {
170 struct in6_addr addr;
171 struct net_udp_hdr hdr, *udp_hdr;
172 uint16_t port;
173
174 DBG("Packet %p received\n", pkt);
175
176 /* Swap IP src and destination address so that we can receive
177 * the packet and the stack will not reject it.
178 */
179 net_ipv6_addr_copy_raw((uint8_t *)&addr, NET_IPV6_HDR(pkt)->src);
180 net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->src,
181 NET_IPV6_HDR(pkt)->dst);
182 net_ipv6_addr_copy_raw(NET_IPV6_HDR(pkt)->dst, (uint8_t *)&addr);
183
184 udp_hdr = net_udp_get_hdr(pkt, &hdr);
185 zassert_not_null(udp_hdr, "UDP header missing");
186
187 port = udp_hdr->src_port;
188 udp_hdr->src_port = udp_hdr->dst_port;
189 udp_hdr->dst_port = port;
190
191 if (net_recv_data(net_pkt_iface(pkt),
192 net_pkt_clone(pkt, K_NO_WAIT)) < 0) {
193 test_failed = true;
194 zassert_true(false, "Packet %p receive failed\n", pkt);
195 }
196
197 return 0;
198 }
199
200 if (test_started) {
201 #if NET_LOG_LEVEL >= LOG_LEVEL_DBG
202 k_tid_t thread = k_current_get();
203 #endif
204 int i, prio, ret;
205
206 prio = net_pkt_priority(pkt);
207
208 for (i = 0; i < MAX_PKT_TO_SEND; i++) {
209 ret = check_higher_priority_pkt_sent(
210 net_tx_priority2tc(prio), pkt);
211 if (ret) {
212 DBG("Current thread priority %d "
213 "pkt %p prio %d tc %d\n",
214 k_thread_priority_get(thread),
215 pkt, prio, net_tx_priority2tc(prio));
216
217 test_failed = true;
218 zassert_false(test_failed,
219 "Invalid priority sent %d TC %d,"
220 " expecting %d (pkt %p)\n",
221 prio,
222 net_tx_priority2tc(prio),
223 send_priorities[net_tx_priority2tc(prio)][i],
224 pkt);
225 goto fail;
226 }
227
228 send_priorities[net_tx_priority2tc(prio)][i] = 0;
229 }
230
231 DBG("Received pkt %p from TC %c (thread prio %d)\n", pkt,
232 *(pkt->frags->data +
233 sizeof(struct net_ipv6_hdr) +
234 sizeof(struct net_udp_hdr)),
235 k_thread_priority_get(thread));
236
237 k_sem_give(&wait_data);
238 }
239
240 fail:
241 return 0;
242 }
243
244 static struct dummy_api api_funcs = {
245 .iface_api.init = eth_iface_init,
246 .send = eth_tx,
247 };
248
generate_mac(uint8_t * mac_addr)249 static void generate_mac(uint8_t *mac_addr)
250 {
251 /* 00-00-5E-00-53-xx Documentation RFC 7042 */
252 mac_addr[0] = 0x00;
253 mac_addr[1] = 0x00;
254 mac_addr[2] = 0x5E;
255 mac_addr[3] = 0x00;
256 mac_addr[4] = 0x53;
257 mac_addr[5] = sys_rand8_get();
258 }
259
eth_init(const struct device * dev)260 static int eth_init(const struct device *dev)
261 {
262 struct eth_context *context = dev->data;
263
264 generate_mac(context->mac_addr);
265
266 return 0;
267 }
268
269 /* Create one ethernet interface that does not have VLAN support. This
270 * is quite unlikely that this would be done in real life but for testing
271 * purposes create it here.
272 */
273 NET_DEVICE_INIT(eth_test, "eth_test", eth_init, NULL,
274 ð_context, NULL, CONFIG_ETH_INIT_PRIORITY, &api_funcs,
275 DUMMY_L2, NET_L2_GET_CTX_TYPE(DUMMY_L2),
276 NET_ETH_MTU);
277
address_setup(void)278 static void address_setup(void)
279 {
280 struct net_if_addr *ifaddr;
281 struct net_if *iface1;
282
283 iface1 = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
284
285 zassert_not_null(iface1, "Interface 1");
286
287 ifaddr = net_if_ipv6_addr_add(iface1, &my_addr1,
288 NET_ADDR_MANUAL, 0);
289 if (!ifaddr) {
290 DBG("Cannot add IPv6 address %s\n",
291 net_sprint_ipv6_addr(&my_addr1));
292 zassert_not_null(ifaddr, "addr1");
293 }
294
295 /* For testing purposes we need to set the addresses preferred */
296 ifaddr->addr_state = NET_ADDR_PREFERRED;
297
298 ifaddr = net_if_ipv6_addr_add(iface1, &ll_addr,
299 NET_ADDR_MANUAL, 0);
300 if (!ifaddr) {
301 DBG("Cannot add IPv6 address %s\n",
302 net_sprint_ipv6_addr(&ll_addr));
303 zassert_not_null(ifaddr, "ll_addr");
304 }
305
306 ifaddr->addr_state = NET_ADDR_PREFERRED;
307
308 ifaddr = net_if_ipv6_addr_add(iface1, &my_addr2,
309 NET_ADDR_MANUAL, 0);
310 if (!ifaddr) {
311 DBG("Cannot add IPv6 address %s\n",
312 net_sprint_ipv6_addr(&my_addr2));
313 zassert_not_null(ifaddr, "addr2");
314 }
315
316 ifaddr->addr_state = NET_ADDR_PREFERRED;
317
318 ifaddr = net_if_ipv6_addr_add(iface1, &my_addr3,
319 NET_ADDR_MANUAL, 0);
320 if (!ifaddr) {
321 DBG("Cannot add IPv6 address %s\n",
322 net_sprint_ipv6_addr(&my_addr3));
323 zassert_not_null(ifaddr, "addr3");
324 }
325
326 net_if_up(iface1);
327
328 /* The interface might receive data which might fail the checks
329 * in the iface sending function, so we need to reset the failure
330 * flag.
331 */
332 test_failed = false;
333 }
334
priority_setup(void)335 static void priority_setup(void)
336 {
337 int i;
338
339 for (i = 0; i < MAX_PRIORITIES; i++) {
340 tx_tc2prio[net_tx_priority2tc(i)] = i;
341 rx_tc2prio[net_rx_priority2tc(i)] = i;
342 }
343 }
344
345 #if defined(CONFIG_NET_IPV6_NBR_CACHE)
add_neighbor(struct net_if * iface,struct in6_addr * addr)346 static bool add_neighbor(struct net_if *iface, struct in6_addr *addr)
347 {
348 struct net_linkaddr_storage llstorage;
349 struct net_linkaddr lladdr;
350 struct net_nbr *nbr;
351
352 llstorage.addr[0] = 0x01;
353 llstorage.addr[1] = 0x02;
354 llstorage.addr[2] = 0x33;
355 llstorage.addr[3] = 0x44;
356 llstorage.addr[4] = 0x05;
357 llstorage.addr[5] = 0x06;
358
359 lladdr.len = 6U;
360 lladdr.addr = llstorage.addr;
361 lladdr.type = NET_LINK_ETHERNET;
362
363 nbr = net_ipv6_nbr_add(iface, addr, &lladdr, false,
364 NET_IPV6_NBR_STATE_REACHABLE);
365 if (!nbr) {
366 DBG("Cannot add dst %s to neighbor cache\n",
367 net_sprint_ipv6_addr(addr));
368 return false;
369 }
370
371 return true;
372 }
373 #else
374 #define add_neighbor(iface, addr) true
375 #endif /* CONFIG_NET_IPV6_NBR_CACHE */
376
setup_net_context(struct net_context ** ctx)377 static void setup_net_context(struct net_context **ctx)
378 {
379 struct sockaddr_in6 src_addr6 = {
380 .sin6_family = AF_INET6,
381 .sin6_port = 0,
382 };
383 int ret;
384 struct net_if *iface1;
385
386 iface1 = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
387
388 ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, ctx);
389 zassert_equal(ret, 0, "Create IPv6 UDP context %p failed (%d)\n",
390 *ctx, ret);
391
392 memcpy(&src_addr6.sin6_addr, &my_addr1, sizeof(struct in6_addr));
393 memcpy(&dst_addr6.sin6_addr, &dst_addr, sizeof(struct in6_addr));
394
395 ret = add_neighbor(iface1, &dst_addr);
396 zassert_true(ret, "Cannot add neighbor");
397
398 ret = net_context_bind(*ctx, (struct sockaddr *)&src_addr6,
399 sizeof(struct sockaddr_in6));
400 zassert_equal(ret, 0,
401 "Context bind failure test failed (%d)\n", ret);
402 }
403
test_traffic_class_general_setup(void)404 static void test_traffic_class_general_setup(void)
405 {
406 address_setup();
407 priority_setup();
408 }
409
test_traffic_class_setup_tx(void)410 static void test_traffic_class_setup_tx(void)
411 {
412 uint8_t priority;
413 int i, ret;
414
415 for (i = 0; i < NET_TC_TX_COUNT; i++) {
416
417 setup_net_context(&net_ctxs_tx[i].ctx);
418
419 priority = tx_tc2prio[i];
420
421 ret = net_context_set_option(net_ctxs_tx[i].ctx,
422 NET_OPT_PRIORITY,
423 &priority, sizeof(priority));
424 zassert_equal(ret, 0,
425 "Cannot set priority %d to ctx %p (%d)\n",
426 priority, net_ctxs_tx[i].ctx, ret);
427 }
428
429 }
430
test_traffic_class_setup_rx(void)431 static void test_traffic_class_setup_rx(void)
432 {
433 uint8_t priority;
434 int i, ret;
435
436 for (i = 0; i < NET_TC_RX_COUNT; i++) {
437
438 setup_net_context(&net_ctxs_rx[i].ctx);
439
440 priority = rx_tc2prio[i];
441
442 ret = net_context_set_option(net_ctxs_rx[i].ctx,
443 NET_OPT_PRIORITY,
444 &priority, sizeof(priority));
445 zassert_equal(ret, 0,
446 "Cannot set priority %d to ctx %p (%d)\n",
447 priority, net_ctxs_rx[i].ctx, ret);
448 }
449 }
450
test_traffic_class_cleanup_tx(void)451 static void test_traffic_class_cleanup_tx(void)
452 {
453 int i;
454
455 for (i = 0; i < NET_TC_TX_COUNT; i++) {
456 if (net_ctxs_tx[i].ctx) {
457 net_context_unref(net_ctxs_tx[i].ctx);
458 net_ctxs_tx[i].ctx = NULL;
459 }
460 }
461 }
462
test_traffic_class_cleanup_rx(void)463 static void test_traffic_class_cleanup_rx(void)
464 {
465 int i;
466
467 for (i = 0; i < NET_TC_RX_COUNT; i++) {
468 if (net_ctxs_rx[i].ctx) {
469 net_context_unref(net_ctxs_rx[i].ctx);
470 net_ctxs_rx[i].ctx = NULL;
471 }
472 }
473 }
474
traffic_class_send_packets_with_prio(enum net_priority prio,int pkt_count)475 static void traffic_class_send_packets_with_prio(enum net_priority prio,
476 int pkt_count)
477 {
478 /* Start to send data to each queue and verify that the data
479 * is received in correct order.
480 */
481 uint8_t data[128];
482 int len, ret;
483 int tc = net_tx_priority2tc(prio);
484
485 /* Convert num to ascii */
486 data[0] = tc + 0x30;
487 len = strlen(test_data);
488 memcpy(data+1, test_data, strlen(test_data));
489
490 len += 1;
491
492 test_started = true;
493
494 DBG("Sending on TC %d priority %d\n", tc, prio);
495
496 send_priorities[net_tx_priority2tc(prio)][pkt_count - 1] = prio + 1;
497
498 ret = net_context_sendto(net_ctxs_tx[tc].ctx, data, len,
499 (struct sockaddr *)&dst_addr6,
500 sizeof(struct sockaddr_in6),
501 NULL, K_NO_WAIT, NULL);
502 zassert_true(ret > 0, "Send UDP pkt failed");
503 }
504
traffic_class_send_priority(enum net_priority prio,int num_packets,bool wait_for_packets)505 static void traffic_class_send_priority(enum net_priority prio,
506 int num_packets,
507 bool wait_for_packets)
508 {
509 int i;
510
511 if (wait_for_packets) {
512 k_sem_init(&wait_data, MAX_PKT_TO_SEND, UINT_MAX);
513 }
514
515 for (i = 0; i < num_packets; i++) {
516 traffic_class_send_packets_with_prio(prio, i + 1);
517 }
518
519 if (wait_for_packets) {
520 if (k_sem_take(&wait_data, WAIT_TIME)) {
521 DBG("Timeout while waiting ok status\n");
522 zassert_false(true, "Timeout");
523 }
524
525 /* This sleep is needed here so that the sending side
526 * can run properly.
527 */
528 k_sleep(K_MSEC(1));
529 }
530 }
531
test_traffic_class_send_data_prio_bk(void)532 static void test_traffic_class_send_data_prio_bk(void)
533 {
534 /* Send number of packets with each priority and make sure
535 * they are sent properly.
536 */
537 traffic_class_send_priority(NET_PRIORITY_BK, MAX_PKT_TO_SEND, true);
538 }
539
test_traffic_class_send_data_prio_be(void)540 static void test_traffic_class_send_data_prio_be(void)
541 {
542 traffic_class_send_priority(NET_PRIORITY_BE, MAX_PKT_TO_SEND, true);
543 }
544
test_traffic_class_send_data_prio_ee(void)545 static void test_traffic_class_send_data_prio_ee(void)
546 {
547 traffic_class_send_priority(NET_PRIORITY_EE, MAX_PKT_TO_SEND, true);
548 }
549
test_traffic_class_send_data_prio_ca(void)550 static void test_traffic_class_send_data_prio_ca(void)
551 {
552 traffic_class_send_priority(NET_PRIORITY_CA, MAX_PKT_TO_SEND, true);
553 }
554
test_traffic_class_send_data_prio_vi(void)555 static void test_traffic_class_send_data_prio_vi(void)
556 {
557 traffic_class_send_priority(NET_PRIORITY_VI, MAX_PKT_TO_SEND, true);
558 }
559
test_traffic_class_send_data_prio_vo(void)560 static void test_traffic_class_send_data_prio_vo(void)
561 {
562 traffic_class_send_priority(NET_PRIORITY_VO, MAX_PKT_TO_SEND, true);
563 }
564
test_traffic_class_send_data_prio_ic(void)565 static void test_traffic_class_send_data_prio_ic(void)
566 {
567 traffic_class_send_priority(NET_PRIORITY_IC, MAX_PKT_TO_SEND, true);
568 }
569
test_traffic_class_send_data_prio_nc(void)570 static void test_traffic_class_send_data_prio_nc(void)
571 {
572 traffic_class_send_priority(NET_PRIORITY_NC, MAX_PKT_TO_SEND, true);
573 }
574
test_traffic_class_send_data_mix(void)575 static void test_traffic_class_send_data_mix(void)
576 {
577 /* Start to send data to each queue and verify that the data
578 * is received in correct order.
579 */
580 int total_packets = 0;
581
582 (void)memset(send_priorities, 0, sizeof(send_priorities));
583
584 traffic_class_send_priority(NET_PRIORITY_BK, MAX_PKT_TO_SEND, false);
585 total_packets += MAX_PKT_TO_SEND;
586
587 traffic_class_send_priority(NET_PRIORITY_BE, MAX_PKT_TO_SEND, false);
588 total_packets += MAX_PKT_TO_SEND;
589
590 /* The semaphore is released as many times as we have sent packets */
591 k_sem_init(&wait_data, total_packets, UINT_MAX);
592
593 if (k_sem_take(&wait_data, WAIT_TIME)) {
594 DBG("Timeout while waiting ok status\n");
595 zassert_false(true, "Timeout");
596 }
597
598 zassert_false(test_failed, "Traffic class verification failed.");
599 }
600
test_traffic_class_send_data_mix_all_1(void)601 static void test_traffic_class_send_data_mix_all_1(void)
602 {
603 int total_packets = 0;
604
605 (void)memset(send_priorities, 0, sizeof(send_priorities));
606
607 traffic_class_send_priority(NET_PRIORITY_BK, MAX_PKT_TO_SEND, false);
608 total_packets += MAX_PKT_TO_SEND;
609
610 traffic_class_send_priority(NET_PRIORITY_BE, MAX_PKT_TO_SEND, false);
611 total_packets += MAX_PKT_TO_SEND;
612
613 traffic_class_send_priority(NET_PRIORITY_EE, MAX_PKT_TO_SEND, false);
614 total_packets += MAX_PKT_TO_SEND;
615
616 traffic_class_send_priority(NET_PRIORITY_CA, MAX_PKT_TO_SEND, false);
617 total_packets += MAX_PKT_TO_SEND;
618
619 traffic_class_send_priority(NET_PRIORITY_VI, MAX_PKT_TO_SEND, false);
620 total_packets += MAX_PKT_TO_SEND;
621
622 traffic_class_send_priority(NET_PRIORITY_VO, MAX_PKT_TO_SEND, false);
623 total_packets += MAX_PKT_TO_SEND;
624
625 traffic_class_send_priority(NET_PRIORITY_IC, MAX_PKT_TO_SEND, false);
626 total_packets += MAX_PKT_TO_SEND;
627
628 traffic_class_send_priority(NET_PRIORITY_NC, MAX_PKT_TO_SEND, false);
629 total_packets += MAX_PKT_TO_SEND;
630
631 /* The semaphore is released as many times as we have sent packets */
632 k_sem_init(&wait_data, total_packets, UINT_MAX);
633
634 if (k_sem_take(&wait_data, WAIT_TIME)) {
635 DBG("Timeout while waiting ok status\n");
636 zassert_false(true, "Timeout");
637 }
638
639 zassert_false(test_failed, "Traffic class verification failed.");
640 }
641
test_traffic_class_send_data_mix_all_2(void)642 static void test_traffic_class_send_data_mix_all_2(void)
643 {
644 /* Start to send data to each queue and verify that the data
645 * is received in correct order.
646 */
647 int total_packets = 0;
648 int i;
649
650 (void)memset(send_priorities, 0, sizeof(send_priorities));
651
652 /* In this test send one packet for each queue instead of sending
653 * n packets to same queue at a time.
654 */
655 for (i = 0; i < MAX_PKT_TO_SEND; i++) {
656 traffic_class_send_priority(NET_PRIORITY_BK, 1, false);
657 total_packets += 1;
658
659 traffic_class_send_priority(NET_PRIORITY_BE, 1, false);
660 total_packets += 1;
661
662 traffic_class_send_priority(NET_PRIORITY_EE, 1, false);
663 total_packets += 1;
664
665 traffic_class_send_priority(NET_PRIORITY_CA, 1, false);
666 total_packets += 1;
667
668 traffic_class_send_priority(NET_PRIORITY_VI, 1, false);
669 total_packets += 1;
670
671 traffic_class_send_priority(NET_PRIORITY_VO, 1, false);
672 total_packets += 1;
673
674 traffic_class_send_priority(NET_PRIORITY_IC, 1, false);
675 total_packets += 1;
676
677 traffic_class_send_priority(NET_PRIORITY_NC, 1, false);
678 total_packets += 1;
679 }
680
681 /* The semaphore is released as many times as we have sent packets */
682 k_sem_init(&wait_data, total_packets, UINT_MAX);
683
684 if (k_sem_take(&wait_data, WAIT_TIME)) {
685 DBG("Timeout while waiting ok status\n");
686 zassert_false(true, "Timeout");
687 }
688
689 zassert_false(test_failed, "Traffic class verification failed.");
690 }
691
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)692 static void recv_cb(struct net_context *context,
693 struct net_pkt *pkt,
694 union net_ip_header *ip_hdr,
695 union net_proto_header *proto_hdr,
696 int status,
697 void *user_data)
698 {
699 #if NET_LOG_LEVEL >= LOG_LEVEL_DBG
700 k_tid_t thread = k_current_get();
701 #endif
702 int i, prio, ret;
703
704 DBG("Data received in priority %d\n", k_thread_priority_get(thread));
705
706 prio = net_pkt_priority(pkt);
707
708 for (i = 0; i < MAX_PKT_TO_RECV; i++) {
709 ret = check_higher_priority_pkt_recv(net_rx_priority2tc(prio),
710 pkt);
711 if (ret) {
712 DBG("Current thread priority %d "
713 "pkt %p prio %d tc %d\n",
714 k_thread_priority_get(thread),
715 pkt, prio, net_rx_priority2tc(prio));
716
717 test_failed = true;
718 zassert_false(test_failed,
719 "Invalid priority received %d TC %d,"
720 " expecting %d (pkt %p)\n",
721 prio,
722 net_rx_priority2tc(prio),
723 recv_priorities[net_rx_priority2tc(prio)][i],
724 pkt);
725 goto fail;
726 }
727
728 recv_priorities[net_rx_priority2tc(prio)][i] = 0;
729 }
730
731 fail:
732 recv_cb_called = true;
733 k_sem_give(&wait_data);
734
735 net_pkt_unref(pkt);
736 }
737
test_traffic_class_setup_recv(void)738 static void test_traffic_class_setup_recv(void)
739 {
740 int ret, i;
741
742 recv_cb_called = false;
743
744 for (i = 0; i < NET_TC_RX_COUNT; i++) {
745 ret = net_context_recv(net_ctxs_rx[i].ctx, recv_cb,
746 K_NO_WAIT, NULL);
747 zassert_equal(ret, 0,
748 "[%d] Context recv UDP setup failed (%d)\n",
749 i, ret);
750 }
751 }
752
traffic_class_recv_packets_with_prio(enum net_priority prio,int pkt_count)753 static void traffic_class_recv_packets_with_prio(enum net_priority prio,
754 int pkt_count)
755 {
756 /* Start to receive data to each queue and verify that the data
757 * is received in correct order.
758 */
759 uint8_t data[128];
760 int len, ret;
761 int tc = net_rx_priority2tc(prio);
762
763 const struct in6_addr *src_addr;
764 struct net_if_addr *ifaddr;
765 struct net_if *iface = NULL;
766
767 /* Convert num to ascii */
768 data[0] = tc + 0x30;
769 len = strlen(test_data);
770 memcpy(data+1, test_data, strlen(test_data));
771
772 len += 1;
773
774 test_started = true;
775 start_receiving = true;
776
777 DBG("Receiving on TC %d priority %d\n", tc, prio);
778
779 recv_priorities[net_rx_priority2tc(prio)][pkt_count - 1] = prio + 1;
780
781 src_addr = net_if_ipv6_select_src_addr(NULL, &dst_addr);
782 zassert_not_null(src_addr, "Cannot select source address");
783
784 ifaddr = net_if_ipv6_addr_lookup(src_addr, &iface);
785 zassert_not_null(ifaddr, "Cannot find source address");
786 zassert_not_null(iface, "Interface not found");
787
788 /* We cannot use net_recv_data() here as the packet does not have
789 * UDP header.
790 */
791 ret = net_context_sendto(net_ctxs_rx[tc].ctx, data, len,
792 (struct sockaddr *)&dst_addr6,
793 sizeof(struct sockaddr_in6),
794 NULL, K_NO_WAIT, NULL);
795 zassert_true(ret > 0, "Send UDP pkt failed");
796
797 /* Let the receiver to receive the packets */
798 k_sleep(K_MSEC(1));
799 }
800
traffic_class_recv_priority(enum net_priority prio,int num_packets,bool wait_for_packets)801 static void traffic_class_recv_priority(enum net_priority prio,
802 int num_packets,
803 bool wait_for_packets)
804 {
805 int i;
806
807 if (wait_for_packets) {
808 k_sem_init(&wait_data, MAX_PKT_TO_RECV, UINT_MAX);
809 }
810
811 for (i = 0; i < num_packets; i++) {
812 traffic_class_recv_packets_with_prio(prio, i + 1);
813 }
814
815 if (wait_for_packets) {
816 if (k_sem_take(&wait_data, WAIT_TIME)) {
817 DBG("Timeout while waiting ok status\n");
818 zassert_false(true, "Timeout");
819 }
820
821 /* This sleep is needed here so that the receiving side
822 * can run properly.
823 */
824 k_sleep(K_MSEC(1));
825 }
826 }
827
test_traffic_class_recv_data_prio_bk(void)828 static void test_traffic_class_recv_data_prio_bk(void)
829 {
830 /* Receive number of packets with each priority and make sure
831 * they are received properly.
832 */
833 traffic_class_recv_priority(NET_PRIORITY_BK, MAX_PKT_TO_RECV, true);
834
835 zassert_false(test_failed, "Traffic class verification failed.");
836 }
837
test_traffic_class_recv_data_prio_be(void)838 static void test_traffic_class_recv_data_prio_be(void)
839 {
840 traffic_class_recv_priority(NET_PRIORITY_BE, MAX_PKT_TO_RECV, true);
841 }
842
test_traffic_class_recv_data_prio_ee(void)843 static void test_traffic_class_recv_data_prio_ee(void)
844 {
845 traffic_class_recv_priority(NET_PRIORITY_EE, MAX_PKT_TO_RECV, true);
846 }
847
test_traffic_class_recv_data_prio_ca(void)848 static void test_traffic_class_recv_data_prio_ca(void)
849 {
850 traffic_class_recv_priority(NET_PRIORITY_CA, MAX_PKT_TO_RECV, true);
851 }
852
test_traffic_class_recv_data_prio_vi(void)853 static void test_traffic_class_recv_data_prio_vi(void)
854 {
855 traffic_class_recv_priority(NET_PRIORITY_VI, MAX_PKT_TO_RECV, true);
856 }
857
test_traffic_class_recv_data_prio_vo(void)858 static void test_traffic_class_recv_data_prio_vo(void)
859 {
860 traffic_class_recv_priority(NET_PRIORITY_VO, MAX_PKT_TO_RECV, true);
861 }
862
test_traffic_class_recv_data_prio_ic(void)863 static void test_traffic_class_recv_data_prio_ic(void)
864 {
865 traffic_class_recv_priority(NET_PRIORITY_IC, MAX_PKT_TO_RECV, true);
866 }
867
test_traffic_class_recv_data_prio_nc(void)868 static void test_traffic_class_recv_data_prio_nc(void)
869 {
870 traffic_class_recv_priority(NET_PRIORITY_NC, MAX_PKT_TO_RECV, true);
871 }
872
test_traffic_class_recv_data_mix(void)873 static void test_traffic_class_recv_data_mix(void)
874 {
875 /* Start to receive data to each queue and verify that the data
876 * is received in correct order.
877 */
878 int total_packets = 0;
879
880 (void)memset(recv_priorities, 0, sizeof(recv_priorities));
881
882 traffic_class_recv_priority(NET_PRIORITY_BK, MAX_PKT_TO_RECV, false);
883 total_packets += MAX_PKT_TO_RECV;
884
885 traffic_class_recv_priority(NET_PRIORITY_BE, MAX_PKT_TO_RECV, false);
886 total_packets += MAX_PKT_TO_RECV;
887
888 /* The semaphore is released as many times as we have sent packets */
889 k_sem_init(&wait_data, total_packets, UINT_MAX);
890
891 if (k_sem_take(&wait_data, WAIT_TIME)) {
892 DBG("Timeout while waiting ok status\n");
893 zassert_false(true, "Timeout");
894 }
895
896 zassert_false(test_failed, "Traffic class verification failed.");
897 }
898
test_traffic_class_recv_data_mix_all_1(void)899 static void test_traffic_class_recv_data_mix_all_1(void)
900 {
901 int total_packets = 0;
902
903 (void)memset(recv_priorities, 0, sizeof(recv_priorities));
904
905 traffic_class_recv_priority(NET_PRIORITY_BK, MAX_PKT_TO_RECV, false);
906 total_packets += MAX_PKT_TO_RECV;
907
908 traffic_class_recv_priority(NET_PRIORITY_BE, MAX_PKT_TO_RECV, false);
909 total_packets += MAX_PKT_TO_RECV;
910
911 traffic_class_recv_priority(NET_PRIORITY_EE, MAX_PKT_TO_RECV, false);
912 total_packets += MAX_PKT_TO_RECV;
913
914 traffic_class_recv_priority(NET_PRIORITY_CA, MAX_PKT_TO_RECV, false);
915 total_packets += MAX_PKT_TO_RECV;
916
917 traffic_class_recv_priority(NET_PRIORITY_VI, MAX_PKT_TO_RECV, false);
918 total_packets += MAX_PKT_TO_RECV;
919
920 traffic_class_recv_priority(NET_PRIORITY_VO, MAX_PKT_TO_RECV, false);
921 total_packets += MAX_PKT_TO_RECV;
922
923 traffic_class_recv_priority(NET_PRIORITY_IC, MAX_PKT_TO_RECV, false);
924 total_packets += MAX_PKT_TO_RECV;
925
926 traffic_class_recv_priority(NET_PRIORITY_NC, MAX_PKT_TO_RECV, false);
927 total_packets += MAX_PKT_TO_RECV;
928
929 /* The semaphore is released as many times as we have sent packets */
930 k_sem_init(&wait_data, total_packets, UINT_MAX);
931
932 if (k_sem_take(&wait_data, WAIT_TIME)) {
933 DBG("Timeout while waiting ok status\n");
934 zassert_false(true, "Timeout");
935 }
936
937 zassert_false(test_failed, "Traffic class verification failed.");
938 }
939
test_traffic_class_recv_data_mix_all_2(void)940 static void test_traffic_class_recv_data_mix_all_2(void)
941 {
942 /* Start to receive data to each queue and verify that the data
943 * is received in correct order.
944 */
945 int total_packets = 0;
946 int i;
947
948 (void)memset(recv_priorities, 0, sizeof(recv_priorities));
949
950 /* In this test receive one packet for each queue instead of receiving
951 * n packets to same queue at a time.
952 */
953 for (i = 0; i < MAX_PKT_TO_RECV; i++) {
954 traffic_class_recv_priority(NET_PRIORITY_BK, 1, false);
955 total_packets += 1;
956
957 traffic_class_recv_priority(NET_PRIORITY_BE, 1, false);
958 total_packets += 1;
959
960 traffic_class_recv_priority(NET_PRIORITY_EE, 1, false);
961 total_packets += 1;
962
963 traffic_class_recv_priority(NET_PRIORITY_CA, 1, false);
964 total_packets += 1;
965
966 traffic_class_recv_priority(NET_PRIORITY_VI, 1, false);
967 total_packets += 1;
968
969 traffic_class_recv_priority(NET_PRIORITY_VO, 1, false);
970 total_packets += 1;
971
972 traffic_class_recv_priority(NET_PRIORITY_IC, 1, false);
973 total_packets += 1;
974
975 traffic_class_recv_priority(NET_PRIORITY_NC, 1, false);
976 total_packets += 1;
977 }
978
979 /* The semaphore is released as many times as we have sent packets */
980 k_sem_init(&wait_data, total_packets, UINT_MAX);
981
982 if (k_sem_take(&wait_data, WAIT_TIME)) {
983 DBG("Timeout while waiting ok status\n");
984 zassert_false(true, "Timeout");
985 }
986
987 zassert_false(test_failed, "Traffic class verification failed.");
988 }
989
ZTEST(net_traffic_class,test_bk)990 ZTEST(net_traffic_class, test_bk)
991 {
992 test_traffic_class_send_data_prio_bk();
993 test_traffic_class_recv_data_prio_bk();
994 }
995
ZTEST(net_traffic_class,test_be)996 ZTEST(net_traffic_class, test_be)
997 {
998 test_traffic_class_send_data_prio_be();
999 test_traffic_class_recv_data_prio_be();
1000 }
1001
ZTEST(net_traffic_class,test_ee)1002 ZTEST(net_traffic_class, test_ee)
1003 {
1004 test_traffic_class_send_data_prio_ee();
1005 test_traffic_class_recv_data_prio_ee();
1006 }
1007
ZTEST(net_traffic_class,test_ca)1008 ZTEST(net_traffic_class, test_ca)
1009 {
1010 test_traffic_class_send_data_prio_ca();
1011 test_traffic_class_recv_data_prio_ca();
1012 }
1013
ZTEST(net_traffic_class,test_vi)1014 ZTEST(net_traffic_class, test_vi)
1015 {
1016 test_traffic_class_send_data_prio_vi();
1017 test_traffic_class_recv_data_prio_vi();
1018 }
1019
ZTEST(net_traffic_class,test_vo)1020 ZTEST(net_traffic_class, test_vo)
1021 {
1022 test_traffic_class_send_data_prio_vo();
1023 test_traffic_class_recv_data_prio_vo();
1024 }
1025
ZTEST(net_traffic_class,test_ic)1026 ZTEST(net_traffic_class, test_ic)
1027 {
1028 test_traffic_class_send_data_prio_ic();
1029 test_traffic_class_recv_data_prio_ic();
1030 }
1031
ZTEST(net_traffic_class,test_nc)1032 ZTEST(net_traffic_class, test_nc)
1033 {
1034 test_traffic_class_send_data_prio_nc();
1035 test_traffic_class_recv_data_prio_nc();
1036 }
1037
ZTEST(net_traffic_class,test_mix)1038 ZTEST(net_traffic_class, test_mix)
1039 {
1040 test_traffic_class_send_data_mix();
1041 test_traffic_class_recv_data_mix();
1042 }
1043
ZTEST(net_traffic_class,test_mix_all_1)1044 ZTEST(net_traffic_class, test_mix_all_1)
1045 {
1046 test_traffic_class_send_data_mix_all_1();
1047 test_traffic_class_recv_data_mix_all_1();
1048 }
1049
ZTEST(net_traffic_class,test_mix_all_2)1050 ZTEST(net_traffic_class, test_mix_all_2)
1051 {
1052 test_traffic_class_send_data_mix_all_2();
1053 test_traffic_class_recv_data_mix_all_2();
1054 }
1055
run_before(void * dummy)1056 static void run_before(void *dummy)
1057 {
1058 ARG_UNUSED(dummy);
1059 test_traffic_class_general_setup();
1060 test_traffic_class_setup_tx();
1061 test_traffic_class_setup_rx();
1062 test_traffic_class_setup_recv();
1063 }
1064
run_after(void * dummy)1065 static void run_after(void *dummy)
1066 {
1067 ARG_UNUSED(dummy);
1068 test_traffic_class_cleanup_tx();
1069 test_traffic_class_cleanup_rx();
1070 }
1071
1072 ZTEST_SUITE(net_traffic_class, NULL, NULL, run_before, run_after, NULL);
1073