1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 Copyright © 2017 Intel Corporation. All rights reserved.
6 #include <netinet/icmp6.h>
7 #include <netinet/in.h>
13 #include "alloc-util.h"
14 #include "dns-domain.h"
16 #include "icmp6-util.h"
17 #include "in-addr-util.h"
18 #include "radv-internal.h"
19 #include "socket-util.h"
20 #include "string-util.h"
23 #include "random-util.h"
25 _public_
int sd_radv_new(sd_radv
**ret
) {
26 _cleanup_(sd_radv_unrefp
) sd_radv
*ra
= NULL
;
28 assert_return(ret
, -EINVAL
);
30 ra
= new0(sd_radv
, 1);
37 LIST_HEAD_INIT(ra
->prefixes
);
44 _public_
int sd_radv_attach_event(sd_radv
*ra
, sd_event
*event
, int64_t priority
) {
47 assert_return(ra
, -EINVAL
);
48 assert_return(!ra
->event
, -EBUSY
);
51 ra
->event
= sd_event_ref(event
);
53 r
= sd_event_default(&ra
->event
);
58 ra
->event_priority
= priority
;
63 _public_
int sd_radv_detach_event(sd_radv
*ra
) {
65 assert_return(ra
, -EINVAL
);
67 ra
->event
= sd_event_unref(ra
->event
);
71 _public_ sd_event
*sd_radv_get_event(sd_radv
*ra
) {
72 assert_return(ra
, NULL
);
77 static void radv_reset(sd_radv
*ra
) {
80 ra
->timeout_event_source
=
81 sd_event_source_unref(ra
->timeout_event_source
);
83 ra
->recv_event_source
=
84 sd_event_source_unref(ra
->recv_event_source
);
89 _public_ sd_radv
*sd_radv_ref(sd_radv
*ra
) {
93 assert(ra
->n_ref
> 0);
99 _public_ sd_radv
*sd_radv_unref(sd_radv
*ra
) {
103 assert(ra
->n_ref
> 0);
109 while (ra
->prefixes
) {
110 sd_radv_prefix
*p
= ra
->prefixes
;
112 LIST_REMOVE(prefix
, ra
->prefixes
, p
);
113 sd_radv_prefix_unref(p
);
121 sd_radv_detach_event(ra
);
123 ra
->fd
= safe_close(ra
->fd
);
128 static int radv_send(sd_radv
*ra
, const struct in6_addr
*dst
,
129 const uint32_t router_lifetime
) {
130 static const struct ether_addr mac_zero
= {};
132 struct sockaddr_in6 dst_addr
= {
133 .sin6_family
= AF_INET6
,
134 .sin6_addr
= IN6ADDR_ALL_NODES_MULTICAST_INIT
,
136 struct nd_router_advert adv
= {};
138 struct nd_opt_hdr opthdr
;
139 struct ether_addr slladdr
;
140 } _packed_ opt_mac
= {
142 .nd_opt_type
= ND_OPT_SOURCE_LINKADDR
,
143 .nd_opt_len
= (sizeof(struct nd_opt_hdr
) +
144 sizeof(struct ether_addr
) - 1) /8 + 1,
147 struct nd_opt_mtu opt_mtu
= {
148 .nd_opt_mtu_type
= ND_OPT_MTU
,
151 /* Reserve iov space for RA header, linkaddr, MTU, N prefixes, RDNSS
153 struct iovec iov
[5 + ra
->n_prefixes
];
154 struct msghdr msg
= {
155 .msg_name
= &dst_addr
,
156 .msg_namelen
= sizeof(dst_addr
),
162 r
= sd_event_now(ra
->event
, clock_boottime_or_monotonic(), &time_now
);
166 if (dst
&& !in_addr_is_null(AF_INET6
, (union in_addr_union
*) dst
))
167 dst_addr
.sin6_addr
= *dst
;
169 adv
.nd_ra_type
= ND_ROUTER_ADVERT
;
170 adv
.nd_ra_curhoplimit
= ra
->hop_limit
;
171 adv
.nd_ra_flags_reserved
= ra
->flags
;
172 adv
.nd_ra_router_lifetime
= htobe16(router_lifetime
);
173 iov
[msg
.msg_iovlen
].iov_base
= &adv
;
174 iov
[msg
.msg_iovlen
].iov_len
= sizeof(adv
);
177 /* MAC address is optional, either because the link does not use L2
178 addresses or load sharing is desired. See RFC 4861, Section 4.2 */
179 if (memcmp(&mac_zero
, &ra
->mac_addr
, sizeof(mac_zero
))) {
180 opt_mac
.slladdr
= ra
->mac_addr
;
181 iov
[msg
.msg_iovlen
].iov_base
= &opt_mac
;
182 iov
[msg
.msg_iovlen
].iov_len
= sizeof(opt_mac
);
187 opt_mtu
.nd_opt_mtu_mtu
= htobe32(ra
->mtu
);
188 iov
[msg
.msg_iovlen
].iov_base
= &opt_mtu
;
189 iov
[msg
.msg_iovlen
].iov_len
= sizeof(opt_mtu
);
193 LIST_FOREACH(prefix
, p
, ra
->prefixes
) {
194 if (p
->valid_until
) {
196 if (time_now
> p
->valid_until
)
197 p
->opt
.valid_lifetime
= 0;
199 p
->opt
.valid_lifetime
= htobe32((p
->valid_until
- time_now
) / USEC_PER_SEC
);
201 if (time_now
> p
->preferred_until
)
202 p
->opt
.preferred_lifetime
= 0;
204 p
->opt
.preferred_lifetime
= htobe32((p
->preferred_until
- time_now
) / USEC_PER_SEC
);
206 iov
[msg
.msg_iovlen
].iov_base
= &p
->opt
;
207 iov
[msg
.msg_iovlen
].iov_len
= sizeof(p
->opt
);
212 iov
[msg
.msg_iovlen
].iov_base
= ra
->rdnss
;
213 iov
[msg
.msg_iovlen
].iov_len
= ra
->rdnss
->length
* 8;
218 iov
[msg
.msg_iovlen
].iov_base
= ra
->dnssl
;
219 iov
[msg
.msg_iovlen
].iov_len
= ra
->dnssl
->length
* 8;
223 if (sendmsg(ra
->fd
, &msg
, 0) < 0)
229 static int radv_recv(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
230 sd_radv
*ra
= userdata
;
231 _cleanup_free_
char *addr
= NULL
;
233 triple_timestamp timestamp
;
236 _cleanup_free_
char *buf
= NULL
;
242 buflen
= next_datagram_size_fd(fd
);
244 if ((unsigned) buflen
< sizeof(struct nd_router_solicit
))
245 return log_radv("Too short packet received");
247 buf
= new0(char, buflen
);
251 r
= icmp6_receive(fd
, buf
, buflen
, &src
, ×tamp
);
255 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &src
, &addr
);
256 log_radv("Received RS from non-link-local address %s. Ignoring", addr
);
260 log_radv("Received RS with invalid hop limit. Ignoring.");
264 log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
268 log_radv_warning_errno(r
, "Error receiving from ICMPv6 socket: %m");
275 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &src
, &addr
);
277 r
= radv_send(ra
, &src
, ra
->lifetime
);
279 log_radv_warning_errno(r
, "Unable to send solicited Router Advertisement to %s: %m", addr
);
281 log_radv("Sent solicited Router Advertisement to %s", addr
);
286 static usec_t
radv_compute_timeout(usec_t min
, usec_t max
) {
287 assert_return(min
<= max
, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
);
289 return min
+ (random_u32() % (max
- min
));
292 static int radv_timeout(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
294 sd_radv
*ra
= userdata
;
295 usec_t min_timeout
= SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
;
296 usec_t max_timeout
= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC
;
297 usec_t time_now
, timeout
;
298 char time_string
[FORMAT_TIMESPAN_MAX
];
304 ra
->timeout_event_source
= sd_event_source_unref(ra
->timeout_event_source
);
306 r
= sd_event_now(ra
->event
, clock_boottime_or_monotonic(), &time_now
);
310 r
= radv_send(ra
, NULL
, ra
->lifetime
);
312 log_radv_warning_errno(r
, "Unable to send Router Advertisement: %m");
314 /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
315 if (ra
->ra_sent
< SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS
) {
316 max_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
;
317 min_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
/ 3;
320 timeout
= radv_compute_timeout(min_timeout
, max_timeout
);
322 log_radv("Next Router Advertisement in %s",
323 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
324 timeout
, USEC_PER_SEC
));
326 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
327 clock_boottime_or_monotonic(),
328 time_now
+ timeout
, MSEC_PER_SEC
,
333 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
338 r
= sd_event_source_set_description(ra
->timeout_event_source
,
352 _public_
int sd_radv_stop(sd_radv
*ra
) {
355 assert_return(ra
, -EINVAL
);
357 if (ra
->state
== SD_RADV_STATE_IDLE
)
360 log_radv("Stopping IPv6 Router Advertisement daemon");
362 /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
363 with zero lifetime */
364 r
= radv_send(ra
, NULL
, 0);
366 log_radv_warning_errno(r
, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
369 ra
->fd
= safe_close(ra
->fd
);
370 ra
->state
= SD_RADV_STATE_IDLE
;
375 _public_
int sd_radv_start(sd_radv
*ra
) {
378 assert_return(ra
, -EINVAL
);
379 assert_return(ra
->event
, -EINVAL
);
380 assert_return(ra
->ifindex
> 0, -EINVAL
);
382 if (ra
->state
!= SD_RADV_STATE_IDLE
)
385 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
386 clock_boottime_or_monotonic(), 0, 0,
391 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
396 (void) sd_event_source_set_description(ra
->timeout_event_source
,
399 r
= icmp6_bind_router_advertisement(ra
->ifindex
);
405 r
= sd_event_add_io(ra
->event
, &ra
->recv_event_source
, ra
->fd
, EPOLLIN
, radv_recv
, ra
);
409 r
= sd_event_source_set_priority(ra
->recv_event_source
, ra
->event_priority
);
413 (void) sd_event_source_set_description(ra
->recv_event_source
, "radv-receive-message");
415 ra
->state
= SD_RADV_STATE_ADVERTISING
;
417 log_radv("Started IPv6 Router Advertisement daemon");
427 _public_
int sd_radv_set_ifindex(sd_radv
*ra
, int ifindex
) {
428 assert_return(ra
, -EINVAL
);
429 assert_return(ifindex
>= -1, -EINVAL
);
431 if (ra
->state
!= SD_RADV_STATE_IDLE
)
434 ra
->ifindex
= ifindex
;
439 _public_
int sd_radv_set_mac(sd_radv
*ra
, const struct ether_addr
*mac_addr
) {
440 assert_return(ra
, -EINVAL
);
442 if (ra
->state
!= SD_RADV_STATE_IDLE
)
446 ra
->mac_addr
= *mac_addr
;
453 _public_
int sd_radv_set_mtu(sd_radv
*ra
, uint32_t mtu
) {
454 assert_return(ra
, -EINVAL
);
455 assert_return(mtu
>= 1280, -EINVAL
);
462 _public_
int sd_radv_set_hop_limit(sd_radv
*ra
, uint8_t hop_limit
) {
463 assert_return(ra
, -EINVAL
);
465 if (ra
->state
!= SD_RADV_STATE_IDLE
)
468 ra
->hop_limit
= hop_limit
;
473 _public_
int sd_radv_set_router_lifetime(sd_radv
*ra
, uint32_t router_lifetime
) {
474 assert_return(ra
, -EINVAL
);
476 if (ra
->state
!= SD_RADV_STATE_IDLE
)
479 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the
480 preference value MUST be set to (00) by the sender..." */
481 if (router_lifetime
== 0 &&
482 (ra
->flags
& (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM
<< 3))
485 ra
->lifetime
= router_lifetime
;
490 _public_
int sd_radv_set_managed_information(sd_radv
*ra
, int managed
) {
491 assert_return(ra
, -EINVAL
);
493 if (ra
->state
!= SD_RADV_STATE_IDLE
)
496 SET_FLAG(ra
->flags
, ND_RA_FLAG_MANAGED
, managed
);
501 _public_
int sd_radv_set_other_information(sd_radv
*ra
, int other
) {
502 assert_return(ra
, -EINVAL
);
504 if (ra
->state
!= SD_RADV_STATE_IDLE
)
507 SET_FLAG(ra
->flags
, ND_RA_FLAG_OTHER
, other
);
512 _public_
int sd_radv_set_preference(sd_radv
*ra
, unsigned preference
) {
515 assert_return(ra
, -EINVAL
);
516 assert_return(IN_SET(preference
,
517 SD_NDISC_PREFERENCE_LOW
,
518 SD_NDISC_PREFERENCE_MEDIUM
,
519 SD_NDISC_PREFERENCE_HIGH
), -EINVAL
);
521 ra
->flags
= (ra
->flags
& ~(0x3 << 3)) | (preference
<< 3);
526 _public_
int sd_radv_add_prefix(sd_radv
*ra
, sd_radv_prefix
*p
, bool dynamic
) {
529 _cleanup_free_
char *addr_p
= NULL
;
530 char time_string_preferred
[FORMAT_TIMESPAN_MAX
];
531 char time_string_valid
[FORMAT_TIMESPAN_MAX
];
532 usec_t time_now
, valid
, preferred
, valid_until
, preferred_until
;
534 assert_return(ra
, -EINVAL
);
539 LIST_FOREACH(prefix
, cur
, ra
->prefixes
) {
541 r
= in_addr_prefix_intersect(AF_INET6
,
542 (union in_addr_union
*) &cur
->opt
.in6_addr
,
544 (union in_addr_union
*) &p
->opt
.in6_addr
,
547 _cleanup_free_
char *addr_cur
= NULL
;
549 (void) in_addr_to_string(AF_INET6
,
550 (union in_addr_union
*) &p
->opt
.in6_addr
,
553 if (dynamic
&& cur
->opt
.prefixlen
== p
->opt
.prefixlen
)
556 (void) in_addr_to_string(AF_INET6
,
557 (union in_addr_union
*) &cur
->opt
.in6_addr
,
559 log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
560 addr_cur
, cur
->opt
.prefixlen
,
561 addr_p
, p
->opt
.prefixlen
);
567 p
= sd_radv_prefix_ref(p
);
569 LIST_APPEND(prefix
, ra
->prefixes
, p
);
573 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &p
->opt
.in6_addr
, &addr_p
);
576 log_radv("Added prefix %s/%d", addr_p
, p
->opt
.prefixlen
);
583 r
= sd_event_now(ra
->event
, clock_boottime_or_monotonic(), &time_now
);
587 valid
= be32toh(p
->opt
.valid_lifetime
) * USEC_PER_SEC
;
588 valid_until
= usec_add(valid
, time_now
);
589 if (valid_until
== USEC_INFINITY
)
592 preferred
= be32toh(p
->opt
.preferred_lifetime
) * USEC_PER_SEC
;
593 preferred_until
= usec_add(preferred
, time_now
);
594 if (preferred_until
== USEC_INFINITY
)
597 cur
->valid_until
= valid_until
;
598 cur
->preferred_until
= preferred_until
;
600 log_radv("%s prefix %s/%u preferred %s valid %s",
601 cur
? "Updated": "Added",
602 addr_p
, p
->opt
.prefixlen
,
603 format_timespan(time_string_preferred
, FORMAT_TIMESPAN_MAX
,
604 preferred
, USEC_PER_SEC
),
605 format_timespan(time_string_valid
, FORMAT_TIMESPAN_MAX
,
606 valid
, USEC_PER_SEC
));
611 _public_ sd_radv_prefix
*sd_radv_remove_prefix(sd_radv
*ra
,
612 const struct in6_addr
*prefix
,
613 unsigned char prefixlen
) {
614 sd_radv_prefix
*cur
, *next
;
616 assert_return(ra
, NULL
);
617 assert_return(prefix
, NULL
);
619 LIST_FOREACH_SAFE(prefix
, cur
, next
, ra
->prefixes
) {
620 if (prefixlen
!= cur
->opt
.prefixlen
)
623 if (!in_addr_equal(AF_INET6
,
624 (union in_addr_union
*)prefix
,
625 (union in_addr_union
*)&cur
->opt
.in6_addr
))
628 LIST_REMOVE(prefix
, ra
->prefixes
, cur
);
637 _public_
int sd_radv_set_rdnss(sd_radv
*ra
, uint32_t lifetime
,
638 const struct in6_addr
*dns
, size_t n_dns
) {
639 _cleanup_free_
struct sd_radv_opt_dns
*opt_rdnss
= NULL
;
642 assert_return(ra
, -EINVAL
);
643 assert_return(n_dns
< 128, -EINVAL
);
645 if (!dns
|| n_dns
== 0) {
646 ra
->rdnss
= mfree(ra
->rdnss
);
652 len
= sizeof(struct sd_radv_opt_dns
) + sizeof(struct in6_addr
) * n_dns
;
654 opt_rdnss
= malloc0(len
);
658 opt_rdnss
->type
= SD_RADV_OPT_RDNSS
;
659 opt_rdnss
->length
= len
/ 8;
660 opt_rdnss
->lifetime
= htobe32(lifetime
);
662 memcpy(opt_rdnss
+ 1, dns
, n_dns
* sizeof(struct in6_addr
));
664 free_and_replace(ra
->rdnss
, opt_rdnss
);
671 _public_
int sd_radv_set_dnssl(sd_radv
*ra
, uint32_t lifetime
,
672 char **search_list
) {
673 _cleanup_free_
struct sd_radv_opt_dns
*opt_dnssl
= NULL
;
678 assert_return(ra
, -EINVAL
);
680 if (strv_isempty(search_list
)) {
681 ra
->dnssl
= mfree(ra
->dnssl
);
685 STRV_FOREACH(s
, search_list
)
686 len
+= strlen(*s
) + 2;
688 len
= (sizeof(struct sd_radv_opt_dns
) + len
+ 7) & ~0x7;
690 opt_dnssl
= malloc0(len
);
694 opt_dnssl
->type
= SD_RADV_OPT_DNSSL
;
695 opt_dnssl
->length
= len
/ 8;
696 opt_dnssl
->lifetime
= htobe32(lifetime
);
698 p
= (uint8_t *)(opt_dnssl
+ 1);
699 len
-= sizeof(struct sd_radv_opt_dns
);
701 STRV_FOREACH(s
, search_list
) {
704 r
= dns_name_to_wire_format(*s
, p
, len
, false);
715 free_and_replace(ra
->dnssl
, opt_dnssl
);
720 _public_
int sd_radv_prefix_new(sd_radv_prefix
**ret
) {
721 _cleanup_(sd_radv_prefix_unrefp
) sd_radv_prefix
*p
= NULL
;
723 assert_return(ret
, -EINVAL
);
725 p
= new0(sd_radv_prefix
, 1);
731 p
->opt
.type
= ND_OPT_PREFIX_INFORMATION
;
732 p
->opt
.length
= (sizeof(p
->opt
) - 1) /8 + 1;
734 p
->opt
.prefixlen
= 64;
736 /* RFC 4861, Section 6.2.1 */
737 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, true);
738 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, true);
739 p
->opt
.preferred_lifetime
= htobe32(604800);
740 p
->opt
.valid_lifetime
= htobe32(2592000);
742 LIST_INIT(prefix
, p
);
749 _public_ sd_radv_prefix
*sd_radv_prefix_ref(sd_radv_prefix
*p
) {
753 assert(p
->n_ref
> 0);
759 _public_ sd_radv_prefix
*sd_radv_prefix_unref(sd_radv_prefix
*p
) {
763 assert(p
->n_ref
> 0);
772 _public_
int sd_radv_prefix_set_prefix(sd_radv_prefix
*p
, const struct in6_addr
*in6_addr
,
773 unsigned char prefixlen
) {
774 assert_return(p
, -EINVAL
);
775 assert_return(in6_addr
, -EINVAL
);
777 if (prefixlen
< 3 || prefixlen
> 128)
781 /* unusual but allowed, log it */
782 log_radv("Unusual prefix length %d greater than 64", prefixlen
);
784 p
->opt
.in6_addr
= *in6_addr
;
785 p
->opt
.prefixlen
= prefixlen
;
790 _public_
int sd_radv_prefix_set_onlink(sd_radv_prefix
*p
, int onlink
) {
791 assert_return(p
, -EINVAL
);
793 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, onlink
);
798 _public_
int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix
*p
,
799 int address_autoconfiguration
) {
800 assert_return(p
, -EINVAL
);
802 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, address_autoconfiguration
);
807 _public_
int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix
*p
,
808 uint32_t valid_lifetime
) {
809 assert_return(p
, -EINVAL
);
811 p
->opt
.valid_lifetime
= htobe32(valid_lifetime
);
816 _public_
int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix
*p
,
817 uint32_t preferred_lifetime
) {
818 assert_return(p
, -EINVAL
);
820 p
->opt
.preferred_lifetime
= htobe32(preferred_lifetime
);