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 "ndisc-router-solicit-internal.h"
23 #include "network-common.h"
24 #include "radv-internal.h"
25 #include "random-util.h"
26 #include "socket-util.h"
27 #include "string-util.h"
29 #include "unaligned.h"
31 int sd_radv_new(sd_radv
**ret
) {
32 _cleanup_(sd_radv_unrefp
) sd_radv
*ra
= NULL
;
34 assert_return(ret
, -EINVAL
);
43 .lifetime_usec
= RADV_DEFAULT_ROUTER_LIFETIME_USEC
,
51 int sd_radv_attach_event(sd_radv
*ra
, sd_event
*event
, int64_t priority
) {
54 assert_return(ra
, -EINVAL
);
55 assert_return(!ra
->event
, -EBUSY
);
58 ra
->event
= sd_event_ref(event
);
60 r
= sd_event_default(&ra
->event
);
65 ra
->event_priority
= priority
;
70 int sd_radv_detach_event(sd_radv
*ra
) {
72 assert_return(ra
, -EINVAL
);
74 ra
->event
= sd_event_unref(ra
->event
);
78 sd_event
*sd_radv_get_event(sd_radv
*ra
) {
79 assert_return(ra
, NULL
);
84 int sd_radv_is_running(sd_radv
*ra
) {
88 return ra
->state
!= RADV_STATE_IDLE
;
91 static void radv_reset(sd_radv
*ra
) {
94 (void) event_source_disable(ra
->timeout_event_source
);
96 ra
->recv_event_source
= sd_event_source_disable_unref(ra
->recv_event_source
);
101 static sd_radv
*radv_free(sd_radv
*ra
) {
105 LIST_CLEAR(prefix
, ra
->prefixes
, sd_radv_prefix_unref
);
106 LIST_CLEAR(prefix
, ra
->route_prefixes
, sd_radv_route_prefix_unref
);
107 LIST_CLEAR(prefix
, ra
->pref64_prefixes
, sd_radv_pref64_prefix_unref
);
114 sd_event_source_unref(ra
->timeout_event_source
);
115 sd_radv_detach_event(ra
);
117 ra
->fd
= safe_close(ra
->fd
);
123 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_radv
, sd_radv
, radv_free
);
125 static bool router_lifetime_is_valid(usec_t lifetime_usec
) {
126 assert_cc(RADV_MAX_ROUTER_LIFETIME_USEC
<= UINT16_MAX
* USEC_PER_SEC
);
127 return lifetime_usec
== 0 ||
128 (lifetime_usec
>= RADV_MIN_ROUTER_LIFETIME_USEC
&&
129 lifetime_usec
<= RADV_MAX_ROUTER_LIFETIME_USEC
);
132 static int radv_send_router_on_stop(sd_radv
*ra
) {
133 static const struct nd_router_advert adv
= {
134 .nd_ra_type
= ND_ROUTER_ADVERT
,
137 _cleanup_set_free_ Set
*options
= NULL
;
143 r
= sd_event_now(ra
->event
, CLOCK_BOOTTIME
, &time_now
);
147 if (!ether_addr_is_null(&ra
->mac_addr
)) {
148 r
= ndisc_option_set_link_layer_address(&options
, SD_NDISC_OPTION_SOURCE_LL_ADDRESS
, &ra
->mac_addr
);
153 return ndisc_send(ra
->fd
, &IN6_ADDR_ALL_NODES_MULTICAST
, &adv
.nd_ra_hdr
, options
, time_now
);
156 static int radv_send_router(sd_radv
*ra
, const struct in6_addr
*dst
) {
159 struct sockaddr_in6 dst_addr
= {
160 .sin6_family
= AF_INET6
,
161 .sin6_addr
= IN6_ADDR_ALL_NODES_MULTICAST
,
163 struct nd_router_advert adv
= {
164 .nd_ra_type
= ND_ROUTER_ADVERT
,
165 .nd_ra_router_lifetime
= usec_to_be16_sec(ra
->lifetime_usec
),
166 .nd_ra_retransmit
= usec_to_be32_msec(ra
->retransmit_usec
),
169 struct nd_opt_hdr opthdr
;
170 struct ether_addr slladdr
;
171 } _packed_ opt_mac
= {
173 .nd_opt_type
= ND_OPT_SOURCE_LINKADDR
,
174 .nd_opt_len
= DIV_ROUND_UP(sizeof(struct nd_opt_hdr
) + sizeof(struct ether_addr
), 8),
176 .slladdr
= ra
->mac_addr
,
178 struct nd_opt_mtu opt_mtu
= {
179 .nd_opt_mtu_type
= ND_OPT_MTU
,
181 .nd_opt_mtu_mtu
= htobe32(ra
->mtu
),
183 /* Reserve iov space for RA header, linkaddr, MTU, N prefixes, N routes, N pref64 prefixes, RDNSS,
184 * DNSSL, and home agent. */
185 struct iovec iov
[6 + ra
->n_prefixes
+ ra
->n_route_prefixes
+ ra
->n_pref64_prefixes
];
186 struct msghdr msg
= {
187 .msg_name
= &dst_addr
,
188 .msg_namelen
= sizeof(dst_addr
),
194 r
= sd_event_now(ra
->event
, CLOCK_BOOTTIME
, &time_now
);
198 if (dst
&& in6_addr_is_set(dst
))
199 dst_addr
.sin6_addr
= *dst
;
201 /* The nd_ra_curhoplimit and nd_ra_flags_reserved fields cannot specified with nd_ra_router_lifetime
202 * simultaneously in the structured initializer in the above. */
203 adv
.nd_ra_curhoplimit
= ra
->hop_limit
;
204 adv
.nd_ra_flags_reserved
= ra
->flags
;
205 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&adv
, sizeof(adv
));
207 /* MAC address is optional, either because the link does not use L2 addresses or load sharing is
208 * desired. See RFC 4861, Section 4.2. */
209 if (!ether_addr_is_null(&ra
->mac_addr
))
210 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&opt_mac
, sizeof(opt_mac
));
213 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&opt_mtu
, sizeof(opt_mtu
));
215 LIST_FOREACH(prefix
, p
, ra
->prefixes
) {
216 usec_t lifetime_valid_usec
, lifetime_preferred_usec
;
218 lifetime_valid_usec
= MIN(usec_sub_unsigned(p
->valid_until
, time_now
),
219 p
->lifetime_valid_usec
);
221 lifetime_preferred_usec
= MIN3(usec_sub_unsigned(p
->preferred_until
, time_now
),
222 p
->lifetime_preferred_usec
,
223 lifetime_valid_usec
);
225 p
->opt
.lifetime_valid
= usec_to_be32_sec(lifetime_valid_usec
);
226 p
->opt
.lifetime_preferred
= usec_to_be32_sec(lifetime_preferred_usec
);
228 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&p
->opt
, sizeof(p
->opt
));
231 LIST_FOREACH(prefix
, rt
, ra
->route_prefixes
) {
232 rt
->opt
.lifetime
= usec_to_be32_sec(MIN(usec_sub_unsigned(rt
->valid_until
, time_now
),
235 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&rt
->opt
, sizeof(rt
->opt
));
238 LIST_FOREACH(prefix
, p
, ra
->pref64_prefixes
)
239 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&p
->opt
, sizeof(p
->opt
));
242 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(ra
->rdnss
, ra
->rdnss
->length
* 8);
245 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(ra
->dnssl
, ra
->dnssl
->length
* 8);
247 if (FLAGS_SET(ra
->flags
, ND_RA_FLAG_HOME_AGENT
)) {
248 ra
->home_agent
.nd_opt_home_agent_info_type
= ND_OPT_HOME_AGENT_INFO
;
249 ra
->home_agent
.nd_opt_home_agent_info_len
= 1;
251 /* 0 means to place the current Router Lifetime value */
252 if (ra
->home_agent
.nd_opt_home_agent_info_lifetime
== 0)
253 ra
->home_agent
.nd_opt_home_agent_info_lifetime
= adv
.nd_ra_router_lifetime
;
255 iov
[msg
.msg_iovlen
++] = IOVEC_MAKE(&ra
->home_agent
, sizeof(ra
->home_agent
));
258 if (sendmsg(ra
->fd
, &msg
, 0) < 0)
264 static int radv_process_packet(sd_radv
*ra
, ICMP6Packet
*packet
) {
270 if (icmp6_packet_get_type(packet
) != ND_ROUTER_SOLICIT
)
271 return log_radv_errno(ra
, SYNTHETIC_ERRNO(EBADMSG
), "Received ICMP6 packet with unexpected type, ignoring.");
273 _cleanup_(sd_ndisc_router_solicit_unrefp
) sd_ndisc_router_solicit
*rs
= NULL
;
274 rs
= ndisc_router_solicit_new(packet
);
276 return log_oom_debug();
278 r
= ndisc_router_solicit_parse(ra
, rs
);
283 r
= sd_ndisc_router_solicit_get_sender_address(rs
, &src
);
284 if (r
== -ENODATA
) /* null address is allowed */
285 return sd_radv_send(ra
); /* When an unsolicited RA, we need to also update timer. */
287 return log_radv_errno(ra
, r
, "Failed to get sender address of RS, ignoring: %m");
288 if (in6_addr_equal(&src
, &ra
->ipv6ll
))
289 /* This should be definitely caused by a misconfiguration. If we send RA to ourself, the
290 * kernel complains about that. Let's ignore the packet. */
291 return log_radv_errno(ra
, SYNTHETIC_ERRNO(EADDRINUSE
), "Received RS from the same interface, ignoring.");
293 r
= radv_send_router(ra
, &src
);
295 return log_radv_errno(ra
, r
, "Unable to send solicited Router Advertisement to %s, ignoring: %m", IN6_ADDR_TO_STRING(&src
));
297 log_radv(ra
, "Sent solicited Router Advertisement to %s.", IN6_ADDR_TO_STRING(&src
));
301 static int radv_recv(sd_event_source
*s
, int fd
, uint32_t revents
, void *userdata
) {
302 _cleanup_(icmp6_packet_unrefp
) ICMP6Packet
*packet
= NULL
;
303 sd_radv
*ra
= ASSERT_PTR(userdata
);
308 r
= icmp6_packet_receive(fd
, &packet
);
310 log_radv_errno(ra
, r
, "Failed to receive ICMPv6 packet, ignoring: %m");
314 (void) radv_process_packet(ra
, packet
);
318 static int radv_timeout(sd_event_source
*s
, uint64_t usec
, void *userdata
) {
319 sd_radv
*ra
= ASSERT_PTR(userdata
);
321 if (sd_radv_send(ra
) < 0)
322 (void) sd_radv_stop(ra
);
327 int sd_radv_send(sd_radv
*ra
) {
328 usec_t min_timeout
, max_timeout
, time_now
, timeout
;
331 assert_return(ra
, -EINVAL
);
332 assert_return(ra
->event
, -EINVAL
);
333 assert_return(sd_radv_is_running(ra
), -EINVAL
);
334 assert(router_lifetime_is_valid(ra
->lifetime_usec
));
336 r
= sd_event_now(ra
->event
, CLOCK_BOOTTIME
, &time_now
);
340 r
= radv_send_router(ra
, NULL
);
342 return log_radv_errno(ra
, r
, "Unable to send Router Advertisement: %m");
346 /* RFC 4861, Section 6.2.4, sending initial Router Advertisements */
347 if (ra
->ra_sent
<= RADV_MAX_INITIAL_RTR_ADVERTISEMENTS
)
348 max_timeout
= RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC
;
350 max_timeout
= RADV_DEFAULT_MAX_TIMEOUT_USEC
;
352 /* RFC 4861, Section 6.2.1, lifetime must be at least MaxRtrAdvInterval,
353 * so lower the interval here */
354 if (ra
->lifetime_usec
> 0)
355 max_timeout
= MIN(max_timeout
, ra
->lifetime_usec
);
357 if (max_timeout
>= 9 * USEC_PER_SEC
)
358 min_timeout
= max_timeout
/ 3;
360 min_timeout
= max_timeout
* 3 / 4;
362 /* RFC 4861, Section 6.2.1.
363 * MaxRtrAdvInterval MUST be no less than 4 seconds and no greater than 1800 seconds.
364 * MinRtrAdvInterval MUST be no less than 3 seconds and no greater than .75 * MaxRtrAdvInterval. */
365 assert(max_timeout
>= RADV_MIN_MAX_TIMEOUT_USEC
);
366 assert(max_timeout
<= RADV_MAX_MAX_TIMEOUT_USEC
);
367 assert(min_timeout
>= RADV_MIN_MIN_TIMEOUT_USEC
);
368 assert(min_timeout
<= max_timeout
* 3 / 4);
370 timeout
= min_timeout
+ random_u64_range(max_timeout
- min_timeout
);
371 log_radv(ra
, "Sent unsolicited Router Advertisement. Next advertisement will be in %s.",
372 FORMAT_TIMESPAN(timeout
, USEC_PER_SEC
));
374 return event_reset_time(
375 ra
->event
, &ra
->timeout_event_source
,
377 usec_add(time_now
, timeout
), MSEC_PER_SEC
,
379 ra
->event_priority
, "radv-timeout", true);
382 int sd_radv_stop(sd_radv
*ra
) {
388 if (ra
->state
== RADV_STATE_IDLE
)
391 log_radv(ra
, "Stopping IPv6 Router Advertisement daemon");
393 /* RFC 4861, Section 6.2.5:
394 * the router SHOULD transmit one or more (but not more than MAX_FINAL_RTR_ADVERTISEMENTS) final
395 * multicast Router Advertisements on the interface with a Router Lifetime field of zero. */
396 r
= radv_send_router_on_stop(ra
);
398 log_radv_errno(ra
, r
, "Unable to send last Router Advertisement with router lifetime set to zero, ignoring: %m");
401 ra
->fd
= safe_close(ra
->fd
);
402 ra
->state
= RADV_STATE_IDLE
;
407 static int radv_setup_recv_event(sd_radv
*ra
) {
412 assert(ra
->ifindex
> 0);
414 _cleanup_close_
int fd
= -EBADF
;
415 fd
= icmp6_bind(ra
->ifindex
, /* is_router = */ true);
419 _cleanup_(sd_event_source_unrefp
) sd_event_source
*s
= NULL
;
420 r
= sd_event_add_io(ra
->event
, &s
, fd
, EPOLLIN
, radv_recv
, ra
);
424 r
= sd_event_source_set_priority(s
, ra
->event_priority
);
428 (void) sd_event_source_set_description(s
, "radv-receive-message");
430 ra
->fd
= TAKE_FD(fd
);
431 ra
->recv_event_source
= TAKE_PTR(s
);
435 int sd_radv_start(sd_radv
*ra
) {
438 assert_return(ra
, -EINVAL
);
439 assert_return(ra
->event
, -EINVAL
);
440 assert_return(ra
->ifindex
> 0, -EINVAL
);
442 if (ra
->state
!= RADV_STATE_IDLE
)
445 r
= radv_setup_recv_event(ra
);
449 r
= event_reset_time(ra
->event
, &ra
->timeout_event_source
,
453 ra
->event_priority
, "radv-timeout", true);
457 ra
->state
= RADV_STATE_ADVERTISING
;
459 log_radv(ra
, "Started IPv6 Router Advertisement daemon");
469 int sd_radv_set_ifindex(sd_radv
*ra
, int ifindex
) {
470 assert_return(ra
, -EINVAL
);
471 assert_return(ifindex
> 0, -EINVAL
);
473 if (ra
->state
!= RADV_STATE_IDLE
)
476 ra
->ifindex
= ifindex
;
481 int sd_radv_set_ifname(sd_radv
*ra
, const char *ifname
) {
482 assert_return(ra
, -EINVAL
);
483 assert_return(ifname
, -EINVAL
);
485 if (!ifname_valid_full(ifname
, IFNAME_VALID_ALTERNATIVE
))
488 return free_and_strdup(&ra
->ifname
, ifname
);
491 int sd_radv_get_ifname(sd_radv
*ra
, const char **ret
) {
494 assert_return(ra
, -EINVAL
);
496 r
= get_ifname(ra
->ifindex
, &ra
->ifname
);
506 int sd_radv_set_link_local_address(sd_radv
*ra
, const struct in6_addr
*addr
) {
507 assert_return(ra
, -EINVAL
);
508 assert_return(!addr
|| in6_addr_is_link_local(addr
), -EINVAL
);
518 int sd_radv_set_mac(sd_radv
*ra
, const struct ether_addr
*mac_addr
) {
519 assert_return(ra
, -EINVAL
);
521 if (ra
->state
!= RADV_STATE_IDLE
)
525 ra
->mac_addr
= *mac_addr
;
532 int sd_radv_set_mtu(sd_radv
*ra
, uint32_t mtu
) {
533 assert_return(ra
, -EINVAL
);
534 assert_return(mtu
>= 1280, -EINVAL
);
541 int sd_radv_set_hop_limit(sd_radv
*ra
, uint8_t hop_limit
) {
542 assert_return(ra
, -EINVAL
);
544 if (ra
->state
!= RADV_STATE_IDLE
)
547 ra
->hop_limit
= hop_limit
;
552 int sd_radv_set_retransmit(sd_radv
*ra
, uint64_t usec
) {
553 assert_return(ra
, -EINVAL
);
555 if (ra
->state
!= RADV_STATE_IDLE
)
558 if (usec
> RADV_MAX_RETRANSMIT_USEC
)
561 ra
->retransmit_usec
= usec
;
565 int sd_radv_set_router_lifetime(sd_radv
*ra
, uint64_t usec
) {
566 assert_return(ra
, -EINVAL
);
568 if (ra
->state
!= RADV_STATE_IDLE
)
571 if (!router_lifetime_is_valid(usec
))
574 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the preference value MUST be set
575 * to (00) by the sender..." */
577 (ra
->flags
& (0x3 << 3)) != (SD_NDISC_PREFERENCE_MEDIUM
<< 3))
580 ra
->lifetime_usec
= usec
;
584 int sd_radv_set_managed_information(sd_radv
*ra
, int managed
) {
585 assert_return(ra
, -EINVAL
);
587 if (ra
->state
!= RADV_STATE_IDLE
)
590 SET_FLAG(ra
->flags
, ND_RA_FLAG_MANAGED
, managed
);
595 int sd_radv_set_other_information(sd_radv
*ra
, int other
) {
596 assert_return(ra
, -EINVAL
);
598 if (ra
->state
!= RADV_STATE_IDLE
)
601 SET_FLAG(ra
->flags
, ND_RA_FLAG_OTHER
, other
);
606 int sd_radv_set_preference(sd_radv
*ra
, unsigned preference
) {
607 assert_return(ra
, -EINVAL
);
608 assert_return(IN_SET(preference
,
609 SD_NDISC_PREFERENCE_LOW
,
610 SD_NDISC_PREFERENCE_MEDIUM
,
611 SD_NDISC_PREFERENCE_HIGH
), -EINVAL
);
613 /* RFC 4191, Section 2.2, "...If the Router Lifetime is zero, the preference value MUST be set
614 * to (00) by the sender..." */
615 if (ra
->lifetime_usec
== 0 && preference
!= SD_NDISC_PREFERENCE_MEDIUM
)
618 ra
->flags
= (ra
->flags
& ~(0x3 << 3)) | (preference
<< 3);
623 int sd_radv_set_home_agent_information(sd_radv
*ra
, int home_agent
) {
624 assert_return(ra
, -EINVAL
);
626 if (ra
->state
!= RADV_STATE_IDLE
)
629 SET_FLAG(ra
->flags
, ND_RA_FLAG_HOME_AGENT
, home_agent
);
634 int sd_radv_set_home_agent_preference(sd_radv
*ra
, uint16_t preference
) {
635 assert_return(ra
, -EINVAL
);
637 if (ra
->state
!= RADV_STATE_IDLE
)
640 ra
->home_agent
.nd_opt_home_agent_info_preference
= htobe16(preference
);
645 int sd_radv_set_home_agent_lifetime(sd_radv
*ra
, uint64_t lifetime_usec
) {
646 assert_return(ra
, -EINVAL
);
648 if (ra
->state
!= RADV_STATE_IDLE
)
651 if (lifetime_usec
> RADV_HOME_AGENT_MAX_LIFETIME_USEC
)
654 ra
->home_agent
.nd_opt_home_agent_info_lifetime
= usec_to_be16_sec(lifetime_usec
);
658 int sd_radv_add_prefix(sd_radv
*ra
, sd_radv_prefix
*p
) {
659 sd_radv_prefix
*found
= NULL
;
662 assert_return(ra
, -EINVAL
);
663 assert_return(p
, -EINVAL
);
665 /* Refuse prefixes that don't have a prefix set */
666 if (in6_addr_is_null(&p
->opt
.in6_addr
))
669 const char *addr_p
= IN6_ADDR_PREFIX_TO_STRING(&p
->opt
.in6_addr
, p
->opt
.prefixlen
);
671 LIST_FOREACH(prefix
, cur
, ra
->prefixes
) {
672 r
= in_addr_prefix_intersect(AF_INET6
,
673 (const union in_addr_union
*) &cur
->opt
.in6_addr
,
675 (const union in_addr_union
*) &p
->opt
.in6_addr
,
682 if (cur
->opt
.prefixlen
== p
->opt
.prefixlen
) {
687 return log_radv_errno(ra
, SYNTHETIC_ERRNO(EEXIST
),
688 "IPv6 prefix %s conflicts with %s, ignoring.",
690 IN6_ADDR_PREFIX_TO_STRING(&cur
->opt
.in6_addr
, cur
->opt
.prefixlen
));
694 /* p and cur may be equivalent. First increment the reference counter. */
695 sd_radv_prefix_ref(p
);
697 /* Then, remove the old entry. */
698 LIST_REMOVE(prefix
, ra
->prefixes
, found
);
699 sd_radv_prefix_unref(found
);
701 /* Finally, add the new entry. */
702 LIST_APPEND(prefix
, ra
->prefixes
, p
);
704 log_radv(ra
, "Updated/replaced IPv6 prefix %s (preferred: %s, valid: %s)",
706 FORMAT_TIMESPAN(p
->lifetime_preferred_usec
, USEC_PER_SEC
),
707 FORMAT_TIMESPAN(p
->lifetime_valid_usec
, USEC_PER_SEC
));
709 /* The prefix is new. Let's simply add it. */
711 sd_radv_prefix_ref(p
);
712 LIST_APPEND(prefix
, ra
->prefixes
, p
);
715 log_radv(ra
, "Added prefix %s", addr_p
);
718 if (ra
->state
== RADV_STATE_IDLE
)
721 if (ra
->ra_sent
== 0)
724 /* If RAs have already been sent, send an RA immediately to announce the newly-added prefix */
725 r
= radv_send_router(ra
, NULL
);
727 log_radv_errno(ra
, r
, "Unable to send Router Advertisement for added prefix %s, ignoring: %m", addr_p
);
729 log_radv(ra
, "Sent Router Advertisement for added/updated prefix %s.", addr_p
);
734 void sd_radv_remove_prefix(
736 const struct in6_addr
*prefix
,
737 unsigned char prefixlen
) {
745 LIST_FOREACH(prefix
, cur
, ra
->prefixes
) {
746 if (prefixlen
!= cur
->opt
.prefixlen
)
749 if (!in6_addr_equal(prefix
, &cur
->opt
.in6_addr
))
752 LIST_REMOVE(prefix
, ra
->prefixes
, cur
);
754 sd_radv_prefix_unref(cur
);
759 int sd_radv_add_route_prefix(sd_radv
*ra
, sd_radv_route_prefix
*p
) {
760 sd_radv_route_prefix
*found
= NULL
;
763 assert_return(ra
, -EINVAL
);
764 assert_return(p
, -EINVAL
);
766 const char *addr_p
= IN6_ADDR_PREFIX_TO_STRING(&p
->opt
.in6_addr
, p
->opt
.prefixlen
);
768 LIST_FOREACH(prefix
, cur
, ra
->route_prefixes
) {
769 r
= in_addr_prefix_intersect(AF_INET6
,
770 (const union in_addr_union
*) &cur
->opt
.in6_addr
,
772 (const union in_addr_union
*) &p
->opt
.in6_addr
,
779 if (cur
->opt
.prefixlen
== p
->opt
.prefixlen
) {
784 return log_radv_errno(ra
, SYNTHETIC_ERRNO(EEXIST
),
785 "IPv6 route prefix %s conflicts with %s, ignoring.",
787 IN6_ADDR_PREFIX_TO_STRING(&cur
->opt
.in6_addr
, cur
->opt
.prefixlen
));
791 /* p and cur may be equivalent. First increment the reference counter. */
792 sd_radv_route_prefix_ref(p
);
794 /* Then, remove the old entry. */
795 LIST_REMOVE(prefix
, ra
->route_prefixes
, found
);
796 sd_radv_route_prefix_unref(found
);
798 /* Finally, add the new entry. */
799 LIST_APPEND(prefix
, ra
->route_prefixes
, p
);
801 log_radv(ra
, "Updated/replaced IPv6 route prefix %s (lifetime: %s)",
803 FORMAT_TIMESPAN(p
->lifetime_usec
, USEC_PER_SEC
));
805 /* The route prefix is new. Let's simply add it. */
807 sd_radv_route_prefix_ref(p
);
808 LIST_APPEND(prefix
, ra
->route_prefixes
, p
);
809 ra
->n_route_prefixes
++;
811 log_radv(ra
, "Added route prefix %s", strna(addr_p
));
814 if (ra
->state
== RADV_STATE_IDLE
)
817 if (ra
->ra_sent
== 0)
820 /* If RAs have already been sent, send an RA immediately to announce the newly-added route prefix */
821 r
= radv_send_router(ra
, NULL
);
823 log_radv_errno(ra
, r
, "Unable to send Router Advertisement for added route prefix %s, ignoring: %m",
826 log_radv(ra
, "Sent Router Advertisement for added route prefix %s.", strna(addr_p
));
831 int sd_radv_add_pref64_prefix(sd_radv
*ra
, sd_radv_pref64_prefix
*p
) {
832 sd_radv_pref64_prefix
*found
= NULL
;
835 assert_return(ra
, -EINVAL
);
836 assert_return(p
, -EINVAL
);
838 const char *addr_p
= IN6_ADDR_PREFIX_TO_STRING(&p
->in6_addr
, p
->prefixlen
);
840 LIST_FOREACH(prefix
, cur
, ra
->pref64_prefixes
) {
841 r
= in_addr_prefix_intersect(AF_INET6
,
842 (const union in_addr_union
*) &cur
->in6_addr
,
844 (const union in_addr_union
*) &p
->in6_addr
,
851 if (cur
->prefixlen
== p
->prefixlen
) {
856 return log_radv_errno(ra
, SYNTHETIC_ERRNO(EEXIST
),
857 "IPv6 PREF64 prefix %s conflicts with %s, ignoring.",
859 IN6_ADDR_PREFIX_TO_STRING(&cur
->in6_addr
, cur
->prefixlen
));
863 /* p and cur may be equivalent. First increment the reference counter. */
864 sd_radv_pref64_prefix_ref(p
);
866 /* Then, remove the old entry. */
867 LIST_REMOVE(prefix
, ra
->pref64_prefixes
, found
);
868 sd_radv_pref64_prefix_unref(found
);
870 /* Finally, add the new entry. */
871 LIST_APPEND(prefix
, ra
->pref64_prefixes
, p
);
873 log_radv(ra
, "Updated/replaced IPv6 PREF64 prefix %s (lifetime: %s)",
875 FORMAT_TIMESPAN(p
->lifetime_usec
, USEC_PER_SEC
));
877 /* The route prefix is new. Let's simply add it. */
879 sd_radv_pref64_prefix_ref(p
);
880 LIST_APPEND(prefix
, ra
->pref64_prefixes
, p
);
881 ra
->n_pref64_prefixes
++;
883 log_radv(ra
, "Added PREF64 prefix %s", strna(addr_p
));
886 if (ra
->state
== RADV_STATE_IDLE
)
889 if (ra
->ra_sent
== 0)
892 /* If RAs have already been sent, send an RA immediately to announce the newly-added route prefix */
893 r
= radv_send_router(ra
, NULL
);
895 log_radv_errno(ra
, r
, "Unable to send Router Advertisement for added PREF64 prefix %s, ignoring: %m",
898 log_radv(ra
, "Sent Router Advertisement for added PREF64 prefix %s.", strna(addr_p
));
903 int sd_radv_set_rdnss(
905 uint64_t lifetime_usec
,
906 const struct in6_addr
*dns
,
909 _cleanup_free_
struct sd_radv_opt_dns
*opt_rdnss
= NULL
;
912 assert_return(ra
, -EINVAL
);
913 assert_return(n_dns
< 128, -EINVAL
);
915 if (lifetime_usec
> RADV_RDNSS_MAX_LIFETIME_USEC
)
918 if (!dns
|| n_dns
== 0) {
919 ra
->rdnss
= mfree(ra
->rdnss
);
925 len
= sizeof(struct sd_radv_opt_dns
) + sizeof(struct in6_addr
) * n_dns
;
927 opt_rdnss
= malloc0(len
);
931 opt_rdnss
->type
= RADV_OPT_RDNSS
;
932 opt_rdnss
->length
= len
/ 8;
933 opt_rdnss
->lifetime
= usec_to_be32_sec(lifetime_usec
);
935 memcpy(opt_rdnss
+ 1, dns
, n_dns
* sizeof(struct in6_addr
));
937 free_and_replace(ra
->rdnss
, opt_rdnss
);
944 int sd_radv_set_dnssl(
946 uint64_t lifetime_usec
,
947 char **search_list
) {
949 _cleanup_free_
struct sd_radv_opt_dns
*opt_dnssl
= NULL
;
953 assert_return(ra
, -EINVAL
);
955 if (lifetime_usec
> RADV_DNSSL_MAX_LIFETIME_USEC
)
958 if (strv_isempty(search_list
)) {
959 ra
->dnssl
= mfree(ra
->dnssl
);
963 STRV_FOREACH(s
, search_list
)
964 len
+= strlen(*s
) + 2;
966 len
= (sizeof(struct sd_radv_opt_dns
) + len
+ 7) & ~0x7;
968 opt_dnssl
= malloc0(len
);
972 opt_dnssl
->type
= RADV_OPT_DNSSL
;
973 opt_dnssl
->length
= len
/ 8;
974 opt_dnssl
->lifetime
= usec_to_be32_sec(lifetime_usec
);
976 p
= (uint8_t *)(opt_dnssl
+ 1);
977 len
-= sizeof(struct sd_radv_opt_dns
);
979 STRV_FOREACH(s
, search_list
) {
982 r
= dns_name_to_wire_format(*s
, p
, len
, false);
993 free_and_replace(ra
->dnssl
, opt_dnssl
);
998 int sd_radv_prefix_new(sd_radv_prefix
**ret
) {
1001 assert_return(ret
, -EINVAL
);
1003 p
= new(sd_radv_prefix
, 1);
1007 *p
= (sd_radv_prefix
) {
1010 .opt
.type
= ND_OPT_PREFIX_INFORMATION
,
1011 .opt
.length
= (sizeof(p
->opt
) - 1)/8 + 1,
1012 .opt
.prefixlen
= 64,
1014 /* RFC 4861, Section 6.2.1 */
1015 .opt
.flags
= ND_OPT_PI_FLAG_ONLINK
|ND_OPT_PI_FLAG_AUTO
,
1017 .lifetime_valid_usec
= RADV_DEFAULT_VALID_LIFETIME_USEC
,
1018 .lifetime_preferred_usec
= RADV_DEFAULT_PREFERRED_LIFETIME_USEC
,
1019 .valid_until
= USEC_INFINITY
,
1020 .preferred_until
= USEC_INFINITY
,
1027 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_radv_prefix
, sd_radv_prefix
, mfree
);
1029 int sd_radv_prefix_set_prefix(
1031 const struct in6_addr
*in6_addr
,
1032 unsigned char prefixlen
) {
1034 assert_return(p
, -EINVAL
);
1035 assert_return(in6_addr
, -EINVAL
);
1037 if (prefixlen
< 3 || prefixlen
> 128)
1041 /* unusual but allowed, log it */
1042 log_radv(NULL
, "Unusual prefix length %d greater than 64", prefixlen
);
1044 p
->opt
.in6_addr
= *in6_addr
;
1045 p
->opt
.prefixlen
= prefixlen
;
1050 int sd_radv_prefix_get_prefix(
1052 struct in6_addr
*ret_in6_addr
,
1053 unsigned char *ret_prefixlen
) {
1055 assert_return(p
, -EINVAL
);
1056 assert_return(ret_in6_addr
, -EINVAL
);
1057 assert_return(ret_prefixlen
, -EINVAL
);
1059 *ret_in6_addr
= p
->opt
.in6_addr
;
1060 *ret_prefixlen
= p
->opt
.prefixlen
;
1065 int sd_radv_prefix_set_onlink(sd_radv_prefix
*p
, int onlink
) {
1066 assert_return(p
, -EINVAL
);
1068 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_ONLINK
, onlink
);
1073 int sd_radv_prefix_set_address_autoconfiguration(sd_radv_prefix
*p
, int address_autoconfiguration
) {
1074 assert_return(p
, -EINVAL
);
1076 SET_FLAG(p
->opt
.flags
, ND_OPT_PI_FLAG_AUTO
, address_autoconfiguration
);
1081 int sd_radv_prefix_set_valid_lifetime(sd_radv_prefix
*p
, uint64_t lifetime_usec
, uint64_t valid_until
) {
1082 assert_return(p
, -EINVAL
);
1084 p
->lifetime_valid_usec
= lifetime_usec
;
1085 p
->valid_until
= valid_until
;
1090 int sd_radv_prefix_set_preferred_lifetime(sd_radv_prefix
*p
, uint64_t lifetime_usec
, uint64_t valid_until
) {
1091 assert_return(p
, -EINVAL
);
1093 p
->lifetime_preferred_usec
= lifetime_usec
;
1094 p
->preferred_until
= valid_until
;
1099 int sd_radv_route_prefix_new(sd_radv_route_prefix
**ret
) {
1100 sd_radv_route_prefix
*p
;
1102 assert_return(ret
, -EINVAL
);
1104 p
= new(sd_radv_route_prefix
, 1);
1108 *p
= (sd_radv_route_prefix
) {
1111 .opt
.type
= RADV_OPT_ROUTE_INFORMATION
,
1112 .opt
.length
= DIV_ROUND_UP(sizeof(p
->opt
), 8),
1113 .opt
.prefixlen
= 64,
1115 .lifetime_usec
= RADV_DEFAULT_VALID_LIFETIME_USEC
,
1116 .valid_until
= USEC_INFINITY
,
1123 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_radv_route_prefix
, sd_radv_route_prefix
, mfree
);
1125 int sd_radv_route_prefix_set_prefix(
1126 sd_radv_route_prefix
*p
,
1127 const struct in6_addr
*in6_addr
,
1128 unsigned char prefixlen
) {
1130 assert_return(p
, -EINVAL
);
1131 assert_return(in6_addr
, -EINVAL
);
1133 if (prefixlen
> 128)
1137 /* unusual but allowed, log it */
1138 log_radv(NULL
, "Unusual prefix length %u greater than 64", prefixlen
);
1140 p
->opt
.in6_addr
= *in6_addr
;
1141 p
->opt
.prefixlen
= prefixlen
;
1146 int sd_radv_route_prefix_set_lifetime(sd_radv_route_prefix
*p
, uint64_t lifetime_usec
, uint64_t valid_until
) {
1147 assert_return(p
, -EINVAL
);
1149 p
->lifetime_usec
= lifetime_usec
;
1150 p
->valid_until
= valid_until
;
1155 int sd_radv_pref64_prefix_new(sd_radv_pref64_prefix
**ret
) {
1156 sd_radv_pref64_prefix
*p
;
1158 assert_return(ret
, -EINVAL
);
1160 p
= new(sd_radv_pref64_prefix
, 1);
1164 *p
= (sd_radv_pref64_prefix
) {
1167 .opt
.type
= RADV_OPT_PREF64
,
1175 DEFINE_PUBLIC_TRIVIAL_REF_UNREF_FUNC(sd_radv_pref64_prefix
, sd_radv_pref64_prefix
, mfree
);
1177 int sd_radv_pref64_prefix_set_prefix(
1178 sd_radv_pref64_prefix
*p
,
1179 const struct in6_addr
*prefix
,
1181 uint64_t lifetime_usec
) {
1183 uint16_t pref64_lifetime
;
1184 uint8_t prefixlen_code
;
1187 assert_return(p
, -EINVAL
);
1188 assert_return(prefix
, -EINVAL
);
1190 r
= pref64_prefix_length_to_plc(prefixlen
, &prefixlen_code
);
1192 return log_radv_errno(NULL
, r
,
1193 "Unsupported PREF64 prefix length %u. Valid lengths are 32, 40, 48, 56, 64 and 96", prefixlen
);
1195 if (lifetime_usec
> PREF64_MAX_LIFETIME_USEC
)
1198 /* RFC 8781 - 4.1 rounding up lifetime to multiply of 8 */
1199 pref64_lifetime
= DIV_ROUND_UP(lifetime_usec
, 8 * USEC_PER_SEC
) << 3;
1200 pref64_lifetime
|= prefixlen_code
;
1202 unaligned_write_be16(&p
->opt
.lifetime_and_plc
, pref64_lifetime
);
1203 memcpy(&p
->opt
.prefix
, prefix
, sizeof(p
->opt
.prefix
));
1205 p
->in6_addr
= *prefix
;
1206 p
->prefixlen
= prefixlen
;