2 This file is part of systemd.
4 Copyright (C) 2017 Intel Corporation. All rights reserved.
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 #include <netinet/icmp6.h>
21 #include <netinet/in.h>
22 #include <arpa/inet.h>
27 #include "alloc-util.h"
29 #include "icmp6-util.h"
30 #include "in-addr-util.h"
31 #include "radv-internal.h"
32 #include "socket-util.h"
33 #include "string-util.h"
35 #include "random-util.h"
37 _public_
int sd_radv_new(sd_radv
**ret
) {
38 _cleanup_(sd_radv_unrefp
) sd_radv
*ra
= NULL
;
40 assert_return(ret
, -EINVAL
);
42 ra
= new0(sd_radv
, 1);
48 LIST_HEAD_INIT(ra
->prefixes
);
56 _public_
int sd_radv_attach_event(sd_radv
*ra
, sd_event
*event
, int64_t priority
) {
59 assert_return(ra
, -EINVAL
);
60 assert_return(!ra
->event
, -EBUSY
);
63 ra
->event
= sd_event_ref(event
);
65 r
= sd_event_default(&ra
->event
);
70 ra
->event_priority
= priority
;
75 _public_
int sd_radv_detach_event(sd_radv
*ra
) {
77 assert_return(ra
, -EINVAL
);
79 ra
->event
= sd_event_unref(ra
->event
);
83 _public_ sd_event
*sd_radv_get_event(sd_radv
*ra
) {
84 assert_return(ra
, NULL
);
89 static void radv_reset(sd_radv
*ra
) {
91 ra
->timeout_event_source
=
92 sd_event_source_unref(ra
->timeout_event_source
);
97 _public_ sd_radv
*sd_radv_ref(sd_radv
*ra
) {
101 assert(ra
->n_ref
> 0);
107 _public_ sd_radv
*sd_radv_unref(sd_radv
*ra
) {
111 assert(ra
->n_ref
> 0);
117 while (ra
->prefixes
) {
118 sd_radv_prefix
*p
= ra
->prefixes
;
120 LIST_REMOVE(prefix
, ra
->prefixes
, p
);
121 sd_radv_prefix_unref(p
);
126 sd_radv_detach_event(ra
);
130 static int radv_send(sd_radv
*ra
, const struct in6_addr
*dst
,
131 const uint32_t router_lifetime
) {
136 static usec_t
radv_compute_timeout(usec_t min
, usec_t max
) {
137 assert_return(min
<= max
, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
);
139 return min
+ (random_u32() % (max
- min
));
142 static int radv_timeout(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
144 sd_radv
*ra
= userdata
;
145 usec_t min_timeout
= SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
;
146 usec_t max_timeout
= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC
;
147 usec_t time_now
, timeout
;
148 char time_string
[FORMAT_TIMESPAN_MAX
];
154 ra
->timeout_event_source
= sd_event_source_unref(ra
->timeout_event_source
);
156 r
= sd_event_now(ra
->event
, clock_boottime_or_monotonic(), &time_now
);
160 r
= radv_send(ra
, NULL
, ra
->lifetime
);
162 log_radv_warning_errno(r
, "Unable to send Router Advertisement: %m");
164 /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
165 if (ra
->ra_sent
< SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS
) {
166 max_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
;
167 min_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
/ 3;
170 timeout
= radv_compute_timeout(min_timeout
, max_timeout
);
172 log_radv("Next Router Advertisement in %s",
173 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
174 timeout
, USEC_PER_SEC
));
176 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
177 clock_boottime_or_monotonic(),
178 time_now
+ timeout
, MSEC_PER_SEC
,
183 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
188 r
= sd_event_source_set_description(ra
->timeout_event_source
,
202 _public_
int sd_radv_stop(sd_radv
*ra
) {
205 assert_return(ra
, -EINVAL
);
207 log_radv("Stopping IPv6 Router Advertisement daemon");
209 /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
210 with zero lifetime */
211 r
= radv_send(ra
, NULL
, 0);
213 log_radv_warning_errno(r
, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
216 ra
->state
= SD_RADV_STATE_IDLE
;
221 _public_
int sd_radv_start(sd_radv
*ra
) {
224 assert_return(ra
, -EINVAL
);
225 assert_return(ra
->event
, -EINVAL
);
226 assert_return(ra
->ifindex
> 0, -EINVAL
);
228 if (ra
->state
!= SD_RADV_STATE_IDLE
)
231 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
232 clock_boottime_or_monotonic(), 0, 0,
237 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
242 (void) sd_event_source_set_description(ra
->timeout_event_source
,
245 ra
->state
= SD_RADV_STATE_ADVERTISING
;
247 log_radv("Started IPv6 Router Advertisement daemon");
257 _public_
int sd_radv_set_ifindex(sd_radv
*ra
, int ifindex
) {
258 assert_return(ra
, -EINVAL
);
259 assert_return(ifindex
>= -1, -EINVAL
);
261 if (ra
->state
!= SD_RADV_STATE_IDLE
)
264 ra
->ifindex
= ifindex
;
269 _public_
int sd_radv_set_mac(sd_radv
*ra
, const struct ether_addr
*mac_addr
) {
270 assert_return(ra
, -EINVAL
);
272 if (ra
->state
!= SD_RADV_STATE_IDLE
)
276 ra
->mac_addr
= *mac_addr
;
283 _public_
int sd_radv_set_mtu(sd_radv
*ra
, uint32_t mtu
) {
284 assert_return(ra
, -EINVAL
);
285 assert_return(mtu
>= 1280, -EINVAL
);
287 if (ra
->state
!= SD_RADV_STATE_IDLE
)
295 _public_
int sd_radv_set_hop_limit(sd_radv
*ra
, uint8_t hop_limit
) {
296 assert_return(ra
, -EINVAL
);
298 if (ra
->state
!= SD_RADV_STATE_IDLE
)
301 ra
->hop_limit
= hop_limit
;
306 _public_
int sd_radv_set_router_lifetime(sd_radv
*ra
, uint32_t router_lifetime
) {
307 assert_return(ra
, -EINVAL
);
309 if (ra
->state
!= SD_RADV_STATE_IDLE
)
312 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the
313 preference value MUST be set to (00) by the sender..." */
314 if (router_lifetime
== 0 &&
315 (ra
->flags
& (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM
<< 3))
318 ra
->lifetime
= router_lifetime
;
323 _public_
int sd_radv_set_managed_information(sd_radv
*ra
, int managed
) {
324 assert_return(ra
, -EINVAL
);
326 if (ra
->state
!= SD_RADV_STATE_IDLE
)
329 SET_FLAG(ra
->flags
, ND_RA_FLAG_MANAGED
, managed
);
334 _public_
int sd_radv_set_other_information(sd_radv
*ra
, int other
) {
335 assert_return(ra
, -EINVAL
);
337 if (ra
->state
!= SD_RADV_STATE_IDLE
)
340 SET_FLAG(ra
->flags
, ND_RA_FLAG_OTHER
, other
);
345 _public_
int sd_radv_set_preference(sd_radv
*ra
, unsigned preference
) {
348 assert_return(ra
, -EINVAL
);
349 assert_return(IN_SET(preference
,
350 SD_NDISC_PREFERENCE_LOW
,
351 SD_NDISC_PREFERENCE_MEDIUM
,
352 SD_NDISC_PREFERENCE_HIGH
), -EINVAL
);
354 ra
->flags
= (ra
->flags
& ~(0x3 << 3)) | (preference
<< 3);
359 _public_
int sd_radv_add_prefix(sd_radv
*ra
, sd_radv_prefix
*p
) {
361 _cleanup_free_
char *addr_p
= NULL
;
363 assert_return(ra
, -EINVAL
);
368 LIST_FOREACH(prefix
, cur
, ra
->prefixes
) {
371 r
= in_addr_prefix_intersect(AF_INET6
,
372 (union in_addr_union
*) &cur
->opt
.in6_addr
,
374 (union in_addr_union
*) &p
->opt
.in6_addr
,
377 _cleanup_free_
char *addr_cur
= NULL
;
379 (void) in_addr_to_string(AF_INET6
,
380 (union in_addr_union
*) &cur
->opt
.in6_addr
,
382 (void) in_addr_to_string(AF_INET6
,
383 (union in_addr_union
*) &p
->opt
.in6_addr
,
386 log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
387 addr_cur
, cur
->opt
.prefixlen
,
388 addr_p
, p
->opt
.prefixlen
);
394 p
= sd_radv_prefix_ref(p
);
396 LIST_APPEND(prefix
, ra
->prefixes
, p
);
400 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &p
->opt
.in6_addr
, &addr_p
);
401 log_radv("Added prefix %s/%d", addr_p
, p
->opt
.prefixlen
);
406 _public_
int sd_radv_prefix_new(sd_radv_prefix
**ret
) {
407 _cleanup_(sd_radv_prefix_unrefp
) sd_radv_prefix
*p
= NULL
;
409 assert_return(ret
, -EINVAL
);
411 p
= new0(sd_radv_prefix
, 1);
417 p
->opt
.type
= ND_OPT_PREFIX_INFORMATION
;
418 p
->opt
.length
= (sizeof(p
->opt
) - 1) /8 + 1;
420 p
->opt
.prefixlen
= 64;
422 /* RFC 4861, Section 6.2.1 */
423 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, true);
424 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, true);
425 p
->opt
.preferred_lifetime
= htobe32(604800);
426 p
->opt
.valid_lifetime
= htobe32(2592000);
428 LIST_INIT(prefix
, p
);
436 _public_ sd_radv_prefix
*sd_radv_prefix_ref(sd_radv_prefix
*p
) {
440 assert(p
->n_ref
> 0);
446 _public_ sd_radv_prefix
*sd_radv_prefix_unref(sd_radv_prefix
*p
) {
450 assert(p
->n_ref
> 0);
459 _public_
int sd_radv_prefix_set_prefix(sd_radv_prefix
*p
, struct in6_addr
*in6_addr
,
460 unsigned char prefixlen
) {
461 assert_return(p
, -EINVAL
);
462 assert_return(in6_addr
, -EINVAL
);
464 if (prefixlen
< 3 || prefixlen
> 128)
468 /* unusual but allowed, log it */
469 log_radv("Unusual prefix length %d greater than 64", prefixlen
);
471 p
->opt
.in6_addr
= *in6_addr
;
472 p
->opt
.prefixlen
= prefixlen
;
477 _public_
int sd_radv_prefix_set_onlink(sd_radv_prefix
*p
, int onlink
) {
478 assert_return(p
, -EINVAL
);
480 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, onlink
);
485 _public_
int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix
*p
,
486 int address_autoconfiguration
) {
487 assert_return(p
, -EINVAL
);
489 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, address_autoconfiguration
);
494 _public_
int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix
*p
,
495 uint32_t valid_lifetime
) {
496 assert_return(p
, -EINVAL
);
498 p
->opt
.valid_lifetime
= htobe32(valid_lifetime
);
503 _public_
int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix
*p
,
504 uint32_t preferred_lifetime
) {
505 assert_return(p
, -EINVAL
);
507 p
->opt
.preferred_lifetime
= htobe32(preferred_lifetime
);