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 		&eth_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