]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
f20a35cc | 2 | /*** |
810adae9 | 3 | Copyright © 2014 Intel Corporation. All rights reserved. |
f20a35cc PF |
4 | ***/ |
5 | ||
6 | #include <netinet/icmp6.h> | |
1e7a0e21 | 7 | #include <arpa/inet.h> |
ca78ad1d | 8 | #include <unistd.h> |
f20a35cc | 9 | |
07630cea | 10 | #include "sd-ndisc.h" |
f20a35cc | 11 | |
1e7a0e21 | 12 | #include "alloc-util.h" |
86d82cb8 | 13 | #include "fd-util.h" |
1e7a0e21 | 14 | #include "hexdecoct.h" |
690afe79 | 15 | #include "icmp6-util-unix.h" |
07630cea | 16 | #include "socket-util.h" |
1e7a0e21 | 17 | #include "strv.h" |
5a67ed24 | 18 | #include "ndisc-internal.h" |
6d7c4033 | 19 | #include "tests.h" |
f20a35cc PF |
20 | |
21 | static struct ether_addr mac_addr = { | |
22 | .ether_addr_octet = {'A', 'B', 'C', '1', '2', '3'} | |
23 | }; | |
24 | ||
25 | static bool verbose = false; | |
5a67ed24 | 26 | static sd_ndisc *test_timeout_nd; |
f20a35cc | 27 | |
1e7a0e21 LP |
28 | static void router_dump(sd_ndisc_router *rt) { |
29 | struct in6_addr addr; | |
1e7a0e21 | 30 | uint8_t hop_limit; |
d4c8de21 | 31 | usec_t t, lifetime, retrans_time; |
6197db53 | 32 | uint64_t flags; |
1e7a0e21 | 33 | uint32_t mtu; |
1e7a0e21 LP |
34 | unsigned preference; |
35 | int r; | |
36 | ||
37 | assert_se(rt); | |
38 | ||
39 | log_info("--"); | |
4961f566 YW |
40 | assert_se(sd_ndisc_router_get_address(rt, &addr) >= 0); |
41 | log_info("Sender: %s", IN6_ADDR_TO_STRING(&addr)); | |
1e7a0e21 LP |
42 | |
43 | assert_se(sd_ndisc_router_get_timestamp(rt, CLOCK_REALTIME, &t) >= 0); | |
04f5c018 | 44 | log_info("Timestamp: %s", FORMAT_TIMESTAMP(t)); |
1e7a0e21 LP |
45 | |
46 | assert_se(sd_ndisc_router_get_timestamp(rt, CLOCK_MONOTONIC, &t) >= 0); | |
47 | log_info("Monotonic: %" PRIu64, t); | |
48 | ||
49 | if (sd_ndisc_router_get_hop_limit(rt, &hop_limit) < 0) | |
50 | log_info("No hop limit set"); | |
51 | else | |
52 | log_info("Hop limit: %u", hop_limit); | |
53 | ||
54 | assert_se(sd_ndisc_router_get_flags(rt, &flags) >= 0); | |
55 | log_info("Flags: <%s|%s>", | |
56 | flags & ND_RA_FLAG_OTHER ? "OTHER" : "", | |
57 | flags & ND_RA_FLAG_MANAGED ? "MANAGED" : ""); | |
58 | ||
59 | assert_se(sd_ndisc_router_get_preference(rt, &preference) >= 0); | |
60 | log_info("Preference: %s", | |
61 | preference == SD_NDISC_PREFERENCE_LOW ? "low" : | |
62 | preference == SD_NDISC_PREFERENCE_HIGH ? "high" : "medium"); | |
63 | ||
64 | assert_se(sd_ndisc_router_get_lifetime(rt, &lifetime) >= 0); | |
6197db53 YW |
65 | assert_se(sd_ndisc_router_get_lifetime_timestamp(rt, CLOCK_REALTIME, &t) >= 0); |
66 | log_info("Lifetime: %s (%s)", FORMAT_TIMESPAN(lifetime, USEC_PER_SEC), FORMAT_TIMESTAMP(t)); | |
1e7a0e21 | 67 | |
d4c8de21 MM |
68 | assert_se(sd_ndisc_router_get_retransmission_time(rt, &retrans_time) >= 0); |
69 | log_info("Retransmission Time: %s", FORMAT_TIMESPAN(retrans_time, USEC_PER_SEC)); | |
70 | ||
1e7a0e21 LP |
71 | if (sd_ndisc_router_get_mtu(rt, &mtu) < 0) |
72 | log_info("No MTU set"); | |
73 | else | |
74 | log_info("MTU: %" PRIu32, mtu); | |
75 | ||
76 | r = sd_ndisc_router_option_rewind(rt); | |
77 | for (;;) { | |
78 | uint8_t type; | |
79 | ||
80 | assert_se(r >= 0); | |
81 | ||
82 | if (r == 0) | |
83 | break; | |
84 | ||
85 | assert_se(sd_ndisc_router_option_get_type(rt, &type) >= 0); | |
86 | ||
87 | log_info(">> Option %u", type); | |
88 | ||
89 | switch (type) { | |
90 | ||
91 | case SD_NDISC_OPTION_SOURCE_LL_ADDRESS: | |
92 | case SD_NDISC_OPTION_TARGET_LL_ADDRESS: { | |
93 | _cleanup_free_ char *c = NULL; | |
94 | const void *p; | |
95 | size_t n; | |
96 | ||
97 | assert_se(sd_ndisc_router_option_get_raw(rt, &p, &n) >= 0); | |
98 | assert_se(n > 2); | |
99 | assert_se(c = hexmem((uint8_t*) p + 2, n - 2)); | |
100 | ||
101 | log_info("Address: %s", c); | |
102 | break; | |
103 | } | |
104 | ||
105 | case SD_NDISC_OPTION_PREFIX_INFORMATION: { | |
1e7a0e21 LP |
106 | unsigned prefix_len; |
107 | uint8_t pfl; | |
108 | struct in6_addr a; | |
1e7a0e21 | 109 | |
6197db53 YW |
110 | assert_se(sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime) >= 0); |
111 | assert_se(sd_ndisc_router_prefix_get_valid_lifetime_timestamp(rt, CLOCK_REALTIME, &t) >= 0); | |
112 | log_info("Valid Lifetime: %s (%s)", FORMAT_TIMESPAN(lifetime, USEC_PER_SEC), FORMAT_TIMESTAMP(t)); | |
1e7a0e21 | 113 | |
6197db53 YW |
114 | assert_se(sd_ndisc_router_prefix_get_preferred_lifetime(rt, &lifetime) >= 0); |
115 | assert_se(sd_ndisc_router_prefix_get_preferred_lifetime_timestamp(rt, CLOCK_REALTIME, &t) >= 0); | |
116 | log_info("Preferred Lifetime: %s (%s)", FORMAT_TIMESPAN(lifetime, USEC_PER_SEC), FORMAT_TIMESTAMP(t)); | |
1e7a0e21 LP |
117 | |
118 | assert_se(sd_ndisc_router_prefix_get_flags(rt, &pfl) >= 0); | |
119 | log_info("Flags: <%s|%s>", | |
120 | pfl & ND_OPT_PI_FLAG_ONLINK ? "ONLINK" : "", | |
121 | pfl & ND_OPT_PI_FLAG_AUTO ? "AUTO" : ""); | |
122 | ||
123 | assert_se(sd_ndisc_router_prefix_get_prefixlen(rt, &prefix_len) >= 0); | |
124 | log_info("Prefix Length: %u", prefix_len); | |
125 | ||
126 | assert_se(sd_ndisc_router_prefix_get_address(rt, &a) >= 0); | |
071e522e | 127 | log_info("Prefix: %s", IN6_ADDR_TO_STRING(&a)); |
1e7a0e21 LP |
128 | |
129 | break; | |
130 | } | |
131 | ||
132 | case SD_NDISC_OPTION_RDNSS: { | |
133 | const struct in6_addr *a; | |
1e7a0e21 LP |
134 | int n, i; |
135 | ||
136 | n = sd_ndisc_router_rdnss_get_addresses(rt, &a); | |
137 | assert_se(n > 0); | |
138 | ||
071e522e ZJS |
139 | for (i = 0; i < n; i++) |
140 | log_info("DNS: %s", IN6_ADDR_TO_STRING(a + i)); | |
1e7a0e21 | 141 | |
6197db53 YW |
142 | assert_se(sd_ndisc_router_rdnss_get_lifetime(rt, &lifetime) >= 0); |
143 | assert_se(sd_ndisc_router_rdnss_get_lifetime_timestamp(rt, CLOCK_REALTIME, &t) >= 0); | |
144 | log_info("Lifetime: %s (%s)", FORMAT_TIMESPAN(lifetime, USEC_PER_SEC), FORMAT_TIMESTAMP(t)); | |
1e7a0e21 LP |
145 | break; |
146 | } | |
147 | ||
148 | case SD_NDISC_OPTION_DNSSL: { | |
149 | _cleanup_strv_free_ char **l = NULL; | |
1e7a0e21 LP |
150 | int n, i; |
151 | ||
152 | n = sd_ndisc_router_dnssl_get_domains(rt, &l); | |
a39d8396 YW |
153 | if (n == -EBADMSG) { |
154 | log_info("Invalid domain(s)."); | |
155 | break; | |
156 | } | |
1e7a0e21 LP |
157 | assert_se(n > 0); |
158 | ||
159 | for (i = 0; i < n; i++) | |
160 | log_info("Domain: %s", l[i]); | |
161 | ||
6197db53 YW |
162 | assert_se(sd_ndisc_router_dnssl_get_lifetime(rt, &lifetime) >= 0); |
163 | assert_se(sd_ndisc_router_dnssl_get_lifetime_timestamp(rt, CLOCK_REALTIME, &t) >= 0); | |
164 | log_info("Lifetime: %s (%s)", FORMAT_TIMESPAN(lifetime, USEC_PER_SEC), FORMAT_TIMESTAMP(t)); | |
1e7a0e21 LP |
165 | break; |
166 | }} | |
167 | ||
168 | r = sd_ndisc_router_option_next(rt); | |
169 | } | |
170 | } | |
171 | ||
f20a35cc PF |
172 | static int send_ra(uint8_t flags) { |
173 | uint8_t advertisement[] = { | |
38a80ba1 | 174 | /* struct nd_router_advert */ |
f20a35cc PF |
175 | 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4, |
176 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
38a80ba1 | 177 | /* type = 0x03 (SD_NDISC_OPTION_PREFIX_INFORMATION), length = 32 */ |
f20a35cc PF |
178 | 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4, |
179 | 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, | |
180 | 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, | |
181 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
38a80ba1 | 182 | /* type = 0x19 (SD_NDISC_OPTION_RDNSS), length = 24 */ |
f20a35cc PF |
183 | 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, |
184 | 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, | |
185 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
d9b8acda | 186 | /* type = 0x1f (SD_NDISC_OPTION_DNSSL), length = 24 */ |
f20a35cc PF |
187 | 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, |
188 | 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74, | |
189 | 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
d9b8acda | 190 | /* type = 0x01 (SD_NDISC_OPTION_SOURCE_LL_ADDRESS), length = 8 */ |
f20a35cc PF |
191 | 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, |
192 | }; | |
193 | ||
194 | advertisement[5] = flags; | |
195 | ||
787784c4 | 196 | assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) == |
c21ed681 | 197 | sizeof(advertisement)); |
f20a35cc PF |
198 | |
199 | if (verbose) | |
200 | printf(" sent RA with flag 0x%02x\n", flags); | |
201 | ||
202 | return 0; | |
203 | } | |
204 | ||
28eef158 | 205 | static void test_callback(sd_ndisc *nd, sd_ndisc_event_t event, void *message, void *userdata) { |
f20a35cc | 206 | sd_event *e = userdata; |
cb53894d | 207 | static unsigned idx = 0; |
1e7a0e21 | 208 | uint64_t flags_array[] = { |
9d96e6c3 TG |
209 | 0, |
210 | 0, | |
211 | 0, | |
212 | ND_RA_FLAG_OTHER, | |
213 | ND_RA_FLAG_MANAGED | |
f20a35cc | 214 | }; |
1e7a0e21 | 215 | uint64_t flags; |
8d7f2c6a | 216 | |
787784c4 | 217 | assert_se(nd); |
f20a35cc | 218 | |
1e7a0e21 LP |
219 | if (event != SD_NDISC_EVENT_ROUTER) |
220 | return; | |
221 | ||
28eef158 YW |
222 | sd_ndisc_router *rt = ASSERT_PTR(message); |
223 | ||
1e7a0e21 LP |
224 | router_dump(rt); |
225 | ||
226 | assert_se(sd_ndisc_router_get_flags(rt, &flags) >= 0); | |
9d96e6c3 | 227 | assert_se(flags == flags_array[idx]); |
f20a35cc PF |
228 | idx++; |
229 | ||
230 | if (verbose) | |
1e7a0e21 | 231 | printf(" got event 0x%02" PRIx64 "\n", flags); |
f20a35cc | 232 | |
9d96e6c3 TG |
233 | if (idx < ELEMENTSOF(flags_array)) { |
234 | send_ra(flags_array[idx]); | |
8d7f2c6a PF |
235 | return; |
236 | } | |
237 | ||
a39d8396 | 238 | idx = 0; |
8d7f2c6a | 239 | sd_event_exit(e, 0); |
f20a35cc PF |
240 | } |
241 | ||
68da8adf | 242 | TEST(rs) { |
86d82cb8 YW |
243 | _cleanup_(sd_event_unrefp) sd_event *e = NULL; |
244 | _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL; | |
f20a35cc | 245 | |
99af546d PF |
246 | send_ra_function = send_ra; |
247 | ||
248 | assert_se(sd_event_new(&e) >= 0); | |
249 | ||
4d7b83da | 250 | assert_se(sd_ndisc_new(&nd) >= 0); |
787784c4 | 251 | assert_se(nd); |
f20a35cc | 252 | |
4d7b83da | 253 | assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0); |
f20a35cc | 254 | |
2f8e7633 | 255 | assert_se(sd_ndisc_set_ifindex(nd, 42) >= 0); |
4d7b83da | 256 | assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0); |
1e7a0e21 | 257 | assert_se(sd_ndisc_set_callback(nd, test_callback, e) >= 0); |
f20a35cc | 258 | |
ba4e0427 | 259 | assert_se(sd_event_add_time_relative(e, NULL, CLOCK_BOOTTIME, |
2e37084f YW |
260 | 30 * USEC_PER_SEC, 0, |
261 | NULL, INT_TO_PTR(-ETIMEDOUT)) >= 0); | |
f20a35cc | 262 | |
4d7b83da | 263 | assert_se(sd_ndisc_stop(nd) >= 0); |
1e7a0e21 | 264 | assert_se(sd_ndisc_start(nd) >= 0); |
6b8a1aa6 | 265 | assert_se(sd_ndisc_start(nd) >= 0); |
4d7b83da | 266 | assert_se(sd_ndisc_stop(nd) >= 0); |
86d82cb8 | 267 | test_fd[1] = safe_close(test_fd[1]); |
836cf090 | 268 | |
1e7a0e21 | 269 | assert_se(sd_ndisc_start(nd) >= 0); |
f20a35cc | 270 | |
2e37084f | 271 | assert_se(sd_event_loop(e) >= 0); |
f20a35cc | 272 | |
86d82cb8 | 273 | test_fd[1] = safe_close(test_fd[1]); |
f20a35cc PF |
274 | } |
275 | ||
a39d8396 YW |
276 | static int send_ra_invalid_domain(uint8_t flags) { |
277 | uint8_t advertisement[] = { | |
278 | /* struct nd_router_advert */ | |
279 | 0x86, 0x00, 0xde, 0x83, 0x40, 0xc0, 0x00, 0xb4, | |
280 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
281 | /* type = 0x03 (SD_NDISC_OPTION_PREFIX_INFORMATION), length = 32 */ | |
282 | 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4, | |
283 | 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00, | |
284 | 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, | |
285 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
286 | /* type = 0x19 (SD_NDISC_OPTION_RDNSS), length = 24 */ | |
287 | 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, | |
288 | 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef, | |
289 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, | |
d9b8acda | 290 | /* type = 0x1f (SD_NDISC_OPTION_DNSSL), length = 112 */ |
a39d8396 YW |
291 | 0x1f, 0x0e, 0xee, 0x68, 0xb0, 0xf4, 0x36, 0x39, |
292 | 0x2c, 0xbc, 0x0b, 0xbc, 0xa9, 0x97, 0x71, 0x37, | |
293 | 0xad, 0x86, 0x80, 0x14, 0x2e, 0x58, 0xaa, 0x8a, | |
294 | 0xb7, 0xa1, 0xbe, 0x91, 0x59, 0x00, 0xc4, 0xe8, | |
295 | 0xdd, 0xd8, 0x6d, 0xe5, 0x4a, 0x7a, 0x71, 0x42, | |
296 | 0x74, 0x45, 0x9e, 0x2e, 0xfd, 0x9d, 0x71, 0x1d, | |
297 | 0xd0, 0xc0, 0x54, 0x0c, 0x4d, 0x1f, 0xbf, 0x90, | |
298 | 0xd9, 0x79, 0x58, 0xc0, 0x1d, 0xa3, 0x39, 0xcf, | |
299 | 0xb8, 0xec, 0xd2, 0xe4, 0xcd, 0xb6, 0x13, 0x2f, | |
300 | 0xc0, 0x46, 0xe8, 0x07, 0x3f, 0xaa, 0x28, 0xa5, | |
301 | 0x23, 0xf1, 0xf0, 0xca, 0xd3, 0x19, 0x3f, 0xfa, | |
302 | 0x6c, 0x7c, 0xec, 0x1b, 0xcf, 0x71, 0xeb, 0xba, | |
303 | 0x68, 0x1b, 0x8e, 0x7d, 0x93, 0x7e, 0x0b, 0x9f, | |
304 | 0xdb, 0x12, 0x9c, 0x75, 0x22, 0x5f, 0x12, 0x00, | |
d9b8acda | 305 | /* type = 0x01 (SD_NDISC_OPTION_SOURCE_LL_ADDRESS), length = 8 */ |
a39d8396 YW |
306 | 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53, |
307 | }; | |
308 | ||
309 | advertisement[5] = flags; | |
310 | ||
311 | printf("sizeof(nd_router_advert)=%zu\n", sizeof(struct nd_router_advert)); | |
312 | ||
313 | assert_se(write(test_fd[1], advertisement, sizeof(advertisement)) == | |
314 | sizeof(advertisement)); | |
315 | ||
316 | if (verbose) | |
317 | printf(" sent RA with flag 0x%02x\n", flags); | |
318 | ||
319 | return 0; | |
320 | } | |
321 | ||
322 | TEST(invalid_domain) { | |
323 | _cleanup_(sd_event_unrefp) sd_event *e = NULL; | |
324 | _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL; | |
325 | ||
326 | send_ra_function = send_ra_invalid_domain; | |
327 | ||
328 | assert_se(sd_event_new(&e) >= 0); | |
329 | ||
330 | assert_se(sd_ndisc_new(&nd) >= 0); | |
331 | assert_se(nd); | |
332 | ||
333 | assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0); | |
334 | ||
335 | assert_se(sd_ndisc_set_ifindex(nd, 42) >= 0); | |
336 | assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0); | |
337 | assert_se(sd_ndisc_set_callback(nd, test_callback, e) >= 0); | |
338 | ||
339 | assert_se(sd_event_add_time_relative(e, NULL, CLOCK_BOOTTIME, | |
340 | 30 * USEC_PER_SEC, 0, | |
341 | NULL, INT_TO_PTR(-ETIMEDOUT)) >= 0); | |
342 | ||
343 | assert_se(sd_ndisc_start(nd) >= 0); | |
344 | ||
345 | assert_se(sd_event_loop(e) >= 0); | |
346 | ||
347 | test_fd[1] = safe_close(test_fd[1]); | |
348 | } | |
349 | ||
5a67ed24 PF |
350 | static int test_timeout_value(uint8_t flags) { |
351 | static int count = 0; | |
352 | static usec_t last = 0; | |
353 | sd_ndisc *nd = test_timeout_nd; | |
354 | usec_t min, max; | |
5a67ed24 PF |
355 | |
356 | assert_se(nd); | |
357 | assert_se(nd->event); | |
358 | ||
359 | if (++count >= 20) | |
360 | sd_event_exit(nd->event, 0); | |
361 | ||
362 | if (last == 0) { | |
363 | /* initial RT = IRT + RAND*IRT */ | |
364 | min = NDISC_ROUTER_SOLICITATION_INTERVAL - | |
365 | NDISC_ROUTER_SOLICITATION_INTERVAL / 10; | |
366 | max = NDISC_ROUTER_SOLICITATION_INTERVAL + | |
367 | NDISC_ROUTER_SOLICITATION_INTERVAL / 10; | |
368 | } else { | |
369 | /* next RT = 2*RTprev + RAND*RTprev */ | |
370 | min = 2 * last - last / 10; | |
371 | max = 2 * last + last / 10; | |
372 | } | |
373 | ||
374 | /* final RT > MRT */ | |
375 | if (last * 2 > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL) { | |
376 | min = NDISC_MAX_ROUTER_SOLICITATION_INTERVAL - | |
377 | NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 10; | |
378 | max = NDISC_MAX_ROUTER_SOLICITATION_INTERVAL + | |
379 | NDISC_MAX_ROUTER_SOLICITATION_INTERVAL / 10; | |
380 | } | |
381 | ||
5a67ed24 PF |
382 | log_info("backoff timeout interval %2d %s%s <= %s <= %s", |
383 | count, | |
5291f26d ZJS |
384 | last * 2 > NDISC_MAX_ROUTER_SOLICITATION_INTERVAL ? "(max) ": "", |
385 | FORMAT_TIMESPAN(min, USEC_PER_MSEC), | |
386 | FORMAT_TIMESPAN(nd->retransmit_time, USEC_PER_MSEC), | |
387 | FORMAT_TIMESPAN(max, USEC_PER_MSEC)); | |
5a67ed24 PF |
388 | |
389 | assert_se(min <= nd->retransmit_time); | |
390 | assert_se(max >= nd->retransmit_time); | |
391 | ||
392 | last = nd->retransmit_time; | |
393 | ||
394 | assert_se(sd_event_source_set_time(nd->timeout_event_source, 0) >= 0); | |
395 | ||
396 | return 0; | |
397 | } | |
398 | ||
68da8adf | 399 | TEST(timeout) { |
86d82cb8 YW |
400 | _cleanup_(sd_event_unrefp) sd_event *e = NULL; |
401 | _cleanup_(sd_ndisc_unrefp) sd_ndisc *nd = NULL; | |
5a67ed24 | 402 | |
5a67ed24 PF |
403 | send_ra_function = test_timeout_value; |
404 | ||
405 | assert_se(sd_event_new(&e) >= 0); | |
406 | ||
407 | assert_se(sd_ndisc_new(&nd) >= 0); | |
408 | assert_se(nd); | |
409 | ||
410 | test_timeout_nd = nd; | |
411 | ||
412 | assert_se(sd_ndisc_attach_event(nd, e, 0) >= 0); | |
413 | ||
414 | assert_se(sd_ndisc_set_ifindex(nd, 42) >= 0); | |
415 | assert_se(sd_ndisc_set_mac(nd, &mac_addr) >= 0); | |
416 | ||
ba4e0427 | 417 | assert_se(sd_event_add_time_relative(e, NULL, CLOCK_BOOTTIME, |
2e37084f YW |
418 | 30 * USEC_PER_SEC, 0, |
419 | NULL, INT_TO_PTR(-ETIMEDOUT)) >= 0); | |
5a67ed24 PF |
420 | |
421 | assert_se(sd_ndisc_start(nd) >= 0); | |
422 | ||
2e37084f | 423 | assert_se(sd_event_loop(e) >= 0); |
5a67ed24 | 424 | |
86d82cb8 | 425 | test_fd[1] = safe_close(test_fd[1]); |
5a67ed24 PF |
426 | } |
427 | ||
68da8adf | 428 | DEFINE_TEST_MAIN(LOG_DEBUG); |