1 /* SPDX-License-Identifier: LGPL-2.1+ */
7 #include "sd-network.h"
9 #include "alloc-util.h"
14 #include "parse-util.h"
15 #include "resolved-link.h"
16 #include "resolved-llmnr.h"
17 #include "resolved-mdns.h"
18 #include "string-util.h"
20 #include "tmpfile-util.h"
22 int link_new(Manager
*m
, Link
**ret
, int ifindex
) {
23 _cleanup_(link_freep
) Link
*l
= NULL
;
29 r
= hashmap_ensure_allocated(&m
->links
, NULL
);
40 .llmnr_support
= RESOLVE_SUPPORT_YES
,
41 .mdns_support
= RESOLVE_SUPPORT_NO
,
42 .dnssec_mode
= _DNSSEC_MODE_INVALID
,
43 .dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
,
44 .operstate
= IF_OPER_UNKNOWN
,
47 if (asprintf(&l
->state_file
, "/run/systemd/resolve/netif/%i", ifindex
) < 0)
50 r
= hashmap_put(m
->links
, INT_TO_PTR(ifindex
), l
);
63 void link_flush_settings(Link
*l
) {
66 l
->default_route
= -1;
67 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
68 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
69 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
70 l
->dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
;
72 dns_server_unlink_all(l
->dns_servers
);
73 dns_search_domain_unlink_all(l
->search_domains
);
75 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
78 Link
*link_free(Link
*l
) {
82 /* Send goodbye messages. */
83 dns_scope_announce(l
->mdns_ipv4_scope
, true);
84 dns_scope_announce(l
->mdns_ipv6_scope
, true);
86 link_flush_settings(l
);
89 (void) link_address_free(l
->addresses
);
92 hashmap_remove(l
->manager
->links
, INT_TO_PTR(l
->ifindex
));
94 dns_scope_free(l
->unicast_scope
);
95 dns_scope_free(l
->llmnr_ipv4_scope
);
96 dns_scope_free(l
->llmnr_ipv6_scope
);
97 dns_scope_free(l
->mdns_ipv4_scope
);
98 dns_scope_free(l
->mdns_ipv6_scope
);
105 void link_allocate_scopes(Link
*l
) {
106 bool unicast_relevant
;
111 /* If a link that used to be relevant is no longer, or a link that did not use to be relevant now becomes
112 * relevant, let's reinit the learnt global DNS server information, since we might talk to different servers
113 * now, even if they have the same addresses as before. */
115 unicast_relevant
= link_relevant(l
, AF_UNSPEC
, false);
116 if (unicast_relevant
!= l
->unicast_relevant
) {
117 l
->unicast_relevant
= unicast_relevant
;
119 dns_server_reset_features_all(l
->manager
->fallback_dns_servers
);
120 dns_server_reset_features_all(l
->manager
->dns_servers
);
122 /* Also, flush the global unicast scope, to deal with split horizon setups, where talking through one
123 * interface reveals different DNS zones than through others. */
124 if (l
->manager
->unicast_scope
)
125 dns_cache_flush(&l
->manager
->unicast_scope
->cache
);
128 /* And now, allocate all scopes that makes sense now if we didn't have them yet, and drop those which we don't
131 if (unicast_relevant
&& l
->dns_servers
) {
132 if (!l
->unicast_scope
) {
133 dns_server_reset_features_all(l
->dns_servers
);
135 r
= dns_scope_new(l
->manager
, &l
->unicast_scope
, l
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
137 log_warning_errno(r
, "Failed to allocate DNS scope: %m");
140 l
->unicast_scope
= dns_scope_free(l
->unicast_scope
);
142 if (link_relevant(l
, AF_INET
, true) &&
143 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
144 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
145 if (!l
->llmnr_ipv4_scope
) {
146 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv4_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET
);
148 log_warning_errno(r
, "Failed to allocate LLMNR IPv4 scope: %m");
151 l
->llmnr_ipv4_scope
= dns_scope_free(l
->llmnr_ipv4_scope
);
153 if (link_relevant(l
, AF_INET6
, true) &&
154 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
155 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
156 socket_ipv6_is_supported()) {
157 if (!l
->llmnr_ipv6_scope
) {
158 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv6_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET6
);
160 log_warning_errno(r
, "Failed to allocate LLMNR IPv6 scope: %m");
163 l
->llmnr_ipv6_scope
= dns_scope_free(l
->llmnr_ipv6_scope
);
165 if (link_relevant(l
, AF_INET
, true) &&
166 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
167 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
168 if (!l
->mdns_ipv4_scope
) {
169 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv4_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET
);
171 log_warning_errno(r
, "Failed to allocate mDNS IPv4 scope: %m");
174 l
->mdns_ipv4_scope
= dns_scope_free(l
->mdns_ipv4_scope
);
176 if (link_relevant(l
, AF_INET6
, true) &&
177 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
178 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
179 if (!l
->mdns_ipv6_scope
) {
180 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv6_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET6
);
182 log_warning_errno(r
, "Failed to allocate mDNS IPv6 scope: %m");
185 l
->mdns_ipv6_scope
= dns_scope_free(l
->mdns_ipv6_scope
);
188 void link_add_rrs(Link
*l
, bool force_remove
) {
192 LIST_FOREACH(addresses
, a
, l
->addresses
)
193 link_address_add_rrs(a
, force_remove
);
196 l
->mdns_support
== RESOLVE_SUPPORT_YES
&&
197 l
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
199 if (l
->mdns_ipv4_scope
) {
200 r
= dns_scope_add_dnssd_services(l
->mdns_ipv4_scope
);
202 log_warning_errno(r
, "Failed to add IPv4 DNS-SD services: %m");
205 if (l
->mdns_ipv6_scope
) {
206 r
= dns_scope_add_dnssd_services(l
->mdns_ipv6_scope
);
208 log_warning_errno(r
, "Failed to add IPv6 DNS-SD services: %m");
213 if (l
->mdns_ipv4_scope
) {
214 r
= dns_scope_remove_dnssd_services(l
->mdns_ipv4_scope
);
216 log_warning_errno(r
, "Failed to remove IPv4 DNS-SD services: %m");
219 if (l
->mdns_ipv6_scope
) {
220 r
= dns_scope_remove_dnssd_services(l
->mdns_ipv6_scope
);
222 log_warning_errno(r
, "Failed to remove IPv6 DNS-SD services: %m");
227 int link_process_rtnl(Link
*l
, sd_netlink_message
*m
) {
228 const char *n
= NULL
;
234 r
= sd_rtnl_message_link_get_flags(m
, &l
->flags
);
238 (void) sd_netlink_message_read_u32(m
, IFLA_MTU
, &l
->mtu
);
239 (void) sd_netlink_message_read_u8(m
, IFLA_OPERSTATE
, &l
->operstate
);
241 if (sd_netlink_message_read_string(m
, IFLA_IFNAME
, &n
) >= 0) {
242 strncpy(l
->name
, n
, sizeof(l
->name
)-1);
243 char_array_0(l
->name
);
246 link_allocate_scopes(l
);
247 link_add_rrs(l
, false);
252 static int link_update_dns_server_one(Link
*l
, const char *name
) {
253 union in_addr_union a
;
260 r
= in_addr_from_string_auto(name
, &family
, &a
);
264 s
= dns_server_find(l
->dns_servers
, family
, &a
, 0);
266 dns_server_move_back_and_unmark(s
);
270 return dns_server_new(l
->manager
, NULL
, DNS_SERVER_LINK
, l
, family
, &a
, 0);
273 static int link_update_dns_servers(Link
*l
) {
274 _cleanup_strv_free_
char **nameservers
= NULL
;
280 r
= sd_network_link_get_dns(l
->ifindex
, &nameservers
);
288 dns_server_mark_all(l
->dns_servers
);
290 STRV_FOREACH(nameserver
, nameservers
) {
291 r
= link_update_dns_server_one(l
, *nameserver
);
296 dns_server_unlink_marked(l
->dns_servers
);
300 dns_server_unlink_all(l
->dns_servers
);
304 static int link_update_default_route(Link
*l
) {
309 r
= sd_network_link_get_dns_default_route(l
->ifindex
);
317 l
->default_route
= r
> 0;
321 l
->default_route
= -1;
325 static int link_update_llmnr_support(Link
*l
) {
326 _cleanup_free_
char *b
= NULL
;
331 r
= sd_network_link_get_llmnr(l
->ifindex
, &b
);
339 l
->llmnr_support
= resolve_support_from_string(b
);
340 if (l
->llmnr_support
< 0) {
348 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
352 static int link_update_mdns_support(Link
*l
) {
353 _cleanup_free_
char *b
= NULL
;
358 r
= sd_network_link_get_mdns(l
->ifindex
, &b
);
366 l
->mdns_support
= resolve_support_from_string(b
);
367 if (l
->mdns_support
< 0) {
375 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
379 void link_set_dns_over_tls_mode(Link
*l
, DnsOverTlsMode mode
) {
383 #if ! ENABLE_DNS_OVER_TLS
384 if (mode
!= DNS_OVER_TLS_NO
)
385 log_warning("DNS-over-TLS option for the link cannot be set to opportunistic when systemd-resolved is built without DNS-over-TLS support. Turning off DNS-over-TLS support.");
389 l
->dns_over_tls_mode
= mode
;
392 static int link_update_dns_over_tls_mode(Link
*l
) {
393 _cleanup_free_
char *b
= NULL
;
398 r
= sd_network_link_get_dns_over_tls(l
->ifindex
, &b
);
406 l
->dns_over_tls_mode
= dns_over_tls_mode_from_string(b
);
407 if (l
->dns_over_tls_mode
< 0) {
415 l
->dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
;
419 void link_set_dnssec_mode(Link
*l
, DnssecMode mode
) {
424 if (IN_SET(mode
, DNSSEC_YES
, DNSSEC_ALLOW_DOWNGRADE
))
425 log_warning("DNSSEC option for the link cannot be enabled or set to allow-downgrade when systemd-resolved is built without gcrypt support. Turning off DNSSEC support.");
429 if (l
->dnssec_mode
== mode
)
432 if ((l
->dnssec_mode
== _DNSSEC_MODE_INVALID
) ||
433 (l
->dnssec_mode
== DNSSEC_NO
&& mode
!= DNSSEC_NO
) ||
434 (l
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
&& mode
== DNSSEC_YES
)) {
436 /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
437 * allow-downgrade mode to full DNSSEC mode, flush it too. */
438 if (l
->unicast_scope
)
439 dns_cache_flush(&l
->unicast_scope
->cache
);
442 l
->dnssec_mode
= mode
;
445 static int link_update_dnssec_mode(Link
*l
) {
446 _cleanup_free_
char *m
= NULL
;
452 r
= sd_network_link_get_dnssec(l
->ifindex
, &m
);
460 mode
= dnssec_mode_from_string(m
);
466 link_set_dnssec_mode(l
, mode
);
471 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
475 static int link_update_dnssec_negative_trust_anchors(Link
*l
) {
476 _cleanup_strv_free_
char **ntas
= NULL
;
477 _cleanup_set_free_free_ Set
*ns
= NULL
;
482 r
= sd_network_link_get_dnssec_negative_trust_anchors(l
->ifindex
, &ntas
);
490 ns
= set_new(&dns_name_hash_ops
);
494 r
= set_put_strdupv(ns
, ntas
);
498 set_free_free(l
->dnssec_negative_trust_anchors
);
499 l
->dnssec_negative_trust_anchors
= TAKE_PTR(ns
);
504 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
508 static int link_update_search_domain_one(Link
*l
, const char *name
, bool route_only
) {
515 r
= dns_search_domain_find(l
->search_domains
, name
, &d
);
519 dns_search_domain_move_back_and_unmark(d
);
521 r
= dns_search_domain_new(l
->manager
, &d
, DNS_SEARCH_DOMAIN_LINK
, l
, name
);
526 d
->route_only
= route_only
;
530 static int link_update_search_domains(Link
*l
) {
531 _cleanup_strv_free_
char **sdomains
= NULL
, **rdomains
= NULL
;
537 r
= sd_network_link_get_search_domains(l
->ifindex
, &sdomains
);
538 if (r
< 0 && r
!= -ENODATA
)
541 q
= sd_network_link_get_route_domains(l
->ifindex
, &rdomains
);
542 if (q
< 0 && q
!= -ENODATA
) {
547 if (r
== -ENODATA
&& q
== -ENODATA
) {
548 /* networkd knows nothing about this interface, and that's fine. */
553 dns_search_domain_mark_all(l
->search_domains
);
555 STRV_FOREACH(i
, sdomains
) {
556 r
= link_update_search_domain_one(l
, *i
, false);
561 STRV_FOREACH(i
, rdomains
) {
562 r
= link_update_search_domain_one(l
, *i
, true);
567 dns_search_domain_unlink_marked(l
->search_domains
);
571 dns_search_domain_unlink_all(l
->search_domains
);
575 static int link_is_managed(Link
*l
) {
576 _cleanup_free_
char *state
= NULL
;
581 r
= sd_network_link_get_setup_state(l
->ifindex
, &state
);
587 return !STR_IN_SET(state
, "pending", "unmanaged");
590 static void link_read_settings(Link
*l
) {
595 /* Read settings from networkd, except when networkd is not managing this interface. */
597 r
= link_is_managed(l
);
599 log_warning_errno(r
, "Failed to determine whether interface %s is managed: %m", l
->name
);
604 /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
606 link_flush_settings(l
);
608 l
->is_managed
= false;
612 l
->is_managed
= true;
614 r
= link_update_dns_servers(l
);
616 log_warning_errno(r
, "Failed to read DNS servers for interface %s, ignoring: %m", l
->name
);
618 r
= link_update_llmnr_support(l
);
620 log_warning_errno(r
, "Failed to read LLMNR support for interface %s, ignoring: %m", l
->name
);
622 r
= link_update_mdns_support(l
);
624 log_warning_errno(r
, "Failed to read mDNS support for interface %s, ignoring: %m", l
->name
);
626 r
= link_update_dns_over_tls_mode(l
);
628 log_warning_errno(r
, "Failed to read DNS-over-TLS mode for interface %s, ignoring: %m", l
->name
);
630 r
= link_update_dnssec_mode(l
);
632 log_warning_errno(r
, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l
->name
);
634 r
= link_update_dnssec_negative_trust_anchors(l
);
636 log_warning_errno(r
, "Failed to read DNSSEC negative trust anchors for interface %s, ignoring: %m", l
->name
);
638 r
= link_update_search_domains(l
);
640 log_warning_errno(r
, "Failed to read search domains for interface %s, ignoring: %m", l
->name
);
642 r
= link_update_default_route(l
);
644 log_warning_errno(r
, "Failed to read default route setting for interface %s, proceeding anyway: %m", l
->name
);
647 int link_update(Link
*l
) {
652 link_read_settings(l
);
655 if (l
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
656 r
= manager_llmnr_start(l
->manager
);
661 if (l
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
662 r
= manager_mdns_start(l
->manager
);
667 link_allocate_scopes(l
);
668 link_add_rrs(l
, false);
673 bool link_relevant(Link
*l
, int family
, bool local_multicast
) {
674 _cleanup_free_
char *state
= NULL
;
679 /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
680 * beat, can do multicast and has at least one link-local (or better) IP address.
682 * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
683 * least one routable address. */
685 if (l
->flags
& (IFF_LOOPBACK
|IFF_DORMANT
))
688 if ((l
->flags
& (IFF_UP
|IFF_LOWER_UP
)) != (IFF_UP
|IFF_LOWER_UP
))
691 if (local_multicast
) {
692 if ((l
->flags
& IFF_MULTICAST
) != IFF_MULTICAST
)
696 /* Check kernel operstate
697 * https://www.kernel.org/doc/Documentation/networking/operstates.txt */
698 if (!IN_SET(l
->operstate
, IF_OPER_UNKNOWN
, IF_OPER_UP
))
701 (void) sd_network_link_get_operational_state(l
->ifindex
, &state
);
702 if (state
&& !STR_IN_SET(state
, "unknown", "degraded", "routable"))
705 LIST_FOREACH(addresses
, a
, l
->addresses
)
706 if ((family
== AF_UNSPEC
|| a
->family
== family
) && link_address_relevant(a
, local_multicast
))
712 LinkAddress
*link_find_address(Link
*l
, int family
, const union in_addr_union
*in_addr
) {
717 LIST_FOREACH(addresses
, a
, l
->addresses
)
718 if (a
->family
== family
&& in_addr_equal(family
, &a
->in_addr
, in_addr
))
724 DnsServer
* link_set_dns_server(Link
*l
, DnsServer
*s
) {
727 if (l
->current_dns_server
== s
)
731 log_debug("Switching to DNS server %s for interface %s.", dns_server_string(s
), l
->name
);
733 dns_server_unref(l
->current_dns_server
);
734 l
->current_dns_server
= dns_server_ref(s
);
736 if (l
->unicast_scope
)
737 dns_cache_flush(&l
->unicast_scope
->cache
);
742 DnsServer
*link_get_dns_server(Link
*l
) {
745 if (!l
->current_dns_server
)
746 link_set_dns_server(l
, l
->dns_servers
);
748 return l
->current_dns_server
;
751 void link_next_dns_server(Link
*l
) {
754 if (!l
->current_dns_server
)
757 /* Change to the next one, but make sure to follow the linked
758 * list only if this server is actually still linked. */
759 if (l
->current_dns_server
->linked
&& l
->current_dns_server
->servers_next
) {
760 link_set_dns_server(l
, l
->current_dns_server
->servers_next
);
764 link_set_dns_server(l
, l
->dns_servers
);
767 DnsOverTlsMode
link_get_dns_over_tls_mode(Link
*l
) {
770 if (l
->dns_over_tls_mode
!= _DNS_OVER_TLS_MODE_INVALID
)
771 return l
->dns_over_tls_mode
;
773 return manager_get_dns_over_tls_mode(l
->manager
);
776 DnssecMode
link_get_dnssec_mode(Link
*l
) {
779 if (l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
780 return l
->dnssec_mode
;
782 return manager_get_dnssec_mode(l
->manager
);
785 bool link_dnssec_supported(Link
*l
) {
790 if (link_get_dnssec_mode(l
) == DNSSEC_NO
)
793 server
= link_get_dns_server(l
);
795 return dns_server_dnssec_supported(server
);
800 int link_address_new(Link
*l
, LinkAddress
**ret
, int family
, const union in_addr_union
*in_addr
) {
806 a
= new0(LinkAddress
, 1);
811 a
->in_addr
= *in_addr
;
814 LIST_PREPEND(addresses
, l
->addresses
, a
);
823 LinkAddress
*link_address_free(LinkAddress
*a
) {
828 LIST_REMOVE(addresses
, a
->link
->addresses
, a
);
830 assert(a
->link
->n_addresses
> 0);
831 a
->link
->n_addresses
--;
833 if (a
->llmnr_address_rr
) {
834 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
835 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
836 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
837 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
840 if (a
->llmnr_ptr_rr
) {
841 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
842 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
843 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
844 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
847 if (a
->mdns_address_rr
) {
848 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
849 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
850 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
851 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
854 if (a
->mdns_ptr_rr
) {
855 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
856 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
857 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
858 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
862 dns_resource_record_unref(a
->llmnr_address_rr
);
863 dns_resource_record_unref(a
->llmnr_ptr_rr
);
864 dns_resource_record_unref(a
->mdns_address_rr
);
865 dns_resource_record_unref(a
->mdns_ptr_rr
);
870 void link_address_add_rrs(LinkAddress
*a
, bool force_remove
) {
875 if (a
->family
== AF_INET
) {
878 link_address_relevant(a
, true) &&
879 a
->link
->llmnr_ipv4_scope
&&
880 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
881 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
883 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
884 a
->link
->manager
->llmnr_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->llmnr_hostname
);
885 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
891 if (!a
->llmnr_address_rr
) {
892 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv4_key
);
893 if (!a
->llmnr_address_rr
) {
898 a
->llmnr_address_rr
->a
.in_addr
= a
->in_addr
.in
;
899 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
902 if (!a
->llmnr_ptr_rr
) {
903 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
907 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
910 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_address_rr
, true);
912 log_warning_errno(r
, "Failed to add A record to LLMNR zone: %m");
914 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_ptr_rr
, false);
916 log_warning_errno(r
, "Failed to add IPv4 PTR record to LLMNR zone: %m");
918 if (a
->llmnr_address_rr
) {
919 if (a
->link
->llmnr_ipv4_scope
)
920 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
921 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
924 if (a
->llmnr_ptr_rr
) {
925 if (a
->link
->llmnr_ipv4_scope
)
926 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
927 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
932 link_address_relevant(a
, true) &&
933 a
->link
->mdns_ipv4_scope
&&
934 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
935 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
936 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
937 a
->link
->manager
->mdns_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->mdns_hostname
);
938 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
944 if (!a
->mdns_address_rr
) {
945 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv4_key
);
946 if (!a
->mdns_address_rr
) {
951 a
->mdns_address_rr
->a
.in_addr
= a
->in_addr
.in
;
952 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
955 if (!a
->mdns_ptr_rr
) {
956 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
960 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
963 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_address_rr
, true);
965 log_warning_errno(r
, "Failed to add A record to MDNS zone: %m");
967 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_ptr_rr
, false);
969 log_warning_errno(r
, "Failed to add IPv4 PTR record to MDNS zone: %m");
971 if (a
->mdns_address_rr
) {
972 if (a
->link
->mdns_ipv4_scope
)
973 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
974 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
977 if (a
->mdns_ptr_rr
) {
978 if (a
->link
->mdns_ipv4_scope
)
979 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
980 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
985 if (a
->family
== AF_INET6
) {
988 link_address_relevant(a
, true) &&
989 a
->link
->llmnr_ipv6_scope
&&
990 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
991 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
993 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
994 a
->link
->manager
->llmnr_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->llmnr_hostname
);
995 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
1001 if (!a
->llmnr_address_rr
) {
1002 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv6_key
);
1003 if (!a
->llmnr_address_rr
) {
1008 a
->llmnr_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
1009 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
1012 if (!a
->llmnr_ptr_rr
) {
1013 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
1017 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
1020 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_address_rr
, true);
1022 log_warning_errno(r
, "Failed to add AAAA record to LLMNR zone: %m");
1024 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_ptr_rr
, false);
1026 log_warning_errno(r
, "Failed to add IPv6 PTR record to LLMNR zone: %m");
1028 if (a
->llmnr_address_rr
) {
1029 if (a
->link
->llmnr_ipv6_scope
)
1030 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
1031 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
1034 if (a
->llmnr_ptr_rr
) {
1035 if (a
->link
->llmnr_ipv6_scope
)
1036 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
1037 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
1041 if (!force_remove
&&
1042 link_address_relevant(a
, true) &&
1043 a
->link
->mdns_ipv6_scope
&&
1044 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
1045 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
1047 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
1048 a
->link
->manager
->mdns_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->mdns_hostname
);
1049 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
1055 if (!a
->mdns_address_rr
) {
1056 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv6_key
);
1057 if (!a
->mdns_address_rr
) {
1062 a
->mdns_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
1063 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
1066 if (!a
->mdns_ptr_rr
) {
1067 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
1071 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
1074 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_address_rr
, true);
1076 log_warning_errno(r
, "Failed to add AAAA record to MDNS zone: %m");
1078 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_ptr_rr
, false);
1080 log_warning_errno(r
, "Failed to add IPv6 PTR record to MDNS zone: %m");
1082 if (a
->mdns_address_rr
) {
1083 if (a
->link
->mdns_ipv6_scope
)
1084 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
1085 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
1088 if (a
->mdns_ptr_rr
) {
1089 if (a
->link
->mdns_ipv6_scope
)
1090 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
1091 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
1099 log_debug_errno(r
, "Failed to update address RRs: %m");
1102 int link_address_update_rtnl(LinkAddress
*a
, sd_netlink_message
*m
) {
1107 r
= sd_rtnl_message_addr_get_flags(m
, &a
->flags
);
1111 sd_rtnl_message_addr_get_scope(m
, &a
->scope
);
1113 link_allocate_scopes(a
->link
);
1114 link_add_rrs(a
->link
, false);
1119 bool link_address_relevant(LinkAddress
*a
, bool local_multicast
) {
1122 if (a
->flags
& (IFA_F_DEPRECATED
|IFA_F_TENTATIVE
))
1125 if (a
->scope
>= (local_multicast
? RT_SCOPE_HOST
: RT_SCOPE_LINK
))
1131 static bool link_needs_save(Link
*l
) {
1134 /* Returns true if any of the settings where set different from the default */
1139 if (l
->llmnr_support
!= RESOLVE_SUPPORT_YES
||
1140 l
->mdns_support
!= RESOLVE_SUPPORT_NO
||
1141 l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
||
1142 l
->dns_over_tls_mode
!= _DNS_OVER_TLS_MODE_INVALID
)
1145 if (l
->dns_servers
||
1149 if (!set_isempty(l
->dnssec_negative_trust_anchors
))
1152 if (l
->default_route
>= 0)
1158 int link_save_user(Link
*l
) {
1159 _cleanup_free_
char *temp_path
= NULL
;
1160 _cleanup_fclose_
FILE *f
= NULL
;
1165 assert(l
->state_file
);
1167 if (!link_needs_save(l
)) {
1168 (void) unlink(l
->state_file
);
1172 r
= mkdir_parents(l
->state_file
, 0700);
1176 r
= fopen_temporary(l
->state_file
, &f
, &temp_path
);
1180 (void) fchmod(fileno(f
), 0644);
1182 fputs("# This is private data. Do not parse.\n", f
);
1184 v
= resolve_support_to_string(l
->llmnr_support
);
1186 fprintf(f
, "LLMNR=%s\n", v
);
1188 v
= resolve_support_to_string(l
->mdns_support
);
1190 fprintf(f
, "MDNS=%s\n", v
);
1192 v
= dnssec_mode_to_string(l
->dnssec_mode
);
1194 fprintf(f
, "DNSSEC=%s\n", v
);
1196 if (l
->default_route
>= 0)
1197 fprintf(f
, "DEFAULT_ROUTE=%s\n", yes_no(l
->default_route
));
1199 if (l
->dns_servers
) {
1202 fputs("SERVERS=", f
);
1203 LIST_FOREACH(servers
, server
, l
->dns_servers
) {
1205 if (server
!= l
->dns_servers
)
1208 v
= dns_server_string(server
);
1219 if (l
->search_domains
) {
1220 DnsSearchDomain
*domain
;
1222 fputs("DOMAINS=", f
);
1223 LIST_FOREACH(domains
, domain
, l
->search_domains
) {
1225 if (domain
!= l
->search_domains
)
1228 if (domain
->route_only
)
1231 fputs(DNS_SEARCH_DOMAIN_NAME(domain
), f
);
1236 if (!set_isempty(l
->dnssec_negative_trust_anchors
)) {
1242 SET_FOREACH(nta
, l
->dnssec_negative_trust_anchors
, i
) {
1253 r
= fflush_and_check(f
);
1257 if (rename(temp_path
, l
->state_file
) < 0) {
1265 (void) unlink(l
->state_file
);
1268 (void) unlink(temp_path
);
1270 return log_error_errno(r
, "Failed to save link data %s: %m", l
->state_file
);
1273 int link_load_user(Link
*l
) {
1281 *default_route
= NULL
;
1288 assert(l
->state_file
);
1290 /* Try to load only a single time */
1296 return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */
1298 r
= parse_env_file(NULL
, l
->state_file
,
1302 "SERVERS", &servers
,
1303 "DOMAINS", &domains
,
1305 "DEFAULT_ROUTE", &default_route
);
1311 link_flush_settings(l
);
1313 /* If we can't recognize the LLMNR or MDNS setting we don't override the default */
1314 s
= resolve_support_from_string(llmnr
);
1316 l
->llmnr_support
= s
;
1318 s
= resolve_support_from_string(mdns
);
1320 l
->mdns_support
= s
;
1322 r
= parse_boolean(default_route
);
1324 l
->default_route
= r
;
1326 /* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
1327 l
->dnssec_mode
= dnssec_mode_from_string(dnssec
);
1329 for (p
= servers
;;) {
1330 _cleanup_free_
char *word
= NULL
;
1332 r
= extract_first_word(&p
, &word
, NULL
, 0);
1338 r
= link_update_dns_server_one(l
, word
);
1340 log_debug_errno(r
, "Failed to load DNS server '%s', ignoring: %m", word
);
1345 for (p
= domains
;;) {
1346 _cleanup_free_
char *word
= NULL
;
1350 r
= extract_first_word(&p
, &word
, NULL
, 0);
1356 is_route
= word
[0] == '~';
1357 n
= is_route
? word
+ 1 : word
;
1359 r
= link_update_search_domain_one(l
, n
, is_route
);
1361 log_debug_errno(r
, "Failed to load search domain '%s', ignoring: %m", word
);
1367 _cleanup_set_free_free_ Set
*ns
= NULL
;
1369 ns
= set_new(&dns_name_hash_ops
);
1375 r
= set_put_strsplit(ns
, ntas
, NULL
, 0);
1379 l
->dnssec_negative_trust_anchors
= TAKE_PTR(ns
);
1385 return log_error_errno(r
, "Failed to load link data %s: %m", l
->state_file
);
1388 void link_remove_user(Link
*l
) {
1390 assert(l
->state_file
);
1392 (void) unlink(l
->state_file
);