1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
3 Copyright © 2014 Intel Corporation. All rights reserved.
7 #include <netinet/icmp6.h>
12 #include "missing_network.h"
13 #include "networkd-address-generation.h"
14 #include "networkd-address.h"
15 #include "networkd-dhcp6.h"
16 #include "networkd-manager.h"
17 #include "networkd-ndisc.h"
18 #include "networkd-queue.h"
19 #include "networkd-route.h"
20 #include "networkd-state-file.h"
21 #include "string-table.h"
22 #include "string-util.h"
25 #define NDISC_DNSSL_MAX 64U
26 #define NDISC_RDNSS_MAX 64U
28 bool link_ipv6_accept_ra_enabled(Link
*link
) {
31 if (!socket_ipv6_is_supported())
34 if (link
->flags
& IFF_LOOPBACK
)
40 if (!link_ipv6ll_enabled(link
))
43 assert(link
->network
->ipv6_accept_ra
>= 0);
44 return link
->network
->ipv6_accept_ra
;
47 void network_adjust_ipv6_accept_ra(Network
*network
) {
50 if (!FLAGS_SET(network
->link_local
, ADDRESS_FAMILY_IPV6
)) {
51 if (network
->ipv6_accept_ra
> 0)
52 log_warning("%s: IPv6AcceptRA= is enabled but IPv6 link local addressing is disabled or not supported. "
53 "Disabling IPv6AcceptRA=.", network
->filename
);
54 network
->ipv6_accept_ra
= false;
57 if (network
->ipv6_accept_ra
< 0)
58 /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */
59 network
->ipv6_accept_ra
= !FLAGS_SET(network
->ip_forward
, ADDRESS_FAMILY_IPV6
);
61 /* When RouterAllowList=, PrefixAllowList= or RouteAllowList= are specified, then
62 * RouterDenyList=, PrefixDenyList= or RouteDenyList= are ignored, respectively. */
63 if (!set_isempty(network
->ndisc_allow_listed_router
))
64 network
->ndisc_deny_listed_router
= set_free_free(network
->ndisc_deny_listed_router
);
65 if (!set_isempty(network
->ndisc_allow_listed_prefix
))
66 network
->ndisc_deny_listed_prefix
= set_free_free(network
->ndisc_deny_listed_prefix
);
67 if (!set_isempty(network
->ndisc_allow_listed_route_prefix
))
68 network
->ndisc_deny_listed_route_prefix
= set_free_free(network
->ndisc_deny_listed_route_prefix
);
71 static int ndisc_remove(Link
*link
, struct in6_addr
*router
) {
81 SET_FOREACH(route
, link
->routes
) {
82 if (route
->source
!= NETWORK_CONFIG_SOURCE_NDISC
)
84 if (!route_is_marked(route
))
86 if (router
&& !in6_addr_equal(router
, &route
->provider
.in6
))
89 k
= route_remove(route
);
93 route_cancel_request(route
);
96 SET_FOREACH(address
, link
->addresses
) {
97 if (address
->source
!= NETWORK_CONFIG_SOURCE_NDISC
)
99 if (!address_is_marked(address
))
101 if (router
&& !in6_addr_equal(router
, &address
->provider
.in6
))
104 k
= address_remove(address
);
108 address_cancel_request(address
);
111 SET_FOREACH(rdnss
, link
->ndisc_rdnss
) {
114 if (router
&& !in6_addr_equal(router
, &rdnss
->router
))
117 free(set_remove(link
->ndisc_rdnss
, rdnss
));
121 SET_FOREACH(dnssl
, link
->ndisc_dnssl
) {
124 if (router
&& !in6_addr_equal(router
, &dnssl
->router
))
127 free(set_remove(link
->ndisc_dnssl
, dnssl
));
137 static int ndisc_check_ready(Link
*link
);
139 static int ndisc_address_ready_callback(Address
*address
) {
143 assert(address
->link
);
145 SET_FOREACH(a
, address
->link
->addresses
)
146 if (a
->source
== NETWORK_CONFIG_SOURCE_NDISC
)
149 return ndisc_check_ready(address
->link
);
152 static int ndisc_check_ready(Link
*link
) {
153 bool found
= false, ready
= false;
159 if (link
->ndisc_messages
> 0) {
160 log_link_debug(link
, "%s(): SLAAC addresses and routes are not set.", __func__
);
164 SET_FOREACH(address
, link
->addresses
) {
165 if (address
->source
!= NETWORK_CONFIG_SOURCE_NDISC
)
170 if (address_is_ready(address
)) {
176 if (found
&& !ready
) {
177 SET_FOREACH(address
, link
->addresses
)
178 if (address
->source
== NETWORK_CONFIG_SOURCE_NDISC
)
179 address
->callback
= ndisc_address_ready_callback
;
181 log_link_debug(link
, "%s(): no SLAAC address is ready.", __func__
);
185 link
->ndisc_configured
= true;
186 log_link_debug(link
, "SLAAC addresses and routes set.");
188 r
= ndisc_remove(link
, NULL
);
192 link_check_ready(link
);
196 static int ndisc_route_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
) {
200 assert(link
->ndisc_messages
> 0);
202 link
->ndisc_messages
--;
204 r
= route_configure_handler_internal(rtnl
, m
, link
, "Could not set NDisc route");
208 r
= ndisc_check_ready(link
);
210 link_enter_failed(link
);
215 static int ndisc_request_route(Route
*in
, Link
*link
, sd_ndisc_router
*rt
) {
216 _cleanup_(route_freep
) Route
*route
= in
;
217 struct in6_addr router
;
225 r
= sd_ndisc_router_get_address(rt
, &router
);
229 route
->source
= NETWORK_CONFIG_SOURCE_NDISC
;
230 route
->provider
.in6
= router
;
231 if (!route
->table_set
)
232 route
->table
= link_get_ipv6_accept_ra_route_table(link
);
233 if (!route
->priority_set
)
234 route
->priority
= link
->network
->ipv6_accept_ra_route_metric
;
235 if (!route
->protocol_set
)
236 route
->protocol
= RTPROT_RA
;
238 if (route_get(NULL
, link
, route
, &existing
) < 0)
239 link
->ndisc_configured
= false;
241 route_unmark(existing
);
243 return link_request_route(link
, TAKE_PTR(route
), true, &link
->ndisc_messages
,
244 ndisc_route_handler
, NULL
);
247 static int ndisc_address_handler(sd_netlink
*rtnl
, sd_netlink_message
*m
, Link
*link
) {
251 assert(link
->ndisc_messages
> 0);
253 link
->ndisc_messages
--;
255 r
= address_configure_handler_internal(rtnl
, m
, link
, "Could not set NDisc address");
259 r
= ndisc_check_ready(link
);
261 link_enter_failed(link
);
266 static int ndisc_request_address(Address
*in
, Link
*link
, sd_ndisc_router
*rt
) {
267 _cleanup_(address_freep
) Address
*address
= in
;
268 struct in6_addr router
;
276 r
= sd_ndisc_router_get_address(rt
, &router
);
280 address
->source
= NETWORK_CONFIG_SOURCE_NDISC
;
281 address
->provider
.in6
= router
;
283 if (address_get(link
, address
, &existing
) < 0)
284 link
->ndisc_configured
= false;
286 address_unmark(existing
);
288 return link_request_address(link
, TAKE_PTR(address
), true, &link
->ndisc_messages
,
289 ndisc_address_handler
, NULL
);
292 static int ndisc_router_process_default(Link
*link
, sd_ndisc_router
*rt
) {
293 _cleanup_(route_freep
) Route
*route
= NULL
;
294 usec_t lifetime_usec
, timestamp_usec
;
295 struct in6_addr gateway
;
296 uint16_t lifetime_sec
;
304 r
= sd_ndisc_router_get_lifetime(rt
, &lifetime_sec
);
306 return log_link_error_errno(link
, r
, "Failed to get gateway lifetime from RA: %m");
308 if (lifetime_sec
== 0) /* not a default router */
311 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
313 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
315 lifetime_usec
= usec_add(timestamp_usec
, lifetime_sec
* USEC_PER_SEC
);
317 r
= sd_ndisc_router_get_address(rt
, &gateway
);
319 return log_link_error_errno(link
, r
, "Failed to get gateway address from RA: %m");
321 if (link_get_ipv6_address(link
, &gateway
, NULL
) >= 0) {
323 _cleanup_free_
char *buffer
= NULL
;
325 (void) in6_addr_to_string(&gateway
, &buffer
);
326 log_link_debug(link
, "No NDisc route added, gateway %s matches local address",
332 r
= sd_ndisc_router_get_preference(rt
, &preference
);
334 return log_link_error_errno(link
, r
, "Failed to get default router preference from RA: %m");
336 if (link
->network
->ipv6_accept_ra_use_mtu
) {
337 r
= sd_ndisc_router_get_mtu(rt
, &mtu
);
338 if (r
< 0 && r
!= -ENODATA
)
339 return log_link_error_errno(link
, r
, "Failed to get default router MTU from RA: %m");
342 r
= route_new(&route
);
346 route
->family
= AF_INET6
;
347 route
->pref
= preference
;
348 route
->gw_family
= AF_INET6
;
349 route
->gw
.in6
= gateway
;
350 route
->lifetime_usec
= lifetime_usec
;
353 r
= ndisc_request_route(TAKE_PTR(route
), link
, rt
);
355 return log_link_error_errno(link
, r
, "Could not request default route: %m");
358 HASHMAP_FOREACH(route_gw
, link
->network
->routes_by_section
) {
359 if (!route_gw
->gateway_from_dhcp_or_ra
)
362 if (route_gw
->gw_family
!= AF_INET6
)
365 r
= route_dup(route_gw
, &route
);
369 route
->gw
.in6
= gateway
;
370 if (!route
->pref_set
)
371 route
->pref
= preference
;
372 route
->lifetime_usec
= lifetime_usec
;
376 r
= ndisc_request_route(TAKE_PTR(route
), link
, rt
);
378 return log_link_error_errno(link
, r
, "Could not request gateway: %m");
384 static int ndisc_router_process_autonomous_prefix(Link
*link
, sd_ndisc_router
*rt
) {
385 uint32_t lifetime_valid_sec
, lifetime_preferred_sec
;
386 usec_t lifetime_valid_usec
, lifetime_preferred_usec
, timestamp_usec
;
387 _cleanup_set_free_ Set
*addresses
= NULL
;
388 struct in6_addr prefix
, *a
;
393 assert(link
->network
);
396 if (!link
->network
->ipv6_accept_ra_use_autonomous_prefix
)
399 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
401 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
403 r
= sd_ndisc_router_prefix_get_address(rt
, &prefix
);
405 return log_link_error_errno(link
, r
, "Failed to get prefix address: %m");
407 r
= sd_ndisc_router_prefix_get_prefixlen(rt
, &prefixlen
);
409 return log_link_error_errno(link
, r
, "Failed to get prefix length: %m");
411 /* ndisc_generate_addresses() below requires the prefix length <= 64. */
412 if (prefixlen
> 64) {
413 _cleanup_free_
char *buf
= NULL
;
415 (void) in6_addr_prefix_to_string(&prefix
, prefixlen
, &buf
);
416 log_link_debug(link
, "Prefix is longer than 64, ignoring autonomous prefix %s.", strna(buf
));
420 r
= sd_ndisc_router_prefix_get_valid_lifetime(rt
, &lifetime_valid_sec
);
422 return log_link_error_errno(link
, r
, "Failed to get prefix valid lifetime: %m");
424 if (lifetime_valid_sec
== 0) {
425 log_link_debug(link
, "Ignoring prefix as its valid lifetime is zero.");
429 r
= sd_ndisc_router_prefix_get_preferred_lifetime(rt
, &lifetime_preferred_sec
);
431 return log_link_error_errno(link
, r
, "Failed to get prefix preferred lifetime: %m");
433 /* The preferred lifetime is never greater than the valid lifetime */
434 if (lifetime_preferred_sec
> lifetime_valid_sec
)
437 lifetime_valid_usec
= usec_add(lifetime_valid_sec
* USEC_PER_SEC
, timestamp_usec
);
438 lifetime_preferred_usec
= usec_add(lifetime_preferred_sec
* USEC_PER_SEC
, timestamp_usec
);
440 r
= ndisc_generate_addresses(link
, &prefix
, prefixlen
, &addresses
);
442 return log_link_error_errno(link
, r
, "Failed to generate SLAAC addresses: %m");
444 SET_FOREACH(a
, addresses
) {
445 _cleanup_(address_freep
) Address
*address
= NULL
;
448 r
= address_new(&address
);
452 address
->family
= AF_INET6
;
453 address
->in_addr
.in6
= *a
;
454 address
->prefixlen
= prefixlen
;
455 address
->flags
= IFA_F_NOPREFIXROUTE
|IFA_F_MANAGETEMPADDR
;
456 address
->lifetime_valid_usec
= lifetime_valid_usec
;
457 address
->lifetime_preferred_usec
= lifetime_preferred_usec
;
459 /* See RFC4862, section 5.5.3.e. But the following logic is deviated from RFC4862 by
460 * honoring all valid lifetimes to improve the reaction of SLAAC to renumbering events.
461 * See draft-ietf-6man-slaac-renum-02, section 4.2. */
462 r
= address_get(link
, address
, &e
);
464 /* If the address is already assigned, but not valid anymore, then refuse to
465 * update the address, and it will be removed. */
466 if (e
->lifetime_valid_usec
< timestamp_usec
)
470 r
= ndisc_request_address(TAKE_PTR(address
), link
, rt
);
472 return log_link_error_errno(link
, r
, "Could not request SLAAC address: %m");
478 static int ndisc_router_process_onlink_prefix(Link
*link
, sd_ndisc_router
*rt
) {
479 _cleanup_(route_freep
) Route
*route
= NULL
;
480 usec_t timestamp_usec
;
481 uint32_t lifetime_sec
;
486 assert(link
->network
);
489 if (!link
->network
->ipv6_accept_ra_use_onlink_prefix
)
492 r
= sd_ndisc_router_prefix_get_valid_lifetime(rt
, &lifetime_sec
);
494 return log_link_error_errno(link
, r
, "Failed to get prefix lifetime: %m");
496 if (lifetime_sec
== 0)
499 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
501 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
503 r
= sd_ndisc_router_prefix_get_prefixlen(rt
, &prefixlen
);
505 return log_link_error_errno(link
, r
, "Failed to get prefix length: %m");
507 r
= route_new(&route
);
511 route
->family
= AF_INET6
;
512 route
->flags
= RTM_F_PREFIX
;
513 route
->dst_prefixlen
= prefixlen
;
514 route
->lifetime_usec
= usec_add(timestamp_usec
, lifetime_sec
* USEC_PER_SEC
);
516 r
= sd_ndisc_router_prefix_get_address(rt
, &route
->dst
.in6
);
518 return log_link_error_errno(link
, r
, "Failed to get prefix address: %m");
520 r
= ndisc_request_route(TAKE_PTR(route
), link
, rt
);
522 return log_link_error_errno(link
, r
, "Could not request prefix route: %m");;
527 static int ndisc_router_process_prefix(Link
*link
, sd_ndisc_router
*rt
) {
534 assert(link
->network
);
537 r
= sd_ndisc_router_prefix_get_address(rt
, &a
);
539 return log_link_error_errno(link
, r
, "Failed to get prefix address: %m");
541 r
= sd_ndisc_router_prefix_get_prefixlen(rt
, &prefixlen
);
543 return log_link_error_errno(link
, r
, "Failed to get prefix length: %m");
545 if (in6_prefix_is_filtered(&a
, prefixlen
, link
->network
->ndisc_allow_listed_prefix
, link
->network
->ndisc_deny_listed_prefix
)) {
547 _cleanup_free_
char *b
= NULL
;
549 (void) in6_addr_prefix_to_string(&a
, prefixlen
, &b
);
550 if (!set_isempty(link
->network
->ndisc_allow_listed_prefix
))
551 log_link_debug(link
, "Prefix '%s' is not in allow list, ignoring", strna(b
));
553 log_link_debug(link
, "Prefix '%s' is in deny list, ignoring", strna(b
));
558 r
= sd_ndisc_router_prefix_get_flags(rt
, &flags
);
560 return log_link_error_errno(link
, r
, "Failed to get RA prefix flags: %m");
562 if (FLAGS_SET(flags
, ND_OPT_PI_FLAG_ONLINK
)) {
563 r
= ndisc_router_process_onlink_prefix(link
, rt
);
568 if (FLAGS_SET(flags
, ND_OPT_PI_FLAG_AUTO
)) {
569 r
= ndisc_router_process_autonomous_prefix(link
, rt
);
577 static int ndisc_router_process_route(Link
*link
, sd_ndisc_router
*rt
) {
578 _cleanup_(route_freep
) Route
*route
= NULL
;
579 unsigned preference
, prefixlen
;
580 struct in6_addr gateway
, dst
;
581 uint32_t lifetime_sec
;
582 usec_t timestamp_usec
;
587 r
= sd_ndisc_router_route_get_lifetime(rt
, &lifetime_sec
);
589 return log_link_error_errno(link
, r
, "Failed to get route lifetime from RA: %m");
591 if (lifetime_sec
== 0)
594 r
= sd_ndisc_router_route_get_address(rt
, &dst
);
596 return log_link_error_errno(link
, r
, "Failed to get route destination address: %m");
598 r
= sd_ndisc_router_route_get_prefixlen(rt
, &prefixlen
);
600 return log_link_error_errno(link
, r
, "Failed to get route prefix length: %m");
602 if (in6_prefix_is_filtered(&dst
, prefixlen
, link
->network
->ndisc_allow_listed_route_prefix
, link
->network
->ndisc_deny_listed_route_prefix
)) {
604 _cleanup_free_
char *buf
= NULL
;
606 (void) in6_addr_prefix_to_string(&dst
, prefixlen
, &buf
);
607 if (!set_isempty(link
->network
->ndisc_allow_listed_route_prefix
))
608 log_link_debug(link
, "Route prefix '%s' is not in allow list, ignoring", strna(buf
));
610 log_link_debug(link
, "Route prefix '%s' is in deny list, ignoring", strna(buf
));
615 r
= sd_ndisc_router_get_address(rt
, &gateway
);
617 return log_link_error_errno(link
, r
, "Failed to get gateway address from RA: %m");
619 if (link_get_ipv6_address(link
, &gateway
, NULL
) >= 0) {
621 _cleanup_free_
char *buf
= NULL
;
623 (void) in6_addr_to_string(&gateway
, &buf
);
624 log_link_debug(link
, "Advertised route gateway %s is local to the link, ignoring route", strna(buf
));
629 r
= sd_ndisc_router_route_get_preference(rt
, &preference
);
631 return log_link_error_errno(link
, r
, "Failed to get default router preference from RA: %m");
633 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
635 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
637 r
= route_new(&route
);
641 route
->family
= AF_INET6
;
642 route
->pref
= preference
;
643 route
->gw
.in6
= gateway
;
644 route
->gw_family
= AF_INET6
;
645 route
->dst
.in6
= dst
;
646 route
->dst_prefixlen
= prefixlen
;
647 route
->lifetime_usec
= usec_add(timestamp_usec
, lifetime_sec
* USEC_PER_SEC
);
649 r
= ndisc_request_route(TAKE_PTR(route
), link
, rt
);
651 return log_link_error_errno(link
, r
, "Could not request additional route: %m");
656 static void ndisc_rdnss_hash_func(const NDiscRDNSS
*x
, struct siphash
*state
) {
657 siphash24_compress(&x
->address
, sizeof(x
->address
), state
);
660 static int ndisc_rdnss_compare_func(const NDiscRDNSS
*a
, const NDiscRDNSS
*b
) {
661 return memcmp(&a
->address
, &b
->address
, sizeof(a
->address
));
664 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
665 ndisc_rdnss_hash_ops
,
667 ndisc_rdnss_hash_func
,
668 ndisc_rdnss_compare_func
,
671 static int ndisc_router_process_rdnss(Link
*link
, sd_ndisc_router
*rt
) {
672 usec_t lifetime_usec
, timestamp_usec
;
673 uint32_t lifetime_sec
;
674 const struct in6_addr
*a
;
675 struct in6_addr router
;
676 bool updated
= false;
680 assert(link
->network
);
683 if (!link
->network
->ipv6_accept_ra_use_dns
)
686 r
= sd_ndisc_router_get_address(rt
, &router
);
688 return log_link_error_errno(link
, r
, "Failed to get router address from RA: %m");
690 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
692 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
694 r
= sd_ndisc_router_rdnss_get_lifetime(rt
, &lifetime_sec
);
696 return log_link_error_errno(link
, r
, "Failed to get RDNSS lifetime: %m");
698 if (lifetime_sec
== 0)
701 lifetime_usec
= usec_add(timestamp_usec
, lifetime_sec
* USEC_PER_SEC
);
703 n
= sd_ndisc_router_rdnss_get_addresses(rt
, &a
);
705 return log_link_error_errno(link
, n
, "Failed to get RDNSS addresses: %m");
707 if (n
>= (int) NDISC_RDNSS_MAX
) {
708 log_link_warning(link
, "Too many RDNSS records per link. Only first %i records will be used.", NDISC_RDNSS_MAX
);
712 for (int j
= 0; j
< n
; j
++) {
713 _cleanup_free_ NDiscRDNSS
*x
= NULL
;
714 NDiscRDNSS
*rdnss
, d
= {
718 rdnss
= set_get(link
->ndisc_rdnss
, &d
);
720 rdnss
->marked
= false;
721 rdnss
->router
= router
;
722 rdnss
->lifetime_usec
= lifetime_usec
;
726 x
= new(NDiscRDNSS
, 1);
733 .lifetime_usec
= lifetime_usec
,
736 r
= set_ensure_consume(&link
->ndisc_rdnss
, &ndisc_rdnss_hash_ops
, TAKE_PTR(x
));
750 static void ndisc_dnssl_hash_func(const NDiscDNSSL
*x
, struct siphash
*state
) {
751 siphash24_compress_string(NDISC_DNSSL_DOMAIN(x
), state
);
754 static int ndisc_dnssl_compare_func(const NDiscDNSSL
*a
, const NDiscDNSSL
*b
) {
755 return strcmp(NDISC_DNSSL_DOMAIN(a
), NDISC_DNSSL_DOMAIN(b
));
758 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
759 ndisc_dnssl_hash_ops
,
761 ndisc_dnssl_hash_func
,
762 ndisc_dnssl_compare_func
,
765 static int ndisc_router_process_dnssl(Link
*link
, sd_ndisc_router
*rt
) {
766 _cleanup_strv_free_
char **l
= NULL
;
767 usec_t lifetime_usec
, timestamp_usec
;
768 struct in6_addr router
;
769 uint32_t lifetime_sec
;
770 bool updated
= false;
775 assert(link
->network
);
778 if (link
->network
->ipv6_accept_ra_use_domains
== DHCP_USE_DOMAINS_NO
)
781 r
= sd_ndisc_router_get_address(rt
, &router
);
783 return log_link_error_errno(link
, r
, "Failed to get router address from RA: %m");
785 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
787 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
789 r
= sd_ndisc_router_dnssl_get_lifetime(rt
, &lifetime_sec
);
791 return log_link_error_errno(link
, r
, "Failed to get DNSSL lifetime: %m");
793 if (lifetime_sec
== 0)
796 lifetime_usec
= usec_add(timestamp_usec
, lifetime_sec
* USEC_PER_SEC
);
798 r
= sd_ndisc_router_dnssl_get_domains(rt
, &l
);
800 return log_link_error_errno(link
, r
, "Failed to get DNSSL addresses: %m");
802 if (strv_length(l
) >= NDISC_DNSSL_MAX
) {
803 log_link_warning(link
, "Too many DNSSL records per link. Only first %i records will be used.", NDISC_DNSSL_MAX
);
804 STRV_FOREACH(j
, l
+ NDISC_DNSSL_MAX
)
809 _cleanup_free_ NDiscDNSSL
*s
= NULL
;
812 s
= malloc0(ALIGN(sizeof(NDiscDNSSL
)) + strlen(*j
) + 1);
816 strcpy(NDISC_DNSSL_DOMAIN(s
), *j
);
818 dnssl
= set_get(link
->ndisc_dnssl
, s
);
820 dnssl
->marked
= false;
821 dnssl
->router
= router
;
822 dnssl
->lifetime_usec
= lifetime_usec
;
827 s
->lifetime_usec
= lifetime_usec
;
829 r
= set_ensure_consume(&link
->ndisc_dnssl
, &ndisc_dnssl_hash_ops
, TAKE_PTR(s
));
843 static int ndisc_router_process_options(Link
*link
, sd_ndisc_router
*rt
) {
847 assert(link
->network
);
850 for (r
= sd_ndisc_router_option_rewind(rt
); ; r
= sd_ndisc_router_option_next(rt
)) {
854 return log_link_error_errno(link
, r
, "Failed to iterate through options: %m");
855 if (r
== 0) /* EOF */
858 r
= sd_ndisc_router_option_get_type(rt
, &type
);
860 return log_link_error_errno(link
, r
, "Failed to get RA option type: %m");
864 case SD_NDISC_OPTION_PREFIX_INFORMATION
:
865 r
= ndisc_router_process_prefix(link
, rt
);
870 case SD_NDISC_OPTION_ROUTE_INFORMATION
:
871 r
= ndisc_router_process_route(link
, rt
);
876 case SD_NDISC_OPTION_RDNSS
:
877 r
= ndisc_router_process_rdnss(link
, rt
);
882 case SD_NDISC_OPTION_DNSSL
:
883 r
= ndisc_router_process_dnssl(link
, rt
);
891 static void ndisc_mark(Link
*link
, const struct in6_addr
*router
) {
898 link_mark_addresses(link
, NETWORK_CONFIG_SOURCE_NDISC
, router
);
899 link_mark_routes(link
, NETWORK_CONFIG_SOURCE_NDISC
, router
);
901 SET_FOREACH(rdnss
, link
->ndisc_rdnss
)
902 if (in6_addr_equal(&rdnss
->router
, router
))
903 rdnss
->marked
= true;
905 SET_FOREACH(dnssl
, link
->ndisc_dnssl
)
906 if (in6_addr_equal(&dnssl
->router
, router
))
907 dnssl
->marked
= true;
910 static int ndisc_start_dhcp6_client(Link
*link
, sd_ndisc_router
*rt
) {
914 assert(link
->network
);
916 switch (link
->network
->ipv6_accept_ra_start_dhcp6_client
) {
917 case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO
:
920 case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
: {
923 r
= sd_ndisc_router_get_flags(rt
, &flags
);
925 return log_link_warning_errno(link
, r
, "Failed to get RA flags: %m");
927 if ((flags
& (ND_RA_FLAG_MANAGED
| ND_RA_FLAG_OTHER
)) == 0)
930 /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags.
931 * Note, if both managed and other information bits are set, then ignore other
932 * information bit. See RFC 4861. */
933 r
= dhcp6_start_on_ra(link
, !(flags
& ND_RA_FLAG_MANAGED
));
936 case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS
:
937 /* When IPv6AcceptRA.DHCPv6Client=always, start dhcp6 client in managed mode
938 * even if the router flags have neither M nor O flags. */
939 r
= dhcp6_start_on_ra(link
, /* information_request = */ false);
943 assert_not_reached();
947 return log_link_error_errno(link
, r
, "Could not acquire DHCPv6 lease on NDisc request: %m");
949 log_link_debug(link
, "Acquiring DHCPv6 lease on NDisc request");
953 static int ndisc_router_handler(Link
*link
, sd_ndisc_router
*rt
) {
954 struct in6_addr router
;
958 assert(link
->network
);
959 assert(link
->manager
);
962 r
= sd_ndisc_router_get_address(rt
, &router
);
964 return log_link_error_errno(link
, r
, "Failed to get router address from RA: %m");
966 if (in6_prefix_is_filtered(&router
, 128, link
->network
->ndisc_allow_listed_router
, link
->network
->ndisc_deny_listed_router
)) {
968 _cleanup_free_
char *buf
= NULL
;
970 (void) in6_addr_to_string(&router
, &buf
);
971 if (!set_isempty(link
->network
->ndisc_allow_listed_router
))
972 log_link_debug(link
, "Router '%s' is not in allow list, ignoring", strna(buf
));
974 log_link_debug(link
, "Router '%s' is in deny list, ignoring", strna(buf
));
979 ndisc_mark(link
, &router
);
981 r
= ndisc_start_dhcp6_client(link
, rt
);
985 r
= ndisc_router_process_default(link
, rt
);
989 r
= ndisc_router_process_options(link
, rt
);
993 if (link
->ndisc_messages
== 0) {
994 link
->ndisc_configured
= true;
996 r
= ndisc_remove(link
, &router
);
1000 log_link_debug(link
, "Setting SLAAC addresses and router.");
1002 if (!link
->ndisc_configured
)
1003 link_set_state(link
, LINK_STATE_CONFIGURING
);
1005 link_check_ready(link
);
1009 static void ndisc_handler(sd_ndisc
*nd
, sd_ndisc_event_t event
, sd_ndisc_router
*rt
, void *userdata
) {
1010 Link
*link
= userdata
;
1015 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
1020 case SD_NDISC_EVENT_ROUTER
:
1021 r
= ndisc_router_handler(link
, rt
);
1023 link_enter_failed(link
);
1028 case SD_NDISC_EVENT_TIMEOUT
:
1029 log_link_debug(link
, "NDisc handler get timeout event");
1030 if (link
->ndisc_messages
== 0) {
1031 link
->ndisc_configured
= true;
1032 link_check_ready(link
);
1036 assert_not_reached();
1040 int ndisc_configure(Link
*link
) {
1045 if (!link_ipv6_accept_ra_enabled(link
))
1049 return -EBUSY
; /* Already configured. */
1051 r
= sd_ndisc_new(&link
->ndisc
);
1055 r
= sd_ndisc_attach_event(link
->ndisc
, link
->manager
->event
, 0);
1059 r
= sd_ndisc_set_mac(link
->ndisc
, &link
->hw_addr
.ether
);
1063 r
= sd_ndisc_set_ifindex(link
->ndisc
, link
->ifindex
);
1067 r
= sd_ndisc_set_callback(link
->ndisc
, ndisc_handler
, link
);
1074 int ndisc_start(Link
*link
) {
1077 if (!link
->ndisc
|| !link
->dhcp6_client
)
1080 if (!link_has_carrier(link
))
1083 if (in6_addr_is_null(&link
->ipv6ll_address
))
1086 log_link_debug(link
, "Discovering IPv6 routers");
1088 return sd_ndisc_start(link
->ndisc
);
1091 void ndisc_vacuum(Link
*link
) {
1098 /* Removes all RDNSS and DNSSL entries whose validity time has passed */
1100 time_now
= now(clock_boottime_or_monotonic());
1102 SET_FOREACH(r
, link
->ndisc_rdnss
)
1103 if (r
->lifetime_usec
< time_now
)
1104 free(set_remove(link
->ndisc_rdnss
, r
));
1106 SET_FOREACH(d
, link
->ndisc_dnssl
)
1107 if (d
->lifetime_usec
< time_now
)
1108 free(set_remove(link
->ndisc_dnssl
, d
));
1111 void ndisc_flush(Link
*link
) {
1114 /* Removes all RDNSS and DNSSL entries, without exception */
1116 link
->ndisc_rdnss
= set_free(link
->ndisc_rdnss
);
1117 link
->ndisc_dnssl
= set_free(link
->ndisc_dnssl
);
1120 static const char* const ipv6_accept_ra_start_dhcp6_client_table
[_IPV6_ACCEPT_RA_START_DHCP6_CLIENT_MAX
] = {
1121 [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO
] = "no",
1122 [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS
] = "always",
1123 [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
] = "yes",
1126 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(ipv6_accept_ra_start_dhcp6_client
, IPv6AcceptRAStartDHCP6Client
, IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
);
1128 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_accept_ra_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1129 "Failed to parse UseDomains= setting");
1130 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_accept_ra_start_dhcp6_client
, ipv6_accept_ra_start_dhcp6_client
, IPv6AcceptRAStartDHCP6Client
,
1131 "Failed to parse DHCPv6Client= setting");