1 /* main.c - Application main entry point */
2 
3 /*
4  * Copyright (c) 2020 Lemonbeat GmbH
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include <zephyr/logging/log.h>
10 LOG_MODULE_REGISTER(net_test, CONFIG_NET_ROUTE_LOG_LEVEL);
11 
12 #include <zephyr/types.h>
13 #include <zephyr/ztest.h>
14 #include <stdbool.h>
15 #include <stddef.h>
16 #include <string.h>
17 #include <errno.h>
18 #include <zephyr/sys/printk.h>
19 #include <zephyr/linker/sections.h>
20 #include <zephyr/random/random.h>
21 
22 #include <zephyr/tc_util.h>
23 
24 #include <zephyr/net/ethernet.h>
25 #include <zephyr/net/dummy.h>
26 #include <zephyr/net/buf.h>
27 #include <zephyr/net/net_ip.h>
28 #include <zephyr/net/net_if.h>
29 #include <zephyr/net/net_context.h>
30 
31 #define NET_LOG_ENABLED 1
32 #include "net_private.h"
33 #include "icmpv6.h"
34 #include "ipv6.h"
35 #include <zephyr/net/udp.h>
36 #include "udp_internal.h"
37 #include "nbr.h"
38 #include "route.h"
39 
40 #if defined(CONFIG_NET_ROUTE_LOG_LEVEL_DBG)
41 #define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
42 #else
43 #define DBG(fmt, ...)
44 #endif
45 
46 static struct in6_addr iface_1_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
47 					  0, 0, 0, 0, 0, 0, 0, 0x1 } } };
48 
49 static struct in6_addr iface_2_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
50 				    0, 0, 0, 0, 0x0b, 0x0e, 0x0e, 0x3 } } };
51 
52 static struct in6_addr iface_3_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
53 				    0, 0, 0, 0, 0x0e, 0x0e, 0x0e, 0x4 } } };
54 
55 /* Extra address is assigned to ll_addr */
56 static struct in6_addr ll_addr_1 = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0,
57 					0, 0, 0, 0xf2,
58 					0xaa, 0x29, 0x02, 0x04 } } };
59 
60 static struct in6_addr ll_addr_2 = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0,
61 				       0, 0, 0, 0xf2,
62 					   0xaa, 0x29, 0x05, 0x06 } } };
63 
64 static struct in6_addr ll_addr_3 = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0,
65 				       0, 0, 0, 0xf2,
66 					   0xaa, 0x29, 0x07, 0x08 } } };
67 
68 static struct in6_addr in6addr_mcast = { { { 0xff, 0x02, 0, 0, 0, 0, 0, 0,
69 					     0, 0, 0, 0, 0, 0, 0, 0x1 } } };
70 
71 static struct net_if *iface_1;
72 static struct net_if *iface_2;
73 static struct net_if *iface_3;
74 
75 #define WAIT_TIME K_MSEC(50)
76 
77 struct net_route_mcast_iface_cfg {
78 	uint8_t mac_addr[sizeof(struct net_eth_addr)];
79 	struct net_linkaddr ll_addr;
80 };
81 
82 #define MAX_MCAST_ROUTES CONFIG_NET_MAX_MCAST_ROUTES
83 
84 static struct net_route_entry_mcast *test_mcast_routes[MAX_MCAST_ROUTES];
85 
86 static struct in6_addr mcast_prefix_iflocal = { { {
87 					0xFF, 0x01, 0, 0,
88 					0, 0, 0, 0,
89 					0, 0, 0, 0,
90 					0, 0, 0, 0 } } };
91 static struct in6_addr mcast_prefix_llocal = { { {
92 					0xFF, 0x02, 0, 0,
93 					0, 0, 0, 0,
94 					0, 0, 0, 0,
95 					0, 0, 0, 0 } } };
96 static struct in6_addr mcast_prefix_admin = { { {
97 					0xFF, 0x04, 0, 0,
98 					0, 0, 0, 0,
99 					0, 0, 0, 0,
100 					0, 0, 0, 0 } } };
101 static struct in6_addr mcast_prefix_site_local = { { {
102 					0xFF, 0x05, 0, 0,
103 					0, 0, 0, 0,
104 					0, 0, 0, 0,
105 					0, 0, 0, 0 } } };
106 static struct in6_addr mcast_prefix_orga = { { {
107 					0xFF, 0x08, 0, 0,
108 					0, 0, 0, 0,
109 					0, 0, 0, 0,
110 					0, 0, 0, 0 } } };
111 static struct in6_addr mcast_prefix_global = { { {
112 					0xFF, 0x0E, 0, 0,
113 					0, 0, 0, 0,
114 					0, 0, 0, 0,
115 					0, 0, 0, 0 } } };
116 /*
117  * full network prefix based address,
118  * see RFC-3306 for details
119  * FF3F:40:FD01:101:: \128
120  * network prefix FD01:101::\64
121  */
122 static struct in6_addr mcast_prefix_nw_based = { { {
123 		0xFF, 0x3F, 0, 0x40,
124 		0xFD, 0x01, 0x01, 0x01,
125 		0, 0, 0, 0,
126 		0, 0, 0, 0 } } };
127 
128 static uint8_t forwarding_counter;
129 static bool iface_1_forwarded;
130 static bool iface_2_forwarded;
131 static bool iface_3_forwarded;
132 
133 struct net_route_mcast_scenario_cfg {
134 	struct in6_addr src;
135 	struct in6_addr mcast;
136 	bool is_active;
137 };
138 
139 static struct net_route_mcast_scenario_cfg active_scenario;
140 
net_route_mcast_dev_init(const struct device * dev)141 int net_route_mcast_dev_init(const struct device *dev)
142 {
143 	return 0;
144 }
145 
net_route_mcast_get_mac(const struct device * dev)146 static uint8_t *net_route_mcast_get_mac(const struct device *dev)
147 {
148 	struct net_route_mcast_iface_cfg *cfg = dev->data;
149 
150 	if (cfg->mac_addr[2] == 0x00) {
151 		/* 00-00-5E-00-53-xx Documentation RFC 7042 */
152 		cfg->mac_addr[0] = 0x00;
153 		cfg->mac_addr[1] = 0x00;
154 		cfg->mac_addr[2] = 0x5E;
155 		cfg->mac_addr[3] = 0x00;
156 		cfg->mac_addr[4] = 0x53;
157 		cfg->mac_addr[5] = sys_rand32_get();
158 	}
159 
160 	cfg->ll_addr.addr = cfg->mac_addr;
161 	cfg->ll_addr.len = 6U;
162 
163 	return cfg->mac_addr;
164 }
165 
net_route_mcast_add_addresses(struct net_if * iface,struct in6_addr * ipv6,struct in6_addr * ll_addr)166 static void net_route_mcast_add_addresses(struct net_if *iface,
167 		struct in6_addr *ipv6, struct in6_addr *ll_addr)
168 {
169 	struct net_if_mcast_addr *maddr;
170 	struct net_if_addr *ifaddr;
171 
172 	uint8_t *mac = net_route_mcast_get_mac(net_if_get_device(iface));
173 
174 	net_if_set_link_addr(iface, mac, sizeof(struct net_eth_addr),
175 				     NET_LINK_ETHERNET);
176 
177 	ifaddr = net_if_ipv6_addr_add(iface, ipv6, NET_ADDR_MANUAL, 0);
178 	zassert_not_null(ifaddr, "Cannot add global IPv6 address");
179 
180 	ifaddr->addr_state = NET_ADDR_PREFERRED;
181 
182 	ifaddr = net_if_ipv6_addr_add(iface, ll_addr, NET_ADDR_MANUAL, 0);
183 	zassert_not_null(ifaddr, "Cannot add ll IPv6 address");
184 
185 	ifaddr->addr_state = NET_ADDR_PREFERRED;
186 
187 	maddr = net_if_ipv6_maddr_add(iface, &in6addr_mcast);
188 	zassert_not_null(maddr, "Cannot add multicast IPv6 address");
189 }
190 
net_route_mcast_iface_init1(struct net_if * iface)191 static void net_route_mcast_iface_init1(struct net_if *iface)
192 {
193 	iface_1 = iface;
194 	net_route_mcast_add_addresses(iface, &iface_1_addr, &ll_addr_1);
195 }
196 
net_route_mcast_iface_init2(struct net_if * iface)197 static void net_route_mcast_iface_init2(struct net_if *iface)
198 {
199 	iface_2 = iface;
200 	net_route_mcast_add_addresses(iface, &iface_2_addr, &ll_addr_2);
201 }
202 
net_route_mcast_iface_init3(struct net_if * iface)203 static void net_route_mcast_iface_init3(struct net_if *iface)
204 {
205 	iface_3 = iface;
206 	net_route_mcast_add_addresses(iface, &iface_3_addr, &ll_addr_3);
207 }
208 
check_packet_addresses(struct net_pkt * pkt)209 static bool check_packet_addresses(struct net_pkt *pkt)
210 {
211 	struct net_ipv6_hdr *ipv6_hdr = NET_IPV6_HDR(pkt);
212 
213 	if ((memcmp(&active_scenario.src,
214 			&ipv6_hdr->src,
215 			sizeof(struct in6_addr)) != 0) ||
216 			(memcmp(&active_scenario.mcast,
217 				ipv6_hdr->dst,
218 				sizeof(struct in6_addr)) != 0)) {
219 		return false;
220 	}
221 
222 	return true;
223 }
224 
iface_send(const struct device * dev,struct net_pkt * pkt)225 static int iface_send(const struct device *dev, struct net_pkt *pkt)
226 {
227 	if (!active_scenario.is_active) {
228 		return 0;
229 	}
230 	if (!check_packet_addresses(pkt)) {
231 		return 0;
232 	}
233 
234 	forwarding_counter++;
235 
236 	if (net_pkt_iface(pkt) == iface_1) {
237 		iface_1_forwarded = true;
238 	} else if (net_pkt_iface(pkt) == iface_2) {
239 		iface_2_forwarded = true;
240 	} else if (net_pkt_iface(pkt) == iface_3) {
241 		iface_3_forwarded = true;
242 	}
243 
244 	return 0;
245 }
246 
247 struct net_route_mcast_iface_cfg net_route_data_if1;
248 struct net_route_mcast_iface_cfg net_route_data_if2;
249 struct net_route_mcast_iface_cfg net_route_data_if3;
250 
251 static struct dummy_api net_route_mcast_if_api_1 = {
252 	.iface_api.init = net_route_mcast_iface_init1,
253 	.send = iface_send,
254 };
255 
256 static struct dummy_api net_route_mcast_if_api_2 = {
257 	.iface_api.init = net_route_mcast_iface_init2,
258 	.send = iface_send,
259 };
260 
261 static struct dummy_api net_route_mcast_if_api_3 = {
262 	.iface_api.init = net_route_mcast_iface_init3,
263 	.send = iface_send,
264 };
265 
266 #define _ETH_L2_LAYER DUMMY_L2
267 #define _ETH_L2_CTX_TYPE NET_L2_GET_CTX_TYPE(DUMMY_L2)
268 
269 NET_DEVICE_INIT_INSTANCE(mcast_iface_1, "mcast_iface_1", iface_1,
270 			net_route_mcast_dev_init, NULL,
271 			&net_route_data_if1, NULL,
272 			CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
273 			&net_route_mcast_if_api_1, _ETH_L2_LAYER,
274 			_ETH_L2_CTX_TYPE, 127);
275 
276 NET_DEVICE_INIT_INSTANCE(mcast_iface_2, "mcast_iface_2", iface_2,
277 			net_route_mcast_dev_init, NULL,
278 			&net_route_data_if2, NULL,
279 			CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
280 			&net_route_mcast_if_api_2, _ETH_L2_LAYER,
281 			_ETH_L2_CTX_TYPE, 127);
282 
283 NET_DEVICE_INIT_INSTANCE(mcast_iface_3, "mcast_iface_3", iface_3,
284 			net_route_mcast_dev_init, NULL,
285 			&net_route_data_if3, NULL,
286 			CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
287 			&net_route_mcast_if_api_3, _ETH_L2_LAYER,
288 			_ETH_L2_CTX_TYPE, 127);
289 
setup_ipv6_udp(struct net_if * iface,struct in6_addr * src_addr,struct in6_addr * remote_addr,uint16_t src_port,uint16_t remote_port)290 static struct net_pkt *setup_ipv6_udp(struct net_if *iface,
291 				      struct in6_addr *src_addr,
292 				      struct in6_addr *remote_addr,
293 				      uint16_t src_port, uint16_t remote_port)
294 {
295 	static const char payload[] = "foobar";
296 	struct net_pkt *pkt;
297 	int res;
298 
299 	pkt = net_pkt_alloc_with_buffer(iface, strlen(payload), AF_INET6,
300 					IPPROTO_UDP, K_FOREVER);
301 	if (!pkt) {
302 		return NULL;
303 	}
304 
305 	net_pkt_set_ipv6_hop_limit(pkt, 2);
306 
307 	res = net_ipv6_create(pkt, src_addr, remote_addr);
308 	zassert_equal(0, res, "ipv6 create failed");
309 
310 	res = net_udp_create(pkt, htons(src_port), htons(remote_port));
311 	zassert_equal(0, res, "udp create failed");
312 
313 	res = net_pkt_write(pkt, (uint8_t *) payload, strlen(payload));
314 	zassert_equal(0, res, "pkt write failed");
315 
316 	net_pkt_cursor_init(pkt);
317 	net_ipv6_finalize(pkt, IPPROTO_UDP);
318 	net_pkt_cursor_init(pkt);
319 
320 	return pkt;
321 }
322 
test_route_mcast_init(void)323 static void test_route_mcast_init(void)
324 {
325 	zassert_not_null(iface_1, "Interface is NULL");
326 	zassert_not_null(iface_2, "Interface is NULL");
327 	zassert_not_null(iface_3, "Interface is NULL");
328 
329 	net_if_flag_set(iface_1, NET_IF_FORWARD_MULTICASTS);
330 	net_if_flag_set(iface_2, NET_IF_FORWARD_MULTICASTS);
331 	/* iface_3 should not forward multicasts */
332 }
333 
test_route_mcast_route_add(void)334 static void test_route_mcast_route_add(void)
335 {
336 	struct in6_addr nw_prefix_based_all_nodes;
337 	struct net_route_entry_mcast *entry;
338 
339 	entry = net_route_mcast_add(iface_1, &mcast_prefix_iflocal, 16);
340 	zassert_is_null(entry, "add iface local should fail");
341 
342 	entry = net_route_mcast_add(iface_1, &mcast_prefix_llocal, 16);
343 	zassert_is_null(entry, "add link local should fail");
344 
345 	test_mcast_routes[0] = net_route_mcast_add(iface_1,
346 				    &mcast_prefix_admin, 16);
347 	zassert_not_null(test_mcast_routes[0], "mcast route add failed");
348 
349 	test_mcast_routes[1] = net_route_mcast_add(iface_2,
350 					      &mcast_prefix_site_local, 16);
351 	zassert_not_null(test_mcast_routes[1], "mcast route add failed");
352 
353 	test_mcast_routes[2] = net_route_mcast_add(iface_1,
354 						      &mcast_prefix_orga, 16);
355 	zassert_not_null(test_mcast_routes[2], "mcast route add failed");
356 
357 	test_mcast_routes[3] = net_route_mcast_add(iface_2,
358 						      &mcast_prefix_global, 16);
359 	zassert_not_null(test_mcast_routes[3], "mcast route add failed");
360 
361 	/* check if route can be added
362 	 * if forwarding flag not set on iface
363 	 */
364 	test_mcast_routes[4] = net_route_mcast_add(iface_3,
365 			&mcast_prefix_global, 16);
366 	zassert_is_null(test_mcast_routes[4], "mcast route add should fail");
367 
368 	test_mcast_routes[4] = net_route_mcast_add(iface_1,
369 				&mcast_prefix_nw_based, 96);
370 	zassert_not_null(test_mcast_routes[4],
371 			"add for nw prefix based failed");
372 
373 	memcpy(&nw_prefix_based_all_nodes, &mcast_prefix_nw_based,
374 			sizeof(struct in6_addr));
375 	nw_prefix_based_all_nodes.s6_addr[15] = 0x01;
376 
377 	test_mcast_routes[5] = net_route_mcast_add(iface_2,
378 				&nw_prefix_based_all_nodes, 128);
379 	zassert_not_null(test_mcast_routes[5],
380 			"add for nw prefix based failed");
381 }
382 
mcast_foreach_cb(struct net_route_entry_mcast * entry,void * user_data)383 static void mcast_foreach_cb(struct net_route_entry_mcast *entry,
384 	     void *user_data)
385 {
386 	zassert_equal_ptr(user_data, &mcast_prefix_global,
387 						  "foreach failed, wrong user_data");
388 }
389 
test_route_mcast_foreach(void)390 static void test_route_mcast_foreach(void)
391 {
392 	int executed_first = net_route_mcast_foreach(mcast_foreach_cb,
393 		NULL, &mcast_prefix_global);
394 
395 	int executed_skip =  net_route_mcast_foreach(mcast_foreach_cb,
396 			&mcast_prefix_admin, &mcast_prefix_global);
397 
398 	zassert_true(executed_skip == (executed_first - 1),
399 			"mcast foreach skip did not skip");
400 }
401 
test_route_mcast_lookup(void)402 static void test_route_mcast_lookup(void)
403 {
404 	struct net_route_entry_mcast *route =
405 			net_route_mcast_lookup(&mcast_prefix_admin);
406 
407 	zassert_equal_ptr(test_mcast_routes[0], route,
408 				  "mcast lookup failed");
409 
410 	route = net_route_mcast_lookup(&mcast_prefix_site_local);
411 
412 	zassert_equal_ptr(test_mcast_routes[1], route,
413 					  "mcast lookup failed");
414 
415 	route = net_route_mcast_lookup(&mcast_prefix_global);
416 
417 	zassert_equal_ptr(test_mcast_routes[3], route,
418 						  "mcast lookup failed");
419 }
test_route_mcast_route_del(void)420 static void test_route_mcast_route_del(void)
421 {
422 	struct net_route_entry_mcast *route;
423 	bool success = net_route_mcast_del(test_mcast_routes[0]);
424 
425 	zassert_true(success, "failed to delete mcast route");
426 
427 	route = net_route_mcast_lookup(&mcast_prefix_admin);
428 	zassert_is_null(route, "lookup found deleted route");
429 
430 	success = net_route_mcast_del(test_mcast_routes[1]);
431 	zassert_true(success, "failed to delete mcast route");
432 
433 	route = net_route_mcast_lookup(&mcast_prefix_site_local);
434 	zassert_is_null(route, "lookup found deleted route");
435 
436 	success = net_route_mcast_del(test_mcast_routes[2]);
437 	zassert_true(success, "failed to delete mcast route");
438 
439 	success = net_route_mcast_del(test_mcast_routes[3]);
440 	zassert_true(success, "failed to delete mcast route");
441 
442 	success = net_route_mcast_del(test_mcast_routes[4]);
443 	zassert_true(success, "failed to delete mcast route");
444 
445 	success = net_route_mcast_del(test_mcast_routes[5]);
446 	zassert_true(success, "failed to delete mcast route");
447 }
448 
reset_counters(void)449 static void reset_counters(void)
450 {
451 	iface_1_forwarded = false;
452 	iface_2_forwarded = false;
453 	iface_3_forwarded = false;
454 	forwarding_counter = 0;
455 }
456 
test_route_mcast_scenario1(void)457 static void test_route_mcast_scenario1(void)
458 {
459 	/* scenario 1 site local:
460 	 * 1.	iface_1 receives site local
461 	 *		only iface_2 forwards
462 	 * 2.	iface_3 receives site_local
463 	 *		only iface_2 forwards
464 	 */
465 	reset_counters();
466 	memcpy(&active_scenario.src, &iface_1_addr, sizeof(struct in6_addr));
467 	active_scenario.src.s6_addr[15] = 0x02;
468 
469 	memcpy(&active_scenario.mcast, &mcast_prefix_site_local,
470 			sizeof(struct in6_addr));
471 	active_scenario.mcast.s6_addr[15] = 0x01;
472 
473 	struct net_pkt *pkt1 = setup_ipv6_udp(iface_1, &active_scenario.src,
474 				&active_scenario.mcast, 20015, 20001);
475 
476 	active_scenario.is_active = true;
477 	if (net_recv_data(iface_1, pkt1) < 0) {
478 		net_pkt_unref(pkt1);
479 		zassert_true(0, "failed to receive initial packet!");
480 	}
481 	k_sleep(WAIT_TIME);
482 	net_pkt_unref(pkt1);
483 
484 
485 	zassert_true(iface_2_forwarded, "iface_2 did not forward");
486 	zassert_false(iface_1_forwarded, "iface_1 forwarded");
487 	zassert_false(iface_3_forwarded, "iface_3 forwarded");
488 	zassert_equal(forwarding_counter, 1,
489 			"unexpected forwarded packet count");
490 
491 	reset_counters();
492 
493 	memcpy(&active_scenario.src, &iface_3_addr, sizeof(struct in6_addr));
494 	active_scenario.src.s6_addr[15] = 0x09;
495 
496 	struct net_pkt *pkt2 = setup_ipv6_udp(iface_3, &active_scenario.src,
497 			&active_scenario.mcast, 20015, 20001);
498 	if (net_recv_data(iface_3, pkt2) < 0) {
499 		net_pkt_unref(pkt2);
500 		zassert_true(0, "failed to receive initial packet!");
501 	}
502 	k_sleep(WAIT_TIME);
503 	net_pkt_unref(pkt2);
504 	active_scenario.is_active = false;
505 	zassert_true(iface_2_forwarded, "iface_2 did not forward");
506 	zassert_false(iface_1_forwarded, "iface_1 forwarded");
507 	zassert_false(iface_3_forwarded, "iface_3 forwarded");
508 	zassert_equal(forwarding_counter, 1,
509 			"unexpected forwarded packet count");
510 	reset_counters();
511 }
512 
test_route_mcast_scenario2(void)513 static void test_route_mcast_scenario2(void)
514 {
515 	/*
516 	 *  scenario 2 admin local:
517 	 *  1.	iface_1 receives
518 	 *		iface_2 must not forward due to missing routing entry.
519 	 *		iface_3 must not forward due to missing
520 	 *			routing entry and missing flag.
521 	 *		iface_1 must not forward because itself
522 	 *			received the packet!
523 	 *
524 	 *  2.	iface_3 receives
525 	 *		now iface_1 must forward due to routing entry
526 	 */
527 	reset_counters();
528 	memcpy(&active_scenario.src, &iface_1_addr, sizeof(struct in6_addr));
529 	active_scenario.src.s6_addr[15] = 0x08;
530 
531 	memcpy(&active_scenario.mcast, &mcast_prefix_admin,
532 			sizeof(struct in6_addr));
533 	active_scenario.mcast.s6_addr[15] = 0x01;
534 
535 	struct net_pkt *pkt = setup_ipv6_udp(iface_1, &active_scenario.src,
536 			&active_scenario.mcast, 215, 201);
537 
538 	active_scenario.is_active = true;
539 	if (net_recv_data(iface_1, pkt) < 0) {
540 		net_pkt_unref(pkt);
541 		zassert_true(0, "failed to receive initial packet!");
542 	}
543 	k_sleep(WAIT_TIME);
544 	net_pkt_unref(pkt);
545 
546 	zassert_false(iface_1_forwarded, "iface_1 forwarded");
547 	zassert_false(iface_2_forwarded, "iface_2 forwarded");
548 	zassert_false(iface_3_forwarded, "iface_3 forwarded");
549 	zassert_equal(forwarding_counter, 0, "wrong count forwarded packets");
550 
551 	reset_counters();
552 	memcpy(&active_scenario.src, &iface_3_addr, sizeof(struct in6_addr));
553 	active_scenario.src.s6_addr[15] = 0x08;
554 
555 	struct net_pkt *pkt2 = setup_ipv6_udp(iface_3, &active_scenario.src,
556 			&active_scenario.mcast, 215, 201);
557 	if (net_recv_data(iface_3, pkt2) < 0) {
558 		net_pkt_unref(pkt2);
559 		zassert_true(0, "failed to receive initial packet!");
560 	}
561 	k_sleep(WAIT_TIME);
562 	active_scenario.is_active = false;
563 	net_pkt_unref(pkt2);
564 
565 	zassert_true(iface_1_forwarded, "iface_1 did not forward");
566 	zassert_false(iface_2_forwarded, "iface_2 forwarded");
567 	zassert_false(iface_3_forwarded, "iface_3 forwarded");
568 	zassert_equal(forwarding_counter, 1, "wrong count forwarded packets");
569 }
570 
test_route_mcast_scenario3(void)571 static void test_route_mcast_scenario3(void)
572 {
573 	/*
574 	 * scenario 3: network prefix based forwarding
575 	 * 1.	iface 3 receives nw prefix based all nodes
576 	 *		iface 1 + 2 forwarding because all nodes group
577 	 * 2.	iface 3 receives nw prefix based custom group
578 	 *		only iface 1 forwards
579 	 *		iface 3 route is set to all nodes
580 	 * 3.	iface 3 receives all nodes group with different prefix
581 	 *		no iface forwards
582 	 */
583 	reset_counters();
584 	memcpy(&active_scenario.src, &iface_3_addr, sizeof(struct in6_addr));
585 	active_scenario.src.s6_addr[15] = 0x08;
586 
587 	memcpy(&active_scenario.mcast, &mcast_prefix_nw_based,
588 				sizeof(struct in6_addr));
589 	active_scenario.mcast.s6_addr[15] = 0x01;
590 
591 	struct net_pkt *pkt = setup_ipv6_udp(iface_3, &active_scenario.src,
592 				&active_scenario.mcast, 215, 201);
593 
594 	active_scenario.is_active = true;
595 	if (net_recv_data(iface_3, pkt) < 0) {
596 		net_pkt_unref(pkt);
597 		zassert_true(0, "failed to receive initial packet!");
598 	}
599 	k_sleep(WAIT_TIME);
600 	net_pkt_unref(pkt);
601 	active_scenario.is_active = false;
602 
603 	zassert_true(iface_1_forwarded, "iface_1 did not forward");
604 	zassert_true(iface_2_forwarded, "iface_2 did not forward");
605 	zassert_false(iface_3_forwarded, "iface_3 forwarded");
606 	zassert_equal(forwarding_counter, 2, "wrong count forwarded packets");
607 
608 	reset_counters();
609 	/* set to custom group id */
610 	active_scenario.mcast.s6_addr[15] = 0x0F;
611 	struct net_pkt *pkt2 = setup_ipv6_udp(iface_3, &active_scenario.src,
612 					&active_scenario.mcast, 215, 201);
613 
614 	active_scenario.is_active = true;
615 	if (net_recv_data(iface_3, pkt2) < 0) {
616 		net_pkt_unref(pkt2);
617 		zassert_true(0, "failed to receive initial packet!");
618 	}
619 	k_sleep(WAIT_TIME);
620 	net_pkt_unref(pkt2);
621 	active_scenario.is_active = false;
622 
623 	zassert_true(iface_1_forwarded, "iface_1 did not forward");
624 	zassert_false(iface_2_forwarded, "iface_2 forwarded");
625 	zassert_false(iface_3_forwarded, "iface_3 forwarded");
626 	zassert_equal(forwarding_counter, 1, "wrong count forwarded packets");
627 
628 	reset_counters();
629 
630 	/* set to all nodes but different prefix */
631 	active_scenario.mcast.s6_addr[11] = 0x0F;
632 	active_scenario.mcast.s6_addr[15] = 0x01;
633 	struct net_pkt *pkt3 = setup_ipv6_udp(iface_3, &active_scenario.src,
634 			&active_scenario.mcast, 215, 201);
635 
636 	active_scenario.is_active = true;
637 	if (net_recv_data(iface_3, pkt3) < 0) {
638 		net_pkt_unref(pkt3);
639 		zassert_true(0, "failed to receive initial packet!");
640 	}
641 	k_sleep(WAIT_TIME);
642 	net_pkt_unref(pkt3);
643 	active_scenario.is_active = false;
644 
645 	zassert_false(iface_1_forwarded, "iface_1 forwarded");
646 	zassert_false(iface_2_forwarded, "iface_2 forwarded");
647 	zassert_false(iface_3_forwarded, "iface_3 forwarded");
648 	zassert_equal(forwarding_counter, 0, "wrong count forwarded packets");
649 }
650 
651 /*test case main entry*/
ZTEST(route_mcast_test_suite,test_route_mcast)652 ZTEST(route_mcast_test_suite, test_route_mcast)
653 {
654 	test_route_mcast_init();
655 	test_route_mcast_route_add();
656 	test_route_mcast_foreach();
657 	test_route_mcast_scenario1();
658 	test_route_mcast_scenario2();
659 	test_route_mcast_scenario3();
660 	test_route_mcast_lookup();
661 	test_route_mcast_route_del();
662 }
663 ZTEST_SUITE(route_mcast_test_suite, NULL, NULL, NULL, NULL, NULL);
664