1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 Copyright © 2017 Intel Corporation. All rights reserved.
6 #include <netinet/icmp6.h>
7 #include <netinet/in.h>
12 #include "alloc-util.h"
13 #include "dns-domain.h"
14 #include "ether-addr-util.h"
15 #include "event-util.h"
17 #include "icmp6-util.h"
18 #include "in-addr-util.h"
19 #include "iovec-util.h"
21 #include "memory-util.h"
22 #include "network-common.h"
23 #include "radv-internal.h"
24 #include "random-util.h"
25 #include "socket-util.h"
26 #include "string-util.h"
28 #include "unaligned.h"
30 int sd_radv_new(sd_radv
**ret
) {
31 _cleanup_(sd_radv_unrefp
) sd_radv
*ra
= NULL
;
33 assert_return(ret
, -EINVAL
);
42 .lifetime_usec
= RADV_DEFAULT_ROUTER_LIFETIME_USEC
,
50 int sd_radv_attach_event(sd_radv
*ra
, sd_event
*event
, int64_t priority
) {
53 assert_return(ra
, -EINVAL
);
54 assert_return(!ra
->event
, -EBUSY
);
57 ra
->event
= sd_event_ref(event
);
59 r
= sd_event_default(&ra
->event
);
64 ra
->event_priority
= priority
;
69 int sd_radv_detach_event(sd_radv
*ra
) {
71 assert_return(ra
, -EINVAL
);
73 ra
->event
= sd_event_unref(ra
->event
);
77 sd_event
*sd_radv_get_event(sd_radv
*ra
) {
78 assert_return(ra
, NULL
);
83 int sd_radv_is_running(sd_radv
*ra
) {
84 assert_return(ra
, false);
86 return ra
->state
!= RADV_STATE_IDLE
;
89 static void radv_reset(sd_radv
*ra
) {
92 (void) event_source_disable(ra
->timeout_event_source
);
94 ra
->recv_event_source
= sd_event_source_disable_unref(ra
->recv_event_source
);
99 static sd_radv
*radv_free(sd_radv
*ra
) {
103 LIST_CLEAR(prefix
, ra
->prefixes
, sd_radv_prefix_unref
);
104 LIST_CLEAR(prefix
, ra
->route_prefixes
, sd_radv_route_prefix_unref
);
105 LIST_CLEAR(prefix
, ra
->pref64_prefixes
, sd_radv_pref64_prefix_unref
);
112 sd_event_source_unref(ra
->timeout_event_source
);
113 sd_radv_detach_event(ra
);
115 ra
->fd
= safe_close(ra
->fd
);
121 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_radv
, sd_radv
, radv_free
);
123 static bool router_lifetime_is_valid(usec_t lifetime_usec
) {
124 return lifetime_usec
== 0 ||
125 (lifetime_usec
>= RADV_MIN_ROUTER_LIFETIME_USEC
&&
126 lifetime_usec
<= RADV_MAX_ROUTER_LIFETIME_USEC
);
129 static int radv_send(sd_radv
*ra
, const struct in6_addr
*dst
, usec_t lifetime_usec
) {
130 struct sockaddr_in6 dst_addr
= {
131 .sin6_family
= AF_INET6
,
132 .sin6_addr
= IN6ADDR_ALL_NODES_MULTICAST_INIT
,
134 struct nd_router_advert adv
= {};
136 struct nd_opt_hdr opthdr
;
137 struct ether_addr slladdr
;
138 } _packed_ opt_mac
= {
140 .nd_opt_type
= ND_OPT_SOURCE_LINKADDR
,
141 .nd_opt_len
= (sizeof(struct nd_opt_hdr
) +
142 sizeof(struct ether_addr
) - 1) /8 + 1,
145 struct nd_opt_mtu opt_mtu
= {
146 .nd_opt_mtu_type
= ND_OPT_MTU
,
149 /* Reserve iov space for RA header, linkaddr, MTU, N prefixes, N routes, N pref64 prefixes, RDNSS,
150 * DNSSL, and home agent. */
151 struct iovec iov
[6 + ra
->n_prefixes
+ ra
->n_route_prefixes
+ ra
->n_pref64_prefixes
];
152 struct msghdr msg
= {
153 .msg_name
= &dst_addr
,
154 .msg_namelen
= sizeof(dst_addr
),
161 assert(router_lifetime_is_valid(lifetime_usec
));
163 r
= sd_event_now(ra
->event
, CLOCK_BOOTTIME
, &time_now
);
167 if (dst
&& in6_addr_is_set(dst
))
168 dst_addr
.sin6_addr
= *dst
;
170 adv
.nd_ra_type
= ND_ROUTER_ADVERT
;
171 adv
.nd_ra_curhoplimit
= ra
->hop_limit
;
172 adv
.nd_ra_retransmit
= usec_to_be32_msec(ra
->retransmit_usec
);
173 adv
.nd_ra_flags_reserved
= ra
->flags
;
174 assert_cc(RADV_MAX_ROUTER_LIFETIME_USEC
<= UINT16_MAX
* USEC_PER_SEC
);
175 adv
.nd_ra_router_lifetime
= usec_to_be16_sec(lifetime_usec
);
176 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&adv
, sizeof(adv
));
178 /* MAC address is optional, either because the link does not use L2
179 addresses or load sharing is desired. See RFC 4861, Section 4.2 */
180 if (!ether_addr_is_null(&ra
->mac_addr
)) {
181 opt_mac
.slladdr
= ra
->mac_addr
;
182 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&opt_mac
, sizeof(opt_mac
));
186 opt_mtu
.nd_opt_mtu_mtu
= htobe32(ra
->mtu
);
187 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&opt_mtu
, sizeof(opt_mtu
));
190 LIST_FOREACH(prefix
, p
, ra
->prefixes
) {
191 usec_t lifetime_valid_usec
, lifetime_preferred_usec
;
193 lifetime_valid_usec
= MIN(usec_sub_unsigned(p
->valid_until
, time_now
),
194 p
->lifetime_valid_usec
);
196 lifetime_preferred_usec
= MIN3(usec_sub_unsigned(p
->preferred_until
, time_now
),
197 p
->lifetime_preferred_usec
,
198 lifetime_valid_usec
);
200 p
->opt
.lifetime_valid
= usec_to_be32_sec(lifetime_valid_usec
);
201 p
->opt
.lifetime_preferred
= usec_to_be32_sec(lifetime_preferred_usec
);
203 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&p
->opt
, sizeof(p
->opt
));
206 LIST_FOREACH(prefix
, rt
, ra
->route_prefixes
) {
207 rt
->opt
.lifetime
= usec_to_be32_sec(MIN(usec_sub_unsigned(rt
->valid_until
, time_now
),
210 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&rt
->opt
, sizeof(rt
->opt
));
213 LIST_FOREACH(prefix
, p
, ra
->pref64_prefixes
)
214 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&p
->opt
, sizeof(p
->opt
));
217 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(ra
->rdnss
, ra
->rdnss
->length
* 8);
220 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(ra
->dnssl
, ra
->dnssl
->length
* 8);
222 if (FLAGS_SET(ra
->flags
, ND_RA_FLAG_HOME_AGENT
)) {
223 ra
->home_agent
.nd_opt_home_agent_info_type
= ND_OPT_HOME_AGENT_INFO
;
224 ra
->home_agent
.nd_opt_home_agent_info_len
= 1;
226 /* 0 means to place the current Router Lifetime value */
227 if (ra
->home_agent
.nd_opt_home_agent_info_lifetime
== 0)
228 ra
->home_agent
.nd_opt_home_agent_info_lifetime
= adv
.nd_ra_router_lifetime
;
230 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&ra
->home_agent
, sizeof(ra
->home_agent
));
233 if (sendmsg(ra
->fd
, &msg
, 0) < 0)
239 static int radv_recv(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
240 sd_radv
*ra
= ASSERT_PTR(userdata
);
242 triple_timestamp timestamp
;
248 ssize_t buflen
= next_datagram_size_fd(fd
);
249 if (ERRNO_IS_NEG_TRANSIENT(buflen
) || ERRNO_IS_NEG_DISCONNECT(buflen
))
252 log_radv_errno(ra
, buflen
, "Failed to determine datagram size to read, ignoring: %m");
256 _cleanup_free_
char *buf
= new0(char, buflen
);
260 r
= icmp6_receive(fd
, buf
, buflen
, &src
, ×tamp
);
261 if (ERRNO_IS_NEG_TRANSIENT(r
) || ERRNO_IS_NEG_DISCONNECT(r
))
266 log_radv(ra
, "Received RS from neither link-local nor null address. Ignoring");
270 log_radv(ra
, "Received RS with invalid hop limit. Ignoring.");
274 log_radv(ra
, "Received invalid source address from ICMPv6 socket. Ignoring.");
278 log_radv_errno(ra
, r
, "Unexpected error receiving from ICMPv6 socket, ignoring: %m");
282 if ((size_t) buflen
< sizeof(struct nd_router_solicit
)) {
283 log_radv(ra
, "Too short packet received, ignoring");
287 /* TODO: if the sender address is null, check that the message does not have the source link-layer
288 * address option. See RFC 4861 Section 6.1.1. */
290 const char *addr
= IN6_ADDR_TO_STRING(&src
);
292 r
= radv_send(ra
, &src
, ra
->lifetime_usec
);
294 log_radv_errno(ra
, r
, "Unable to send solicited Router Advertisement to %s, ignoring: %m", addr
);
296 log_radv(ra
, "Sent solicited Router Advertisement to %s", addr
);
301 static int radv_timeout(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
302 usec_t min_timeout
, max_timeout
, time_now
, timeout
;
303 sd_radv
*ra
= ASSERT_PTR(userdata
);
308 assert(router_lifetime_is_valid(ra
->lifetime_usec
));
310 r
= sd_event_now(ra
->event
, CLOCK_BOOTTIME
, &time_now
);
314 r
= radv_send(ra
, NULL
, ra
->lifetime_usec
);
316 log_radv_errno(ra
, r
, "Unable to send Router Advertisement, ignoring: %m");
318 /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
319 if (ra
->ra_sent
< RADV_MAX_INITIAL_RTR_ADVERTISEMENTS
)
320 max_timeout
= RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
;
322 max_timeout
= RADV_DEFAULT_MAX_TIMEOUT_USEC
;
324 /* RFC 4861, Section 6.2.1, lifetime must be at least MaxRtrAdvInterval,
325 * so lower the interval here */
326 if (ra
->lifetime_usec
> 0)
327 max_timeout
= MIN(max_timeout
, ra
->lifetime_usec
);
329 if (max_timeout
>= 9 * USEC_PER_SEC
)
330 min_timeout
= max_timeout
/ 3;
332 min_timeout
= max_timeout
* 3 / 4;
334 /* RFC 4861, Section 6.2.1.
335 * MaxRtrAdvInterval MUST be no less than 4 seconds and no greater than 1800 seconds.
336 * MinRtrAdvInterval MUST be no less than 3 seconds and no greater than .75 * MaxRtrAdvInterval. */
337 assert(max_timeout
>= RADV_MIN_MAX_TIMEOUT_USEC
);
338 assert(max_timeout
<= RADV_MAX_MAX_TIMEOUT_USEC
);
339 assert(min_timeout
>= RADV_MIN_MIN_TIMEOUT_USEC
);
340 assert(min_timeout
<= max_timeout
* 3 / 4);
342 timeout
= min_timeout
+ random_u64_range(max_timeout
- min_timeout
);
343 log_radv(ra
, "Next Router Advertisement in %s", FORMAT_TIMESPAN(timeout
, USEC_PER_SEC
));
345 r
= event_reset_time(ra
->event
, &ra
->timeout_event_source
,
347 usec_add(time_now
, timeout
), MSEC_PER_SEC
,
349 ra
->event_priority
, "radv-timeout", true);
363 int sd_radv_stop(sd_radv
*ra
) {
369 if (ra
->state
== RADV_STATE_IDLE
)
372 log_radv(ra
, "Stopping IPv6 Router Advertisement daemon");
374 /* RFC 4861, Section 6.2.5, send at least one Router Advertisement
375 with zero lifetime */
376 r
= radv_send(ra
, NULL
, 0);
378 log_radv_errno(ra
, r
, "Unable to send last Router Advertisement with router lifetime set to zero, ignoring: %m");
381 ra
->fd
= safe_close(ra
->fd
);
382 ra
->state
= RADV_STATE_IDLE
;
387 int sd_radv_start(sd_radv
*ra
) {
390 assert_return(ra
, -EINVAL
);
391 assert_return(ra
->event
, -EINVAL
);
392 assert_return(ra
->ifindex
> 0, -EINVAL
);
394 if (ra
->state
!= RADV_STATE_IDLE
)
397 r
= event_reset_time(ra
->event
, &ra
->timeout_event_source
,
401 ra
->event_priority
, "radv-timeout", true);
405 r
= icmp6_bind_router_advertisement(ra
->ifindex
);
411 r
= sd_event_add_io(ra
->event
, &ra
->recv_event_source
, ra
->fd
, EPOLLIN
, radv_recv
, ra
);
415 r
= sd_event_source_set_priority(ra
->recv_event_source
, ra
->event_priority
);
419 (void) sd_event_source_set_description(ra
->recv_event_source
, "radv-receive-message");
421 ra
->state
= RADV_STATE_ADVERTISING
;
423 log_radv(ra
, "Started IPv6 Router Advertisement daemon");
433 int sd_radv_set_ifindex(sd_radv
*ra
, int ifindex
) {
434 assert_return(ra
, -EINVAL
);
435 assert_return(ifindex
> 0, -EINVAL
);
437 if (ra
->state
!= RADV_STATE_IDLE
)
440 ra
->ifindex
= ifindex
;
445 int sd_radv_set_ifname(sd_radv
*ra
, const char *ifname
) {
446 assert_return(ra
, -EINVAL
);
447 assert_return(ifname
, -EINVAL
);
449 if (!ifname_valid_full(ifname
, IFNAME_VALID_ALTERNATIVE
))
452 return free_and_strdup(&ra
->ifname
, ifname
);
455 int sd_radv_get_ifname(sd_radv
*ra
, const char **ret
) {
458 assert_return(ra
, -EINVAL
);
460 r
= get_ifname(ra
->ifindex
, &ra
->ifname
);
470 int sd_radv_set_mac(sd_radv
*ra
, const struct ether_addr
*mac_addr
) {
471 assert_return(ra
, -EINVAL
);
473 if (ra
->state
!= RADV_STATE_IDLE
)
477 ra
->mac_addr
= *mac_addr
;
484 int sd_radv_set_mtu(sd_radv
*ra
, uint32_t mtu
) {
485 assert_return(ra
, -EINVAL
);
486 assert_return(mtu
>= 1280, -EINVAL
);
493 int sd_radv_set_hop_limit(sd_radv
*ra
, uint8_t hop_limit
) {
494 assert_return(ra
, -EINVAL
);
496 if (ra
->state
!= RADV_STATE_IDLE
)
499 ra
->hop_limit
= hop_limit
;
504 int sd_radv_set_retransmit(sd_radv
*ra
, uint64_t usec
) {
505 assert_return(ra
, -EINVAL
);
507 if (ra
->state
!= RADV_STATE_IDLE
)
510 if (usec
> RADV_MAX_RETRANSMIT_USEC
)
513 ra
->retransmit_usec
= usec
;
517 int sd_radv_set_router_lifetime(sd_radv
*ra
, uint64_t usec
) {
518 assert_return(ra
, -EINVAL
);
520 if (ra
->state
!= RADV_STATE_IDLE
)
523 if (!router_lifetime_is_valid(usec
))
526 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the preference value MUST be set
527 * to (00) by the sender..." */
529 (ra
->flags
& (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM
<< 3))
532 ra
->lifetime_usec
= usec
;
536 int sd_radv_set_managed_information(sd_radv
*ra
, int managed
) {
537 assert_return(ra
, -EINVAL
);
539 if (ra
->state
!= RADV_STATE_IDLE
)
542 SET_FLAG(ra
->flags
, ND_RA_FLAG_MANAGED
, managed
);
547 int sd_radv_set_other_information(sd_radv
*ra
, int other
) {
548 assert_return(ra
, -EINVAL
);
550 if (ra
->state
!= RADV_STATE_IDLE
)
553 SET_FLAG(ra
->flags
, ND_RA_FLAG_OTHER
, other
);
558 int sd_radv_set_preference(sd_radv
*ra
, unsigned preference
) {
559 assert_return(ra
, -EINVAL
);
560 assert_return(IN_SET(preference
,
561 SD_NDISC_PREFERENCE_LOW
,
562 SD_NDISC_PREFERENCE_MEDIUM
,
563 SD_NDISC_PREFERENCE_HIGH
), -EINVAL
);
565 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the preference value MUST be set
566 * to (00) by the sender..." */
567 if (ra
->lifetime_usec
== 0 && preference
!= SD_NDISC_PREFERENCE_MEDIUM
)
570 ra
->flags
= (ra
->flags
& ~(0x3 << 3)) | (preference
<< 3);
575 int sd_radv_set_home_agent_information(sd_radv
*ra
, int home_agent
) {
576 assert_return(ra
, -EINVAL
);
578 if (ra
->state
!= RADV_STATE_IDLE
)
581 SET_FLAG(ra
->flags
, ND_RA_FLAG_HOME_AGENT
, home_agent
);
586 int sd_radv_set_home_agent_preference(sd_radv
*ra
, uint16_t preference
) {
587 assert_return(ra
, -EINVAL
);
589 if (ra
->state
!= RADV_STATE_IDLE
)
592 ra
->home_agent
.nd_opt_home_agent_info_preference
= htobe16(preference
);
597 int sd_radv_set_home_agent_lifetime(sd_radv
*ra
, uint64_t lifetime_usec
) {
598 assert_return(ra
, -EINVAL
);
600 if (ra
->state
!= RADV_STATE_IDLE
)
603 if (lifetime_usec
> RADV_HOME_AGENT_MAX_LIFETIME_USEC
)
606 ra
->home_agent
.nd_opt_home_agent_info_lifetime
= usec_to_be16_sec(lifetime_usec
);
610 int sd_radv_add_prefix(sd_radv
*ra
, sd_radv_prefix
*p
) {
611 sd_radv_prefix
*found
= NULL
;
614 assert_return(ra
, -EINVAL
);
615 assert_return(p
, -EINVAL
);
617 /* Refuse prefixes that don't have a prefix set */
618 if (in6_addr_is_null(&p
->opt
.in6_addr
))
621 const char *addr_p
= IN6_ADDR_PREFIX_TO_STRING(&p
->opt
.in6_addr
, p
->opt
.prefixlen
);
623 LIST_FOREACH(prefix
, cur
, ra
->prefixes
) {
624 r
= in_addr_prefix_intersect(AF_INET6
,
625 (const union in_addr_union
*) &cur
->opt
.in6_addr
,
627 (const union in_addr_union
*) &p
->opt
.in6_addr
,
634 if (cur
->opt
.prefixlen
== p
->opt
.prefixlen
) {
639 return log_radv_errno(ra
, SYNTHETIC_ERRNO(EEXIST
),
640 "IPv6 prefix %s conflicts with %s, ignoring.",
642 IN6_ADDR_PREFIX_TO_STRING(&cur
->opt
.in6_addr
, cur
->opt
.prefixlen
));
646 /* p and cur may be equivalent. First increment the reference counter. */
647 sd_radv_prefix_ref(p
);
649 /* Then, remove the old entry. */
650 LIST_REMOVE(prefix
, ra
->prefixes
, found
);
651 sd_radv_prefix_unref(found
);
653 /* Finally, add the new entry. */
654 LIST_APPEND(prefix
, ra
->prefixes
, p
);
656 log_radv(ra
, "Updated/replaced IPv6 prefix %s (preferred: %s, valid: %s)",
658 FORMAT_TIMESPAN(p
->lifetime_preferred_usec
, USEC_PER_SEC
),
659 FORMAT_TIMESPAN(p
->lifetime_valid_usec
, USEC_PER_SEC
));
661 /* The prefix is new. Let's simply add it. */
663 sd_radv_prefix_ref(p
);
664 LIST_APPEND(prefix
, ra
->prefixes
, p
);
667 log_radv(ra
, "Added prefix %s", addr_p
);
670 if (ra
->state
== RADV_STATE_IDLE
)
673 if (ra
->ra_sent
== 0)
676 /* If RAs have already been sent, send an RA immediately to announce the newly-added prefix */
677 r
= radv_send(ra
, NULL
, ra
->lifetime_usec
);
679 log_radv_errno(ra
, r
, "Unable to send Router Advertisement for added prefix %s, ignoring: %m", addr_p
);
681 log_radv(ra
, "Sent Router Advertisement for added/updated prefix %s.", addr_p
);
686 void sd_radv_remove_prefix(
688 const struct in6_addr
*prefix
,
689 unsigned char prefixlen
) {
697 LIST_FOREACH(prefix
, cur
, ra
->prefixes
) {
698 if (prefixlen
!= cur
->opt
.prefixlen
)
701 if (!in6_addr_equal(prefix
, &cur
->opt
.in6_addr
))
704 LIST_REMOVE(prefix
, ra
->prefixes
, cur
);
706 sd_radv_prefix_unref(cur
);
711 int sd_radv_add_route_prefix(sd_radv
*ra
, sd_radv_route_prefix
*p
) {
712 sd_radv_route_prefix
*found
= NULL
;
715 assert_return(ra
, -EINVAL
);
716 assert_return(p
, -EINVAL
);
718 const char *addr_p
= IN6_ADDR_PREFIX_TO_STRING(&p
->opt
.in6_addr
, p
->opt
.prefixlen
);
720 LIST_FOREACH(prefix
, cur
, ra
->route_prefixes
) {
721 r
= in_addr_prefix_intersect(AF_INET6
,
722 (const union in_addr_union
*) &cur
->opt
.in6_addr
,
724 (const union in_addr_union
*) &p
->opt
.in6_addr
,
731 if (cur
->opt
.prefixlen
== p
->opt
.prefixlen
) {
736 return log_radv_errno(ra
, SYNTHETIC_ERRNO(EEXIST
),
737 "IPv6 route prefix %s conflicts with %s, ignoring.",
739 IN6_ADDR_PREFIX_TO_STRING(&cur
->opt
.in6_addr
, cur
->opt
.prefixlen
));
743 /* p and cur may be equivalent. First increment the reference counter. */
744 sd_radv_route_prefix_ref(p
);
746 /* Then, remove the old entry. */
747 LIST_REMOVE(prefix
, ra
->route_prefixes
, found
);
748 sd_radv_route_prefix_unref(found
);
750 /* Finally, add the new entry. */
751 LIST_APPEND(prefix
, ra
->route_prefixes
, p
);
753 log_radv(ra
, "Updated/replaced IPv6 route prefix %s (lifetime: %s)",
755 FORMAT_TIMESPAN(p
->lifetime_usec
, USEC_PER_SEC
));
757 /* The route prefix is new. Let's simply add it. */
759 sd_radv_route_prefix_ref(p
);
760 LIST_APPEND(prefix
, ra
->route_prefixes
, p
);
761 ra
->n_route_prefixes
++;
763 log_radv(ra
, "Added route prefix %s", strna(addr_p
));
766 if (ra
->state
== RADV_STATE_IDLE
)
769 if (ra
->ra_sent
== 0)
772 /* If RAs have already been sent, send an RA immediately to announce the newly-added route prefix */
773 r
= radv_send(ra
, NULL
, ra
->lifetime_usec
);
775 log_radv_errno(ra
, r
, "Unable to send Router Advertisement for added route prefix %s, ignoring: %m",
778 log_radv(ra
, "Sent Router Advertisement for added route prefix %s.", strna(addr_p
));
783 int sd_radv_add_pref64_prefix(sd_radv
*ra
, sd_radv_pref64_prefix
*p
) {
784 sd_radv_pref64_prefix
*found
= NULL
;
787 assert_return(ra
, -EINVAL
);
788 assert_return(p
, -EINVAL
);
790 const char *addr_p
= IN6_ADDR_PREFIX_TO_STRING(&p
->in6_addr
, p
->prefixlen
);
792 LIST_FOREACH(prefix
, cur
, ra
->pref64_prefixes
) {
793 r
= in_addr_prefix_intersect(AF_INET6
,
794 (const union in_addr_union
*) &cur
->in6_addr
,
796 (const union in_addr_union
*) &p
->in6_addr
,
803 if (cur
->prefixlen
== p
->prefixlen
) {
808 return log_radv_errno(ra
, SYNTHETIC_ERRNO(EEXIST
),
809 "IPv6 PREF64 prefix %s conflicts with %s, ignoring.",
811 IN6_ADDR_PREFIX_TO_STRING(&cur
->in6_addr
, cur
->prefixlen
));
815 /* p and cur may be equivalent. First increment the reference counter. */
816 sd_radv_pref64_prefix_ref(p
);
818 /* Then, remove the old entry. */
819 LIST_REMOVE(prefix
, ra
->pref64_prefixes
, found
);
820 sd_radv_pref64_prefix_unref(found
);
822 /* Finally, add the new entry. */
823 LIST_APPEND(prefix
, ra
->pref64_prefixes
, p
);
825 log_radv(ra
, "Updated/replaced IPv6 PREF64 prefix %s (lifetime: %s)",
827 FORMAT_TIMESPAN(p
->lifetime_usec
, USEC_PER_SEC
));
829 /* The route prefix is new. Let's simply add it. */
831 sd_radv_pref64_prefix_ref(p
);
832 LIST_APPEND(prefix
, ra
->pref64_prefixes
, p
);
833 ra
->n_pref64_prefixes
++;
835 log_radv(ra
, "Added PREF64 prefix %s", strna(addr_p
));
838 if (ra
->state
== RADV_STATE_IDLE
)
841 if (ra
->ra_sent
== 0)
844 /* If RAs have already been sent, send an RA immediately to announce the newly-added route prefix */
845 r
= radv_send(ra
, NULL
, ra
->lifetime_usec
);
847 log_radv_errno(ra
, r
, "Unable to send Router Advertisement for added PREF64 prefix %s, ignoring: %m",
850 log_radv(ra
, "Sent Router Advertisement for added PREF64 prefix %s.", strna(addr_p
));
855 int sd_radv_set_rdnss(
857 uint64_t lifetime_usec
,
858 const struct in6_addr
*dns
,
861 _cleanup_free_
struct sd_radv_opt_dns
*opt_rdnss
= NULL
;
864 assert_return(ra
, -EINVAL
);
865 assert_return(n_dns
< 128, -EINVAL
);
867 if (lifetime_usec
> RADV_RDNSS_MAX_LIFETIME_USEC
)
870 if (!dns
|| n_dns
== 0) {
871 ra
->rdnss
= mfree(ra
->rdnss
);
877 len
= sizeof(struct sd_radv_opt_dns
) + sizeof(struct in6_addr
) * n_dns
;
879 opt_rdnss
= malloc0(len
);
883 opt_rdnss
->type
= RADV_OPT_RDNSS
;
884 opt_rdnss
->length
= len
/ 8;
885 opt_rdnss
->lifetime
= usec_to_be32_sec(lifetime_usec
);
887 memcpy(opt_rdnss
+ 1, dns
, n_dns
* sizeof(struct in6_addr
));
889 free_and_replace(ra
->rdnss
, opt_rdnss
);
896 int sd_radv_set_dnssl(
898 uint64_t lifetime_usec
,
899 char **search_list
) {
901 _cleanup_free_
struct sd_radv_opt_dns
*opt_dnssl
= NULL
;
905 assert_return(ra
, -EINVAL
);
907 if (lifetime_usec
> RADV_DNSSL_MAX_LIFETIME_USEC
)
910 if (strv_isempty(search_list
)) {
911 ra
->dnssl
= mfree(ra
->dnssl
);
915 STRV_FOREACH(s
, search_list
)
916 len
+= strlen(*s
) + 2;
918 len
= (sizeof(struct sd_radv_opt_dns
) + len
+ 7) & ~0x7;
920 opt_dnssl
= malloc0(len
);
924 opt_dnssl
->type
= RADV_OPT_DNSSL
;
925 opt_dnssl
->length
= len
/ 8;
926 opt_dnssl
->lifetime
= usec_to_be32_sec(lifetime_usec
);
928 p
= (uint8_t *)(opt_dnssl
+ 1);
929 len
-= sizeof(struct sd_radv_opt_dns
);
931 STRV_FOREACH(s
, search_list
) {
934 r
= dns_name_to_wire_format(*s
, p
, len
, false);
945 free_and_replace(ra
->dnssl
, opt_dnssl
);
950 int sd_radv_prefix_new(sd_radv_prefix
**ret
) {
953 assert_return(ret
, -EINVAL
);
955 p
= new(sd_radv_prefix
, 1);
959 *p
= (sd_radv_prefix
) {
962 .opt
.type
= ND_OPT_PREFIX_INFORMATION
,
963 .opt
.length
= (sizeof(p
->opt
) - 1)/8 + 1,
966 /* RFC 4861, Section 6.2.1 */
967 .opt
.flags
= ND_OPT_PI_FLAG_ONLINK
|ND_OPT_PI_FLAG_AUTO
,
969 .lifetime_valid_usec
= RADV_DEFAULT_VALID_LIFETIME_USEC
,
970 .lifetime_preferred_usec
= RADV_DEFAULT_PREFERRED_LIFETIME_USEC
,
971 .valid_until
= USEC_INFINITY
,
972 .preferred_until
= USEC_INFINITY
,
979 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_radv_prefix
, sd_radv_prefix
, mfree
);
981 int sd_radv_prefix_set_prefix(
983 const struct in6_addr
*in6_addr
,
984 unsigned char prefixlen
) {
986 assert_return(p
, -EINVAL
);
987 assert_return(in6_addr
, -EINVAL
);
989 if (prefixlen
< 3 || prefixlen
> 128)
993 /* unusual but allowed, log it */
994 log_radv(NULL
, "Unusual prefix length %d greater than 64", prefixlen
);
996 p
->opt
.in6_addr
= *in6_addr
;
997 p
->opt
.prefixlen
= prefixlen
;
1002 int sd_radv_prefix_get_prefix(
1004 struct in6_addr
*ret_in6_addr
,
1005 unsigned char *ret_prefixlen
) {
1007 assert_return(p
, -EINVAL
);
1008 assert_return(ret_in6_addr
, -EINVAL
);
1009 assert_return(ret_prefixlen
, -EINVAL
);
1011 *ret_in6_addr
= p
->opt
.in6_addr
;
1012 *ret_prefixlen
= p
->opt
.prefixlen
;
1017 int sd_radv_prefix_set_onlink(sd_radv_prefix
*p
, int onlink
) {
1018 assert_return(p
, -EINVAL
);
1020 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, onlink
);
1025 int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix
*p
, int address_autoconfiguration
) {
1026 assert_return(p
, -EINVAL
);
1028 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, address_autoconfiguration
);
1033 int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix
*p
, uint64_t lifetime_usec
, uint64_t valid_until
) {
1034 assert_return(p
, -EINVAL
);
1036 p
->lifetime_valid_usec
= lifetime_usec
;
1037 p
->valid_until
= valid_until
;
1042 int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix
*p
, uint64_t lifetime_usec
, uint64_t valid_until
) {
1043 assert_return(p
, -EINVAL
);
1045 p
->lifetime_preferred_usec
= lifetime_usec
;
1046 p
->preferred_until
= valid_until
;
1051 int sd_radv_route_prefix_new(sd_radv_route_prefix
**ret
) {
1052 sd_radv_route_prefix
*p
;
1054 assert_return(ret
, -EINVAL
);
1056 p
= new(sd_radv_route_prefix
, 1);
1060 *p
= (sd_radv_route_prefix
) {
1063 .opt
.type
= RADV_OPT_ROUTE_INFORMATION
,
1064 .opt
.length
= DIV_ROUND_UP(sizeof(p
->opt
), 8),
1065 .opt
.prefixlen
= 64,
1067 .lifetime_usec
= RADV_DEFAULT_VALID_LIFETIME_USEC
,
1068 .valid_until
= USEC_INFINITY
,
1075 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_radv_route_prefix
, sd_radv_route_prefix
, mfree
);
1077 int sd_radv_route_prefix_set_prefix(
1078 sd_radv_route_prefix
*p
,
1079 const struct in6_addr
*in6_addr
,
1080 unsigned char prefixlen
) {
1082 assert_return(p
, -EINVAL
);
1083 assert_return(in6_addr
, -EINVAL
);
1085 if (prefixlen
> 128)
1089 /* unusual but allowed, log it */
1090 log_radv(NULL
, "Unusual prefix length %u greater than 64", prefixlen
);
1092 p
->opt
.in6_addr
= *in6_addr
;
1093 p
->opt
.prefixlen
= prefixlen
;
1098 int sd_radv_route_prefix_set_lifetime(sd_radv_route_prefix
*p
, uint64_t lifetime_usec
, uint64_t valid_until
) {
1099 assert_return(p
, -EINVAL
);
1101 p
->lifetime_usec
= lifetime_usec
;
1102 p
->valid_until
= valid_until
;
1107 int sd_radv_pref64_prefix_new(sd_radv_pref64_prefix
**ret
) {
1108 sd_radv_pref64_prefix
*p
;
1110 assert_return(ret
, -EINVAL
);
1112 p
= new(sd_radv_pref64_prefix
, 1);
1116 *p
= (sd_radv_pref64_prefix
) {
1119 .opt
.type
= RADV_OPT_PREF64
,
1127 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_radv_pref64_prefix
, sd_radv_pref64_prefix
, mfree
);
1129 int sd_radv_pref64_prefix_set_prefix(
1130 sd_radv_pref64_prefix
*p
,
1131 const struct in6_addr
*prefix
,
1133 uint64_t lifetime_usec
) {
1135 uint16_t pref64_lifetime
;
1136 uint8_t prefixlen_code
;
1139 assert_return(p
, -EINVAL
);
1140 assert_return(prefix
, -EINVAL
);
1142 r
= pref64_prefix_length_to_plc(prefixlen
, &prefixlen_code
);
1144 return log_radv_errno(NULL
, r
,
1145 "Unsupported PREF64 prefix length %u. Valid lengths are 32, 40, 48, 56, 64 and 96", prefixlen
);
1147 if (lifetime_usec
> PREF64_MAX_LIFETIME_USEC
)
1150 /* RFC 8781 - 4.1 rounding up lifetime to multiply of 8 */
1151 pref64_lifetime
= DIV_ROUND_UP(lifetime_usec
, 8 * USEC_PER_SEC
) << 3;
1152 pref64_lifetime
|= prefixlen_code
;
1154 unaligned_write_be16(&p
->opt
.lifetime_and_plc
, pref64_lifetime
);
1155 memcpy(&p
->opt
.prefix
, prefix
, sizeof(p
->opt
.prefix
));
1157 p
->in6_addr
= *prefix
;
1158 p
->prefixlen
= prefixlen
;