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 lladdr;
349 struct net_nbr *nbr;
350
351 lladdr.addr[0] = 0x01;
352 lladdr.addr[1] = 0x02;
353 lladdr.addr[2] = 0x33;
354 lladdr.addr[3] = 0x44;
355 lladdr.addr[4] = 0x05;
356 lladdr.addr[5] = 0x06;
357
358 lladdr.len = 6U;
359 lladdr.type = NET_LINK_ETHERNET;
360
361 nbr = net_ipv6_nbr_add(iface, addr, &lladdr, false,
362 NET_IPV6_NBR_STATE_REACHABLE);
363 if (!nbr) {
364 DBG("Cannot add dst %s to neighbor cache\n",
365 net_sprint_ipv6_addr(addr));
366 return false;
367 }
368
369 return true;
370 }
371 #else
372 #define add_neighbor(iface, addr) true
373 #endif /* CONFIG_NET_IPV6_NBR_CACHE */
374
setup_net_context(struct net_context ** ctx)375 static void setup_net_context(struct net_context **ctx)
376 {
377 struct sockaddr_in6 src_addr6 = {
378 .sin6_family = AF_INET6,
379 .sin6_port = 0,
380 };
381 int ret;
382 struct net_if *iface1;
383
384 iface1 = net_if_get_first_by_type(&NET_L2_GET_NAME(DUMMY));
385
386 ret = net_context_get(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, ctx);
387 zassert_equal(ret, 0, "Create IPv6 UDP context %p failed (%d)\n",
388 *ctx, ret);
389
390 memcpy(&src_addr6.sin6_addr, &my_addr1, sizeof(struct in6_addr));
391 memcpy(&dst_addr6.sin6_addr, &dst_addr, sizeof(struct in6_addr));
392
393 ret = add_neighbor(iface1, &dst_addr);
394 zassert_true(ret, "Cannot add neighbor");
395
396 ret = net_context_bind(*ctx, (struct sockaddr *)&src_addr6,
397 sizeof(struct sockaddr_in6));
398 zassert_equal(ret, 0,
399 "Context bind failure test failed (%d)\n", ret);
400 }
401
test_traffic_class_general_setup(void)402 static void test_traffic_class_general_setup(void)
403 {
404 address_setup();
405 priority_setup();
406 }
407
test_traffic_class_setup_tx(void)408 static void test_traffic_class_setup_tx(void)
409 {
410 uint8_t priority;
411 int i, ret;
412
413 for (i = 0; i < NET_TC_TX_COUNT; i++) {
414
415 setup_net_context(&net_ctxs_tx[i].ctx);
416
417 priority = tx_tc2prio[i];
418
419 ret = net_context_set_option(net_ctxs_tx[i].ctx,
420 NET_OPT_PRIORITY,
421 &priority, sizeof(priority));
422 zassert_equal(ret, 0,
423 "Cannot set priority %d to ctx %p (%d)\n",
424 priority, net_ctxs_tx[i].ctx, ret);
425 }
426
427 }
428
test_traffic_class_setup_rx(void)429 static void test_traffic_class_setup_rx(void)
430 {
431 uint8_t priority;
432 int i, ret;
433
434 for (i = 0; i < NET_TC_RX_COUNT; i++) {
435
436 setup_net_context(&net_ctxs_rx[i].ctx);
437
438 priority = rx_tc2prio[i];
439
440 ret = net_context_set_option(net_ctxs_rx[i].ctx,
441 NET_OPT_PRIORITY,
442 &priority, sizeof(priority));
443 zassert_equal(ret, 0,
444 "Cannot set priority %d to ctx %p (%d)\n",
445 priority, net_ctxs_rx[i].ctx, ret);
446 }
447 }
448
test_traffic_class_cleanup_tx(void)449 static void test_traffic_class_cleanup_tx(void)
450 {
451 int i;
452
453 for (i = 0; i < NET_TC_TX_COUNT; i++) {
454 if (net_ctxs_tx[i].ctx) {
455 net_context_unref(net_ctxs_tx[i].ctx);
456 net_ctxs_tx[i].ctx = NULL;
457 }
458 }
459 }
460
test_traffic_class_cleanup_rx(void)461 static void test_traffic_class_cleanup_rx(void)
462 {
463 int i;
464
465 for (i = 0; i < NET_TC_RX_COUNT; i++) {
466 if (net_ctxs_rx[i].ctx) {
467 net_context_unref(net_ctxs_rx[i].ctx);
468 net_ctxs_rx[i].ctx = NULL;
469 }
470 }
471 }
472
traffic_class_send_packets_with_prio(enum net_priority prio,int pkt_count)473 static void traffic_class_send_packets_with_prio(enum net_priority prio,
474 int pkt_count)
475 {
476 /* Start to send data to each queue and verify that the data
477 * is received in correct order.
478 */
479 uint8_t data[128];
480 int len, ret;
481 int tc = net_tx_priority2tc(prio);
482
483 /* Convert num to ascii */
484 data[0] = tc + 0x30;
485 len = strlen(test_data);
486 memcpy(data+1, test_data, strlen(test_data));
487
488 len += 1;
489
490 test_started = true;
491
492 DBG("Sending on TC %d priority %d\n", tc, prio);
493
494 send_priorities[net_tx_priority2tc(prio)][pkt_count - 1] = prio + 1;
495
496 ret = net_context_sendto(net_ctxs_tx[tc].ctx, data, len,
497 (struct sockaddr *)&dst_addr6,
498 sizeof(struct sockaddr_in6),
499 NULL, K_NO_WAIT, NULL);
500 zassert_true(ret > 0, "Send UDP pkt failed");
501 }
502
traffic_class_send_priority(enum net_priority prio,int num_packets,bool wait_for_packets)503 static void traffic_class_send_priority(enum net_priority prio,
504 int num_packets,
505 bool wait_for_packets)
506 {
507 int i;
508
509 if (wait_for_packets) {
510 k_sem_init(&wait_data, MAX_PKT_TO_SEND, UINT_MAX);
511 }
512
513 for (i = 0; i < num_packets; i++) {
514 traffic_class_send_packets_with_prio(prio, i + 1);
515 }
516
517 if (wait_for_packets) {
518 if (k_sem_take(&wait_data, WAIT_TIME)) {
519 DBG("Timeout while waiting ok status\n");
520 zassert_false(true, "Timeout");
521 }
522
523 /* This sleep is needed here so that the sending side
524 * can run properly.
525 */
526 k_sleep(K_MSEC(1));
527 }
528 }
529
test_traffic_class_send_data_prio_bk(void)530 static void test_traffic_class_send_data_prio_bk(void)
531 {
532 /* Send number of packets with each priority and make sure
533 * they are sent properly.
534 */
535 traffic_class_send_priority(NET_PRIORITY_BK, MAX_PKT_TO_SEND, true);
536 }
537
test_traffic_class_send_data_prio_be(void)538 static void test_traffic_class_send_data_prio_be(void)
539 {
540 traffic_class_send_priority(NET_PRIORITY_BE, MAX_PKT_TO_SEND, true);
541 }
542
test_traffic_class_send_data_prio_ee(void)543 static void test_traffic_class_send_data_prio_ee(void)
544 {
545 traffic_class_send_priority(NET_PRIORITY_EE, MAX_PKT_TO_SEND, true);
546 }
547
test_traffic_class_send_data_prio_ca(void)548 static void test_traffic_class_send_data_prio_ca(void)
549 {
550 traffic_class_send_priority(NET_PRIORITY_CA, MAX_PKT_TO_SEND, true);
551 }
552
test_traffic_class_send_data_prio_vi(void)553 static void test_traffic_class_send_data_prio_vi(void)
554 {
555 traffic_class_send_priority(NET_PRIORITY_VI, MAX_PKT_TO_SEND, true);
556 }
557
test_traffic_class_send_data_prio_vo(void)558 static void test_traffic_class_send_data_prio_vo(void)
559 {
560 traffic_class_send_priority(NET_PRIORITY_VO, MAX_PKT_TO_SEND, true);
561 }
562
test_traffic_class_send_data_prio_ic(void)563 static void test_traffic_class_send_data_prio_ic(void)
564 {
565 traffic_class_send_priority(NET_PRIORITY_IC, MAX_PKT_TO_SEND, true);
566 }
567
test_traffic_class_send_data_prio_nc(void)568 static void test_traffic_class_send_data_prio_nc(void)
569 {
570 traffic_class_send_priority(NET_PRIORITY_NC, MAX_PKT_TO_SEND, true);
571 }
572
test_traffic_class_send_data_mix(void)573 static void test_traffic_class_send_data_mix(void)
574 {
575 /* Start to send data to each queue and verify that the data
576 * is received in correct order.
577 */
578 int total_packets = 0;
579
580 (void)memset(send_priorities, 0, sizeof(send_priorities));
581
582 traffic_class_send_priority(NET_PRIORITY_BK, MAX_PKT_TO_SEND, false);
583 total_packets += MAX_PKT_TO_SEND;
584
585 traffic_class_send_priority(NET_PRIORITY_BE, MAX_PKT_TO_SEND, false);
586 total_packets += MAX_PKT_TO_SEND;
587
588 /* The semaphore is released as many times as we have sent packets */
589 k_sem_init(&wait_data, total_packets, UINT_MAX);
590
591 if (k_sem_take(&wait_data, WAIT_TIME)) {
592 DBG("Timeout while waiting ok status\n");
593 zassert_false(true, "Timeout");
594 }
595
596 zassert_false(test_failed, "Traffic class verification failed.");
597 }
598
test_traffic_class_send_data_mix_all_1(void)599 static void test_traffic_class_send_data_mix_all_1(void)
600 {
601 int total_packets = 0;
602
603 (void)memset(send_priorities, 0, sizeof(send_priorities));
604
605 traffic_class_send_priority(NET_PRIORITY_BK, MAX_PKT_TO_SEND, false);
606 total_packets += MAX_PKT_TO_SEND;
607
608 traffic_class_send_priority(NET_PRIORITY_BE, MAX_PKT_TO_SEND, false);
609 total_packets += MAX_PKT_TO_SEND;
610
611 traffic_class_send_priority(NET_PRIORITY_EE, MAX_PKT_TO_SEND, false);
612 total_packets += MAX_PKT_TO_SEND;
613
614 traffic_class_send_priority(NET_PRIORITY_CA, MAX_PKT_TO_SEND, false);
615 total_packets += MAX_PKT_TO_SEND;
616
617 traffic_class_send_priority(NET_PRIORITY_VI, MAX_PKT_TO_SEND, false);
618 total_packets += MAX_PKT_TO_SEND;
619
620 traffic_class_send_priority(NET_PRIORITY_VO, MAX_PKT_TO_SEND, false);
621 total_packets += MAX_PKT_TO_SEND;
622
623 traffic_class_send_priority(NET_PRIORITY_IC, MAX_PKT_TO_SEND, false);
624 total_packets += MAX_PKT_TO_SEND;
625
626 traffic_class_send_priority(NET_PRIORITY_NC, MAX_PKT_TO_SEND, false);
627 total_packets += MAX_PKT_TO_SEND;
628
629 /* The semaphore is released as many times as we have sent packets */
630 k_sem_init(&wait_data, total_packets, UINT_MAX);
631
632 if (k_sem_take(&wait_data, WAIT_TIME)) {
633 DBG("Timeout while waiting ok status\n");
634 zassert_false(true, "Timeout");
635 }
636
637 zassert_false(test_failed, "Traffic class verification failed.");
638 }
639
test_traffic_class_send_data_mix_all_2(void)640 static void test_traffic_class_send_data_mix_all_2(void)
641 {
642 /* Start to send data to each queue and verify that the data
643 * is received in correct order.
644 */
645 int total_packets = 0;
646 int i;
647
648 (void)memset(send_priorities, 0, sizeof(send_priorities));
649
650 /* In this test send one packet for each queue instead of sending
651 * n packets to same queue at a time.
652 */
653 for (i = 0; i < MAX_PKT_TO_SEND; i++) {
654 traffic_class_send_priority(NET_PRIORITY_BK, 1, false);
655 total_packets += 1;
656
657 traffic_class_send_priority(NET_PRIORITY_BE, 1, false);
658 total_packets += 1;
659
660 traffic_class_send_priority(NET_PRIORITY_EE, 1, false);
661 total_packets += 1;
662
663 traffic_class_send_priority(NET_PRIORITY_CA, 1, false);
664 total_packets += 1;
665
666 traffic_class_send_priority(NET_PRIORITY_VI, 1, false);
667 total_packets += 1;
668
669 traffic_class_send_priority(NET_PRIORITY_VO, 1, false);
670 total_packets += 1;
671
672 traffic_class_send_priority(NET_PRIORITY_IC, 1, false);
673 total_packets += 1;
674
675 traffic_class_send_priority(NET_PRIORITY_NC, 1, false);
676 total_packets += 1;
677 }
678
679 /* The semaphore is released as many times as we have sent packets */
680 k_sem_init(&wait_data, total_packets, UINT_MAX);
681
682 if (k_sem_take(&wait_data, WAIT_TIME)) {
683 DBG("Timeout while waiting ok status\n");
684 zassert_false(true, "Timeout");
685 }
686
687 zassert_false(test_failed, "Traffic class verification failed.");
688 }
689
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)690 static void recv_cb(struct net_context *context,
691 struct net_pkt *pkt,
692 union net_ip_header *ip_hdr,
693 union net_proto_header *proto_hdr,
694 int status,
695 void *user_data)
696 {
697 #if NET_LOG_LEVEL >= LOG_LEVEL_DBG
698 k_tid_t thread = k_current_get();
699 #endif
700 int i, prio, ret;
701
702 DBG("Data received in priority %d\n", k_thread_priority_get(thread));
703
704 prio = net_pkt_priority(pkt);
705
706 for (i = 0; i < MAX_PKT_TO_RECV; i++) {
707 ret = check_higher_priority_pkt_recv(net_rx_priority2tc(prio),
708 pkt);
709 if (ret) {
710 DBG("Current thread priority %d "
711 "pkt %p prio %d tc %d\n",
712 k_thread_priority_get(thread),
713 pkt, prio, net_rx_priority2tc(prio));
714
715 test_failed = true;
716 zassert_false(test_failed,
717 "Invalid priority received %d TC %d,"
718 " expecting %d (pkt %p)\n",
719 prio,
720 net_rx_priority2tc(prio),
721 recv_priorities[net_rx_priority2tc(prio)][i],
722 pkt);
723 goto fail;
724 }
725
726 recv_priorities[net_rx_priority2tc(prio)][i] = 0;
727 }
728
729 fail:
730 recv_cb_called = true;
731 k_sem_give(&wait_data);
732
733 net_pkt_unref(pkt);
734 }
735
test_traffic_class_setup_recv(void)736 static void test_traffic_class_setup_recv(void)
737 {
738 int ret, i;
739
740 recv_cb_called = false;
741
742 for (i = 0; i < NET_TC_RX_COUNT; i++) {
743 ret = net_context_recv(net_ctxs_rx[i].ctx, recv_cb,
744 K_NO_WAIT, NULL);
745 zassert_equal(ret, 0,
746 "[%d] Context recv UDP setup failed (%d)\n",
747 i, ret);
748 }
749 }
750
traffic_class_recv_packets_with_prio(enum net_priority prio,int pkt_count)751 static void traffic_class_recv_packets_with_prio(enum net_priority prio,
752 int pkt_count)
753 {
754 /* Start to receive data to each queue and verify that the data
755 * is received in correct order.
756 */
757 uint8_t data[128];
758 int len, ret;
759 int tc = net_rx_priority2tc(prio);
760
761 const struct in6_addr *src_addr;
762 struct net_if_addr *ifaddr;
763 struct net_if *iface = NULL;
764
765 /* Convert num to ascii */
766 data[0] = tc + 0x30;
767 len = strlen(test_data);
768 memcpy(data+1, test_data, strlen(test_data));
769
770 len += 1;
771
772 test_started = true;
773 start_receiving = true;
774
775 DBG("Receiving on TC %d priority %d\n", tc, prio);
776
777 recv_priorities[net_rx_priority2tc(prio)][pkt_count - 1] = prio + 1;
778
779 src_addr = net_if_ipv6_select_src_addr(NULL, &dst_addr);
780 zassert_not_null(src_addr, "Cannot select source address");
781
782 ifaddr = net_if_ipv6_addr_lookup(src_addr, &iface);
783 zassert_not_null(ifaddr, "Cannot find source address");
784 zassert_not_null(iface, "Interface not found");
785
786 /* We cannot use net_recv_data() here as the packet does not have
787 * UDP header.
788 */
789 ret = net_context_sendto(net_ctxs_rx[tc].ctx, data, len,
790 (struct sockaddr *)&dst_addr6,
791 sizeof(struct sockaddr_in6),
792 NULL, K_NO_WAIT, NULL);
793 zassert_true(ret > 0, "Send UDP pkt failed");
794
795 /* Let the receiver to receive the packets */
796 k_sleep(K_MSEC(1));
797 }
798
traffic_class_recv_priority(enum net_priority prio,int num_packets,bool wait_for_packets)799 static void traffic_class_recv_priority(enum net_priority prio,
800 int num_packets,
801 bool wait_for_packets)
802 {
803 int i;
804
805 if (wait_for_packets) {
806 k_sem_init(&wait_data, MAX_PKT_TO_RECV, UINT_MAX);
807 }
808
809 for (i = 0; i < num_packets; i++) {
810 traffic_class_recv_packets_with_prio(prio, i + 1);
811 }
812
813 if (wait_for_packets) {
814 if (k_sem_take(&wait_data, WAIT_TIME)) {
815 DBG("Timeout while waiting ok status\n");
816 zassert_false(true, "Timeout");
817 }
818
819 /* This sleep is needed here so that the receiving side
820 * can run properly.
821 */
822 k_sleep(K_MSEC(1));
823 }
824 }
825
test_traffic_class_recv_data_prio_bk(void)826 static void test_traffic_class_recv_data_prio_bk(void)
827 {
828 /* Receive number of packets with each priority and make sure
829 * they are received properly.
830 */
831 traffic_class_recv_priority(NET_PRIORITY_BK, MAX_PKT_TO_RECV, true);
832
833 zassert_false(test_failed, "Traffic class verification failed.");
834 }
835
test_traffic_class_recv_data_prio_be(void)836 static void test_traffic_class_recv_data_prio_be(void)
837 {
838 traffic_class_recv_priority(NET_PRIORITY_BE, MAX_PKT_TO_RECV, true);
839 }
840
test_traffic_class_recv_data_prio_ee(void)841 static void test_traffic_class_recv_data_prio_ee(void)
842 {
843 traffic_class_recv_priority(NET_PRIORITY_EE, MAX_PKT_TO_RECV, true);
844 }
845
test_traffic_class_recv_data_prio_ca(void)846 static void test_traffic_class_recv_data_prio_ca(void)
847 {
848 traffic_class_recv_priority(NET_PRIORITY_CA, MAX_PKT_TO_RECV, true);
849 }
850
test_traffic_class_recv_data_prio_vi(void)851 static void test_traffic_class_recv_data_prio_vi(void)
852 {
853 traffic_class_recv_priority(NET_PRIORITY_VI, MAX_PKT_TO_RECV, true);
854 }
855
test_traffic_class_recv_data_prio_vo(void)856 static void test_traffic_class_recv_data_prio_vo(void)
857 {
858 traffic_class_recv_priority(NET_PRIORITY_VO, MAX_PKT_TO_RECV, true);
859 }
860
test_traffic_class_recv_data_prio_ic(void)861 static void test_traffic_class_recv_data_prio_ic(void)
862 {
863 traffic_class_recv_priority(NET_PRIORITY_IC, MAX_PKT_TO_RECV, true);
864 }
865
test_traffic_class_recv_data_prio_nc(void)866 static void test_traffic_class_recv_data_prio_nc(void)
867 {
868 traffic_class_recv_priority(NET_PRIORITY_NC, MAX_PKT_TO_RECV, true);
869 }
870
test_traffic_class_recv_data_mix(void)871 static void test_traffic_class_recv_data_mix(void)
872 {
873 /* Start to receive data to each queue and verify that the data
874 * is received in correct order.
875 */
876 int total_packets = 0;
877
878 (void)memset(recv_priorities, 0, sizeof(recv_priorities));
879
880 traffic_class_recv_priority(NET_PRIORITY_BK, MAX_PKT_TO_RECV, false);
881 total_packets += MAX_PKT_TO_RECV;
882
883 traffic_class_recv_priority(NET_PRIORITY_BE, MAX_PKT_TO_RECV, false);
884 total_packets += MAX_PKT_TO_RECV;
885
886 /* The semaphore is released as many times as we have sent packets */
887 k_sem_init(&wait_data, total_packets, UINT_MAX);
888
889 if (k_sem_take(&wait_data, WAIT_TIME)) {
890 DBG("Timeout while waiting ok status\n");
891 zassert_false(true, "Timeout");
892 }
893
894 zassert_false(test_failed, "Traffic class verification failed.");
895 }
896
test_traffic_class_recv_data_mix_all_1(void)897 static void test_traffic_class_recv_data_mix_all_1(void)
898 {
899 int total_packets = 0;
900
901 (void)memset(recv_priorities, 0, sizeof(recv_priorities));
902
903 traffic_class_recv_priority(NET_PRIORITY_BK, MAX_PKT_TO_RECV, false);
904 total_packets += MAX_PKT_TO_RECV;
905
906 traffic_class_recv_priority(NET_PRIORITY_BE, MAX_PKT_TO_RECV, false);
907 total_packets += MAX_PKT_TO_RECV;
908
909 traffic_class_recv_priority(NET_PRIORITY_EE, MAX_PKT_TO_RECV, false);
910 total_packets += MAX_PKT_TO_RECV;
911
912 traffic_class_recv_priority(NET_PRIORITY_CA, MAX_PKT_TO_RECV, false);
913 total_packets += MAX_PKT_TO_RECV;
914
915 traffic_class_recv_priority(NET_PRIORITY_VI, MAX_PKT_TO_RECV, false);
916 total_packets += MAX_PKT_TO_RECV;
917
918 traffic_class_recv_priority(NET_PRIORITY_VO, MAX_PKT_TO_RECV, false);
919 total_packets += MAX_PKT_TO_RECV;
920
921 traffic_class_recv_priority(NET_PRIORITY_IC, MAX_PKT_TO_RECV, false);
922 total_packets += MAX_PKT_TO_RECV;
923
924 traffic_class_recv_priority(NET_PRIORITY_NC, MAX_PKT_TO_RECV, false);
925 total_packets += MAX_PKT_TO_RECV;
926
927 /* The semaphore is released as many times as we have sent packets */
928 k_sem_init(&wait_data, total_packets, UINT_MAX);
929
930 if (k_sem_take(&wait_data, WAIT_TIME)) {
931 DBG("Timeout while waiting ok status\n");
932 zassert_false(true, "Timeout");
933 }
934
935 zassert_false(test_failed, "Traffic class verification failed.");
936 }
937
test_traffic_class_recv_data_mix_all_2(void)938 static void test_traffic_class_recv_data_mix_all_2(void)
939 {
940 /* Start to receive data to each queue and verify that the data
941 * is received in correct order.
942 */
943 int total_packets = 0;
944 int i;
945
946 (void)memset(recv_priorities, 0, sizeof(recv_priorities));
947
948 /* In this test receive one packet for each queue instead of receiving
949 * n packets to same queue at a time.
950 */
951 for (i = 0; i < MAX_PKT_TO_RECV; i++) {
952 traffic_class_recv_priority(NET_PRIORITY_BK, 1, false);
953 total_packets += 1;
954
955 traffic_class_recv_priority(NET_PRIORITY_BE, 1, false);
956 total_packets += 1;
957
958 traffic_class_recv_priority(NET_PRIORITY_EE, 1, false);
959 total_packets += 1;
960
961 traffic_class_recv_priority(NET_PRIORITY_CA, 1, false);
962 total_packets += 1;
963
964 traffic_class_recv_priority(NET_PRIORITY_VI, 1, false);
965 total_packets += 1;
966
967 traffic_class_recv_priority(NET_PRIORITY_VO, 1, false);
968 total_packets += 1;
969
970 traffic_class_recv_priority(NET_PRIORITY_IC, 1, false);
971 total_packets += 1;
972
973 traffic_class_recv_priority(NET_PRIORITY_NC, 1, false);
974 total_packets += 1;
975 }
976
977 /* The semaphore is released as many times as we have sent packets */
978 k_sem_init(&wait_data, total_packets, UINT_MAX);
979
980 if (k_sem_take(&wait_data, WAIT_TIME)) {
981 DBG("Timeout while waiting ok status\n");
982 zassert_false(true, "Timeout");
983 }
984
985 zassert_false(test_failed, "Traffic class verification failed.");
986 }
987
ZTEST(net_traffic_class,test_bk)988 ZTEST(net_traffic_class, test_bk)
989 {
990 test_traffic_class_send_data_prio_bk();
991 test_traffic_class_recv_data_prio_bk();
992 }
993
ZTEST(net_traffic_class,test_be)994 ZTEST(net_traffic_class, test_be)
995 {
996 test_traffic_class_send_data_prio_be();
997 test_traffic_class_recv_data_prio_be();
998 }
999
ZTEST(net_traffic_class,test_ee)1000 ZTEST(net_traffic_class, test_ee)
1001 {
1002 test_traffic_class_send_data_prio_ee();
1003 test_traffic_class_recv_data_prio_ee();
1004 }
1005
ZTEST(net_traffic_class,test_ca)1006 ZTEST(net_traffic_class, test_ca)
1007 {
1008 test_traffic_class_send_data_prio_ca();
1009 test_traffic_class_recv_data_prio_ca();
1010 }
1011
ZTEST(net_traffic_class,test_vi)1012 ZTEST(net_traffic_class, test_vi)
1013 {
1014 test_traffic_class_send_data_prio_vi();
1015 test_traffic_class_recv_data_prio_vi();
1016 }
1017
ZTEST(net_traffic_class,test_vo)1018 ZTEST(net_traffic_class, test_vo)
1019 {
1020 test_traffic_class_send_data_prio_vo();
1021 test_traffic_class_recv_data_prio_vo();
1022 }
1023
ZTEST(net_traffic_class,test_ic)1024 ZTEST(net_traffic_class, test_ic)
1025 {
1026 test_traffic_class_send_data_prio_ic();
1027 test_traffic_class_recv_data_prio_ic();
1028 }
1029
ZTEST(net_traffic_class,test_nc)1030 ZTEST(net_traffic_class, test_nc)
1031 {
1032 test_traffic_class_send_data_prio_nc();
1033 test_traffic_class_recv_data_prio_nc();
1034 }
1035
ZTEST(net_traffic_class,test_mix)1036 ZTEST(net_traffic_class, test_mix)
1037 {
1038 test_traffic_class_send_data_mix();
1039 test_traffic_class_recv_data_mix();
1040 }
1041
ZTEST(net_traffic_class,test_mix_all_1)1042 ZTEST(net_traffic_class, test_mix_all_1)
1043 {
1044 test_traffic_class_send_data_mix_all_1();
1045 test_traffic_class_recv_data_mix_all_1();
1046 }
1047
ZTEST(net_traffic_class,test_mix_all_2)1048 ZTEST(net_traffic_class, test_mix_all_2)
1049 {
1050 test_traffic_class_send_data_mix_all_2();
1051 test_traffic_class_recv_data_mix_all_2();
1052 }
1053
run_before(void * dummy)1054 static void run_before(void *dummy)
1055 {
1056 ARG_UNUSED(dummy);
1057 test_traffic_class_general_setup();
1058 test_traffic_class_setup_tx();
1059 test_traffic_class_setup_rx();
1060 test_traffic_class_setup_recv();
1061 }
1062
run_after(void * dummy)1063 static void run_after(void *dummy)
1064 {
1065 ARG_UNUSED(dummy);
1066 test_traffic_class_cleanup_tx();
1067 test_traffic_class_cleanup_rx();
1068 }
1069
1070 ZTEST_SUITE(net_traffic_class, NULL, NULL, run_before, run_after, NULL);
1071