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
),
172 if (dst
&& !in_addr_is_null(AF_INET6
, (union in_addr_union
*) dst
))
173 dst_addr
.sin6_addr
= *dst
;
175 adv
.nd_ra_type
= ND_ROUTER_ADVERT
;
176 adv
.nd_ra_curhoplimit
= ra
->hop_limit
;
177 adv
.nd_ra_flags_reserved
= ra
->flags
;
178 adv
.nd_ra_router_lifetime
= htobe16(router_lifetime
);
179 iov
[msg
.msg_iovlen
].iov_base
= &adv
;
180 iov
[msg
.msg_iovlen
].iov_len
= sizeof(adv
);
183 /* MAC address is optional, either because the link does not use L2
184 addresses or load sharing is desired. See RFC 4861, Section 4.2 */
185 if (memcmp(&mac_zero
, &ra
->mac_addr
, sizeof(mac_zero
))) {
186 opt_mac
.slladdr
= ra
->mac_addr
;
187 iov
[msg
.msg_iovlen
].iov_base
= &opt_mac
;
188 iov
[msg
.msg_iovlen
].iov_len
= sizeof(opt_mac
);
193 opt_mtu
.nd_opt_mtu_mtu
= htobe32(ra
->mtu
);
194 iov
[msg
.msg_iovlen
].iov_base
= &opt_mtu
;
195 iov
[msg
.msg_iovlen
].iov_len
= sizeof(opt_mtu
);
199 LIST_FOREACH(prefix
, p
, ra
->prefixes
) {
200 iov
[msg
.msg_iovlen
].iov_base
= &p
->opt
;
201 iov
[msg
.msg_iovlen
].iov_len
= sizeof(p
->opt
);
206 iov
[msg
.msg_iovlen
].iov_base
= ra
->rdnss
;
207 iov
[msg
.msg_iovlen
].iov_len
= ra
->rdnss
->length
* 8;
212 iov
[msg
.msg_iovlen
].iov_base
= ra
->dnssl
;
213 iov
[msg
.msg_iovlen
].iov_len
= ra
->dnssl
->length
* 8;
217 if (sendmsg(ra
->fd
, &msg
, 0) < 0)
223 static int radv_recv(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
224 sd_radv
*ra
= userdata
;
225 _cleanup_free_
char *addr
= NULL
;
227 triple_timestamp timestamp
;
230 _cleanup_free_
char *buf
= NULL
;
236 buflen
= next_datagram_size_fd(fd
);
238 if ((unsigned) buflen
< sizeof(struct nd_router_solicit
))
239 return log_radv("Too short packet received");
241 buf
= new0(char, buflen
);
245 r
= icmp6_receive(fd
, buf
, buflen
, &src
, ×tamp
);
249 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &src
, &addr
);
250 log_radv("Received RS from non-link-local address %s. Ignoring", addr
);
254 log_radv("Received RS with invalid hop limit. Ignoring.");
258 log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
262 log_radv_warning_errno(r
, "Error receiving from ICMPv6 socket: %m");
269 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &src
, &addr
);
271 r
= radv_send(ra
, &src
, ra
->lifetime
);
273 log_radv_warning_errno(r
, "Unable to send solicited Router Advertisment to %s: %m", addr
);
275 log_radv("Sent solicited Router Advertisement to %s", addr
);
280 static usec_t
radv_compute_timeout(usec_t min
, usec_t max
) {
281 assert_return(min
<= max
, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
);
283 return min
+ (random_u32() % (max
- min
));
286 static int radv_timeout(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
288 sd_radv
*ra
= userdata
;
289 usec_t min_timeout
= SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
;
290 usec_t max_timeout
= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC
;
291 usec_t time_now
, timeout
;
292 char time_string
[FORMAT_TIMESPAN_MAX
];
298 ra
->timeout_event_source
= sd_event_source_unref(ra
->timeout_event_source
);
300 r
= sd_event_now(ra
->event
, clock_boottime_or_monotonic(), &time_now
);
304 r
= radv_send(ra
, NULL
, ra
->lifetime
);
306 log_radv_warning_errno(r
, "Unable to send Router Advertisement: %m");
308 /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
309 if (ra
->ra_sent
< SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS
) {
310 max_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
;
311 min_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
/ 3;
314 timeout
= radv_compute_timeout(min_timeout
, max_timeout
);
316 log_radv("Next Router Advertisement in %s",
317 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
318 timeout
, USEC_PER_SEC
));
320 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
321 clock_boottime_or_monotonic(),
322 time_now
+ timeout
, MSEC_PER_SEC
,
327 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
332 r
= sd_event_source_set_description(ra
->timeout_event_source
,
346 _public_
int sd_radv_stop(sd_radv
*ra
) {
349 assert_return(ra
, -EINVAL
);
351 log_radv("Stopping IPv6 Router Advertisement daemon");
353 /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
354 with zero lifetime */
355 r
= radv_send(ra
, NULL
, 0);
357 log_radv_warning_errno(r
, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
360 ra
->fd
= safe_close(ra
->fd
);
361 ra
->state
= SD_RADV_STATE_IDLE
;
366 _public_
int sd_radv_start(sd_radv
*ra
) {
369 assert_return(ra
, -EINVAL
);
370 assert_return(ra
->event
, -EINVAL
);
371 assert_return(ra
->ifindex
> 0, -EINVAL
);
373 if (ra
->state
!= SD_RADV_STATE_IDLE
)
376 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
377 clock_boottime_or_monotonic(), 0, 0,
382 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
387 (void) sd_event_source_set_description(ra
->timeout_event_source
,
390 r
= icmp6_bind_router_advertisement(ra
->ifindex
);
396 r
= sd_event_add_io(ra
->event
, &ra
->recv_event_source
, ra
->fd
, EPOLLIN
, radv_recv
, ra
);
400 r
= sd_event_source_set_priority(ra
->recv_event_source
, ra
->event_priority
);
404 (void) sd_event_source_set_description(ra
->recv_event_source
, "radv-receive-message");
406 ra
->state
= SD_RADV_STATE_ADVERTISING
;
408 log_radv("Started IPv6 Router Advertisement daemon");
418 _public_
int sd_radv_set_ifindex(sd_radv
*ra
, int ifindex
) {
419 assert_return(ra
, -EINVAL
);
420 assert_return(ifindex
>= -1, -EINVAL
);
422 if (ra
->state
!= SD_RADV_STATE_IDLE
)
425 ra
->ifindex
= ifindex
;
430 _public_
int sd_radv_set_mac(sd_radv
*ra
, const struct ether_addr
*mac_addr
) {
431 assert_return(ra
, -EINVAL
);
433 if (ra
->state
!= SD_RADV_STATE_IDLE
)
437 ra
->mac_addr
= *mac_addr
;
444 _public_
int sd_radv_set_mtu(sd_radv
*ra
, uint32_t mtu
) {
445 assert_return(ra
, -EINVAL
);
446 assert_return(mtu
>= 1280, -EINVAL
);
448 if (ra
->state
!= SD_RADV_STATE_IDLE
)
456 _public_
int sd_radv_set_hop_limit(sd_radv
*ra
, uint8_t hop_limit
) {
457 assert_return(ra
, -EINVAL
);
459 if (ra
->state
!= SD_RADV_STATE_IDLE
)
462 ra
->hop_limit
= hop_limit
;
467 _public_
int sd_radv_set_router_lifetime(sd_radv
*ra
, uint32_t router_lifetime
) {
468 assert_return(ra
, -EINVAL
);
470 if (ra
->state
!= SD_RADV_STATE_IDLE
)
473 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the
474 preference value MUST be set to (00) by the sender..." */
475 if (router_lifetime
== 0 &&
476 (ra
->flags
& (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM
<< 3))
479 ra
->lifetime
= router_lifetime
;
484 _public_
int sd_radv_set_managed_information(sd_radv
*ra
, int managed
) {
485 assert_return(ra
, -EINVAL
);
487 if (ra
->state
!= SD_RADV_STATE_IDLE
)
490 SET_FLAG(ra
->flags
, ND_RA_FLAG_MANAGED
, managed
);
495 _public_
int sd_radv_set_other_information(sd_radv
*ra
, int other
) {
496 assert_return(ra
, -EINVAL
);
498 if (ra
->state
!= SD_RADV_STATE_IDLE
)
501 SET_FLAG(ra
->flags
, ND_RA_FLAG_OTHER
, other
);
506 _public_
int sd_radv_set_preference(sd_radv
*ra
, unsigned preference
) {
509 assert_return(ra
, -EINVAL
);
510 assert_return(IN_SET(preference
,
511 SD_NDISC_PREFERENCE_LOW
,
512 SD_NDISC_PREFERENCE_MEDIUM
,
513 SD_NDISC_PREFERENCE_HIGH
), -EINVAL
);
515 ra
->flags
= (ra
->flags
& ~(0x3 << 3)) | (preference
<< 3);
520 _public_
int sd_radv_add_prefix(sd_radv
*ra
, sd_radv_prefix
*p
) {
522 _cleanup_free_
char *addr_p
= NULL
;
524 assert_return(ra
, -EINVAL
);
529 LIST_FOREACH(prefix
, cur
, ra
->prefixes
) {
532 r
= in_addr_prefix_intersect(AF_INET6
,
533 (union in_addr_union
*) &cur
->opt
.in6_addr
,
535 (union in_addr_union
*) &p
->opt
.in6_addr
,
538 _cleanup_free_
char *addr_cur
= NULL
;
540 (void) in_addr_to_string(AF_INET6
,
541 (union in_addr_union
*) &cur
->opt
.in6_addr
,
543 (void) in_addr_to_string(AF_INET6
,
544 (union in_addr_union
*) &p
->opt
.in6_addr
,
547 log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
548 addr_cur
, cur
->opt
.prefixlen
,
549 addr_p
, p
->opt
.prefixlen
);
555 p
= sd_radv_prefix_ref(p
);
557 LIST_APPEND(prefix
, ra
->prefixes
, p
);
561 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &p
->opt
.in6_addr
, &addr_p
);
562 log_radv("Added prefix %s/%d", addr_p
, p
->opt
.prefixlen
);
567 _public_
int sd_radv_set_rdnss(sd_radv
*ra
, uint32_t lifetime
,
568 const struct in6_addr
*dns
, size_t n_dns
) {
569 _cleanup_free_
struct sd_radv_opt_dns
*opt_rdnss
= NULL
;
572 assert_return(ra
, -EINVAL
);
573 assert_return(n_dns
< 128, -EINVAL
);
575 if (!dns
|| n_dns
== 0) {
576 ra
->rdnss
= mfree(ra
->rdnss
);
582 len
= sizeof(struct sd_radv_opt_dns
) + sizeof(struct in6_addr
) * n_dns
;
584 opt_rdnss
= malloc0(len
);
588 opt_rdnss
->type
= SD_RADV_OPT_RDNSS
;
589 opt_rdnss
->length
= len
/ 8;
590 opt_rdnss
->lifetime
= htobe32(lifetime
);
592 memcpy(opt_rdnss
+ 1, dns
, n_dns
* sizeof(struct in6_addr
));
595 ra
->rdnss
= opt_rdnss
;
603 _public_
int sd_radv_set_dnssl(sd_radv
*ra
, uint32_t lifetime
,
604 char **search_list
) {
605 _cleanup_free_
struct sd_radv_opt_dns
*opt_dnssl
= NULL
;
610 assert_return(ra
, -EINVAL
);
612 if (!search_list
|| *search_list
== NULL
) {
613 ra
->dnssl
= mfree(ra
->dnssl
);
618 STRV_FOREACH(s
, search_list
)
619 len
+= strlen(*s
) + 2;
621 len
= (sizeof(struct sd_radv_opt_dns
) + len
+ 7) & ~0x7;
623 opt_dnssl
= malloc0(len
);
627 opt_dnssl
->type
= SD_RADV_OPT_DNSSL
;
628 opt_dnssl
->length
= len
/ 8;
629 opt_dnssl
->lifetime
= htobe32(lifetime
);
631 p
= (uint8_t *)(opt_dnssl
+ 1);
632 len
-= sizeof(struct sd_radv_opt_dns
);
634 STRV_FOREACH(s
, search_list
) {
637 r
= dns_name_to_wire_format(*s
, p
, len
, false);
649 ra
->dnssl
= opt_dnssl
;
655 _public_
int sd_radv_prefix_new(sd_radv_prefix
**ret
) {
656 _cleanup_(sd_radv_prefix_unrefp
) sd_radv_prefix
*p
= NULL
;
658 assert_return(ret
, -EINVAL
);
660 p
= new0(sd_radv_prefix
, 1);
666 p
->opt
.type
= ND_OPT_PREFIX_INFORMATION
;
667 p
->opt
.length
= (sizeof(p
->opt
) - 1) /8 + 1;
669 p
->opt
.prefixlen
= 64;
671 /* RFC 4861, Section 6.2.1 */
672 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, true);
673 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, true);
674 p
->opt
.preferred_lifetime
= htobe32(604800);
675 p
->opt
.valid_lifetime
= htobe32(2592000);
677 LIST_INIT(prefix
, p
);
685 _public_ sd_radv_prefix
*sd_radv_prefix_ref(sd_radv_prefix
*p
) {
689 assert(p
->n_ref
> 0);
695 _public_ sd_radv_prefix
*sd_radv_prefix_unref(sd_radv_prefix
*p
) {
699 assert(p
->n_ref
> 0);
708 _public_
int sd_radv_prefix_set_prefix(sd_radv_prefix
*p
, struct in6_addr
*in6_addr
,
709 unsigned char prefixlen
) {
710 assert_return(p
, -EINVAL
);
711 assert_return(in6_addr
, -EINVAL
);
713 if (prefixlen
< 3 || prefixlen
> 128)
717 /* unusual but allowed, log it */
718 log_radv("Unusual prefix length %d greater than 64", prefixlen
);
720 p
->opt
.in6_addr
= *in6_addr
;
721 p
->opt
.prefixlen
= prefixlen
;
726 _public_
int sd_radv_prefix_set_onlink(sd_radv_prefix
*p
, int onlink
) {
727 assert_return(p
, -EINVAL
);
729 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, onlink
);
734 _public_
int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix
*p
,
735 int address_autoconfiguration
) {
736 assert_return(p
, -EINVAL
);
738 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, address_autoconfiguration
);
743 _public_
int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix
*p
,
744 uint32_t valid_lifetime
) {
745 assert_return(p
, -EINVAL
);
747 p
->opt
.valid_lifetime
= htobe32(valid_lifetime
);
752 _public_
int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix
*p
,
753 uint32_t preferred_lifetime
) {
754 assert_return(p
, -EINVAL
);
756 p
->opt
.preferred_lifetime
= htobe32(preferred_lifetime
);