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>
24 #include <linux/in6.h>
29 #include "alloc-util.h"
30 #include "dns-domain.h"
32 #include "icmp6-util.h"
33 #include "in-addr-util.h"
34 #include "radv-internal.h"
35 #include "socket-util.h"
36 #include "string-util.h"
39 #include "random-util.h"
41 _public_
int sd_radv_new(sd_radv
**ret
) {
42 _cleanup_(sd_radv_unrefp
) sd_radv
*ra
= NULL
;
44 assert_return(ret
, -EINVAL
);
46 ra
= new0(sd_radv
, 1);
53 LIST_HEAD_INIT(ra
->prefixes
);
61 _public_
int sd_radv_attach_event(sd_radv
*ra
, sd_event
*event
, int64_t priority
) {
64 assert_return(ra
, -EINVAL
);
65 assert_return(!ra
->event
, -EBUSY
);
68 ra
->event
= sd_event_ref(event
);
70 r
= sd_event_default(&ra
->event
);
75 ra
->event_priority
= priority
;
80 _public_
int sd_radv_detach_event(sd_radv
*ra
) {
82 assert_return(ra
, -EINVAL
);
84 ra
->event
= sd_event_unref(ra
->event
);
88 _public_ sd_event
*sd_radv_get_event(sd_radv
*ra
) {
89 assert_return(ra
, NULL
);
94 static void radv_reset(sd_radv
*ra
) {
96 ra
->timeout_event_source
=
97 sd_event_source_unref(ra
->timeout_event_source
);
99 ra
->recv_event_source
=
100 sd_event_source_unref(ra
->recv_event_source
);
105 _public_ sd_radv
*sd_radv_ref(sd_radv
*ra
) {
109 assert(ra
->n_ref
> 0);
115 _public_ sd_radv
*sd_radv_unref(sd_radv
*ra
) {
119 assert(ra
->n_ref
> 0);
125 while (ra
->prefixes
) {
126 sd_radv_prefix
*p
= ra
->prefixes
;
128 LIST_REMOVE(prefix
, ra
->prefixes
, p
);
129 sd_radv_prefix_unref(p
);
137 sd_radv_detach_event(ra
);
141 static int radv_send(sd_radv
*ra
, const struct in6_addr
*dst
,
142 const uint32_t router_lifetime
) {
143 static const struct ether_addr mac_zero
= {};
145 struct sockaddr_in6 dst_addr
= {
146 .sin6_family
= AF_INET6
,
147 .sin6_addr
= IN6ADDR_ALL_NODES_MULTICAST_INIT
,
149 struct nd_router_advert adv
= {};
151 struct nd_opt_hdr opthdr
;
152 struct ether_addr slladdr
;
153 } _packed_ opt_mac
= {
155 .nd_opt_type
= ND_OPT_SOURCE_LINKADDR
,
156 .nd_opt_len
= (sizeof(struct nd_opt_hdr
) +
157 sizeof(struct ether_addr
) - 1) /8 + 1,
160 struct nd_opt_mtu opt_mtu
= {
161 .nd_opt_mtu_type
= ND_OPT_MTU
,
164 /* Reserve iov space for RA header, linkaddr, MTU, N prefixes, RDNSS
166 struct iovec iov
[5 + ra
->n_prefixes
];
167 struct msghdr msg
= {
168 .msg_name
= &dst_addr
,
169 .msg_namelen
= sizeof(dst_addr
),
173 if (dst
&& !in_addr_is_null(AF_INET6
, (union in_addr_union
*) dst
))
174 dst_addr
.sin6_addr
= *dst
;
176 adv
.nd_ra_type
= ND_ROUTER_ADVERT
;
177 adv
.nd_ra_curhoplimit
= ra
->hop_limit
;
178 adv
.nd_ra_flags_reserved
= ra
->flags
;
179 adv
.nd_ra_router_lifetime
= htobe16(router_lifetime
);
180 iov
[msg
.msg_iovlen
].iov_base
= &adv
;
181 iov
[msg
.msg_iovlen
].iov_len
= sizeof(adv
);
184 /* MAC address is optional, either because the link does not use L2
185 addresses or load sharing is desired. See RFC 4861, Section 4.2 */
186 if (memcmp(&mac_zero
, &ra
->mac_addr
, sizeof(mac_zero
))) {
187 opt_mac
.slladdr
= ra
->mac_addr
;
188 iov
[msg
.msg_iovlen
].iov_base
= &opt_mac
;
189 iov
[msg
.msg_iovlen
].iov_len
= sizeof(opt_mac
);
194 opt_mtu
.nd_opt_mtu_mtu
= htobe32(ra
->mtu
);
195 iov
[msg
.msg_iovlen
].iov_base
= &opt_mtu
;
196 iov
[msg
.msg_iovlen
].iov_len
= sizeof(opt_mtu
);
200 LIST_FOREACH(prefix
, p
, ra
->prefixes
) {
201 iov
[msg
.msg_iovlen
].iov_base
= &p
->opt
;
202 iov
[msg
.msg_iovlen
].iov_len
= sizeof(p
->opt
);
207 iov
[msg
.msg_iovlen
].iov_base
= ra
->rdnss
;
208 iov
[msg
.msg_iovlen
].iov_len
= ra
->rdnss
->length
* 8;
213 iov
[msg
.msg_iovlen
].iov_base
= ra
->dnssl
;
214 iov
[msg
.msg_iovlen
].iov_len
= ra
->dnssl
->length
* 8;
218 if (sendmsg(ra
->fd
, &msg
, 0) < 0)
224 static int radv_recv(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
225 sd_radv
*ra
= userdata
;
226 _cleanup_free_
char *addr
= NULL
;
228 triple_timestamp timestamp
;
231 _cleanup_free_
char *buf
= NULL
;
237 buflen
= next_datagram_size_fd(fd
);
239 if ((unsigned) buflen
< sizeof(struct nd_router_solicit
))
240 return log_radv("Too short packet received");
242 buf
= new0(char, buflen
);
246 r
= icmp6_receive(fd
, buf
, buflen
, &src
, ×tamp
);
250 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &src
, &addr
);
251 log_radv("Received RS from non-link-local address %s. Ignoring", addr
);
255 log_radv("Received RS with invalid hop limit. Ignoring.");
259 log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
263 log_radv_warning_errno(r
, "Error receiving from ICMPv6 socket: %m");
270 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &src
, &addr
);
272 r
= radv_send(ra
, &src
, ra
->lifetime
);
274 log_radv_warning_errno(r
, "Unable to send solicited Router Advertisment to %s: %m", addr
);
276 log_radv("Sent solicited Router Advertisement to %s", addr
);
281 static usec_t
radv_compute_timeout(usec_t min
, usec_t max
) {
282 assert_return(min
<= max
, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
);
284 return min
+ (random_u32() % (max
- min
));
287 static int radv_timeout(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
289 sd_radv
*ra
= userdata
;
290 usec_t min_timeout
= SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
;
291 usec_t max_timeout
= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC
;
292 usec_t time_now
, timeout
;
293 char time_string
[FORMAT_TIMESPAN_MAX
];
299 ra
->timeout_event_source
= sd_event_source_unref(ra
->timeout_event_source
);
301 r
= sd_event_now(ra
->event
, clock_boottime_or_monotonic(), &time_now
);
305 r
= radv_send(ra
, NULL
, ra
->lifetime
);
307 log_radv_warning_errno(r
, "Unable to send Router Advertisement: %m");
309 /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
310 if (ra
->ra_sent
< SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS
) {
311 max_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
;
312 min_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
/ 3;
315 timeout
= radv_compute_timeout(min_timeout
, max_timeout
);
317 log_radv("Next Router Advertisement in %s",
318 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
319 timeout
, USEC_PER_SEC
));
321 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
322 clock_boottime_or_monotonic(),
323 time_now
+ timeout
, MSEC_PER_SEC
,
328 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
333 r
= sd_event_source_set_description(ra
->timeout_event_source
,
347 _public_
int sd_radv_stop(sd_radv
*ra
) {
350 assert_return(ra
, -EINVAL
);
352 log_radv("Stopping IPv6 Router Advertisement daemon");
354 /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
355 with zero lifetime */
356 r
= radv_send(ra
, NULL
, 0);
358 log_radv_warning_errno(r
, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
361 ra
->fd
= safe_close(ra
->fd
);
362 ra
->state
= SD_RADV_STATE_IDLE
;
367 _public_
int sd_radv_start(sd_radv
*ra
) {
370 assert_return(ra
, -EINVAL
);
371 assert_return(ra
->event
, -EINVAL
);
372 assert_return(ra
->ifindex
> 0, -EINVAL
);
374 if (ra
->state
!= SD_RADV_STATE_IDLE
)
377 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
378 clock_boottime_or_monotonic(), 0, 0,
383 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
388 (void) sd_event_source_set_description(ra
->timeout_event_source
,
391 r
= icmp6_bind_router_advertisement(ra
->ifindex
);
397 r
= sd_event_add_io(ra
->event
, &ra
->recv_event_source
, ra
->fd
, EPOLLIN
, radv_recv
, ra
);
401 r
= sd_event_source_set_priority(ra
->recv_event_source
, ra
->event_priority
);
405 (void) sd_event_source_set_description(ra
->recv_event_source
, "radv-receive-message");
407 ra
->state
= SD_RADV_STATE_ADVERTISING
;
409 log_radv("Started IPv6 Router Advertisement daemon");
419 _public_
int sd_radv_set_ifindex(sd_radv
*ra
, int ifindex
) {
420 assert_return(ra
, -EINVAL
);
421 assert_return(ifindex
>= -1, -EINVAL
);
423 if (ra
->state
!= SD_RADV_STATE_IDLE
)
426 ra
->ifindex
= ifindex
;
431 _public_
int sd_radv_set_mac(sd_radv
*ra
, const struct ether_addr
*mac_addr
) {
432 assert_return(ra
, -EINVAL
);
434 if (ra
->state
!= SD_RADV_STATE_IDLE
)
438 ra
->mac_addr
= *mac_addr
;
445 _public_
int sd_radv_set_mtu(sd_radv
*ra
, uint32_t mtu
) {
446 assert_return(ra
, -EINVAL
);
447 assert_return(mtu
>= 1280, -EINVAL
);
449 if (ra
->state
!= SD_RADV_STATE_IDLE
)
457 _public_
int sd_radv_set_hop_limit(sd_radv
*ra
, uint8_t hop_limit
) {
458 assert_return(ra
, -EINVAL
);
460 if (ra
->state
!= SD_RADV_STATE_IDLE
)
463 ra
->hop_limit
= hop_limit
;
468 _public_
int sd_radv_set_router_lifetime(sd_radv
*ra
, uint32_t router_lifetime
) {
469 assert_return(ra
, -EINVAL
);
471 if (ra
->state
!= SD_RADV_STATE_IDLE
)
474 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the
475 preference value MUST be set to (00) by the sender..." */
476 if (router_lifetime
== 0 &&
477 (ra
->flags
& (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM
<< 3))
480 ra
->lifetime
= router_lifetime
;
485 _public_
int sd_radv_set_managed_information(sd_radv
*ra
, int managed
) {
486 assert_return(ra
, -EINVAL
);
488 if (ra
->state
!= SD_RADV_STATE_IDLE
)
491 SET_FLAG(ra
->flags
, ND_RA_FLAG_MANAGED
, managed
);
496 _public_
int sd_radv_set_other_information(sd_radv
*ra
, int other
) {
497 assert_return(ra
, -EINVAL
);
499 if (ra
->state
!= SD_RADV_STATE_IDLE
)
502 SET_FLAG(ra
->flags
, ND_RA_FLAG_OTHER
, other
);
507 _public_
int sd_radv_set_preference(sd_radv
*ra
, unsigned preference
) {
510 assert_return(ra
, -EINVAL
);
511 assert_return(IN_SET(preference
,
512 SD_NDISC_PREFERENCE_LOW
,
513 SD_NDISC_PREFERENCE_MEDIUM
,
514 SD_NDISC_PREFERENCE_HIGH
), -EINVAL
);
516 ra
->flags
= (ra
->flags
& ~(0x3 << 3)) | (preference
<< 3);
521 _public_
int sd_radv_add_prefix(sd_radv
*ra
, sd_radv_prefix
*p
) {
523 _cleanup_free_
char *addr_p
= NULL
;
525 assert_return(ra
, -EINVAL
);
530 LIST_FOREACH(prefix
, cur
, ra
->prefixes
) {
533 r
= in_addr_prefix_intersect(AF_INET6
,
534 (union in_addr_union
*) &cur
->opt
.in6_addr
,
536 (union in_addr_union
*) &p
->opt
.in6_addr
,
539 _cleanup_free_
char *addr_cur
= NULL
;
541 (void) in_addr_to_string(AF_INET6
,
542 (union in_addr_union
*) &cur
->opt
.in6_addr
,
544 (void) in_addr_to_string(AF_INET6
,
545 (union in_addr_union
*) &p
->opt
.in6_addr
,
548 log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
549 addr_cur
, cur
->opt
.prefixlen
,
550 addr_p
, p
->opt
.prefixlen
);
556 p
= sd_radv_prefix_ref(p
);
558 LIST_APPEND(prefix
, ra
->prefixes
, p
);
562 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &p
->opt
.in6_addr
, &addr_p
);
563 log_radv("Added prefix %s/%d", addr_p
, p
->opt
.prefixlen
);
568 _public_
int sd_radv_set_rdnss(sd_radv
*ra
, uint32_t lifetime
,
569 const struct in6_addr
*dns
, size_t n_dns
) {
570 _cleanup_free_
struct sd_radv_opt_dns
*opt_rdnss
= NULL
;
573 assert_return(ra
, -EINVAL
);
574 assert_return(n_dns
< 128, -EINVAL
);
576 if (!dns
|| n_dns
== 0) {
577 ra
->rdnss
= mfree(ra
->rdnss
);
583 len
= sizeof(struct sd_radv_opt_dns
) + sizeof(struct in6_addr
) * n_dns
;
585 opt_rdnss
= malloc0(len
);
589 opt_rdnss
->type
= SD_RADV_OPT_RDNSS
;
590 opt_rdnss
->length
= len
/ 8;
591 opt_rdnss
->lifetime
= htobe32(lifetime
);
593 memcpy(opt_rdnss
+ 1, dns
, n_dns
* sizeof(struct in6_addr
));
596 ra
->rdnss
= opt_rdnss
;
604 _public_
int sd_radv_set_dnssl(sd_radv
*ra
, uint32_t lifetime
,
605 char **search_list
) {
606 _cleanup_free_
struct sd_radv_opt_dns
*opt_dnssl
= NULL
;
611 assert_return(ra
, -EINVAL
);
613 if (!search_list
|| *search_list
== NULL
) {
614 ra
->dnssl
= mfree(ra
->dnssl
);
619 STRV_FOREACH(s
, search_list
)
620 len
+= strlen(*s
) + 2;
622 len
= (sizeof(struct sd_radv_opt_dns
) + len
+ 7) & ~0x7;
624 opt_dnssl
= malloc0(len
);
628 opt_dnssl
->type
= SD_RADV_OPT_DNSSL
;
629 opt_dnssl
->length
= len
/ 8;
630 opt_dnssl
->lifetime
= htobe32(lifetime
);
632 p
= (uint8_t *)(opt_dnssl
+ 1);
633 len
-= sizeof(struct sd_radv_opt_dns
);
635 STRV_FOREACH(s
, search_list
) {
638 r
= dns_name_to_wire_format(*s
, p
, len
, false);
650 ra
->dnssl
= opt_dnssl
;
656 _public_
int sd_radv_prefix_new(sd_radv_prefix
**ret
) {
657 _cleanup_(sd_radv_prefix_unrefp
) sd_radv_prefix
*p
= NULL
;
659 assert_return(ret
, -EINVAL
);
661 p
= new0(sd_radv_prefix
, 1);
667 p
->opt
.type
= ND_OPT_PREFIX_INFORMATION
;
668 p
->opt
.length
= (sizeof(p
->opt
) - 1) /8 + 1;
670 p
->opt
.prefixlen
= 64;
672 /* RFC 4861, Section 6.2.1 */
673 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, true);
674 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, true);
675 p
->opt
.preferred_lifetime
= htobe32(604800);
676 p
->opt
.valid_lifetime
= htobe32(2592000);
678 LIST_INIT(prefix
, p
);
686 _public_ sd_radv_prefix
*sd_radv_prefix_ref(sd_radv_prefix
*p
) {
690 assert(p
->n_ref
> 0);
696 _public_ sd_radv_prefix
*sd_radv_prefix_unref(sd_radv_prefix
*p
) {
700 assert(p
->n_ref
> 0);
709 _public_
int sd_radv_prefix_set_prefix(sd_radv_prefix
*p
, struct in6_addr
*in6_addr
,
710 unsigned char prefixlen
) {
711 assert_return(p
, -EINVAL
);
712 assert_return(in6_addr
, -EINVAL
);
714 if (prefixlen
< 3 || prefixlen
> 128)
718 /* unusual but allowed, log it */
719 log_radv("Unusual prefix length %d greater than 64", prefixlen
);
721 p
->opt
.in6_addr
= *in6_addr
;
722 p
->opt
.prefixlen
= prefixlen
;
727 _public_
int sd_radv_prefix_set_onlink(sd_radv_prefix
*p
, int onlink
) {
728 assert_return(p
, -EINVAL
);
730 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, onlink
);
735 _public_
int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix
*p
,
736 int address_autoconfiguration
) {
737 assert_return(p
, -EINVAL
);
739 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, address_autoconfiguration
);
744 _public_
int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix
*p
,
745 uint32_t valid_lifetime
) {
746 assert_return(p
, -EINVAL
);
748 p
->opt
.valid_lifetime
= htobe32(valid_lifetime
);
753 _public_
int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix
*p
,
754 uint32_t preferred_lifetime
) {
755 assert_return(p
, -EINVAL
);
757 p
->opt
.preferred_lifetime
= htobe32(preferred_lifetime
);