]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/libsystemd-network/test-ndisc-ra.c
sd-radv: allow to modify RA header elements without stopping sd-radv
[thirdparty/systemd.git] / src / libsystemd-network / test-ndisc-ra.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
24852172 2/***
810adae9 3 Copyright © 2017 Intel Corporation. All rights reserved.
24852172
PF
4***/
5
6#include <netinet/icmp6.h>
7#include <arpa/inet.h>
ca78ad1d 8#include <unistd.h>
24852172
PF
9
10#include "sd-radv.h"
11
12#include "alloc-util.h"
13#include "hexdecoct.h"
690afe79 14#include "icmp6-util-unix.h"
24852172
PF
15#include "socket-util.h"
16#include "strv.h"
6d7c4033 17#include "tests.h"
24852172
PF
18
19static struct ether_addr mac_addr = {
20 .ether_addr_octet = { 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53 }
21};
22
24852172 23static bool test_stopped;
24852172
PF
24static struct {
25 struct in6_addr address;
26 unsigned char prefixlen;
27 uint32_t valid;
28 uint32_t preferred;
5238e957 29 bool successful;
24852172
PF
30} prefix[] = {
31 { { { { 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
32 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64,
33 500, 440, true },
34 { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
35 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 64,
36 /* indicate default valid and preferred lifetimes for the test code */
37 0, 0, true },
38 { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 58,
40 0, 0,
41 /* indicate that this prefix already exists */
42 false },
43 { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
44 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 120,
45 0, 0,
46 /* indicate that this prefix already exists */
47 false },
48 { { { { 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 12,
50 0, 0,
51 /* indicate that this prefix already exists */
52 false },
53 { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 48,
55 0, 0, true },
56 { { { { 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } } }, 60,
58 0, 0,
59 /* indicate that this prefix already exists */
60 false },
61};
62
06e6c805
PF
63static const struct in6_addr test_rdnss = { { { 0x20, 0x01, 0x0d, 0xb8,
64 0xde, 0xad, 0xbe, 0xef,
65 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x01 } } };
fa178dd2
PF
67static const char *test_dnssl[] = { "lab.intra",
68 NULL };
06e6c805 69
68da8adf 70TEST(radv_prefix) {
24852172
PF
71 sd_radv_prefix *p;
72
24852172
PF
73 assert_se(sd_radv_prefix_new(&p) >= 0);
74
8161f608 75 ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_onlink(NULL, true) < 0);
24852172
PF
76 assert_se(sd_radv_prefix_set_onlink(p, true) >= 0);
77 assert_se(sd_radv_prefix_set_onlink(p, false) >= 0);
78
8161f608 79 ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_address_autoconfiguration(NULL, true) < 0);
24852172
PF
80 assert_se(sd_radv_prefix_set_address_autoconfiguration(p, true) >= 0);
81 assert_se(sd_radv_prefix_set_address_autoconfiguration(p, false) >= 0);
82
8161f608 83 ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_valid_lifetime(NULL, 1, 1) < 0);
95e104e0
YW
84 assert_se(sd_radv_prefix_set_valid_lifetime(p, 0, 0) >= 0);
85 assert_se(sd_radv_prefix_set_valid_lifetime(p, 300 * USEC_PER_SEC, USEC_INFINITY) >= 0);
86 assert_se(sd_radv_prefix_set_valid_lifetime(p, 300 * USEC_PER_SEC, USEC_PER_YEAR) >= 0);
24852172 87
8161f608 88 ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_preferred_lifetime(NULL, 1, 1) < 0);
95e104e0
YW
89 assert_se(sd_radv_prefix_set_preferred_lifetime(p, 0, 0) >= 0);
90 assert_se(sd_radv_prefix_set_preferred_lifetime(p, 300 * USEC_PER_SEC, USEC_INFINITY) >= 0);
91 assert_se(sd_radv_prefix_set_preferred_lifetime(p, 300 * USEC_PER_SEC, USEC_PER_YEAR) >= 0);
24852172 92
8161f608
YW
93 ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_prefix(NULL, NULL, 0) < 0);
94 ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_prefix(p, NULL, 0) < 0);
24852172
PF
95
96 assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 64) >= 0);
97 assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 0) < 0);
98 assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 1) < 0);
99 assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 2) < 0);
100 assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 3) >= 0);
101 assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 125) >= 0);
102 assert_se(sd_radv_prefix_set_prefix(p, &prefix[0].address, 128) >= 0);
8161f608
YW
103 ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_prefix(p, &prefix[0].address, 129) < 0);
104 ASSERT_RETURN_EXPECTED_SE(sd_radv_prefix_set_prefix(p, &prefix[0].address, 255) < 0);
24852172 105
8ff992d1
YW
106 assert_se(!sd_radv_prefix_unref(p));
107}
108
109TEST(radv_route_prefix) {
110 sd_radv_route_prefix *p;
111
112 assert_se(sd_radv_route_prefix_new(&p) >= 0);
113
8161f608 114 ASSERT_RETURN_EXPECTED_SE(sd_radv_route_prefix_set_lifetime(NULL, 1, 1) < 0);
8ff992d1
YW
115 assert_se(sd_radv_route_prefix_set_lifetime(p, 0, 0) >= 0);
116 assert_se(sd_radv_route_prefix_set_lifetime(p, 300 * USEC_PER_SEC, USEC_INFINITY) >= 0);
117 assert_se(sd_radv_route_prefix_set_lifetime(p, 300 * USEC_PER_SEC, USEC_PER_YEAR) >= 0);
118
8161f608
YW
119 ASSERT_RETURN_EXPECTED_SE(sd_radv_route_prefix_set_prefix(NULL, NULL, 0) < 0);
120 ASSERT_RETURN_EXPECTED_SE(sd_radv_route_prefix_set_prefix(p, NULL, 0) < 0);
8ff992d1
YW
121
122 assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 64) >= 0);
123 assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 0) >= 0);
124 assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 1) >= 0);
125 assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 2) >= 0);
126 assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 3) >= 0);
127 assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 125) >= 0);
128 assert_se(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 128) >= 0);
8161f608
YW
129 ASSERT_RETURN_EXPECTED_SE(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 129) < 0);
130 ASSERT_RETURN_EXPECTED_SE(sd_radv_route_prefix_set_prefix(p, &prefix[0].address, 255) < 0);
8ff992d1
YW
131
132 assert_se(!sd_radv_route_prefix_unref(p));
133}
134
135TEST(radv_pref64_prefix) {
136 sd_radv_pref64_prefix *p;
137
138 assert_se(sd_radv_pref64_prefix_new(&p) >= 0);
139
8161f608
YW
140 ASSERT_RETURN_EXPECTED_SE(sd_radv_pref64_prefix_set_prefix(NULL, NULL, 0, 0) < 0);
141 ASSERT_RETURN_EXPECTED_SE(sd_radv_pref64_prefix_set_prefix(p, NULL, 0, 0) < 0);
8ff992d1
YW
142
143 assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 32, 300 * USEC_PER_SEC) >= 0);
144 assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 40, 300 * USEC_PER_SEC) >= 0);
145 assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 48, 300 * USEC_PER_SEC) >= 0);
146 assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 56, 300 * USEC_PER_SEC) >= 0);
147 assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 64, 300 * USEC_PER_SEC) >= 0);
148 assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 96, 300 * USEC_PER_SEC) >= 0);
149
150 assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 80, 300 * USEC_PER_SEC) < 0);
151 assert_se(sd_radv_pref64_prefix_set_prefix(p, &prefix[0].address, 80, USEC_PER_DAY) < 0);
152
153 assert_se(!sd_radv_pref64_prefix_unref(p));
24852172
PF
154}
155
68da8adf 156TEST(radv) {
24852172
PF
157 sd_radv *ra;
158
24852172
PF
159 assert_se(sd_radv_new(&ra) >= 0);
160 assert_se(ra);
161
8161f608
YW
162 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(NULL, 0) < 0);
163 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(ra, 0) < 0);
164 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(ra, -1) < 0);
165 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_ifindex(ra, -2) < 0);
24852172
PF
166 assert_se(sd_radv_set_ifindex(ra, 42) >= 0);
167
8161f608
YW
168 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mac(NULL, NULL) < 0);
169 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mac(ra, NULL) >= 0);
24852172
PF
170 assert_se(sd_radv_set_mac(ra, &mac_addr) >= 0);
171
8161f608
YW
172 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mtu(NULL, 0) < 0);
173 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mtu(ra, 0) < 0);
174 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_mtu(ra, 1279) < 0);
24852172
PF
175 assert_se(sd_radv_set_mtu(ra, 1280) >= 0);
176 assert_se(sd_radv_set_mtu(ra, ~0) >= 0);
177
8161f608 178 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_hop_limit(NULL, 0) < 0);
24852172
PF
179 assert_se(sd_radv_set_hop_limit(ra, 0) >= 0);
180 assert_se(sd_radv_set_hop_limit(ra, ~0) >= 0);
181
8161f608 182 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_router_lifetime(NULL, 0) < 0);
24852172 183 assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0);
09457670
YW
184 assert_se(sd_radv_set_router_lifetime(ra, USEC_INFINITY) < 0);
185 assert_se(sd_radv_set_router_lifetime(ra, USEC_PER_YEAR) < 0);
186 assert_se(sd_radv_set_router_lifetime(ra, 300 * USEC_PER_SEC) >= 0);
24852172 187
8161f608 188 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_preference(NULL, 0) < 0);
24852172
PF
189 assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_LOW) >= 0);
190 assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0);
191 assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0);
8161f608 192 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_preference(ra, ~0) < 0);
24852172
PF
193
194 assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_HIGH) >= 0);
09457670 195 assert_se(sd_radv_set_router_lifetime(ra, 300 * USEC_PER_SEC) >= 0);
24852172
PF
196 assert_se(sd_radv_set_router_lifetime(ra, 0) < 0);
197 assert_se(sd_radv_set_preference(ra, SD_NDISC_PREFERENCE_MEDIUM) >= 0);
198 assert_se(sd_radv_set_router_lifetime(ra, 0) >= 0);
199
8161f608 200 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_managed_information(NULL, true) < 0);
24852172
PF
201 assert_se(sd_radv_set_managed_information(ra, true) >= 0);
202 assert_se(sd_radv_set_managed_information(ra, false) >= 0);
203
8161f608 204 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_other_information(NULL, true) < 0);
24852172
PF
205 assert_se(sd_radv_set_other_information(ra, true) >= 0);
206 assert_se(sd_radv_set_other_information(ra, false) >= 0);
207
8161f608 208 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_retransmit(NULL, 10 * USEC_PER_MSEC) < 0);
8ff992d1
YW
209 assert_se(sd_radv_set_retransmit(ra, 10 * USEC_PER_MSEC) >= 0);
210 assert_se(sd_radv_set_retransmit(ra, 0) >= 0);
03401969 211 assert_se(sd_radv_set_retransmit(ra, USEC_INFINITY) >= 0);
8ff992d1 212
8161f608 213 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_rdnss(NULL, 0, NULL, 0) < 0);
06e6c805 214 assert_se(sd_radv_set_rdnss(ra, 0, NULL, 0) >= 0);
8161f608 215 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_rdnss(ra, 0, NULL, 128) < 0);
eca280c8
YW
216 assert_se(sd_radv_set_rdnss(ra, 600 * USEC_PER_SEC, &test_rdnss, 0) >= 0);
217 assert_se(sd_radv_set_rdnss(ra, 600 * USEC_PER_SEC, &test_rdnss, 1) >= 0);
06e6c805
PF
218 assert_se(sd_radv_set_rdnss(ra, 0, &test_rdnss, 1) >= 0);
219 assert_se(sd_radv_set_rdnss(ra, 0, NULL, 0) >= 0);
220
fa178dd2 221 assert_se(sd_radv_set_dnssl(ra, 0, NULL) >= 0);
eca280c8 222 assert_se(sd_radv_set_dnssl(ra, 600 * USEC_PER_SEC, NULL) >= 0);
fa178dd2 223 assert_se(sd_radv_set_dnssl(ra, 0, (char **)test_dnssl) >= 0);
eca280c8 224 assert_se(sd_radv_set_dnssl(ra, 600 * USEC_PER_SEC, (char **)test_dnssl) >= 0);
fa178dd2 225
8161f608 226 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_home_agent_information(NULL, true) < 0);
8ff992d1
YW
227 assert_se(sd_radv_set_home_agent_information(ra, true) >= 0);
228 assert_se(sd_radv_set_home_agent_information(ra, false) >= 0);
229
8161f608 230 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_home_agent_preference(NULL, 10) < 0);
8ff992d1
YW
231 assert_se(sd_radv_set_home_agent_preference(ra, 10) >= 0);
232 assert_se(sd_radv_set_home_agent_preference(ra, 0) >= 0);
233
8161f608 234 ASSERT_RETURN_EXPECTED_SE(sd_radv_set_home_agent_lifetime(NULL, 300 * USEC_PER_SEC) < 0);
8ff992d1
YW
235 assert_se(sd_radv_set_home_agent_lifetime(ra, 300 * USEC_PER_SEC) >= 0);
236 assert_se(sd_radv_set_home_agent_lifetime(ra, 0) >= 0);
237 assert_se(sd_radv_set_home_agent_lifetime(ra, USEC_PER_DAY) < 0);
238
24852172
PF
239 ra = sd_radv_unref(ra);
240 assert_se(!ra);
241}
242
a860df82
YW
243static void dump_message(const uint8_t *buf, size_t len) {
244 assert(len >= sizeof(struct nd_router_advert));
24852172 245
a860df82
YW
246 printf("Received Router Advertisement with lifetime %i sec\n",
247 (buf[6] << 8) + buf[7]);
24852172 248
a860df82 249 for (size_t i = 0; i < len; i++) {
06e6c805 250 if (!(i % 8))
c0f86d66 251 printf("%3zu: ", i);
06e6c805 252
24852172
PF
253 printf("0x%02x", buf[i]);
254
24852172
PF
255 if ((i + 1) % 8)
256 printf(", ");
257 else
258 printf("\n");
259 }
a860df82 260}
24852172 261
a860df82
YW
262static void verify_message(const uint8_t *buf, size_t len) {
263 static const uint8_t advertisement[] = {
264 /* ICMPv6 Router Advertisement, no checksum */
265 0x86, 0x00, 0x00, 0x00, 0x40, 0xc0, 0x00, 0xb4,
266 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 /* Source Link Layer Address Option */
268 0x01, 0x01, 0x78, 0x2b, 0xcb, 0xb3, 0x6d, 0x53,
269 /* Prefix Information Option */
270 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x01, 0xf4,
271 0x00, 0x00, 0x01, 0xb8, 0x00, 0x00, 0x00, 0x00,
272 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
273 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 /* Prefix Information Option */
275 0x03, 0x04, 0x40, 0xc0, 0x00, 0x00, 0x0e, 0x10,
276 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
277 0x20, 0x01, 0x0d, 0xb8, 0x0b, 0x16, 0xd0, 0x0d,
278 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
279 /* Prefix Information Option */
280 0x03, 0x04, 0x30, 0xc0, 0x00, 0x00, 0x0e, 0x10,
281 0x00, 0x00, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00,
282 0x20, 0x01, 0x0d, 0xb8, 0xc0, 0x01, 0x0d, 0xad,
283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284 /* Recursive DNS Server Option */
285 0x19, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
286 0x20, 0x01, 0x0d, 0xb8, 0xde, 0xad, 0xbe, 0xef,
287 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
288 /* DNS Search List Option */
289 0x1f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c,
290 0x03, 0x6c, 0x61, 0x62, 0x05, 0x69, 0x6e, 0x74,
291 0x72, 0x61, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
292 };
293
294 /* verify only up to known options, rest is not yet implemented */
295 for (size_t i = 0, m = MIN(len, sizeof(advertisement)); i < m; i++) {
296 if (test_stopped)
19f3cc86 297 /* on stop, many header fields are zero */
a860df82 298 switch (i) {
19f3cc86
YW
299 case 4: /* hop limit */
300 case 5: /* flags */
301 case 6 ... 7: /* router lifetime */
302 case 8 ... 11: /* reachable time */
303 case 12 ... 15: /* retrans timer */
a860df82
YW
304 assert_se(buf[i] == 0);
305 continue;
306 }
24852172 307
a860df82
YW
308 assert_se(buf[i] == advertisement[i]);
309 }
310}
311
312static int radv_recv(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
313 sd_radv *ra = ASSERT_PTR(userdata);
314 _cleanup_free_ uint8_t *buf = NULL;
315 ssize_t buflen;
24852172 316
a860df82
YW
317 buflen = next_datagram_size_fd(fd);
318 assert_se(buflen >= 0);
319 assert_se(buf = new0(uint8_t, buflen));
320
321 assert_se(read(fd, buf, buflen) == buflen);
322
323 dump_message(buf, buflen);
324 verify_message(buf, buflen);
325
326 if (test_stopped) {
327 assert_se(sd_event_exit(sd_radv_get_event(ra), 0) >= 0);
24852172
PF
328 return 0;
329 }
330
290696e5 331 assert_se(sd_radv_stop(ra) >= 0);
24852172 332 test_stopped = true;
24852172
PF
333 return 0;
334}
335
68da8adf 336TEST(ra) {
86d82cb8
YW
337 _cleanup_(sd_event_unrefp) sd_event *e = NULL;
338 _cleanup_(sd_event_source_unrefp) sd_event_source *recv_router_advertisement = NULL;
339 _cleanup_(sd_radv_unrefp) sd_radv *ra = NULL;
24852172 340
3e29b889 341 assert_se(socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC | SOCK_NONBLOCK, 0, test_fd) >= 0);
24852172
PF
342
343 assert_se(sd_event_new(&e) >= 0);
344
345 assert_se(sd_radv_new(&ra) >= 0);
346 assert_se(ra);
347
348 assert_se(sd_radv_attach_event(ra, e, 0) >= 0);
349
350 assert_se(sd_radv_set_ifindex(ra, 42) >= 0);
351 assert_se(sd_radv_set_mac(ra, &mac_addr) >= 0);
09457670 352 assert_se(sd_radv_set_router_lifetime(ra, 180 * USEC_PER_SEC) >= 0);
24852172
PF
353 assert_se(sd_radv_set_hop_limit(ra, 64) >= 0);
354 assert_se(sd_radv_set_managed_information(ra, true) >= 0);
355 assert_se(sd_radv_set_other_information(ra, true) >= 0);
eca280c8
YW
356 assert_se(sd_radv_set_rdnss(ra, 60 * USEC_PER_SEC, &test_rdnss, 1) >= 0);
357 assert_se(sd_radv_set_dnssl(ra, 60 * USEC_PER_SEC, (char **)test_dnssl) >= 0);
24852172 358
86d82cb8 359 for (unsigned i = 0; i < ELEMENTSOF(prefix); i++) {
24852172
PF
360 sd_radv_prefix *p;
361
362 printf("Test prefix %u\n", i);
363 assert_se(sd_radv_prefix_new(&p) >= 0);
364
365 assert_se(sd_radv_prefix_set_prefix(p, &prefix[i].address,
366 prefix[i].prefixlen) >= 0);
95e104e0
YW
367 if (prefix[i].valid > 0)
368 assert_se(sd_radv_prefix_set_valid_lifetime(p, prefix[i].valid * USEC_PER_SEC, USEC_INFINITY) >= 0);
369 if (prefix[i].preferred > 0)
370 assert_se(sd_radv_prefix_set_preferred_lifetime(p, prefix[i].preferred * USEC_PER_SEC, USEC_INFINITY) >= 0);
371
372 assert_se((sd_radv_add_prefix(ra, p) >= 0) == prefix[i].successful);
373 /* If the previous sd_radv_add_prefix() succeeds, then also the second call should also succeed. */
374 assert_se((sd_radv_add_prefix(ra, p) >= 0) == prefix[i].successful);
24852172
PF
375
376 p = sd_radv_prefix_unref(p);
377 assert_se(!p);
378 }
379
86d82cb8
YW
380 assert_se(sd_event_add_io(e, &recv_router_advertisement, test_fd[0], EPOLLIN, radv_recv, ra) >= 0);
381 assert_se(sd_event_source_set_io_fd_own(recv_router_advertisement, true) >= 0);
24852172 382
ba4e0427 383 assert_se(sd_event_add_time_relative(e, NULL, CLOCK_BOOTTIME,
2e37084f
YW
384 2 * USEC_PER_SEC, 0,
385 NULL, INT_TO_PTR(-ETIMEDOUT)) >= 0);
24852172
PF
386
387 assert_se(sd_radv_start(ra) >= 0);
388
2e37084f 389 assert_se(sd_event_loop(e) >= 0);
24852172
PF
390}
391
68da8adf 392DEFINE_TEST_MAIN(LOG_DEBUG);