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_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