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
, link
);
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 usec_t lifetime_usec
, timestamp_usec
;
294 struct in6_addr gateway
;
295 uint16_t lifetime_sec
;
301 assert(link
->network
);
304 if (!link
->network
->ipv6_accept_ra_use_gateway
&&
305 hashmap_isempty(link
->network
->routes_by_section
))
308 r
= sd_ndisc_router_get_lifetime(rt
, &lifetime_sec
);
310 return log_link_error_errno(link
, r
, "Failed to get gateway lifetime from RA: %m");
312 if (lifetime_sec
== 0) /* not a default router */
315 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
317 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
319 lifetime_usec
= usec_add(timestamp_usec
, lifetime_sec
* USEC_PER_SEC
);
321 r
= sd_ndisc_router_get_address(rt
, &gateway
);
323 return log_link_error_errno(link
, r
, "Failed to get gateway address from RA: %m");
325 if (link_get_ipv6_address(link
, &gateway
, NULL
) >= 0) {
327 _cleanup_free_
char *buffer
= NULL
;
329 (void) in6_addr_to_string(&gateway
, &buffer
);
330 log_link_debug(link
, "No NDisc route added, gateway %s matches local address",
336 r
= sd_ndisc_router_get_preference(rt
, &preference
);
338 return log_link_error_errno(link
, r
, "Failed to get default router preference from RA: %m");
340 if (link
->network
->ipv6_accept_ra_use_mtu
) {
341 r
= sd_ndisc_router_get_mtu(rt
, &mtu
);
342 if (r
< 0 && r
!= -ENODATA
)
343 return log_link_error_errno(link
, r
, "Failed to get default router MTU from RA: %m");
346 if (link
->network
->ipv6_accept_ra_use_gateway
) {
347 _cleanup_(route_freep
) Route
*route
= NULL
;
349 r
= route_new(&route
);
353 route
->family
= AF_INET6
;
354 route
->pref
= preference
;
355 route
->gw_family
= AF_INET6
;
356 route
->gw
.in6
= gateway
;
357 route
->lifetime_usec
= lifetime_usec
;
360 r
= ndisc_request_route(TAKE_PTR(route
), link
, rt
);
362 return log_link_error_errno(link
, r
, "Could not request default route: %m");
366 HASHMAP_FOREACH(route_gw
, link
->network
->routes_by_section
) {
367 _cleanup_(route_freep
) Route
*route
= NULL
;
369 if (!route_gw
->gateway_from_dhcp_or_ra
)
372 if (route_gw
->gw_family
!= AF_INET6
)
375 r
= route_dup(route_gw
, &route
);
379 route
->gw
.in6
= gateway
;
380 if (!route
->pref_set
)
381 route
->pref
= preference
;
382 route
->lifetime_usec
= lifetime_usec
;
386 r
= ndisc_request_route(TAKE_PTR(route
), link
, rt
);
388 return log_link_error_errno(link
, r
, "Could not request gateway: %m");
394 static int ndisc_router_process_autonomous_prefix(Link
*link
, sd_ndisc_router
*rt
) {
395 uint32_t lifetime_valid_sec
, lifetime_preferred_sec
;
396 usec_t lifetime_valid_usec
, lifetime_preferred_usec
, timestamp_usec
;
397 _cleanup_set_free_ Set
*addresses
= NULL
;
398 struct in6_addr prefix
, *a
;
403 assert(link
->network
);
406 if (!link
->network
->ipv6_accept_ra_use_autonomous_prefix
)
409 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
411 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
413 r
= sd_ndisc_router_prefix_get_address(rt
, &prefix
);
415 return log_link_error_errno(link
, r
, "Failed to get prefix address: %m");
417 r
= sd_ndisc_router_prefix_get_prefixlen(rt
, &prefixlen
);
419 return log_link_error_errno(link
, r
, "Failed to get prefix length: %m");
421 /* ndisc_generate_addresses() below requires the prefix length <= 64. */
422 if (prefixlen
> 64) {
423 _cleanup_free_
char *buf
= NULL
;
425 (void) in6_addr_prefix_to_string(&prefix
, prefixlen
, &buf
);
426 log_link_debug(link
, "Prefix is longer than 64, ignoring autonomous prefix %s.", strna(buf
));
430 r
= sd_ndisc_router_prefix_get_valid_lifetime(rt
, &lifetime_valid_sec
);
432 return log_link_error_errno(link
, r
, "Failed to get prefix valid lifetime: %m");
434 if (lifetime_valid_sec
== 0) {
435 log_link_debug(link
, "Ignoring prefix as its valid lifetime is zero.");
439 r
= sd_ndisc_router_prefix_get_preferred_lifetime(rt
, &lifetime_preferred_sec
);
441 return log_link_error_errno(link
, r
, "Failed to get prefix preferred lifetime: %m");
443 /* The preferred lifetime is never greater than the valid lifetime */
444 if (lifetime_preferred_sec
> lifetime_valid_sec
)
447 lifetime_valid_usec
= usec_add(lifetime_valid_sec
* USEC_PER_SEC
, timestamp_usec
);
448 lifetime_preferred_usec
= usec_add(lifetime_preferred_sec
* USEC_PER_SEC
, timestamp_usec
);
450 r
= ndisc_generate_addresses(link
, &prefix
, prefixlen
, &addresses
);
452 return log_link_error_errno(link
, r
, "Failed to generate SLAAC addresses: %m");
454 SET_FOREACH(a
, addresses
) {
455 _cleanup_(address_freep
) Address
*address
= NULL
;
458 r
= address_new(&address
);
462 address
->family
= AF_INET6
;
463 address
->in_addr
.in6
= *a
;
464 address
->prefixlen
= prefixlen
;
465 address
->flags
= IFA_F_NOPREFIXROUTE
|IFA_F_MANAGETEMPADDR
;
466 address
->lifetime_valid_usec
= lifetime_valid_usec
;
467 address
->lifetime_preferred_usec
= lifetime_preferred_usec
;
469 /* See RFC4862, section 5.5.3.e. But the following logic is deviated from RFC4862 by
470 * honoring all valid lifetimes to improve the reaction of SLAAC to renumbering events.
471 * See draft-ietf-6man-slaac-renum-02, section 4.2. */
472 r
= address_get(link
, address
, &e
);
474 /* If the address is already assigned, but not valid anymore, then refuse to
475 * update the address, and it will be removed. */
476 if (e
->lifetime_valid_usec
< timestamp_usec
)
480 r
= ndisc_request_address(TAKE_PTR(address
), link
, rt
);
482 return log_link_error_errno(link
, r
, "Could not request SLAAC address: %m");
488 static int ndisc_router_process_onlink_prefix(Link
*link
, sd_ndisc_router
*rt
) {
489 _cleanup_(route_freep
) Route
*route
= NULL
;
490 usec_t timestamp_usec
;
491 uint32_t lifetime_sec
;
496 assert(link
->network
);
499 if (!link
->network
->ipv6_accept_ra_use_onlink_prefix
)
502 r
= sd_ndisc_router_prefix_get_valid_lifetime(rt
, &lifetime_sec
);
504 return log_link_error_errno(link
, r
, "Failed to get prefix lifetime: %m");
506 if (lifetime_sec
== 0)
509 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
511 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
513 r
= sd_ndisc_router_prefix_get_prefixlen(rt
, &prefixlen
);
515 return log_link_error_errno(link
, r
, "Failed to get prefix length: %m");
517 r
= route_new(&route
);
521 route
->family
= AF_INET6
;
522 route
->flags
= RTM_F_PREFIX
;
523 route
->dst_prefixlen
= prefixlen
;
524 route
->lifetime_usec
= usec_add(timestamp_usec
, lifetime_sec
* USEC_PER_SEC
);
526 r
= sd_ndisc_router_prefix_get_address(rt
, &route
->dst
.in6
);
528 return log_link_error_errno(link
, r
, "Failed to get prefix address: %m");
530 r
= ndisc_request_route(TAKE_PTR(route
), link
, rt
);
532 return log_link_error_errno(link
, r
, "Could not request prefix route: %m");;
537 static int ndisc_router_process_prefix(Link
*link
, sd_ndisc_router
*rt
) {
544 assert(link
->network
);
547 r
= sd_ndisc_router_prefix_get_address(rt
, &a
);
549 return log_link_error_errno(link
, r
, "Failed to get prefix address: %m");
551 r
= sd_ndisc_router_prefix_get_prefixlen(rt
, &prefixlen
);
553 return log_link_error_errno(link
, r
, "Failed to get prefix length: %m");
555 if (in6_prefix_is_filtered(&a
, prefixlen
, link
->network
->ndisc_allow_listed_prefix
, link
->network
->ndisc_deny_listed_prefix
)) {
557 _cleanup_free_
char *b
= NULL
;
559 (void) in6_addr_prefix_to_string(&a
, prefixlen
, &b
);
560 if (!set_isempty(link
->network
->ndisc_allow_listed_prefix
))
561 log_link_debug(link
, "Prefix '%s' is not in allow list, ignoring", strna(b
));
563 log_link_debug(link
, "Prefix '%s' is in deny list, ignoring", strna(b
));
568 r
= sd_ndisc_router_prefix_get_flags(rt
, &flags
);
570 return log_link_error_errno(link
, r
, "Failed to get RA prefix flags: %m");
572 if (FLAGS_SET(flags
, ND_OPT_PI_FLAG_ONLINK
)) {
573 r
= ndisc_router_process_onlink_prefix(link
, rt
);
578 if (FLAGS_SET(flags
, ND_OPT_PI_FLAG_AUTO
)) {
579 r
= ndisc_router_process_autonomous_prefix(link
, rt
);
587 static int ndisc_router_process_route(Link
*link
, sd_ndisc_router
*rt
) {
588 _cleanup_(route_freep
) Route
*route
= NULL
;
589 unsigned preference
, prefixlen
;
590 struct in6_addr gateway
, dst
;
591 uint32_t lifetime_sec
;
592 usec_t timestamp_usec
;
597 if (!link
->network
->ipv6_accept_ra_use_route_prefix
)
600 r
= sd_ndisc_router_route_get_lifetime(rt
, &lifetime_sec
);
602 return log_link_error_errno(link
, r
, "Failed to get route lifetime from RA: %m");
604 if (lifetime_sec
== 0)
607 r
= sd_ndisc_router_route_get_address(rt
, &dst
);
609 return log_link_error_errno(link
, r
, "Failed to get route destination address: %m");
611 r
= sd_ndisc_router_route_get_prefixlen(rt
, &prefixlen
);
613 return log_link_error_errno(link
, r
, "Failed to get route prefix length: %m");
615 if (in6_prefix_is_filtered(&dst
, prefixlen
, link
->network
->ndisc_allow_listed_route_prefix
, link
->network
->ndisc_deny_listed_route_prefix
)) {
617 _cleanup_free_
char *buf
= NULL
;
619 (void) in6_addr_prefix_to_string(&dst
, prefixlen
, &buf
);
620 if (!set_isempty(link
->network
->ndisc_allow_listed_route_prefix
))
621 log_link_debug(link
, "Route prefix '%s' is not in allow list, ignoring", strna(buf
));
623 log_link_debug(link
, "Route prefix '%s' is in deny list, ignoring", strna(buf
));
628 r
= sd_ndisc_router_get_address(rt
, &gateway
);
630 return log_link_error_errno(link
, r
, "Failed to get gateway address from RA: %m");
632 if (link_get_ipv6_address(link
, &gateway
, NULL
) >= 0) {
634 _cleanup_free_
char *buf
= NULL
;
636 (void) in6_addr_to_string(&gateway
, &buf
);
637 log_link_debug(link
, "Advertised route gateway %s is local to the link, ignoring route", strna(buf
));
642 r
= sd_ndisc_router_route_get_preference(rt
, &preference
);
644 return log_link_error_errno(link
, r
, "Failed to get default router preference from RA: %m");
646 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
648 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
650 r
= route_new(&route
);
654 route
->family
= AF_INET6
;
655 route
->pref
= preference
;
656 route
->gw
.in6
= gateway
;
657 route
->gw_family
= AF_INET6
;
658 route
->dst
.in6
= dst
;
659 route
->dst_prefixlen
= prefixlen
;
660 route
->lifetime_usec
= usec_add(timestamp_usec
, lifetime_sec
* USEC_PER_SEC
);
662 r
= ndisc_request_route(TAKE_PTR(route
), link
, rt
);
664 return log_link_error_errno(link
, r
, "Could not request additional route: %m");
669 static void ndisc_rdnss_hash_func(const NDiscRDNSS
*x
, struct siphash
*state
) {
670 siphash24_compress(&x
->address
, sizeof(x
->address
), state
);
673 static int ndisc_rdnss_compare_func(const NDiscRDNSS
*a
, const NDiscRDNSS
*b
) {
674 return memcmp(&a
->address
, &b
->address
, sizeof(a
->address
));
677 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
678 ndisc_rdnss_hash_ops
,
680 ndisc_rdnss_hash_func
,
681 ndisc_rdnss_compare_func
,
684 static int ndisc_router_process_rdnss(Link
*link
, sd_ndisc_router
*rt
) {
685 usec_t lifetime_usec
, timestamp_usec
;
686 uint32_t lifetime_sec
;
687 const struct in6_addr
*a
;
688 struct in6_addr router
;
689 bool updated
= false;
693 assert(link
->network
);
696 if (!link
->network
->ipv6_accept_ra_use_dns
)
699 r
= sd_ndisc_router_get_address(rt
, &router
);
701 return log_link_error_errno(link
, r
, "Failed to get router address from RA: %m");
703 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
705 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
707 r
= sd_ndisc_router_rdnss_get_lifetime(rt
, &lifetime_sec
);
709 return log_link_error_errno(link
, r
, "Failed to get RDNSS lifetime: %m");
711 if (lifetime_sec
== 0)
714 lifetime_usec
= usec_add(timestamp_usec
, lifetime_sec
* USEC_PER_SEC
);
716 n
= sd_ndisc_router_rdnss_get_addresses(rt
, &a
);
718 return log_link_error_errno(link
, n
, "Failed to get RDNSS addresses: %m");
720 if (n
>= (int) NDISC_RDNSS_MAX
) {
721 log_link_warning(link
, "Too many RDNSS records per link. Only first %i records will be used.", NDISC_RDNSS_MAX
);
725 for (int j
= 0; j
< n
; j
++) {
726 _cleanup_free_ NDiscRDNSS
*x
= NULL
;
727 NDiscRDNSS
*rdnss
, d
= {
731 rdnss
= set_get(link
->ndisc_rdnss
, &d
);
733 rdnss
->marked
= false;
734 rdnss
->router
= router
;
735 rdnss
->lifetime_usec
= lifetime_usec
;
739 x
= new(NDiscRDNSS
, 1);
746 .lifetime_usec
= lifetime_usec
,
749 r
= set_ensure_consume(&link
->ndisc_rdnss
, &ndisc_rdnss_hash_ops
, TAKE_PTR(x
));
763 static void ndisc_dnssl_hash_func(const NDiscDNSSL
*x
, struct siphash
*state
) {
764 siphash24_compress_string(NDISC_DNSSL_DOMAIN(x
), state
);
767 static int ndisc_dnssl_compare_func(const NDiscDNSSL
*a
, const NDiscDNSSL
*b
) {
768 return strcmp(NDISC_DNSSL_DOMAIN(a
), NDISC_DNSSL_DOMAIN(b
));
771 DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
772 ndisc_dnssl_hash_ops
,
774 ndisc_dnssl_hash_func
,
775 ndisc_dnssl_compare_func
,
778 static int ndisc_router_process_dnssl(Link
*link
, sd_ndisc_router
*rt
) {
779 _cleanup_strv_free_
char **l
= NULL
;
780 usec_t lifetime_usec
, timestamp_usec
;
781 struct in6_addr router
;
782 uint32_t lifetime_sec
;
783 bool updated
= false;
788 assert(link
->network
);
791 if (link
->network
->ipv6_accept_ra_use_domains
== DHCP_USE_DOMAINS_NO
)
794 r
= sd_ndisc_router_get_address(rt
, &router
);
796 return log_link_error_errno(link
, r
, "Failed to get router address from RA: %m");
798 r
= sd_ndisc_router_get_timestamp(rt
, clock_boottime_or_monotonic(), ×tamp_usec
);
800 return log_link_error_errno(link
, r
, "Failed to get RA timestamp: %m");
802 r
= sd_ndisc_router_dnssl_get_lifetime(rt
, &lifetime_sec
);
804 return log_link_error_errno(link
, r
, "Failed to get DNSSL lifetime: %m");
806 if (lifetime_sec
== 0)
809 lifetime_usec
= usec_add(timestamp_usec
, lifetime_sec
* USEC_PER_SEC
);
811 r
= sd_ndisc_router_dnssl_get_domains(rt
, &l
);
813 return log_link_error_errno(link
, r
, "Failed to get DNSSL addresses: %m");
815 if (strv_length(l
) >= NDISC_DNSSL_MAX
) {
816 log_link_warning(link
, "Too many DNSSL records per link. Only first %i records will be used.", NDISC_DNSSL_MAX
);
817 STRV_FOREACH(j
, l
+ NDISC_DNSSL_MAX
)
822 _cleanup_free_ NDiscDNSSL
*s
= NULL
;
825 s
= malloc0(ALIGN(sizeof(NDiscDNSSL
)) + strlen(*j
) + 1);
829 strcpy(NDISC_DNSSL_DOMAIN(s
), *j
);
831 dnssl
= set_get(link
->ndisc_dnssl
, s
);
833 dnssl
->marked
= false;
834 dnssl
->router
= router
;
835 dnssl
->lifetime_usec
= lifetime_usec
;
840 s
->lifetime_usec
= lifetime_usec
;
842 r
= set_ensure_consume(&link
->ndisc_dnssl
, &ndisc_dnssl_hash_ops
, TAKE_PTR(s
));
856 static int ndisc_router_process_options(Link
*link
, sd_ndisc_router
*rt
) {
860 assert(link
->network
);
863 for (r
= sd_ndisc_router_option_rewind(rt
); ; r
= sd_ndisc_router_option_next(rt
)) {
867 return log_link_error_errno(link
, r
, "Failed to iterate through options: %m");
868 if (r
== 0) /* EOF */
871 r
= sd_ndisc_router_option_get_type(rt
, &type
);
873 return log_link_error_errno(link
, r
, "Failed to get RA option type: %m");
877 case SD_NDISC_OPTION_PREFIX_INFORMATION
:
878 r
= ndisc_router_process_prefix(link
, rt
);
883 case SD_NDISC_OPTION_ROUTE_INFORMATION
:
884 r
= ndisc_router_process_route(link
, rt
);
889 case SD_NDISC_OPTION_RDNSS
:
890 r
= ndisc_router_process_rdnss(link
, rt
);
895 case SD_NDISC_OPTION_DNSSL
:
896 r
= ndisc_router_process_dnssl(link
, rt
);
904 static void ndisc_mark(Link
*link
, const struct in6_addr
*router
) {
911 link_mark_addresses(link
, NETWORK_CONFIG_SOURCE_NDISC
, router
);
912 link_mark_routes(link
, NETWORK_CONFIG_SOURCE_NDISC
, router
);
914 SET_FOREACH(rdnss
, link
->ndisc_rdnss
)
915 if (in6_addr_equal(&rdnss
->router
, router
))
916 rdnss
->marked
= true;
918 SET_FOREACH(dnssl
, link
->ndisc_dnssl
)
919 if (in6_addr_equal(&dnssl
->router
, router
))
920 dnssl
->marked
= true;
923 static int ndisc_start_dhcp6_client(Link
*link
, sd_ndisc_router
*rt
) {
927 assert(link
->network
);
929 switch (link
->network
->ipv6_accept_ra_start_dhcp6_client
) {
930 case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO
:
933 case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
: {
936 r
= sd_ndisc_router_get_flags(rt
, &flags
);
938 return log_link_warning_errno(link
, r
, "Failed to get RA flags: %m");
940 if ((flags
& (ND_RA_FLAG_MANAGED
| ND_RA_FLAG_OTHER
)) == 0)
943 /* (re)start DHCPv6 client in stateful or stateless mode according to RA flags.
944 * Note, if both managed and other information bits are set, then ignore other
945 * information bit. See RFC 4861. */
946 r
= dhcp6_start_on_ra(link
, !(flags
& ND_RA_FLAG_MANAGED
));
949 case IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS
:
950 /* When IPv6AcceptRA.DHCPv6Client=always, start dhcp6 client in managed mode
951 * even if the router flags have neither M nor O flags. */
952 r
= dhcp6_start_on_ra(link
, /* information_request = */ false);
956 assert_not_reached();
960 return log_link_error_errno(link
, r
, "Could not acquire DHCPv6 lease on NDisc request: %m");
962 log_link_debug(link
, "Acquiring DHCPv6 lease on NDisc request");
966 static int ndisc_router_handler(Link
*link
, sd_ndisc_router
*rt
) {
967 struct in6_addr router
;
971 assert(link
->network
);
972 assert(link
->manager
);
975 r
= sd_ndisc_router_get_address(rt
, &router
);
977 return log_link_error_errno(link
, r
, "Failed to get router address from RA: %m");
979 if (in6_prefix_is_filtered(&router
, 128, link
->network
->ndisc_allow_listed_router
, link
->network
->ndisc_deny_listed_router
)) {
981 _cleanup_free_
char *buf
= NULL
;
983 (void) in6_addr_to_string(&router
, &buf
);
984 if (!set_isempty(link
->network
->ndisc_allow_listed_router
))
985 log_link_debug(link
, "Router '%s' is not in allow list, ignoring", strna(buf
));
987 log_link_debug(link
, "Router '%s' is in deny list, ignoring", strna(buf
));
992 ndisc_mark(link
, &router
);
994 r
= ndisc_start_dhcp6_client(link
, rt
);
998 r
= ndisc_router_process_default(link
, rt
);
1002 r
= ndisc_router_process_options(link
, rt
);
1006 if (link
->ndisc_messages
== 0) {
1007 link
->ndisc_configured
= true;
1009 r
= ndisc_remove(link
, &router
);
1013 log_link_debug(link
, "Setting SLAAC addresses and router.");
1015 if (!link
->ndisc_configured
)
1016 link_set_state(link
, LINK_STATE_CONFIGURING
);
1018 link_check_ready(link
);
1022 static void ndisc_handler(sd_ndisc
*nd
, sd_ndisc_event_t event
, sd_ndisc_router
*rt
, void *userdata
) {
1023 Link
*link
= userdata
;
1028 if (IN_SET(link
->state
, LINK_STATE_FAILED
, LINK_STATE_LINGER
))
1033 case SD_NDISC_EVENT_ROUTER
:
1034 r
= ndisc_router_handler(link
, rt
);
1036 link_enter_failed(link
);
1041 case SD_NDISC_EVENT_TIMEOUT
:
1042 log_link_debug(link
, "NDisc handler get timeout event");
1043 if (link
->ndisc_messages
== 0) {
1044 link
->ndisc_configured
= true;
1045 link_check_ready(link
);
1049 assert_not_reached();
1053 int ndisc_configure(Link
*link
) {
1058 if (!link_ipv6_accept_ra_enabled(link
))
1062 return -EBUSY
; /* Already configured. */
1064 r
= sd_ndisc_new(&link
->ndisc
);
1068 r
= sd_ndisc_attach_event(link
->ndisc
, link
->manager
->event
, 0);
1072 r
= sd_ndisc_set_mac(link
->ndisc
, &link
->hw_addr
.ether
);
1076 r
= sd_ndisc_set_ifindex(link
->ndisc
, link
->ifindex
);
1080 r
= sd_ndisc_set_callback(link
->ndisc
, ndisc_handler
, link
);
1087 int ndisc_start(Link
*link
) {
1090 if (!link
->ndisc
|| !link
->dhcp6_client
)
1093 if (!link_has_carrier(link
))
1096 if (in6_addr_is_null(&link
->ipv6ll_address
))
1099 log_link_debug(link
, "Discovering IPv6 routers");
1101 return sd_ndisc_start(link
->ndisc
);
1104 void ndisc_vacuum(Link
*link
) {
1111 /* Removes all RDNSS and DNSSL entries whose validity time has passed */
1113 time_now
= now(clock_boottime_or_monotonic());
1115 SET_FOREACH(r
, link
->ndisc_rdnss
)
1116 if (r
->lifetime_usec
< time_now
)
1117 free(set_remove(link
->ndisc_rdnss
, r
));
1119 SET_FOREACH(d
, link
->ndisc_dnssl
)
1120 if (d
->lifetime_usec
< time_now
)
1121 free(set_remove(link
->ndisc_dnssl
, d
));
1124 void ndisc_flush(Link
*link
) {
1127 /* Removes all RDNSS and DNSSL entries, without exception */
1129 link
->ndisc_rdnss
= set_free(link
->ndisc_rdnss
);
1130 link
->ndisc_dnssl
= set_free(link
->ndisc_dnssl
);
1133 static const char* const ipv6_accept_ra_start_dhcp6_client_table
[_IPV6_ACCEPT_RA_START_DHCP6_CLIENT_MAX
] = {
1134 [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_NO
] = "no",
1135 [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_ALWAYS
] = "always",
1136 [IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
] = "yes",
1139 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING_WITH_BOOLEAN(ipv6_accept_ra_start_dhcp6_client
, IPv6AcceptRAStartDHCP6Client
, IPV6_ACCEPT_RA_START_DHCP6_CLIENT_YES
);
1141 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_accept_ra_use_domains
, dhcp_use_domains
, DHCPUseDomains
,
1142 "Failed to parse UseDomains= setting");
1143 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_accept_ra_start_dhcp6_client
, ipv6_accept_ra_start_dhcp6_client
, IPv6AcceptRAStartDHCP6Client
,
1144 "Failed to parse DHCPv6Client= setting");