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