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>
23 #include <linux/in6.h>
28 #include "alloc-util.h"
30 #include "icmp6-util.h"
31 #include "in-addr-util.h"
32 #include "radv-internal.h"
33 #include "socket-util.h"
34 #include "string-util.h"
36 #include "random-util.h"
38 _public_
int sd_radv_new(sd_radv
**ret
) {
39 _cleanup_(sd_radv_unrefp
) sd_radv
*ra
= NULL
;
41 assert_return(ret
, -EINVAL
);
43 ra
= new0(sd_radv
, 1);
50 LIST_HEAD_INIT(ra
->prefixes
);
58 _public_
int sd_radv_attach_event(sd_radv
*ra
, sd_event
*event
, int64_t priority
) {
61 assert_return(ra
, -EINVAL
);
62 assert_return(!ra
->event
, -EBUSY
);
65 ra
->event
= sd_event_ref(event
);
67 r
= sd_event_default(&ra
->event
);
72 ra
->event_priority
= priority
;
77 _public_
int sd_radv_detach_event(sd_radv
*ra
) {
79 assert_return(ra
, -EINVAL
);
81 ra
->event
= sd_event_unref(ra
->event
);
85 _public_ sd_event
*sd_radv_get_event(sd_radv
*ra
) {
86 assert_return(ra
, NULL
);
91 static void radv_reset(sd_radv
*ra
) {
93 ra
->timeout_event_source
=
94 sd_event_source_unref(ra
->timeout_event_source
);
96 ra
->recv_event_source
=
97 sd_event_source_unref(ra
->recv_event_source
);
102 _public_ sd_radv
*sd_radv_ref(sd_radv
*ra
) {
106 assert(ra
->n_ref
> 0);
112 _public_ sd_radv
*sd_radv_unref(sd_radv
*ra
) {
116 assert(ra
->n_ref
> 0);
122 while (ra
->prefixes
) {
123 sd_radv_prefix
*p
= ra
->prefixes
;
125 LIST_REMOVE(prefix
, ra
->prefixes
, p
);
126 sd_radv_prefix_unref(p
);
131 sd_radv_detach_event(ra
);
135 static int radv_send(sd_radv
*ra
, const struct in6_addr
*dst
,
136 const uint32_t router_lifetime
) {
137 static const struct ether_addr mac_zero
= {};
139 struct sockaddr_in6 dst_addr
= {
140 .sin6_family
= AF_INET6
,
141 .sin6_addr
= IN6ADDR_ALL_NODES_MULTICAST_INIT
,
143 struct nd_router_advert adv
= {};
145 struct nd_opt_hdr opthdr
;
146 struct ether_addr slladdr
;
147 } _packed_ opt_mac
= {
149 .nd_opt_type
= ND_OPT_SOURCE_LINKADDR
,
150 .nd_opt_len
= (sizeof(struct nd_opt_hdr
) +
151 sizeof(struct ether_addr
) - 1) /8 + 1,
154 struct nd_opt_mtu opt_mtu
= {
155 .nd_opt_mtu_type
= ND_OPT_MTU
,
158 /* Reserve iov space for RA header, linkaddr, MTU + N prefixes */
159 struct iovec iov
[3 + ra
->n_prefixes
];
160 struct msghdr msg
= {
161 .msg_name
= &dst_addr
,
162 .msg_namelen
= sizeof(dst_addr
),
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 iov
[msg
.msg_iovlen
].iov_base
= &p
->opt
;
195 iov
[msg
.msg_iovlen
].iov_len
= sizeof(p
->opt
);
199 if (sendmsg(ra
->fd
, &msg
, 0) < 0)
205 static int radv_recv(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
206 sd_radv
*ra
= userdata
;
207 _cleanup_free_
char *addr
= NULL
;
209 triple_timestamp timestamp
;
212 _cleanup_free_
char *buf
= NULL
;
218 buflen
= next_datagram_size_fd(fd
);
220 if ((unsigned) buflen
< sizeof(struct nd_router_solicit
))
221 return log_radv("Too short packet received");
223 buf
= new0(char, buflen
);
227 r
= icmp6_receive(fd
, buf
, buflen
, &src
, ×tamp
);
231 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &src
, &addr
);
232 log_radv("Received RS from non-link-local address %s. Ignoring", addr
);
236 log_radv("Received RS with invalid hop limit. Ignoring.");
240 log_radv("Received invalid source address from ICMPv6 socket. Ignoring.");
244 log_radv_warning_errno(r
, "Error receiving from ICMPv6 socket: %m");
251 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &src
, &addr
);
253 r
= radv_send(ra
, &src
, ra
->lifetime
);
255 log_radv_warning_errno(r
, "Unable to send solicited Router Advertisment to %s: %m", addr
);
257 log_radv("Sent solicited Router Advertisement to %s", addr
);
262 static usec_t
radv_compute_timeout(usec_t min
, usec_t max
) {
263 assert_return(min
<= max
, SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
);
265 return min
+ (random_u32() % (max
- min
));
268 static int radv_timeout(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
270 sd_radv
*ra
= userdata
;
271 usec_t min_timeout
= SD_RADV_DEFAULT_MIN_TIMEOUT_USEC
;
272 usec_t max_timeout
= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC
;
273 usec_t time_now
, timeout
;
274 char time_string
[FORMAT_TIMESPAN_MAX
];
280 ra
->timeout_event_source
= sd_event_source_unref(ra
->timeout_event_source
);
282 r
= sd_event_now(ra
->event
, clock_boottime_or_monotonic(), &time_now
);
286 r
= radv_send(ra
, NULL
, ra
->lifetime
);
288 log_radv_warning_errno(r
, "Unable to send Router Advertisement: %m");
290 /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
291 if (ra
->ra_sent
< SD_RADV_MAX_INITIAL_RTR_ADVERTISEMENTS
) {
292 max_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
;
293 min_timeout
= SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
/ 3;
296 timeout
= radv_compute_timeout(min_timeout
, max_timeout
);
298 log_radv("Next Router Advertisement in %s",
299 format_timespan(time_string
, FORMAT_TIMESPAN_MAX
,
300 timeout
, USEC_PER_SEC
));
302 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
303 clock_boottime_or_monotonic(),
304 time_now
+ timeout
, MSEC_PER_SEC
,
309 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
314 r
= sd_event_source_set_description(ra
->timeout_event_source
,
328 _public_
int sd_radv_stop(sd_radv
*ra
) {
331 assert_return(ra
, -EINVAL
);
333 log_radv("Stopping IPv6 Router Advertisement daemon");
335 /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
336 with zero lifetime */
337 r
= radv_send(ra
, NULL
, 0);
339 log_radv_warning_errno(r
, "Unable to send last Router Advertisement with router lifetime set to zero: %m");
342 ra
->fd
= safe_close(ra
->fd
);
343 ra
->state
= SD_RADV_STATE_IDLE
;
348 _public_
int sd_radv_start(sd_radv
*ra
) {
351 assert_return(ra
, -EINVAL
);
352 assert_return(ra
->event
, -EINVAL
);
353 assert_return(ra
->ifindex
> 0, -EINVAL
);
355 if (ra
->state
!= SD_RADV_STATE_IDLE
)
358 r
= sd_event_add_time(ra
->event
, &ra
->timeout_event_source
,
359 clock_boottime_or_monotonic(), 0, 0,
364 r
= sd_event_source_set_priority(ra
->timeout_event_source
,
369 (void) sd_event_source_set_description(ra
->timeout_event_source
,
372 r
= icmp6_bind_router_advertisement(ra
->ifindex
);
378 r
= sd_event_add_io(ra
->event
, &ra
->recv_event_source
, ra
->fd
, EPOLLIN
, radv_recv
, ra
);
382 r
= sd_event_source_set_priority(ra
->recv_event_source
, ra
->event_priority
);
386 (void) sd_event_source_set_description(ra
->recv_event_source
, "radv-receive-message");
388 ra
->state
= SD_RADV_STATE_ADVERTISING
;
390 log_radv("Started IPv6 Router Advertisement daemon");
400 _public_
int sd_radv_set_ifindex(sd_radv
*ra
, int ifindex
) {
401 assert_return(ra
, -EINVAL
);
402 assert_return(ifindex
>= -1, -EINVAL
);
404 if (ra
->state
!= SD_RADV_STATE_IDLE
)
407 ra
->ifindex
= ifindex
;
412 _public_
int sd_radv_set_mac(sd_radv
*ra
, const struct ether_addr
*mac_addr
) {
413 assert_return(ra
, -EINVAL
);
415 if (ra
->state
!= SD_RADV_STATE_IDLE
)
419 ra
->mac_addr
= *mac_addr
;
426 _public_
int sd_radv_set_mtu(sd_radv
*ra
, uint32_t mtu
) {
427 assert_return(ra
, -EINVAL
);
428 assert_return(mtu
>= 1280, -EINVAL
);
430 if (ra
->state
!= SD_RADV_STATE_IDLE
)
438 _public_
int sd_radv_set_hop_limit(sd_radv
*ra
, uint8_t hop_limit
) {
439 assert_return(ra
, -EINVAL
);
441 if (ra
->state
!= SD_RADV_STATE_IDLE
)
444 ra
->hop_limit
= hop_limit
;
449 _public_
int sd_radv_set_router_lifetime(sd_radv
*ra
, uint32_t router_lifetime
) {
450 assert_return(ra
, -EINVAL
);
452 if (ra
->state
!= SD_RADV_STATE_IDLE
)
455 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the
456 preference value MUST be set to (00) by the sender..." */
457 if (router_lifetime
== 0 &&
458 (ra
->flags
& (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM
<< 3))
461 ra
->lifetime
= router_lifetime
;
466 _public_
int sd_radv_set_managed_information(sd_radv
*ra
, int managed
) {
467 assert_return(ra
, -EINVAL
);
469 if (ra
->state
!= SD_RADV_STATE_IDLE
)
472 SET_FLAG(ra
->flags
, ND_RA_FLAG_MANAGED
, managed
);
477 _public_
int sd_radv_set_other_information(sd_radv
*ra
, int other
) {
478 assert_return(ra
, -EINVAL
);
480 if (ra
->state
!= SD_RADV_STATE_IDLE
)
483 SET_FLAG(ra
->flags
, ND_RA_FLAG_OTHER
, other
);
488 _public_
int sd_radv_set_preference(sd_radv
*ra
, unsigned preference
) {
491 assert_return(ra
, -EINVAL
);
492 assert_return(IN_SET(preference
,
493 SD_NDISC_PREFERENCE_LOW
,
494 SD_NDISC_PREFERENCE_MEDIUM
,
495 SD_NDISC_PREFERENCE_HIGH
), -EINVAL
);
497 ra
->flags
= (ra
->flags
& ~(0x3 << 3)) | (preference
<< 3);
502 _public_
int sd_radv_add_prefix(sd_radv
*ra
, sd_radv_prefix
*p
) {
504 _cleanup_free_
char *addr_p
= NULL
;
506 assert_return(ra
, -EINVAL
);
511 LIST_FOREACH(prefix
, cur
, ra
->prefixes
) {
514 r
= in_addr_prefix_intersect(AF_INET6
,
515 (union in_addr_union
*) &cur
->opt
.in6_addr
,
517 (union in_addr_union
*) &p
->opt
.in6_addr
,
520 _cleanup_free_
char *addr_cur
= NULL
;
522 (void) in_addr_to_string(AF_INET6
,
523 (union in_addr_union
*) &cur
->opt
.in6_addr
,
525 (void) in_addr_to_string(AF_INET6
,
526 (union in_addr_union
*) &p
->opt
.in6_addr
,
529 log_radv("IPv6 prefix %s/%u already configured, ignoring %s/%u",
530 addr_cur
, cur
->opt
.prefixlen
,
531 addr_p
, p
->opt
.prefixlen
);
537 p
= sd_radv_prefix_ref(p
);
539 LIST_APPEND(prefix
, ra
->prefixes
, p
);
543 (void) in_addr_to_string(AF_INET6
, (union in_addr_union
*) &p
->opt
.in6_addr
, &addr_p
);
544 log_radv("Added prefix %s/%d", addr_p
, p
->opt
.prefixlen
);
549 _public_
int sd_radv_prefix_new(sd_radv_prefix
**ret
) {
550 _cleanup_(sd_radv_prefix_unrefp
) sd_radv_prefix
*p
= NULL
;
552 assert_return(ret
, -EINVAL
);
554 p
= new0(sd_radv_prefix
, 1);
560 p
->opt
.type
= ND_OPT_PREFIX_INFORMATION
;
561 p
->opt
.length
= (sizeof(p
->opt
) - 1) /8 + 1;
563 p
->opt
.prefixlen
= 64;
565 /* RFC 4861, Section 6.2.1 */
566 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, true);
567 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, true);
568 p
->opt
.preferred_lifetime
= htobe32(604800);
569 p
->opt
.valid_lifetime
= htobe32(2592000);
571 LIST_INIT(prefix
, p
);
579 _public_ sd_radv_prefix
*sd_radv_prefix_ref(sd_radv_prefix
*p
) {
583 assert(p
->n_ref
> 0);
589 _public_ sd_radv_prefix
*sd_radv_prefix_unref(sd_radv_prefix
*p
) {
593 assert(p
->n_ref
> 0);
602 _public_
int sd_radv_prefix_set_prefix(sd_radv_prefix
*p
, struct in6_addr
*in6_addr
,
603 unsigned char prefixlen
) {
604 assert_return(p
, -EINVAL
);
605 assert_return(in6_addr
, -EINVAL
);
607 if (prefixlen
< 3 || prefixlen
> 128)
611 /* unusual but allowed, log it */
612 log_radv("Unusual prefix length %d greater than 64", prefixlen
);
614 p
->opt
.in6_addr
= *in6_addr
;
615 p
->opt
.prefixlen
= prefixlen
;
620 _public_
int sd_radv_prefix_set_onlink(sd_radv_prefix
*p
, int onlink
) {
621 assert_return(p
, -EINVAL
);
623 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, onlink
);
628 _public_
int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix
*p
,
629 int address_autoconfiguration
) {
630 assert_return(p
, -EINVAL
);
632 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, address_autoconfiguration
);
637 _public_
int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix
*p
,
638 uint32_t valid_lifetime
) {
639 assert_return(p
, -EINVAL
);
641 p
->opt
.valid_lifetime
= htobe32(valid_lifetime
);
646 _public_
int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix
*p
,
647 uint32_t preferred_lifetime
) {
648 assert_return(p
, -EINVAL
);
650 p
->opt
.preferred_lifetime
= htobe32(preferred_lifetime
);