1 /*
2 * Copyright (c) 2023 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/types.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <zephyr/linker/sections.h>
13
14 #include <zephyr/ztest.h>
15
16 #include <zephyr/net/net_if.h>
17 #include <zephyr/net/dummy.h>
18 #include <zephyr/net/conn_mgr_monitor.h>
19 #include <zephyr/net/conn_mgr_connectivity.h>
20 #include "conn_mgr_private.h"
21 #include "test_ifaces.h"
22 #include <zephyr/net/net_ip.h>
23
24 #include <zephyr/logging/log.h>
25
26 /* Time to wait for NET_MGMT events to finish firing */
27 #define EVENT_WAIT_TIME_SHORT K_MSEC(10)
28 #define EVENT_WAIT_TIME_MEDIUM K_MSEC(100)
29 #define EVENT_WAIT_TIME K_MSEC(200)
30
31
32 /* Time to wait for IPv6 DAD-gated events to finish.
33 * Equivalent to EVENT_WAIT_TIME if DAD is dissabled.
34 */
35 #if defined(CONFIG_NET_IPV6_DAD)
36 #define DAD_WAIT_TIME K_MSEC(110)
37 #else
38 #define DAD_WAIT_TIME EVENT_WAIT_TIME
39 #endif
40
41 #define TEST_EXPECT_L4_CONNECTED BIT(NET_EVENT_L4_CMD_CONNECTED)
42 #define TEST_EXPECT_L4_DISCONNECTED BIT(NET_EVENT_L4_CMD_DISCONNECTED)
43 #define TEST_EXPECT_L4_IPV6_CONNECTED BIT(NET_EVENT_L4_CMD_IPV6_CONNECTED)
44 #define TEST_EXPECT_L4_IPV6_DISCONNECTED BIT(NET_EVENT_L4_CMD_IPV6_DISCONNECTED)
45 #define TEST_EXPECT_L4_IPV4_CONNECTED BIT(NET_EVENT_L4_CMD_IPV4_CONNECTED)
46 #define TEST_EXPECT_L4_IPV4_DISCONNECTED BIT(NET_EVENT_L4_CMD_IPV4_DISCONNECTED)
47
48 #define TEST_EXPECT_CLEAR(event) (global_stats.expected_events &= ~event)
49
50 /* IP addresses -- Two of each are needed because address sharing will cause address removal to
51 * fail silently (Address is only removed from one iface).
52 */
53 static struct in_addr test_ipv4_a = { { { 10, 0, 0, 1 } } };
54 static struct in_addr test_ipv4_b = { { { 10, 0, 0, 2 } } };
55 static struct in6_addr test_ipv6_a = { { {
56 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1
57 } } };
58 static struct in6_addr test_ipv6_b = { { {
59 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x2
60 } } };
61
62
63 /* Helpers */
reset_test_iface(struct net_if * iface)64 static void reset_test_iface(struct net_if *iface)
65 {
66 struct in6_addr *ll_ipv6;
67
68 if (net_if_is_admin_up(iface)) {
69 (void)net_if_down(iface);
70 }
71
72 net_if_ipv4_addr_rm(iface, &test_ipv4_a);
73 net_if_ipv4_addr_rm(iface, &test_ipv4_b);
74 net_if_ipv6_addr_rm(iface, &test_ipv6_a);
75 net_if_ipv6_addr_rm(iface, &test_ipv6_b);
76
77 /* DAD adds the link-local address automatically. Check for it, and remove it if present. */
78 ll_ipv6 = net_if_ipv6_get_ll(iface, NET_ADDR_ANY_STATE);
79 if (ll_ipv6) {
80 net_if_ipv6_addr_rm(iface, ll_ipv6);
81 }
82
83 conn_mgr_watch_iface(iface);
84 }
85
86 /* Thread-safe test statistics */
87 static K_MUTEX_DEFINE(stats_mutex);
88 static K_SEM_DEFINE(event_sem, 0, 1);
89
90 static struct test_stats {
91 /** IPv4 connectivity event counters */
92 int event_count_ipv4; /* any */
93 int conn_count_ipv4; /* connect */
94 int dconn_count_ipv4; /* disconnect */
95
96 /** IPv6 connectivity event counters */
97 int event_count_ipv6; /* any */
98 int conn_count_ipv6; /* connect */
99 int dconn_count_ipv6; /* disconnect */
100
101 /** General connectivity event counters */
102 int event_count_gen; /* any */
103 int conn_count_gen; /* connect */
104 int dconn_count_gen; /* disconnect */
105
106 /** The iface blamed for the last disconnect event */
107 struct net_if *dconn_iface_gen;
108 struct net_if *dconn_iface_ipv4;
109 struct net_if *dconn_iface_ipv6;
110
111 /** The iface blamed for the last connect event */
112 struct net_if *conn_iface_gen;
113 struct net_if *conn_iface_ipv4;
114 struct net_if *conn_iface_ipv6;
115
116 uint32_t expected_events;
117 } global_stats;
118
reset_stats(void)119 static void reset_stats(void)
120 {
121 k_mutex_lock(&stats_mutex, K_FOREVER);
122
123 global_stats.conn_count_gen = 0;
124 global_stats.dconn_count_gen = 0;
125 global_stats.event_count_gen = 0;
126 global_stats.dconn_iface_gen = NULL;
127 global_stats.conn_iface_gen = NULL;
128
129 global_stats.conn_count_ipv4 = 0;
130 global_stats.dconn_count_ipv4 = 0;
131 global_stats.event_count_ipv4 = 0;
132 global_stats.dconn_iface_ipv4 = NULL;
133 global_stats.conn_iface_ipv4 = NULL;
134
135 global_stats.conn_count_ipv6 = 0;
136 global_stats.dconn_count_ipv6 = 0;
137 global_stats.event_count_ipv6 = 0;
138 global_stats.dconn_iface_ipv6 = NULL;
139 global_stats.conn_iface_ipv6 = NULL;
140
141 global_stats.expected_events = 0;
142
143 k_mutex_unlock(&stats_mutex);
144 }
145
146 /**
147 * @brief Copy and then reset global test stats.
148 *
149 * @return struct test_stats -- The copy of the global test stats struct before it was reset
150 */
get_reset_stats(void)151 static struct test_stats get_reset_stats(void)
152 {
153 struct test_stats copy;
154
155 k_mutex_lock(&stats_mutex, K_FOREVER);
156 copy = global_stats;
157 reset_stats();
158 k_mutex_unlock(&stats_mutex);
159 return copy;
160 }
161
162 /* Callback hooks */
163 struct net_mgmt_event_callback l4_callback;
164
l4_handler(struct net_mgmt_event_callback * cb,uint32_t event,struct net_if * iface)165 void l4_handler(struct net_mgmt_event_callback *cb, uint32_t event, struct net_if *iface)
166 {
167 if (event == NET_EVENT_L4_CONNECTED) {
168 k_mutex_lock(&stats_mutex, K_FOREVER);
169 global_stats.conn_count_gen += 1;
170 global_stats.event_count_gen += 1;
171 global_stats.conn_iface_gen = iface;
172 TEST_EXPECT_CLEAR(TEST_EXPECT_L4_CONNECTED);
173 k_mutex_unlock(&stats_mutex);
174 } else if (event == NET_EVENT_L4_DISCONNECTED) {
175 k_mutex_lock(&stats_mutex, K_FOREVER);
176 global_stats.dconn_count_gen += 1;
177 global_stats.event_count_gen += 1;
178 global_stats.dconn_iface_gen = iface;
179 TEST_EXPECT_CLEAR(TEST_EXPECT_L4_DISCONNECTED);
180 k_mutex_unlock(&stats_mutex);
181 }
182
183 if (global_stats.expected_events == 0) {
184 k_sem_give(&event_sem);
185 }
186 }
187
188 struct net_mgmt_event_callback conn_callback;
189
conn_handler(struct net_mgmt_event_callback * cb,uint32_t event,struct net_if * iface)190 void conn_handler(struct net_mgmt_event_callback *cb, uint32_t event, struct net_if *iface)
191 {
192 if (event == NET_EVENT_L4_IPV6_CONNECTED) {
193 k_mutex_lock(&stats_mutex, K_FOREVER);
194 global_stats.conn_count_ipv6 += 1;
195 global_stats.event_count_ipv6 += 1;
196 global_stats.conn_iface_ipv6 = iface;
197 TEST_EXPECT_CLEAR(TEST_EXPECT_L4_IPV6_CONNECTED);
198 k_mutex_unlock(&stats_mutex);
199 } else if (event == NET_EVENT_L4_IPV6_DISCONNECTED) {
200 k_mutex_lock(&stats_mutex, K_FOREVER);
201 global_stats.dconn_count_ipv6 += 1;
202 global_stats.event_count_ipv6 += 1;
203 global_stats.dconn_iface_ipv6 = iface;
204 TEST_EXPECT_CLEAR(TEST_EXPECT_L4_IPV6_DISCONNECTED);
205 k_mutex_unlock(&stats_mutex);
206 } else if (event == NET_EVENT_L4_IPV4_CONNECTED) {
207 k_mutex_lock(&stats_mutex, K_FOREVER);
208 global_stats.conn_count_ipv4 += 1;
209 global_stats.event_count_ipv4 += 1;
210 global_stats.conn_iface_ipv4 = iface;
211 TEST_EXPECT_CLEAR(TEST_EXPECT_L4_IPV4_CONNECTED);
212 k_mutex_unlock(&stats_mutex);
213 } else if (event == NET_EVENT_L4_IPV4_DISCONNECTED) {
214 k_mutex_lock(&stats_mutex, K_FOREVER);
215 global_stats.dconn_count_ipv4 += 1;
216 global_stats.event_count_ipv4 += 1;
217 global_stats.dconn_iface_ipv4 = iface;
218 TEST_EXPECT_CLEAR(TEST_EXPECT_L4_IPV4_DISCONNECTED);
219 k_mutex_unlock(&stats_mutex);
220 }
221
222 if (global_stats.expected_events == 0) {
223 k_sem_give(&event_sem);
224 }
225 }
226
wait_for_events(uint32_t event_mask,k_timeout_t timeout)227 static void wait_for_events(uint32_t event_mask, k_timeout_t timeout)
228 {
229 k_mutex_lock(&stats_mutex, K_FOREVER);
230 k_sem_reset(&event_sem);
231 global_stats.expected_events = event_mask;
232 k_mutex_unlock(&stats_mutex);
233
234 (void)k_sem_take(&event_sem, timeout);
235
236 /* Add small extra sleep to give any unexpected events to show up. */
237 k_sleep(EVENT_WAIT_TIME_SHORT);
238 }
239
240 /* Test suite shared functions & routines */
241
conn_mgr_setup(void)242 static void *conn_mgr_setup(void)
243 {
244 net_mgmt_init_event_callback(
245 &l4_callback, l4_handler, NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED
246 );
247 net_mgmt_add_event_callback(&l4_callback);
248
249 net_mgmt_init_event_callback(
250 &conn_callback, conn_handler,
251 NET_EVENT_L4_IPV6_CONNECTED | NET_EVENT_L4_IPV6_DISCONNECTED |
252 NET_EVENT_L4_IPV4_CONNECTED | NET_EVENT_L4_IPV4_DISCONNECTED
253 );
254 net_mgmt_add_event_callback(&conn_callback);
255 return NULL;
256 }
257
258
conn_mgr_before(void * data)259 static void conn_mgr_before(void *data)
260 {
261 ARG_UNUSED(data);
262
263 reset_test_iface(if_simp_a);
264 reset_test_iface(if_simp_b);
265 reset_test_iface(if_conn_a);
266 reset_test_iface(if_conn_b);
267
268 /* Allow any triggered events to shake out */
269 k_sleep(K_MSEC(50));
270
271 reset_stats();
272 }
273
274 /**
275 * @brief Cycles two ifaces through several transitions from readiness to unreadiness.
276 *
277 * Ifaces are assigned a single IPv4 address at the start, and cycled through oper-states, since
278 * the other manners in which an iface can become L4-ready are covered by cycle_iface_pre_ready
279 *
280 * It is not necessary to cover all possible state transitions, only half of them, since
281 * this will be called twice by the test suites for each combination of iface type (except
282 * combinations where both ifaces are of the same type).
283 */
284
cycle_ready_ifaces(struct net_if * ifa,struct net_if * ifb)285 static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb)
286 {
287 struct test_stats stats;
288
289 /* Add IPv4 addresses */
290 net_if_ipv4_addr_add(ifa, &test_ipv4_a, NET_ADDR_MANUAL, 0);
291 net_if_ipv4_addr_add(ifb, &test_ipv4_b, NET_ADDR_MANUAL, 0);
292
293 /* Expect no events */
294 k_sleep(EVENT_WAIT_TIME_SHORT);
295 stats = get_reset_stats();
296 zassert_equal(stats.event_count_gen, 0,
297 "No events should be fired if connectivity availability did not change.");
298
299 /* Take A up */
300 zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa.");
301
302 /* Expect connectivity gained */
303 wait_for_events(TEST_EXPECT_L4_CONNECTED, EVENT_WAIT_TIME);
304 stats = get_reset_stats();
305 zassert_equal(stats.conn_count_gen, 1,
306 "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
307 zassert_equal(stats.event_count_gen, 1,
308 "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
309 zassert_equal(stats.conn_iface_gen, ifa, "ifa should be blamed.");
310
311 /* Take B up */
312 zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb.");
313
314 /* Expect no events */
315 k_sleep(EVENT_WAIT_TIME_SHORT);
316 stats = get_reset_stats();
317 zassert_equal(stats.event_count_gen, 0,
318 "No events should be fired if connectivity availability did not change.");
319
320 /* Take A down */
321 zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa.");
322
323 /* Expect no events */
324 k_sleep(EVENT_WAIT_TIME_SHORT);
325 stats = get_reset_stats();
326 zassert_equal(stats.event_count_gen, 0,
327 "No events should be fired if connectivity availability did not change.");
328
329 /* Take B down */
330 zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb.");
331
332 /* Expect connectivity loss */
333 wait_for_events(TEST_EXPECT_L4_DISCONNECTED, EVENT_WAIT_TIME);
334 stats = get_reset_stats();
335 zassert_equal(stats.dconn_count_gen, 1,
336 "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost.");
337 zassert_equal(stats.event_count_gen, 1,
338 "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost.");
339 zassert_equal(stats.dconn_iface_gen, ifb, "ifb should be blamed.");
340 }
341
342 /**
343 * @brief Ignores and then toggles ifb's readiness several times, ensuring no events are fired.
344 *
345 * At several points, change the readiness state of ifa and ensure events are fired.
346 *
347 * Steps which bring ifa or ifb online wait for the DAD delay to allow IPv6 events to finish.
348 * For test builds that have DAD disabled, this is equivalent to the usual event wait time.
349 *
350 * @param ifa
351 * @param ifb
352 */
cycle_ignored_iface(struct net_if * ifa,struct net_if * ifb)353 static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb)
354 {
355 struct test_stats stats;
356 printk("cycle_ignored_iface\n");
357
358 /* Ignore B */
359 conn_mgr_ignore_iface(ifb);
360
361 /* Add IPv4 and IPv6 addresses so that all possible event types are fired. */
362 net_if_ipv4_addr_add(ifa, &test_ipv4_a, NET_ADDR_MANUAL, 0);
363 net_if_ipv4_addr_add(ifb, &test_ipv4_b, NET_ADDR_MANUAL, 0);
364 net_if_ipv6_addr_add(ifa, &test_ipv6_a, NET_ADDR_MANUAL, 0);
365 net_if_ipv6_addr_add(ifb, &test_ipv6_b, NET_ADDR_MANUAL, 0);
366
367 /* Set one: Change A state between B state toggles */
368
369 /* Take B up */
370 zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb.");
371
372 /* Expect no events.
373 * Wait for the DAD delay since IPv6 connected events might be delayed by this amount.
374 */
375 printk("Expect no events.\n");
376 k_sleep(DAD_WAIT_TIME);
377 stats = get_reset_stats();
378 zassert_equal(stats.event_count_gen, 0,
379 "No events should be fired if connectivity availability did not change.");
380 zassert_equal(stats.event_count_ipv4, 0,
381 "No events should be fired if connectivity availability did not change.");
382 zassert_equal(stats.event_count_ipv6, 0,
383 "No events should be fired if connectivity availability did not change.");
384
385 /* Take B down */
386 zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb.");
387
388 /* Expect no events */
389 k_sleep(EVENT_WAIT_TIME_SHORT);
390 stats = get_reset_stats();
391 zassert_equal(stats.event_count_gen, 0,
392 "No events should be fired if connectivity availability did not change.");
393 zassert_equal(stats.event_count_ipv4, 0,
394 "No events should be fired if connectivity availability did not change.");
395 zassert_equal(stats.event_count_ipv6, 0,
396 "No events should be fired if connectivity availability did not change.");
397
398 /* Take A up */
399 zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa.");
400
401 /* Expect connectivity gained */
402 wait_for_events(TEST_EXPECT_L4_CONNECTED |
403 TEST_EXPECT_L4_IPV4_CONNECTED |
404 TEST_EXPECT_L4_IPV6_CONNECTED,
405 EVENT_WAIT_TIME);
406 stats = get_reset_stats();
407 zassert_equal(stats.conn_count_gen, 1,
408 "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
409 zassert_equal(stats.event_count_gen, 1,
410 "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
411 zassert_equal(stats.conn_count_ipv6, 1,
412 "NET_EVENT_L4_IPV6_CONNECTED should be fired when connectivity is gained.");
413 zassert_equal(stats.event_count_ipv6, 1,
414 "Only NET_EVENT_L4_IPV6_CONNECTED should be fired when connectivity is gained.");
415 zassert_equal(stats.conn_count_ipv4, 1,
416 "NET_EVENT_L4_IPV4_CONNECTED should be fired when connectivity is gained.");
417 zassert_equal(stats.event_count_ipv4, 1,
418 "Only NET_EVENT_L4_IPV4_CONNECTED should be fired when connectivity is gained.");
419 zassert_equal(stats.conn_iface_gen, ifa, "ifa should be blamed.");
420 zassert_equal(stats.conn_iface_ipv4, ifa, "ifa should be blamed.");
421 zassert_equal(stats.conn_iface_ipv6, ifa, "ifa should be blamed.");
422
423 /* Take B up */
424 zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb.");
425
426 /* Expect no events */
427 k_sleep(DAD_WAIT_TIME);
428 stats = get_reset_stats();
429 zassert_equal(stats.event_count_gen, 0,
430 "No events should be fired if connectivity availability did not change.");
431 zassert_equal(stats.event_count_ipv4, 0,
432 "No events should be fired if connectivity availability did not change.");
433 zassert_equal(stats.event_count_ipv6, 0,
434 "No events should be fired if connectivity availability did not change.");
435
436 /* Take B down */
437 zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb.");
438
439 /* Expect no events */
440 k_sleep(EVENT_WAIT_TIME_SHORT);
441 stats = get_reset_stats();
442 zassert_equal(stats.event_count_gen, 0,
443 "No events should be fired if connectivity availability did not change.");
444 zassert_equal(stats.event_count_ipv4, 0,
445 "No events should be fired if connectivity availability did not change.");
446 zassert_equal(stats.event_count_ipv6, 0,
447 "No events should be fired if connectivity availability did not change.");
448
449 /* Take A down */
450 zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa.");
451
452 /* Expect connectivity lost */
453 wait_for_events(TEST_EXPECT_L4_DISCONNECTED |
454 TEST_EXPECT_L4_IPV4_DISCONNECTED |
455 TEST_EXPECT_L4_IPV6_DISCONNECTED,
456 EVENT_WAIT_TIME);
457 stats = get_reset_stats();
458 zassert_equal(stats.dconn_count_gen, 1,
459 "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost.");
460 zassert_equal(stats.event_count_gen, 1,
461 "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost.");
462 zassert_equal(stats.dconn_count_ipv6, 1,
463 "NET_EVENT_L4_IPV6_DISCONNECTED should be fired when connectivity is lost.");
464 zassert_equal(stats.event_count_ipv6, 1,
465 "Only NET_EVENT_L4_IPV6_DISCONNECTED should be fired when connectivity is lost.");
466 zassert_equal(stats.dconn_count_ipv4, 1,
467 "NET_EVENT_L4_IPV4_DISCONNECTED should be fired when connectivity is lost.");
468 zassert_equal(stats.event_count_ipv4, 1,
469 "Only NET_EVENT_L4_IPV4_DISCONNECTED should be fired when connectivity is lost.");
470 zassert_equal(stats.dconn_iface_gen, ifa, "ifa should be blamed.");
471 zassert_equal(stats.dconn_iface_ipv4, ifa, "ifa should be blamed.");
472 zassert_equal(stats.dconn_iface_ipv6, ifa, "ifa should be blamed.");
473
474
475 /* Set two: Change A state during B state toggles */
476
477 /* Take B up */
478 zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb.");
479
480 /* Expect no events */
481 k_sleep(DAD_WAIT_TIME);
482 stats = get_reset_stats();
483 zassert_equal(stats.event_count_gen, 0,
484 "No events should be fired if connectivity availability did not change.");
485 zassert_equal(stats.event_count_ipv4, 0,
486 "No events should be fired if connectivity availability did not change.");
487 zassert_equal(stats.event_count_ipv6, 0,
488 "No events should be fired if connectivity availability did not change.");
489
490 /* Take A up */
491 zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa.");
492
493 /* Expect connectivity gained */
494 wait_for_events(TEST_EXPECT_L4_CONNECTED |
495 TEST_EXPECT_L4_IPV4_CONNECTED |
496 TEST_EXPECT_L4_IPV6_CONNECTED,
497 EVENT_WAIT_TIME);
498 stats = get_reset_stats();
499 zassert_equal(stats.conn_count_gen, 1,
500 "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
501 zassert_equal(stats.event_count_gen, 1,
502 "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
503 zassert_equal(stats.conn_count_ipv6, 1,
504 "NET_EVENT_L4_IPV6_CONNECTED should be fired when connectivity is gained.");
505 zassert_equal(stats.event_count_ipv6, 1,
506 "Only NET_EVENT_L4_IPV6_CONNECTED should be fired when connectivity is gained.");
507 zassert_equal(stats.conn_count_ipv4, 1,
508 "NET_EVENT_L4_IPV4_CONNECTED should be fired when connectivity is gained.");
509 zassert_equal(stats.event_count_ipv4, 1,
510 "Only NET_EVENT_L4_IPV4_CONNECTED should be fired when connectivity is gained.");
511 zassert_equal(stats.conn_iface_gen, ifa, "ifa should be blamed.");
512 zassert_equal(stats.conn_iface_ipv4, ifa, "ifa should be blamed.");
513 zassert_equal(stats.conn_iface_ipv6, ifa, "ifa should be blamed.");
514
515 /* Take B down */
516 zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb.");
517
518 /* Expect no events */
519 k_sleep(EVENT_WAIT_TIME_SHORT);
520 stats = get_reset_stats();
521 zassert_equal(stats.event_count_gen, 0,
522 "No events should be fired if connectivity availability did not change.");
523 zassert_equal(stats.event_count_ipv4, 0,
524 "No events should be fired if connectivity availability did not change.");
525 zassert_equal(stats.event_count_ipv6, 0,
526 "No events should be fired if connectivity availability did not change.");
527
528
529 /* Take B up */
530 zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb.");
531
532 /* Expect no events */
533 k_sleep(DAD_WAIT_TIME);
534 stats = get_reset_stats();
535 zassert_equal(stats.event_count_gen, 0,
536 "No events should be fired if connectivity availability did not change.");
537 zassert_equal(stats.event_count_ipv4, 0,
538 "No events should be fired if connectivity availability did not change.");
539 zassert_equal(stats.event_count_ipv6, 0,
540 "No events should be fired if connectivity availability did not change.");
541
542 /* Take A down */
543 zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa.");
544
545 /* Expect connectivity lost */
546 wait_for_events(TEST_EXPECT_L4_DISCONNECTED |
547 TEST_EXPECT_L4_IPV4_DISCONNECTED |
548 TEST_EXPECT_L4_IPV6_DISCONNECTED,
549 EVENT_WAIT_TIME);
550 stats = get_reset_stats();
551 zassert_equal(stats.dconn_count_gen, 1,
552 "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost.");
553 zassert_equal(stats.event_count_gen, 1,
554 "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost.");
555 zassert_equal(stats.dconn_count_ipv6, 1,
556 "NET_EVENT_L4_IPV6_DISCONNECTED should be fired when connectivity is lost.");
557 zassert_equal(stats.event_count_ipv6, 1,
558 "Only NET_EVENT_L4_IPV6_DISCONNECTED should be fired when connectivity is lost.");
559 zassert_equal(stats.dconn_count_ipv4, 1,
560 "NET_EVENT_L4_IPV4_DISCONNECTED should be fired when connectivity is lost.");
561 zassert_equal(stats.event_count_ipv4, 1,
562 "Only NET_EVENT_L4_IPV4_DISCONNECTED should be fired when connectivity is lost.");
563 zassert_equal(stats.dconn_iface_gen, ifa, "ifa should be blamed.");
564 zassert_equal(stats.dconn_iface_ipv4, ifa, "ifa should be blamed.");
565 zassert_equal(stats.dconn_iface_ipv6, ifa, "ifa should be blamed.");
566
567 /* Take B down */
568 zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb.");
569
570 /* Expect no events */
571 k_sleep(EVENT_WAIT_TIME_SHORT);
572 stats = get_reset_stats();
573 zassert_equal(stats.event_count_gen, 0,
574 "No events should be fired if connectivity availability did not change.");
575 zassert_equal(stats.event_count_ipv4, 0,
576 "No events should be fired if connectivity availability did not change.");
577 zassert_equal(stats.event_count_ipv6, 0,
578 "No events should be fired if connectivity availability did not change.");
579 }
580
581 enum ip_order {
582 IPV4_FIRST,
583 IPV6_FIRST
584 };
585
586 /**
587 * @brief Cycles a single iface through all possible ready and pre-ready states,
588 * ensuring the correct events are observed and generated by conn_mgr_monitor.
589 *
590 * Ifaces can be in one of four states that are relevant to L4 readiness:
591 * 00: oper-down, no IPs associated (unready state)
592 * 01: Has IP, is oper-down (semi-ready state)
593 * 10: Is oper-up, has no IP (semi-ready state)
594 * 11: Has IP and is oper-up (ready state)
595 *
596 * In total there are eight possible state transitions:
597 *
598 * (00 -> 10): Gain oper-up from unready state
599 * (10 -> 11): Gain IP from semi-ready state
600 * (11 -> 10): Lose IP from ready state
601 * (10 -> 00): Lose oper-up from semi-ready state
602 * (00 -> 01): Gain IP from unready state
603 * (01 -> 11): Gain Oper-up from semi-ready state
604 * (11 -> 01): Lose oper-up from ready state
605 * (01 -> 00): Lose IP from semi-ready state
606 *
607 * We test these state transitions in that order.
608 *
609 * This is slightly complicated by the fact that ifaces can be assigned multiple IPs, and multiple
610 * types of IPs. Whenever IPs are assigned or removed, two of them, an IPv6 and IPv4 address is
611 * added or removed.
612 *
613 * @param iface
614 * @param ifa_ipm
615 */
cycle_iface_states(struct net_if * iface,enum ip_order ifa_ipm)616 static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm)
617 {
618 struct test_stats stats;
619
620 /* (00 -> 10): Gain oper-up from unready state */
621
622 /* Take iface up */
623 zassert_equal(net_if_up(iface), 0, "net_if_up should succeed.");
624
625 /* Verify that no events have been fired yet */
626 k_sleep(EVENT_WAIT_TIME_MEDIUM);
627 stats = get_reset_stats();
628 zassert_equal(stats.event_count_gen, 0,
629 "No events should be fired if connectivity availability did not change.");
630
631 /* (10 -> 11): Gain IP from semi-ready state */
632 switch (ifa_ipm) {
633 case IPV4_FIRST:
634 /* Add IPv4 */
635 net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0);
636
637 /* Verify correct events */
638 wait_for_events(TEST_EXPECT_L4_CONNECTED |
639 TEST_EXPECT_L4_IPV4_CONNECTED,
640 EVENT_WAIT_TIME);
641 stats = get_reset_stats();
642 zassert_equal(stats.conn_count_gen, 1,
643 "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
644 zassert_equal(stats.event_count_gen, 1,
645 "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
646 zassert_equal(stats.conn_count_ipv4, 1,
647 "NET_EVENT_L4_IPV4_CONNECTED should be fired when IPv4 "
648 "connectivity is gained.");
649 zassert_equal(stats.event_count_ipv4, 1,
650 "Only NET_EVENT_L4_IPV4_CONNECTED should be fired when IPv4 "
651 "connectivity is gained.");
652 zassert_equal(stats.event_count_ipv6, 0,
653 "No IPv6 events should be fired when IPv4 connectivity is gained.");
654 zassert_equal(stats.conn_iface_gen, iface, "The test iface should be blamed.");
655 zassert_equal(stats.conn_iface_ipv4, iface, "The test iface should be blamed.");
656
657 /* Add IPv6 */
658 net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0);
659
660 /* Verify only IPv6 events */
661 wait_for_events(TEST_EXPECT_L4_IPV6_CONNECTED, EVENT_WAIT_TIME);
662 stats = get_reset_stats();
663 zassert_equal(stats.event_count_gen, 0,
664 "No events should be fired if connectivity availability did not change.");
665 zassert_equal(stats.conn_count_ipv6, 1,
666 "NET_EVENT_L4_IPV6_CONNECTED should be fired when IPv6 "
667 "connectivity is gained.");
668 zassert_equal(stats.event_count_ipv6, 1,
669 "Only NET_EVENT_L4_IPV6_CONNECTED should be fired when IPv6 "
670 "connectivity is gained.");
671 zassert_equal(stats.event_count_ipv4, 0,
672 "No IPv4 events should be fired when IPv6 connectivity is gained.");
673 zassert_equal(stats.conn_iface_ipv6, iface, "The test iface should be blamed.");
674
675 break;
676 case IPV6_FIRST:
677 /* Add IPv6 */
678 net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0);
679
680 /* Verify correct events */
681 wait_for_events(TEST_EXPECT_L4_CONNECTED |
682 TEST_EXPECT_L4_IPV6_CONNECTED,
683 EVENT_WAIT_TIME);
684 stats = get_reset_stats();
685 zassert_equal(stats.conn_count_gen, 1,
686 "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
687 zassert_equal(stats.event_count_gen, 1,
688 "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
689 zassert_equal(stats.conn_count_ipv6, 1,
690 "NET_EVENT_L4_IPV6_CONNECTED should be fired when IPv6 "
691 "connectivity is gained.");
692 zassert_equal(stats.event_count_ipv6, 1,
693 "Only NET_EVENT_L4_IPV6_CONNECTED should be fired when IPv6 "
694 "connectivity is gained.");
695 zassert_equal(stats.event_count_ipv4, 0,
696 "No IPv4 events should be fired when IPv6 connectivity is gained.");
697 zassert_equal(stats.conn_iface_gen, iface, "The test iface should be blamed.");
698 zassert_equal(stats.conn_iface_ipv6, iface, "The test iface should be blamed.");
699
700 /* Add IPv4 */
701 net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0);
702
703 /* Verify only IPv4 events */
704 wait_for_events(TEST_EXPECT_L4_IPV4_CONNECTED, EVENT_WAIT_TIME);
705 stats = get_reset_stats();
706 zassert_equal(stats.event_count_gen, 0,
707 "No events should be fired if connectivity availability did not change.");
708 zassert_equal(stats.conn_count_ipv4, 1,
709 "NET_EVENT_L4_IPV4_CONNECTED should be fired when IPv4 "
710 "connectivity is gained.");
711 zassert_equal(stats.event_count_ipv4, 1,
712 "Only NET_EVENT_L4_IPV4_CONNECTED should be fired when IPv4 "
713 "connectivity is gained.");
714 zassert_equal(stats.event_count_ipv6, 0,
715 "No IPv6 events should be fired when IPv4 connectivity is gained.");
716 zassert_equal(stats.conn_iface_ipv4, iface, "The test iface should be blamed.");
717 break;
718 }
719
720 /* (11 -> 10): Lose IP from ready state */
721 switch (ifa_ipm) {
722 case IPV4_FIRST:
723 /* Remove IPv4 */
724 zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a),
725 "IPv4 removal should succeed.");
726
727 /* Verify only IPv4 events */
728 wait_for_events(TEST_EXPECT_L4_IPV4_DISCONNECTED, EVENT_WAIT_TIME);
729 stats = get_reset_stats();
730 zassert_equal(stats.event_count_gen, 0,
731 "No events should be fired if connectivity availability did not change.");
732 zassert_equal(stats.dconn_count_ipv4, 1,
733 "NET_EVENT_L4_IPV4_DISCONNECTED should be fired when IPv4 "
734 "connectivity is lost.");
735 zassert_equal(stats.event_count_ipv4, 1,
736 "Only NET_EVENT_L4_IPV4_DISCONNECTED should be fired when IPv4 "
737 "connectivity is lost.");
738 zassert_equal(stats.event_count_ipv6, 0,
739 "No IPv6 events should be fired when IPv4 connectivity is gained.");
740 zassert_equal(stats.dconn_iface_ipv4, iface, "The test iface should be blamed.");
741
742 /* Remove IPv6 */
743 zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a),
744 "IPv6 removal should succeed.");
745
746 /* Verify correct events */
747 wait_for_events(TEST_EXPECT_L4_DISCONNECTED |
748 TEST_EXPECT_L4_IPV6_DISCONNECTED,
749 EVENT_WAIT_TIME);
750 stats = get_reset_stats();
751 zassert_equal(stats.dconn_count_gen, 1,
752 "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost.");
753 zassert_equal(stats.event_count_gen, 1,
754 "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity "
755 "is lost.");
756 zassert_equal(stats.dconn_count_ipv6, 1,
757 "NET_EVENT_L4_IPV6_DISCONNECTED should be fired when IPv6 "
758 "connectivity is lost.");
759 zassert_equal(stats.event_count_ipv6, 1,
760 "Only NET_EVENT_L4_IPV6_DISCONNECTED should be fired when IPv6 "
761 "connectivity is lost.");
762 zassert_equal(stats.event_count_ipv4, 0,
763 "No IPv4 events should be fired when IPv6 connectivity is gained.");
764
765 zassert_equal(stats.dconn_iface_gen, iface, "The test iface should be blamed.");
766 zassert_equal(stats.dconn_iface_ipv6, iface, "The test iface should be blamed.");
767
768 break;
769 case IPV6_FIRST:
770 /* Remove IPv6 */
771 zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a),
772 "IPv6 removal should succeed.");
773
774 /* Verify only IPv6 events */
775 wait_for_events(TEST_EXPECT_L4_IPV6_DISCONNECTED, EVENT_WAIT_TIME);
776 stats = get_reset_stats();
777 zassert_equal(stats.event_count_gen, 0,
778 "No events should be fired if connectivity availability did not change.");
779 zassert_equal(stats.dconn_count_ipv6, 1,
780 "NET_EVENT_L4_IPV6_DISCONNECTED should be fired when IPv6 "
781 "connectivity is lost.");
782 zassert_equal(stats.event_count_ipv6, 1,
783 "Only NET_EVENT_L4_IPV6_DISCONNECTED should be fired when IPv6 "
784 "connectivity is lost.");
785 zassert_equal(stats.event_count_ipv4, 0,
786 "No IPv4 events should be fired when IPv6 connectivity is gained.");
787 zassert_equal(stats.dconn_iface_ipv6, iface, "The test iface should be blamed.");
788
789 /* Remove IPv4 */
790 zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a),
791 "IPv4 removal should succeed.");
792
793 /* Verify correct events */
794 wait_for_events(TEST_EXPECT_L4_DISCONNECTED |
795 TEST_EXPECT_L4_IPV4_DISCONNECTED,
796 EVENT_WAIT_TIME);
797 stats = get_reset_stats();
798 zassert_equal(stats.dconn_count_gen, 1,
799 "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost.");
800 zassert_equal(stats.event_count_gen, 1,
801 "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity "
802 "is lost.");
803 zassert_equal(stats.dconn_count_ipv4, 1,
804 "NET_EVENT_L4_IPV4_DISCONNECTED should be fired when IPv4 "
805 "connectivity is lost.");
806 zassert_equal(stats.event_count_ipv4, 1,
807 "Only NET_EVENT_L4_IPV4_DISCONNECTED should be fired when IPv4 "
808 "connectivity is lost.");
809 zassert_equal(stats.event_count_ipv6, 0,
810 "No IPv6 events should be fired when IPv4 connectivity is gained.");
811 zassert_equal(stats.dconn_iface_gen, iface, "The test iface should be blamed.");
812 zassert_equal(stats.dconn_iface_ipv4, iface, "The test iface should be blamed.");
813
814 break;
815 }
816
817 /* (10 -> 00): Lose oper-up from semi-ready state */
818
819 /* Take iface down */
820 zassert_equal(net_if_down(iface), 0, "net_if_down should succeed.");
821
822 /* Verify there are no events fired */
823 k_sleep(EVENT_WAIT_TIME_SHORT);
824 stats = get_reset_stats();
825 zassert_equal(stats.event_count_gen, 0,
826 "No events should be fired if connectivity availability did not change.");
827 zassert_equal(stats.event_count_ipv4, 0,
828 "No events should be fired if connectivity availability did not change.");
829 zassert_equal(stats.event_count_ipv6, 0,
830 "No events should be fired if connectivity availability did not change.");
831
832 /* (00 -> 01): Gain IP from unready state */
833
834 /* Add IP addresses to iface */
835 switch (ifa_ipm) {
836 case IPV4_FIRST:
837 /* Add IPv4 and IPv6 */
838 net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0);
839 net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0);
840 k_sleep(DAD_WAIT_TIME);
841 break;
842 case IPV6_FIRST:
843 /* Add IPv6 then IPv4 */
844 net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0);
845 k_sleep(DAD_WAIT_TIME);
846 net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0);
847 break;
848 }
849
850 /* Verify that no events are fired */
851 k_sleep(EVENT_WAIT_TIME_SHORT);
852 stats = get_reset_stats();
853 zassert_equal(stats.event_count_gen, 0,
854 "No events should be fired if connectivity availability did not change.");
855 zassert_equal(stats.event_count_ipv4, 0,
856 "No events should be fired if connectivity availability did not change.");
857 zassert_equal(stats.event_count_ipv6, 0,
858 "No events should be fired if connectivity availability did not change.");
859
860 /* (01 -> 11): Gain Oper-up from semi-ready state */
861
862 /* Take iface up */
863 zassert_equal(net_if_up(iface), 0, "net_if_up should succeed.");
864
865 /* Verify events are fired */
866 wait_for_events(TEST_EXPECT_L4_CONNECTED |
867 TEST_EXPECT_L4_IPV4_CONNECTED |
868 TEST_EXPECT_L4_IPV6_CONNECTED,
869 EVENT_WAIT_TIME);
870 stats = get_reset_stats();
871 zassert_equal(stats.conn_count_gen, 1,
872 "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
873 zassert_equal(stats.event_count_gen, 1,
874 "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained.");
875 zassert_equal(stats.conn_count_ipv4, 1,
876 "NET_EVENT_L4_IPV4_CONNECTED should be fired when IPv4 "
877 "connectivity is gained.");
878 zassert_equal(stats.event_count_ipv4, 1,
879 "Only NET_EVENT_L4_IPV4_CONNECTED should be fired when IPv4 "
880 "connectivity is gained.");
881 zassert_equal(stats.conn_count_ipv6, 1,
882 "NET_EVENT_L4_IPV6_CONNECTED should be fired when IPv6 "
883 "connectivity is gained.");
884 zassert_equal(stats.event_count_ipv6, 1,
885 "Only NET_EVENT_L4_IPV6_CONNECTED should be fired when IPv6 "
886 "connectivity is gained.");
887 zassert_equal(stats.conn_iface_gen, iface, "The test iface should be blamed.");
888 zassert_equal(stats.conn_iface_ipv4, iface, "The test iface should be blamed.");
889 zassert_equal(stats.conn_iface_ipv6, iface, "The test iface should be blamed.");
890
891 /* (11 -> 01): Lose oper-up from ready state */
892
893 /* Take iface down */
894 zassert_equal(net_if_down(iface), 0, "net_if_down should succeed.");
895
896 /* Verify events are fired */
897 wait_for_events(TEST_EXPECT_L4_DISCONNECTED |
898 TEST_EXPECT_L4_IPV4_DISCONNECTED |
899 TEST_EXPECT_L4_IPV6_DISCONNECTED,
900 EVENT_WAIT_TIME);
901 stats = get_reset_stats();
902 zassert_equal(stats.dconn_count_gen, 1,
903 "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost.");
904 zassert_equal(stats.event_count_gen, 1,
905 "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost.");
906 zassert_equal(stats.dconn_count_ipv4, 1,
907 "NET_EVENT_L4_IPV4_DISCONNECTED should be fired when IPv4 "
908 "connectivity is lost.");
909 zassert_equal(stats.event_count_ipv4, 1,
910 "Only NET_EVENT_L4_IPV4_DISCONNECTED should be fired when IPv4 "
911 "connectivity is lost.");
912 zassert_equal(stats.dconn_count_ipv6, 1,
913 "NET_EVENT_L4_IPV6_DISCONNECTED should be fired when IPv6 "
914 "connectivity is lost.");
915 zassert_equal(stats.event_count_ipv6, 1,
916 "Only NET_EVENT_L4_IPV6_DISCONNECTED should be fired when IPv6 "
917 "connectivity is lost.");
918 zassert_equal(stats.dconn_iface_gen, iface, "The test iface should be blamed.");
919 zassert_equal(stats.dconn_iface_ipv4, iface, "The test iface should be blamed.");
920 zassert_equal(stats.dconn_iface_ipv6, iface, "The test iface should be blamed.");
921
922 /* (01 -> 00): Lose IP from semi-ready state */
923
924 /* Remove IPs */
925 switch (ifa_ipm) {
926 case IPV4_FIRST:
927 /* Remove IPv4 then IPv6 */
928 zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a),
929 "IPv4 removal should succeed.");
930 zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a),
931 "IPv6 removal should succeed.");
932 break;
933 case IPV6_FIRST:
934 /* Remove IPv6 then IPv4 */
935 zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a),
936 "IPv6 removal should succeed.");
937 zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a),
938 "IPv4 removal should succeed.");
939 break;
940 }
941
942 /* Verify no events fired */
943 k_sleep(EVENT_WAIT_TIME_SHORT);
944 stats = get_reset_stats();
945 zassert_equal(stats.event_count_gen, 0,
946 "No events should be fired if connectivity availability did not change.");
947 zassert_equal(stats.event_count_ipv4, 0,
948 "No events should be fired if connectivity availability did not change.");
949 zassert_equal(stats.event_count_ipv6, 0,
950 "No events should be fired if connectivity availability did not change.");
951 }
952
953 /* Cases */
954
955 /* Make sure all readiness transitions of a pair of connectivity-enabled ifaces results in all
956 * expected events.
957 */
ZTEST(conn_mgr_monitor,test_cycle_ready_CC)958 ZTEST(conn_mgr_monitor, test_cycle_ready_CC)
959 {
960 cycle_ready_ifaces(if_conn_a, if_conn_b);
961 }
962
963 /* Make sure half of all readiness transitions of a connectivity-enabled iface and a simple
964 * iface results in all expected events.
965 */
ZTEST(conn_mgr_monitor,test_cycle_ready_CNC)966 ZTEST(conn_mgr_monitor, test_cycle_ready_CNC)
967 {
968 cycle_ready_ifaces(if_conn_a, if_simp_a);
969 }
970
971 /* Make sure the other half of all readiness transitions of a connectivity-enabled iface and a
972 * simple iface results in all expected events.
973 */
ZTEST(conn_mgr_monitor,test_cycle_ready_NCC)974 ZTEST(conn_mgr_monitor, test_cycle_ready_NCC)
975 {
976 cycle_ready_ifaces(if_simp_a, if_conn_a);
977 }
978
979 /* Make sure all readiness transitions of a pair of simple ifaces results in all expected events.
980 */
ZTEST(conn_mgr_monitor,test_cycle_ready_NCNC)981 ZTEST(conn_mgr_monitor, test_cycle_ready_NCNC)
982 {
983 cycle_ready_ifaces(if_simp_a, if_simp_b);
984 }
985
986 /* Make sure that a simple iface can be successfully ignored without interfering with the events
987 * fired by another simple iface
988 */
ZTEST(conn_mgr_monitor,test_cycle_ready_NCINC)989 ZTEST(conn_mgr_monitor, test_cycle_ready_NCINC)
990 {
991 cycle_ignored_iface(if_simp_a, if_simp_b);
992 }
993
994 /* Make sure that a connectivity-enabled iface can be successfully ignored without interfering
995 * with the events fired by another connectivity-enabled iface
996 */
ZTEST(conn_mgr_monitor,test_cycle_ready_CIC)997 ZTEST(conn_mgr_monitor, test_cycle_ready_CIC)
998 {
999 cycle_ignored_iface(if_conn_a, if_conn_b);
1000 }
1001
1002 /* Make sure that a connectivity-enabled iface can be successfully ignored without interfering
1003 * with the events fired by a simple iface
1004 */
ZTEST(conn_mgr_monitor,test_cycle_ready_CINC)1005 ZTEST(conn_mgr_monitor, test_cycle_ready_CINC)
1006 {
1007 cycle_ignored_iface(if_conn_a, if_simp_a);
1008 }
1009
1010 /* Make sure that a simple iface can be successfully ignored without interfering
1011 * with the events fired by a connectivity-enabled iface
1012 */
ZTEST(conn_mgr_monitor,test_cycle_ready_NCIC)1013 ZTEST(conn_mgr_monitor, test_cycle_ready_NCIC)
1014 {
1015 cycle_ignored_iface(if_simp_a, if_conn_a);
1016 }
1017
1018 /* Make sure that DAD readiness is actually verified by conn_mgr_monitor */
ZTEST(conn_mgr_monitor,test_DAD)1019 ZTEST(conn_mgr_monitor, test_DAD)
1020 {
1021 struct test_stats stats;
1022
1023 /* This test specifically requires DAD to function */
1024 Z_TEST_SKIP_IFNDEF(CONFIG_NET_IPV6_DAD);
1025
1026 /* Take iface up */
1027 zassert_equal(net_if_up(if_simp_a), 0, "net_if_up should succeed.");
1028
1029 /* Add IPv6 */
1030 net_if_ipv6_addr_add(if_simp_a, &test_ipv6_a, NET_ADDR_MANUAL, 0);
1031
1032 /* After a delay too short for DAD, ensure no events */
1033 k_sleep(EVENT_WAIT_TIME_SHORT);
1034 stats = get_reset_stats();
1035 zassert_equal(stats.event_count_gen, 0,
1036 "No events should be fired before DAD success.");
1037
1038 /* After a delay long enough for DAD, ensure connectivity acquired */
1039 wait_for_events(TEST_EXPECT_L4_CONNECTED, EVENT_WAIT_TIME);
1040 stats = get_reset_stats();
1041 zassert_equal(stats.conn_count_gen, 1,
1042 "NET_EVENT_L4_CONNECTED should be fired after DAD success.");
1043 }
1044
1045 /* Test whether ignoring and un-ignoring a ready iface fires the appropriate events */
ZTEST(conn_mgr_monitor,test_ignore_while_ready)1046 ZTEST(conn_mgr_monitor, test_ignore_while_ready)
1047 {
1048 struct test_stats stats;
1049
1050 /* Ignore iface */
1051 conn_mgr_ignore_iface(if_simp_a);
1052
1053 /* Add IP and take iface up */
1054 net_if_ipv4_addr_add(if_simp_a, &test_ipv4_a, NET_ADDR_MANUAL, 0);
1055 net_if_ipv6_addr_add(if_simp_a, &test_ipv6_a, NET_ADDR_MANUAL, 0);
1056 zassert_equal(net_if_up(if_simp_a), 0, "net_if_up should succeed for if_simp_a.");
1057
1058 /* Ensure no events */
1059 k_sleep(DAD_WAIT_TIME);
1060 stats = get_reset_stats();
1061 zassert_equal(stats.event_count_gen, 0,
1062 "No events should be fired if connecting iface is ignored.");
1063 zassert_equal(stats.event_count_ipv4, 0,
1064 "No events should be fired if connecting iface is ignored.");
1065 zassert_equal(stats.event_count_ipv6, 0,
1066 "No events should be fired if connecting iface is ignored.");
1067
1068 /* Watch iface */
1069 conn_mgr_watch_iface(if_simp_a);
1070
1071 /* Ensure connectivity gained */
1072 wait_for_events(TEST_EXPECT_L4_CONNECTED |
1073 TEST_EXPECT_L4_IPV4_CONNECTED |
1074 TEST_EXPECT_L4_IPV6_CONNECTED,
1075 EVENT_WAIT_TIME);
1076 stats = get_reset_stats();
1077 zassert_equal(stats.conn_count_gen, 1,
1078 "NET_EVENT_L4_CONNECTED should be fired when online iface is watched.");
1079 zassert_equal(stats.event_count_gen, 1,
1080 "Only NET_EVENT_L4_CONNECTED should be fired.");
1081 zassert_equal(stats.conn_count_ipv4, 1,
1082 "NET_EVENT_L4_IPV4_CONNECTED should be fired when online iface is watched.");
1083 zassert_equal(stats.event_count_ipv4, 1,
1084 "Only NET_EVENT_L4_IPV4_CONNECTED should be fired.");
1085 zassert_equal(stats.conn_count_ipv6, 1,
1086 "NET_EVENT_L4_IPV6_CONNECTED should be fired when online iface is watched.");
1087 zassert_equal(stats.event_count_ipv6, 1,
1088 "Only NET_EVENT_L4_IPV6_CONNECTED should be fired.");
1089 zassert_equal(stats.conn_iface_gen, if_simp_a, "if_simp_a should be blamed");
1090 zassert_equal(stats.conn_iface_ipv4, if_simp_a, "if_simp_a should be blamed");
1091 zassert_equal(stats.conn_iface_ipv6, if_simp_a, "if_simp_a should be blamed");
1092
1093
1094 /* Ignore iface */
1095 conn_mgr_ignore_iface(if_simp_a);
1096
1097 /* Ensure connectivity lost */
1098 wait_for_events(TEST_EXPECT_L4_DISCONNECTED |
1099 TEST_EXPECT_L4_IPV4_DISCONNECTED |
1100 TEST_EXPECT_L4_IPV6_DISCONNECTED,
1101 EVENT_WAIT_TIME);
1102 stats = get_reset_stats();
1103 zassert_equal(stats.dconn_count_gen, 1,
1104 "NET_EVENT_L4_DISCONNECTED should be fired when online iface is ignored.");
1105 zassert_equal(stats.event_count_gen, 1,
1106 "Only NET_EVENT_L4_DISCONNECTED should be fired.");
1107 zassert_equal(stats.dconn_count_ipv4, 1,
1108 "NET_EVENT_L4_IPV4_DISCONNECTED should be fired when online iface is ignored.");
1109 zassert_equal(stats.event_count_ipv4, 1,
1110 "Only NET_EVENT_L4_IPV4_DISCONNECTED should be fired.");
1111 zassert_equal(stats.dconn_count_ipv6, 1,
1112 "NET_EVENT_L4_IPV6_DISCONNECTED should be fired when online iface is ignored.");
1113 zassert_equal(stats.event_count_ipv6, 1,
1114 "Only NET_EVENT_L4_IPV6_DISCONNECTED should be fired.");
1115 zassert_equal(stats.dconn_iface_gen, if_simp_a, "if_simp_a should be blamed");
1116 zassert_equal(stats.dconn_iface_ipv4, if_simp_a, "if_simp_a should be blamed");
1117 zassert_equal(stats.dconn_iface_ipv6, if_simp_a, "if_simp_a should be blamed");
1118
1119 /* Take iface down*/
1120 zassert_equal(net_if_down(if_simp_a), 0, "net_if_down should succeed for if_simp_a.");
1121
1122 /* Ensure no events */
1123 k_sleep(EVENT_WAIT_TIME_SHORT);
1124 stats = get_reset_stats();
1125 zassert_equal(stats.event_count_gen, 0,
1126 "No events should be fired if disconnecting iface is ignored.");
1127 zassert_equal(stats.event_count_ipv4, 0,
1128 "No events should be fired if disconnecting iface is ignored.");
1129 zassert_equal(stats.event_count_ipv6, 0,
1130 "No events should be fired if disconnecting iface is ignored.");
1131 }
1132
1133 /* Test L2 and iface ignore API */
ZTEST(conn_mgr_monitor,test_ignores)1134 ZTEST(conn_mgr_monitor, test_ignores)
1135 {
1136 /* Ignore if_simp_a, ensuring if_simp_b is unaffected */
1137 conn_mgr_ignore_iface(if_simp_a);
1138 zassert_true(conn_mgr_is_iface_ignored(if_simp_a),
1139 "if_simp_a should be ignored.");
1140 zassert_false(conn_mgr_is_iface_ignored(if_simp_b),
1141 "if_simp_b should not be affected.");
1142
1143 /* Ignore if_simp_b, ensuring if_simp_a is unaffected */
1144 conn_mgr_ignore_iface(if_simp_b);
1145 zassert_true(conn_mgr_is_iface_ignored(if_simp_b),
1146 "if_simp_b should be ignored.");
1147 zassert_true(conn_mgr_is_iface_ignored(if_simp_a),
1148 "if_simp_a should not be affected.");
1149
1150 /* Watch if_simp_a, ensuring if_simp_b is unaffected */
1151 conn_mgr_watch_iface(if_simp_a);
1152 zassert_false(conn_mgr_is_iface_ignored(if_simp_a),
1153 "if_simp_a should be watched.");
1154 zassert_true(conn_mgr_is_iface_ignored(if_simp_b),
1155 "if_simp_b should not be affected.");
1156
1157 /* Watch if_simp_b, ensuring if_simp_a is unaffected */
1158 conn_mgr_watch_iface(if_simp_b);
1159 zassert_false(conn_mgr_is_iface_ignored(if_simp_b),
1160 "if_simp_b should be watched.");
1161 zassert_false(conn_mgr_is_iface_ignored(if_simp_a),
1162 "if_simp_a should not be affected.");
1163
1164 /* Ignore the entire DUMMY_L2, ensuring all ifaces except if_dummy_eth are affected */
1165 conn_mgr_ignore_l2(&NET_L2_GET_NAME(DUMMY));
1166 zassert_true(conn_mgr_is_iface_ignored(if_simp_a),
1167 "All DUMMY_L2 ifaces should be ignored.");
1168 zassert_true(conn_mgr_is_iface_ignored(if_simp_b),
1169 "All DUMMY_L2 ifaces should be ignored.");
1170 zassert_true(conn_mgr_is_iface_ignored(if_conn_a),
1171 "All DUMMY_L2 ifaces should be ignored.");
1172 zassert_true(conn_mgr_is_iface_ignored(if_conn_b),
1173 "All DUMMY_L2 ifaces should be ignored.");
1174 zassert_false(conn_mgr_is_iface_ignored(if_dummy_eth),
1175 "if_dummy_eth should not be affected.");
1176
1177 /* Watch the entire DUMMY_L2, ensuring all ifaces except if_dummy_eth are affected */
1178 conn_mgr_watch_l2(&NET_L2_GET_NAME(DUMMY));
1179 zassert_false(conn_mgr_is_iface_ignored(if_simp_a),
1180 "All DUMMY_L2 ifaces should be watched.");
1181 zassert_false(conn_mgr_is_iface_ignored(if_simp_b),
1182 "All DUMMY_L2 ifaces should be watched.");
1183 zassert_false(conn_mgr_is_iface_ignored(if_conn_a),
1184 "All DUMMY_L2 ifaces should be watched.");
1185 zassert_false(conn_mgr_is_iface_ignored(if_conn_b),
1186 "All DUMMY_L2 ifaces should be watched.");
1187 zassert_false(conn_mgr_is_iface_ignored(if_dummy_eth),
1188 "if_dummy_eth should not be affected.");
1189 }
1190
1191 /* Make sure all state transitions of a single connectivity-enabled iface result in all expected
1192 * events. Perform IPv4 changes before IPv6 changes.
1193 */
ZTEST(conn_mgr_monitor,test_cycle_states_connected_ipv46)1194 ZTEST(conn_mgr_monitor, test_cycle_states_connected_ipv46)
1195 {
1196 cycle_iface_states(if_conn_a, IPV4_FIRST);
1197 }
1198
1199 /* Make sure all state transitions of a single connectivity-enabled iface result in all expected
1200 * events. Perform IPv6 changes before IPv4 changes.
1201 */
ZTEST(conn_mgr_monitor,test_cycle_states_connected_ipv64)1202 ZTEST(conn_mgr_monitor, test_cycle_states_connected_ipv64)
1203 {
1204 cycle_iface_states(if_conn_a, IPV6_FIRST);
1205 }
1206
1207 /* Make sure all state transitions of a single simple iface result in all expected events.
1208 * Perform IPv4 changes before IPv6 changes.
1209 */
ZTEST(conn_mgr_monitor,test_cycle_states_simple_ipv46)1210 ZTEST(conn_mgr_monitor, test_cycle_states_simple_ipv46)
1211 {
1212 cycle_iface_states(if_simp_a, IPV4_FIRST);
1213 }
1214
1215 /* Make sure all state transitions of a single simple iface result in all expected events.
1216 * Perform IPv6 changes before IPv4 changes.
1217 */
ZTEST(conn_mgr_monitor,test_cycle_states_simple_ipv64)1218 ZTEST(conn_mgr_monitor, test_cycle_states_simple_ipv64)
1219 {
1220 cycle_iface_states(if_simp_a, IPV6_FIRST);
1221 }
1222
1223 ZTEST_SUITE(conn_mgr_monitor, NULL, conn_mgr_setup, conn_mgr_before, NULL, NULL);
1224