1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright (C) 2017 Intel Corporation. All rights reserved.
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 #include <netinet/icmp6.h>
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
28 #include "alloc-util.h"
29 #include "dns-domain.h"
31 #include "icmp6-util.h"
32 #include "in-addr-util.h"
33 #include "radv-internal.h"
34 #include "socket-util.h"
35 #include "string-util.h"
38 #include "random-util.h"
40 _public_
int sd_radv_new(sd_radv
**ret
) {
41 _cleanup_(sd_radv_unrefp
) sd_radv
*ra
= NULL
;
43 assert_return(ret
, -EINVAL
);
45 ra
= new0(sd_radv
, 1);
52 LIST_HEAD_INIT(ra
->prefixes
);
60 _public_
int sd_radv_attach_event(sd_radv
*ra
, sd_event
*event
, int64_t priority
) {
63 assert_return(ra
, -EINVAL
);
64 assert_return(!ra
->event
, -EBUSY
);
67 ra
->event
= sd_event_ref(event
);
69 r
= sd_event_default(&ra
->event
);
74 ra
->event_priority
= priority
;
79 _public_
int sd_radv_detach_event(sd_radv
*ra
) {
81 assert_return(ra
, -EINVAL
);
83 ra
->event
= sd_event_unref(ra
->event
);
87 _public_ sd_event
*sd_radv_get_event(sd_radv
*ra
) {
88 assert_return(ra
, NULL
);
93 static void radv_reset(sd_radv
*ra
) {
95 ra
->timeout_event_source
=
96 sd_event_source_unref(ra
->timeout_event_source
);
98 ra
->recv_event_source
=
99 sd_event_source_unref(ra
->recv_event_source
);
104 _public_ sd_radv
*sd_radv_ref(sd_radv
*ra
) {
108 assert(ra
->n_ref
> 0);
114 _public_ sd_radv
*sd_radv_unref(sd_radv
*ra
) {
118 assert(ra
->n_ref
> 0);
124 while (ra
->prefixes
) {
125 sd_radv_prefix
*p
= ra
->prefixes
;
127 LIST_REMOVE(prefix
, ra
->prefixes
, p
);
128 sd_radv_prefix_unref(p
);
136 sd_radv_detach_event(ra
);
140 static int radv_send(sd_radv
*ra
, const struct in6_addr
*dst
,
141 const uint32_t router_lifetime
) {
142 static const struct ether_addr mac_zero
= {};
144 struct sockaddr_in6 dst_addr
= {
145 .sin6_family
= AF_INET6
,
146 .sin6_addr
= IN6ADDR_ALL_NODES_MULTICAST_INIT
,
148 struct nd_router_advert adv
= {};
150 struct nd_opt_hdr opthdr
;
151 struct ether_addr slladdr
;
152 } _packed_ opt_mac
= {
154 .nd_opt_type
= ND_OPT_SOURCE_LINKADDR
,
155 .nd_opt_len
= (sizeof(struct nd_opt_hdr
) +
156 sizeof(struct ether_addr
) - 1) /8 + 1,
159 struct nd_opt_mtu opt_mtu
= {
160 .nd_opt_mtu_type
= ND_OPT_MTU
,
163 /* Reserve iov space for RA header, linkaddr, MTU, N prefixes, RDNSS
165 struct iovec iov
[5 + ra
->n_prefixes
];
166 struct msghdr msg
= {
167 .msg_name
= &dst_addr
,
168 .msg_namelen
= sizeof(dst_addr
),
174 r
= sd_event_now(ra
->event
, clock_boottime_or_monotonic(), &time_now
);
178 if (dst
&& !in_addr_is_null(AF_INET6
, (union in_addr_union
*) dst
))
179 dst_addr
.sin6_addr
= *dst
;
181 adv
.nd_ra_type
= ND_ROUTER_ADVERT
;
182 adv
.nd_ra_curhoplimit
= ra
->hop_limit
;
183 adv
.nd_ra_flags_reserved
= ra
->flags
;
184 adv
.nd_ra_router_lifetime
= htobe16(router_lifetime
);
185 iov
[msg
.msg_iovlen
].iov_base
= &adv
;
186 iov
[msg
.msg_iovlen
].iov_len
= sizeof(adv
);
189 /* MAC address is optional, either because the link does not use L2
190 addresses or load sharing is desired. See RFC 4861, Section 4.2 */
191 if (memcmp(&mac_zero
, &ra
->mac_addr
, sizeof(mac_zero
))) {
192 opt_mac
.slladdr
= ra
->mac_addr
;
193 iov
[msg
.msg_iovlen
].iov_base
= &opt_mac
;
194 iov
[msg
.msg_iovlen
].iov_len
= sizeof(opt_mac
);
199 opt_mtu
.nd_opt_mtu_mtu
= htobe32(ra
->mtu
);
200 iov
[msg
.msg_iovlen
].iov_base
= &opt_mtu
;
201 iov
[msg
.msg_iovlen
].iov_len
= sizeof(opt_mtu
);
205 LIST_FOREACH(prefix
, p
, ra
->prefixes
) {
206 if (p
->valid_until
) {
208 if (time_now
> p
->valid_until
)
209 p
->opt
.valid_lifetime
= 0;
211 p
->opt
.valid_lifetime
= htobe32((p
->valid_until
- time_now
) / USEC_PER_SEC
);
213 if (time_now
> p
->preferred_until
)
214 p
->opt
.preferred_lifetime
= 0;
216 p
->opt
.preferred_lifetime
= htobe32((p
->preferred_until
- time_now
) / USEC_PER_SEC
);
218 iov
[msg
.msg_iovlen
].iov_base
= &p
->opt
;
219 iov
[msg
.msg_iovlen
].iov_len
= sizeof(p
->opt
);
224 iov
[msg
.msg_iovlen
].iov_base
= ra
->rdnss
;
225 iov
[msg
.msg_iovlen
].iov_len
= ra
->rdnss
->length
* 8;
230 iov
[msg
.msg_iovlen
].iov_base
= ra
->dnssl
;
231 iov
[msg
.msg_iovlen
].iov_len
= ra
->dnssl
->length
* 8;
235 if (sendmsg(ra
->fd
, &msg
, 0) < 0)
241 static int radv_recv(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
242 sd_radv
*ra
= userdata
;
243 _cleanup_free_
char *addr
= NULL
;
245 triple_timestamp timestamp
;
248 _cleanup_free_
char *buf
= NULL
;
254 buflen
= next_datagram_size_fd(fd
);
256 if ((unsigned) buflen
< sizeof(struct nd_router_solicit
))
257 return log_radv("Too short packet received");
259 buf
= new0(char, buflen
);
263 r
= icmp6_receive(fd
, buf
, buflen
, &src
, ×tamp
);
267 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &src
, &addr
);
268 log_radv("Received RS from non-link-local address %s. Ignoring", addr
);
272 log_radv("Received RS with invalid hop limit. Ignoring.");
276 log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
280 log_radv_warning_errno(r
, "Error receiving from ICMPv6 socket: %m");
287 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &src
, &addr
);
289 r
= radv_send(ra
, &src
, ra
->lifetime
);
291 log_radv_warning_errno(r
, "Unable to send solicited Router Advertisment to %s: %m", addr
);
293 log_radv("Sent solicited Router Advertisement to %s", addr
);
298 static usec_t
radv_compute_timeout(usec_t min
, usec_t max
) {
299 assert_return(min
<= max
, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
);
301 return min
+ (random_u32() % (max
- min
));
304 static int radv_timeout(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
306 sd_radv
*ra
= userdata
;
307 usec_t min_timeout
= SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
;
308 usec_t max_timeout
= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC
;
309 usec_t time_now
, timeout
;
310 char time_string
[FORMAT_TIMESPAN_MAX
];
316 ra
->timeout_event_source
= sd_event_source_unref(ra
->timeout_event_source
);
318 r
= sd_event_now(ra
->event
, clock_boottime_or_monotonic(), &time_now
);
322 r
= radv_send(ra
, NULL
, ra
->lifetime
);
324 log_radv_warning_errno(r
, "Unable to send Router Advertisement: %m");
326 /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
327 if (ra
->ra_sent
< SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS
) {
328 max_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
;
329 min_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
/ 3;
332 timeout
= radv_compute_timeout(min_timeout
, max_timeout
);
334 log_radv("Next Router Advertisement in %s",
335 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
336 timeout
, USEC_PER_SEC
));
338 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
339 clock_boottime_or_monotonic(),
340 time_now
+ timeout
, MSEC_PER_SEC
,
345 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
350 r
= sd_event_source_set_description(ra
->timeout_event_source
,
364 _public_
int sd_radv_stop(sd_radv
*ra
) {
367 assert_return(ra
, -EINVAL
);
369 log_radv("Stopping IPv6 Router Advertisement daemon");
371 /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
372 with zero lifetime */
373 r
= radv_send(ra
, NULL
, 0);
375 log_radv_warning_errno(r
, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
378 ra
->fd
= safe_close(ra
->fd
);
379 ra
->state
= SD_RADV_STATE_IDLE
;
384 _public_
int sd_radv_start(sd_radv
*ra
) {
387 assert_return(ra
, -EINVAL
);
388 assert_return(ra
->event
, -EINVAL
);
389 assert_return(ra
->ifindex
> 0, -EINVAL
);
391 if (ra
->state
!= SD_RADV_STATE_IDLE
)
394 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
395 clock_boottime_or_monotonic(), 0, 0,
400 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
405 (void) sd_event_source_set_description(ra
->timeout_event_source
,
408 r
= icmp6_bind_router_advertisement(ra
->ifindex
);
414 r
= sd_event_add_io(ra
->event
, &ra
->recv_event_source
, ra
->fd
, EPOLLIN
, radv_recv
, ra
);
418 r
= sd_event_source_set_priority(ra
->recv_event_source
, ra
->event_priority
);
422 (void) sd_event_source_set_description(ra
->recv_event_source
, "radv-receive-message");
424 ra
->state
= SD_RADV_STATE_ADVERTISING
;
426 log_radv("Started IPv6 Router Advertisement daemon");
436 _public_
int sd_radv_set_ifindex(sd_radv
*ra
, int ifindex
) {
437 assert_return(ra
, -EINVAL
);
438 assert_return(ifindex
>= -1, -EINVAL
);
440 if (ra
->state
!= SD_RADV_STATE_IDLE
)
443 ra
->ifindex
= ifindex
;
448 _public_
int sd_radv_set_mac(sd_radv
*ra
, const struct ether_addr
*mac_addr
) {
449 assert_return(ra
, -EINVAL
);
451 if (ra
->state
!= SD_RADV_STATE_IDLE
)
455 ra
->mac_addr
= *mac_addr
;
462 _public_
int sd_radv_set_mtu(sd_radv
*ra
, uint32_t mtu
) {
463 assert_return(ra
, -EINVAL
);
464 assert_return(mtu
>= 1280, -EINVAL
);
471 _public_
int sd_radv_set_hop_limit(sd_radv
*ra
, uint8_t hop_limit
) {
472 assert_return(ra
, -EINVAL
);
474 if (ra
->state
!= SD_RADV_STATE_IDLE
)
477 ra
->hop_limit
= hop_limit
;
482 _public_
int sd_radv_set_router_lifetime(sd_radv
*ra
, uint32_t router_lifetime
) {
483 assert_return(ra
, -EINVAL
);
485 if (ra
->state
!= SD_RADV_STATE_IDLE
)
488 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the
489 preference value MUST be set to (00) by the sender..." */
490 if (router_lifetime
== 0 &&
491 (ra
->flags
& (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM
<< 3))
494 ra
->lifetime
= router_lifetime
;
499 _public_
int sd_radv_set_managed_information(sd_radv
*ra
, int managed
) {
500 assert_return(ra
, -EINVAL
);
502 if (ra
->state
!= SD_RADV_STATE_IDLE
)
505 SET_FLAG(ra
->flags
, ND_RA_FLAG_MANAGED
, managed
);
510 _public_
int sd_radv_set_other_information(sd_radv
*ra
, int other
) {
511 assert_return(ra
, -EINVAL
);
513 if (ra
->state
!= SD_RADV_STATE_IDLE
)
516 SET_FLAG(ra
->flags
, ND_RA_FLAG_OTHER
, other
);
521 _public_
int sd_radv_set_preference(sd_radv
*ra
, unsigned preference
) {
524 assert_return(ra
, -EINVAL
);
525 assert_return(IN_SET(preference
,
526 SD_NDISC_PREFERENCE_LOW
,
527 SD_NDISC_PREFERENCE_MEDIUM
,
528 SD_NDISC_PREFERENCE_HIGH
), -EINVAL
);
530 ra
->flags
= (ra
->flags
& ~(0x3 << 3)) | (preference
<< 3);
535 _public_
int sd_radv_add_prefix(sd_radv
*ra
, sd_radv_prefix
*p
, bool dynamic
) {
538 _cleanup_free_
char *addr_p
= NULL
;
539 char time_string_preferred
[FORMAT_TIMESPAN_MAX
];
540 char time_string_valid
[FORMAT_TIMESPAN_MAX
];
541 usec_t time_now
, valid
, preferred
, valid_until
, preferred_until
;
543 assert_return(ra
, -EINVAL
);
548 LIST_FOREACH(prefix
, cur
, ra
->prefixes
) {
550 r
= in_addr_prefix_intersect(AF_INET6
,
551 (union in_addr_union
*) &cur
->opt
.in6_addr
,
553 (union in_addr_union
*) &p
->opt
.in6_addr
,
556 _cleanup_free_
char *addr_cur
= NULL
;
558 (void) in_addr_to_string(AF_INET6
,
559 (union in_addr_union
*) &p
->opt
.in6_addr
,
562 if (dynamic
&& cur
->opt
.prefixlen
== p
->opt
.prefixlen
)
565 (void) in_addr_to_string(AF_INET6
,
566 (union in_addr_union
*) &cur
->opt
.in6_addr
,
568 log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
569 addr_cur
, cur
->opt
.prefixlen
,
570 addr_p
, p
->opt
.prefixlen
);
576 p
= sd_radv_prefix_ref(p
);
578 LIST_APPEND(prefix
, ra
->prefixes
, p
);
582 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &p
->opt
.in6_addr
, &addr_p
);
585 log_radv("Added prefix %s/%d", addr_p
, p
->opt
.prefixlen
);
592 r
= sd_event_now(ra
->event
, clock_boottime_or_monotonic(), &time_now
);
596 valid
= be32toh(p
->opt
.valid_lifetime
) * USEC_PER_SEC
;
597 valid_until
= usec_add(valid
, time_now
);
598 if (valid_until
== USEC_INFINITY
)
601 preferred
= be32toh(p
->opt
.preferred_lifetime
) * USEC_PER_SEC
;
602 preferred_until
= usec_add(preferred
, time_now
);
603 if (preferred_until
== USEC_INFINITY
)
606 cur
->valid_until
= valid_until
;
607 cur
->preferred_until
= preferred_until
;
609 log_radv("%s prefix %s/%u preferred %s valid %s",
610 cur
? "Updated": "Added",
611 addr_p
, p
->opt
.prefixlen
,
612 format_timespan(time_string_preferred
, FORMAT_TIMESPAN_MAX
,
613 preferred
, USEC_PER_SEC
),
614 format_timespan(time_string_valid
, FORMAT_TIMESPAN_MAX
,
615 valid
, USEC_PER_SEC
));
620 _public_ sd_radv_prefix
*sd_radv_remove_prefix(sd_radv
*ra
,
621 struct in6_addr
*prefix
,
623 sd_radv_prefix
*cur
, *next
;
625 assert_return(ra
, NULL
);
626 assert_return(prefix
, NULL
);
628 LIST_FOREACH_SAFE(prefix
, cur
, next
, ra
->prefixes
) {
629 if (prefixlen
!= cur
->opt
.prefixlen
)
632 if (!in_addr_equal(AF_INET6
,
633 (union in_addr_union
*)prefix
,
634 (union in_addr_union
*)&cur
->opt
.in6_addr
))
637 LIST_REMOVE(prefix
, ra
->prefixes
, cur
);
646 _public_
int sd_radv_set_rdnss(sd_radv
*ra
, uint32_t lifetime
,
647 const struct in6_addr
*dns
, size_t n_dns
) {
648 _cleanup_free_
struct sd_radv_opt_dns
*opt_rdnss
= NULL
;
651 assert_return(ra
, -EINVAL
);
652 assert_return(n_dns
< 128, -EINVAL
);
654 if (!dns
|| n_dns
== 0) {
655 ra
->rdnss
= mfree(ra
->rdnss
);
661 len
= sizeof(struct sd_radv_opt_dns
) + sizeof(struct in6_addr
) * n_dns
;
663 opt_rdnss
= malloc0(len
);
667 opt_rdnss
->type
= SD_RADV_OPT_RDNSS
;
668 opt_rdnss
->length
= len
/ 8;
669 opt_rdnss
->lifetime
= htobe32(lifetime
);
671 memcpy(opt_rdnss
+ 1, dns
, n_dns
* sizeof(struct in6_addr
));
674 ra
->rdnss
= opt_rdnss
;
682 _public_
int sd_radv_set_dnssl(sd_radv
*ra
, uint32_t lifetime
,
683 char **search_list
) {
684 _cleanup_free_
struct sd_radv_opt_dns
*opt_dnssl
= NULL
;
689 assert_return(ra
, -EINVAL
);
691 if (!search_list
|| *search_list
== NULL
) {
692 ra
->dnssl
= mfree(ra
->dnssl
);
697 STRV_FOREACH(s
, search_list
)
698 len
+= strlen(*s
) + 2;
700 len
= (sizeof(struct sd_radv_opt_dns
) + len
+ 7) & ~0x7;
702 opt_dnssl
= malloc0(len
);
706 opt_dnssl
->type
= SD_RADV_OPT_DNSSL
;
707 opt_dnssl
->length
= len
/ 8;
708 opt_dnssl
->lifetime
= htobe32(lifetime
);
710 p
= (uint8_t *)(opt_dnssl
+ 1);
711 len
-= sizeof(struct sd_radv_opt_dns
);
713 STRV_FOREACH(s
, search_list
) {
716 r
= dns_name_to_wire_format(*s
, p
, len
, false);
728 ra
->dnssl
= opt_dnssl
;
734 _public_
int sd_radv_prefix_new(sd_radv_prefix
**ret
) {
735 _cleanup_(sd_radv_prefix_unrefp
) sd_radv_prefix
*p
= NULL
;
737 assert_return(ret
, -EINVAL
);
739 p
= new0(sd_radv_prefix
, 1);
745 p
->opt
.type
= ND_OPT_PREFIX_INFORMATION
;
746 p
->opt
.length
= (sizeof(p
->opt
) - 1) /8 + 1;
748 p
->opt
.prefixlen
= 64;
750 /* RFC 4861, Section 6.2.1 */
751 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, true);
752 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, true);
753 p
->opt
.preferred_lifetime
= htobe32(604800);
754 p
->opt
.valid_lifetime
= htobe32(2592000);
756 LIST_INIT(prefix
, p
);
764 _public_ sd_radv_prefix
*sd_radv_prefix_ref(sd_radv_prefix
*p
) {
768 assert(p
->n_ref
> 0);
774 _public_ sd_radv_prefix
*sd_radv_prefix_unref(sd_radv_prefix
*p
) {
778 assert(p
->n_ref
> 0);
787 _public_
int sd_radv_prefix_set_prefix(sd_radv_prefix
*p
, struct in6_addr
*in6_addr
,
788 unsigned char prefixlen
) {
789 assert_return(p
, -EINVAL
);
790 assert_return(in6_addr
, -EINVAL
);
792 if (prefixlen
< 3 || prefixlen
> 128)
796 /* unusual but allowed, log it */
797 log_radv("Unusual prefix length %d greater than 64", prefixlen
);
799 p
->opt
.in6_addr
= *in6_addr
;
800 p
->opt
.prefixlen
= prefixlen
;
805 _public_
int sd_radv_prefix_set_onlink(sd_radv_prefix
*p
, int onlink
) {
806 assert_return(p
, -EINVAL
);
808 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, onlink
);
813 _public_
int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix
*p
,
814 int address_autoconfiguration
) {
815 assert_return(p
, -EINVAL
);
817 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, address_autoconfiguration
);
822 _public_
int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix
*p
,
823 uint32_t valid_lifetime
) {
824 assert_return(p
, -EINVAL
);
826 p
->opt
.valid_lifetime
= htobe32(valid_lifetime
);
831 _public_
int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix
*p
,
832 uint32_t preferred_lifetime
) {
833 assert_return(p
, -EINVAL
);
835 p
->opt
.preferred_lifetime
= htobe32(preferred_lifetime
);