1 /* SPDX-License-Identifier: LGPL-2.1+ */
6 #include "sd-network.h"
8 #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
);
106 void link_allocate_scopes(Link
*l
) {
107 bool unicast_relevant
;
112 /* If a link that used to be relevant is no longer, or a link that did not use to be relevant now becomes
113 * relevant, let's reinit the learnt global DNS server information, since we might talk to different servers
114 * now, even if they have the same addresses as before. */
116 unicast_relevant
= link_relevant(l
, AF_UNSPEC
, false);
117 if (unicast_relevant
!= l
->unicast_relevant
) {
118 l
->unicast_relevant
= unicast_relevant
;
120 dns_server_reset_features_all(l
->manager
->fallback_dns_servers
);
121 dns_server_reset_features_all(l
->manager
->dns_servers
);
123 /* Also, flush the global unicast scope, to deal with split horizon setups, where talking through one
124 * interface reveals different DNS zones than through others. */
125 if (l
->manager
->unicast_scope
)
126 dns_cache_flush(&l
->manager
->unicast_scope
->cache
);
129 /* And now, allocate all scopes that makes sense now if we didn't have them yet, and drop those which we don't
132 if (unicast_relevant
&& l
->dns_servers
) {
133 if (!l
->unicast_scope
) {
134 dns_server_reset_features_all(l
->dns_servers
);
136 r
= dns_scope_new(l
->manager
, &l
->unicast_scope
, l
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
138 log_warning_errno(r
, "Failed to allocate DNS scope: %m");
141 l
->unicast_scope
= dns_scope_free(l
->unicast_scope
);
143 if (link_relevant(l
, AF_INET
, true) &&
144 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
145 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
146 if (!l
->llmnr_ipv4_scope
) {
147 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv4_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET
);
149 log_warning_errno(r
, "Failed to allocate LLMNR IPv4 scope: %m");
152 l
->llmnr_ipv4_scope
= dns_scope_free(l
->llmnr_ipv4_scope
);
154 if (link_relevant(l
, AF_INET6
, true) &&
155 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
156 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
157 socket_ipv6_is_supported()) {
158 if (!l
->llmnr_ipv6_scope
) {
159 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv6_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET6
);
161 log_warning_errno(r
, "Failed to allocate LLMNR IPv6 scope: %m");
164 l
->llmnr_ipv6_scope
= dns_scope_free(l
->llmnr_ipv6_scope
);
166 if (link_relevant(l
, AF_INET
, true) &&
167 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
168 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
169 if (!l
->mdns_ipv4_scope
) {
170 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv4_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET
);
172 log_warning_errno(r
, "Failed to allocate mDNS IPv4 scope: %m");
175 l
->mdns_ipv4_scope
= dns_scope_free(l
->mdns_ipv4_scope
);
177 if (link_relevant(l
, AF_INET6
, true) &&
178 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
179 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
180 if (!l
->mdns_ipv6_scope
) {
181 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv6_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET6
);
183 log_warning_errno(r
, "Failed to allocate mDNS IPv6 scope: %m");
186 l
->mdns_ipv6_scope
= dns_scope_free(l
->mdns_ipv6_scope
);
189 void link_add_rrs(Link
*l
, bool force_remove
) {
193 LIST_FOREACH(addresses
, a
, l
->addresses
)
194 link_address_add_rrs(a
, force_remove
);
197 l
->mdns_support
== RESOLVE_SUPPORT_YES
&&
198 l
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
200 if (l
->mdns_ipv4_scope
) {
201 r
= dns_scope_add_dnssd_services(l
->mdns_ipv4_scope
);
203 log_warning_errno(r
, "Failed to add IPv4 DNS-SD services: %m");
206 if (l
->mdns_ipv6_scope
) {
207 r
= dns_scope_add_dnssd_services(l
->mdns_ipv6_scope
);
209 log_warning_errno(r
, "Failed to add IPv6 DNS-SD services: %m");
214 if (l
->mdns_ipv4_scope
) {
215 r
= dns_scope_remove_dnssd_services(l
->mdns_ipv4_scope
);
217 log_warning_errno(r
, "Failed to remove IPv4 DNS-SD services: %m");
220 if (l
->mdns_ipv6_scope
) {
221 r
= dns_scope_remove_dnssd_services(l
->mdns_ipv6_scope
);
223 log_warning_errno(r
, "Failed to remove IPv6 DNS-SD services: %m");
228 int link_process_rtnl(Link
*l
, sd_netlink_message
*m
) {
229 const char *n
= NULL
;
235 r
= sd_rtnl_message_link_get_flags(m
, &l
->flags
);
239 (void) sd_netlink_message_read_u32(m
, IFLA_MTU
, &l
->mtu
);
240 (void) sd_netlink_message_read_u8(m
, IFLA_OPERSTATE
, &l
->operstate
);
242 if (sd_netlink_message_read_string(m
, IFLA_IFNAME
, &n
) >= 0) {
243 r
= free_and_strdup(&l
->ifname
, n
);
248 link_allocate_scopes(l
);
249 link_add_rrs(l
, false);
254 static int link_update_dns_server_one(Link
*l
, const char *name
) {
255 union in_addr_union a
;
262 r
= in_addr_from_string_auto(name
, &family
, &a
);
266 s
= dns_server_find(l
->dns_servers
, family
, &a
, 0);
268 dns_server_move_back_and_unmark(s
);
272 return dns_server_new(l
->manager
, NULL
, DNS_SERVER_LINK
, l
, family
, &a
, 0);
275 static int link_update_dns_servers(Link
*l
) {
276 _cleanup_strv_free_
char **nameservers
= NULL
;
282 r
= sd_network_link_get_dns(l
->ifindex
, &nameservers
);
290 dns_server_mark_all(l
->dns_servers
);
292 STRV_FOREACH(nameserver
, nameservers
) {
293 r
= link_update_dns_server_one(l
, *nameserver
);
298 dns_server_unlink_marked(l
->dns_servers
);
302 dns_server_unlink_all(l
->dns_servers
);
306 static int link_update_default_route(Link
*l
) {
311 r
= sd_network_link_get_dns_default_route(l
->ifindex
);
319 l
->default_route
= r
> 0;
323 l
->default_route
= -1;
327 static int link_update_llmnr_support(Link
*l
) {
328 _cleanup_free_
char *b
= NULL
;
333 r
= sd_network_link_get_llmnr(l
->ifindex
, &b
);
341 l
->llmnr_support
= resolve_support_from_string(b
);
342 if (l
->llmnr_support
< 0) {
350 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
354 static int link_update_mdns_support(Link
*l
) {
355 _cleanup_free_
char *b
= NULL
;
360 r
= sd_network_link_get_mdns(l
->ifindex
, &b
);
368 l
->mdns_support
= resolve_support_from_string(b
);
369 if (l
->mdns_support
< 0) {
377 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
381 void link_set_dns_over_tls_mode(Link
*l
, DnsOverTlsMode mode
) {
385 #if ! ENABLE_DNS_OVER_TLS
386 if (mode
!= DNS_OVER_TLS_NO
)
387 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.");
391 l
->dns_over_tls_mode
= mode
;
394 static int link_update_dns_over_tls_mode(Link
*l
) {
395 _cleanup_free_
char *b
= NULL
;
400 r
= sd_network_link_get_dns_over_tls(l
->ifindex
, &b
);
408 l
->dns_over_tls_mode
= dns_over_tls_mode_from_string(b
);
409 if (l
->dns_over_tls_mode
< 0) {
417 l
->dns_over_tls_mode
= _DNS_OVER_TLS_MODE_INVALID
;
421 void link_set_dnssec_mode(Link
*l
, DnssecMode mode
) {
426 if (IN_SET(mode
, DNSSEC_YES
, DNSSEC_ALLOW_DOWNGRADE
))
427 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.");
431 if (l
->dnssec_mode
== mode
)
434 if ((l
->dnssec_mode
== _DNSSEC_MODE_INVALID
) ||
435 (l
->dnssec_mode
== DNSSEC_NO
&& mode
!= DNSSEC_NO
) ||
436 (l
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
&& mode
== DNSSEC_YES
)) {
438 /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
439 * allow-downgrade mode to full DNSSEC mode, flush it too. */
440 if (l
->unicast_scope
)
441 dns_cache_flush(&l
->unicast_scope
->cache
);
444 l
->dnssec_mode
= mode
;
447 static int link_update_dnssec_mode(Link
*l
) {
448 _cleanup_free_
char *m
= NULL
;
454 r
= sd_network_link_get_dnssec(l
->ifindex
, &m
);
462 mode
= dnssec_mode_from_string(m
);
468 link_set_dnssec_mode(l
, mode
);
473 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
477 static int link_update_dnssec_negative_trust_anchors(Link
*l
) {
478 _cleanup_strv_free_
char **ntas
= NULL
;
479 _cleanup_set_free_free_ Set
*ns
= NULL
;
484 r
= sd_network_link_get_dnssec_negative_trust_anchors(l
->ifindex
, &ntas
);
492 ns
= set_new(&dns_name_hash_ops
);
496 r
= set_put_strdupv(ns
, ntas
);
500 set_free_free(l
->dnssec_negative_trust_anchors
);
501 l
->dnssec_negative_trust_anchors
= TAKE_PTR(ns
);
506 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
510 static int link_update_search_domain_one(Link
*l
, const char *name
, bool route_only
) {
517 r
= dns_search_domain_find(l
->search_domains
, name
, &d
);
521 dns_search_domain_move_back_and_unmark(d
);
523 r
= dns_search_domain_new(l
->manager
, &d
, DNS_SEARCH_DOMAIN_LINK
, l
, name
);
528 d
->route_only
= route_only
;
532 static int link_update_search_domains(Link
*l
) {
533 _cleanup_strv_free_
char **sdomains
= NULL
, **rdomains
= NULL
;
539 r
= sd_network_link_get_search_domains(l
->ifindex
, &sdomains
);
540 if (r
< 0 && r
!= -ENODATA
)
543 q
= sd_network_link_get_route_domains(l
->ifindex
, &rdomains
);
544 if (q
< 0 && q
!= -ENODATA
) {
549 if (r
== -ENODATA
&& q
== -ENODATA
) {
550 /* networkd knows nothing about this interface, and that's fine. */
555 dns_search_domain_mark_all(l
->search_domains
);
557 STRV_FOREACH(i
, sdomains
) {
558 r
= link_update_search_domain_one(l
, *i
, false);
563 STRV_FOREACH(i
, rdomains
) {
564 r
= link_update_search_domain_one(l
, *i
, true);
569 dns_search_domain_unlink_marked(l
->search_domains
);
573 dns_search_domain_unlink_all(l
->search_domains
);
577 static int link_is_managed(Link
*l
) {
578 _cleanup_free_
char *state
= NULL
;
583 r
= sd_network_link_get_setup_state(l
->ifindex
, &state
);
589 return !STR_IN_SET(state
, "pending", "unmanaged");
592 static void link_read_settings(Link
*l
) {
597 /* Read settings from networkd, except when networkd is not managing this interface. */
599 r
= link_is_managed(l
);
601 log_link_warning_errno(l
, r
, "Failed to determine whether the interface is managed: %m");
606 /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
608 link_flush_settings(l
);
610 l
->is_managed
= false;
614 l
->is_managed
= true;
616 r
= link_update_dns_servers(l
);
618 log_link_warning_errno(l
, r
, "Failed to read DNS servers for the interface, ignoring: %m");
620 r
= link_update_llmnr_support(l
);
622 log_link_warning_errno(l
, r
, "Failed to read LLMNR support for the interface, ignoring: %m");
624 r
= link_update_mdns_support(l
);
626 log_link_warning_errno(l
, r
, "Failed to read mDNS support for the interface, ignoring: %m");
628 r
= link_update_dns_over_tls_mode(l
);
630 log_link_warning_errno(l
, r
, "Failed to read DNS-over-TLS mode for the interface, ignoring: %m");
632 r
= link_update_dnssec_mode(l
);
634 log_link_warning_errno(l
, r
, "Failed to read DNSSEC mode for the interface, ignoring: %m");
636 r
= link_update_dnssec_negative_trust_anchors(l
);
638 log_link_warning_errno(l
, r
, "Failed to read DNSSEC negative trust anchors for the interface, ignoring: %m");
640 r
= link_update_search_domains(l
);
642 log_link_warning_errno(l
, r
, "Failed to read search domains for the interface, ignoring: %m");
644 r
= link_update_default_route(l
);
646 log_link_warning_errno(l
, r
, "Failed to read default route setting for the interface, proceeding anyway: %m");
649 int link_update(Link
*l
) {
654 link_read_settings(l
);
657 if (l
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
658 r
= manager_llmnr_start(l
->manager
);
663 if (l
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
664 r
= manager_mdns_start(l
->manager
);
669 link_allocate_scopes(l
);
670 link_add_rrs(l
, false);
675 bool link_relevant(Link
*l
, int family
, bool local_multicast
) {
676 _cleanup_free_
char *state
= NULL
;
681 /* A link is relevant for local multicast traffic if it isn't a loopback device, has a link
682 * beat, can do multicast and has at least one link-local (or better) IP address.
684 * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
685 * least one routable address. */
687 if (l
->flags
& (IFF_LOOPBACK
|IFF_DORMANT
))
690 if ((l
->flags
& (IFF_UP
|IFF_LOWER_UP
)) != (IFF_UP
|IFF_LOWER_UP
))
693 if (local_multicast
) {
694 if ((l
->flags
& IFF_MULTICAST
) != IFF_MULTICAST
)
698 /* Check kernel operstate
699 * https://www.kernel.org/doc/Documentation/networking/operstates.txt */
700 if (!IN_SET(l
->operstate
, IF_OPER_UNKNOWN
, IF_OPER_UP
))
703 (void) sd_network_link_get_operational_state(l
->ifindex
, &state
);
704 if (state
&& !STR_IN_SET(state
, "unknown", "degraded", "degraded-carrier", "routable"))
707 LIST_FOREACH(addresses
, a
, l
->addresses
)
708 if ((family
== AF_UNSPEC
|| a
->family
== family
) && link_address_relevant(a
, local_multicast
))
714 LinkAddress
*link_find_address(Link
*l
, int family
, const union in_addr_union
*in_addr
) {
719 LIST_FOREACH(addresses
, a
, l
->addresses
)
720 if (a
->family
== family
&& in_addr_equal(family
, &a
->in_addr
, in_addr
))
726 DnsServer
* link_set_dns_server(Link
*l
, DnsServer
*s
) {
729 if (l
->current_dns_server
== s
)
733 log_debug("Switching to DNS server %s for interface %s.", dns_server_string(s
), l
->ifname
);
735 dns_server_unref(l
->current_dns_server
);
736 l
->current_dns_server
= dns_server_ref(s
);
738 if (l
->unicast_scope
)
739 dns_cache_flush(&l
->unicast_scope
->cache
);
744 DnsServer
*link_get_dns_server(Link
*l
) {
747 if (!l
->current_dns_server
)
748 link_set_dns_server(l
, l
->dns_servers
);
750 return l
->current_dns_server
;
753 void link_next_dns_server(Link
*l
) {
756 if (!l
->current_dns_server
)
759 /* Change to the next one, but make sure to follow the linked
760 * list only if this server is actually still linked. */
761 if (l
->current_dns_server
->linked
&& l
->current_dns_server
->servers_next
) {
762 link_set_dns_server(l
, l
->current_dns_server
->servers_next
);
766 link_set_dns_server(l
, l
->dns_servers
);
769 DnsOverTlsMode
link_get_dns_over_tls_mode(Link
*l
) {
772 if (l
->dns_over_tls_mode
!= _DNS_OVER_TLS_MODE_INVALID
)
773 return l
->dns_over_tls_mode
;
775 return manager_get_dns_over_tls_mode(l
->manager
);
778 DnssecMode
link_get_dnssec_mode(Link
*l
) {
781 if (l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
782 return l
->dnssec_mode
;
784 return manager_get_dnssec_mode(l
->manager
);
787 bool link_dnssec_supported(Link
*l
) {
792 if (link_get_dnssec_mode(l
) == DNSSEC_NO
)
795 server
= link_get_dns_server(l
);
797 return dns_server_dnssec_supported(server
);
802 int link_address_new(Link
*l
, LinkAddress
**ret
, int family
, const union in_addr_union
*in_addr
) {
808 a
= new0(LinkAddress
, 1);
813 a
->in_addr
= *in_addr
;
816 LIST_PREPEND(addresses
, l
->addresses
, a
);
825 LinkAddress
*link_address_free(LinkAddress
*a
) {
830 LIST_REMOVE(addresses
, a
->link
->addresses
, a
);
832 assert(a
->link
->n_addresses
> 0);
833 a
->link
->n_addresses
--;
835 if (a
->llmnr_address_rr
) {
836 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
837 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
838 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
839 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
842 if (a
->llmnr_ptr_rr
) {
843 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
844 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
845 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
846 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
849 if (a
->mdns_address_rr
) {
850 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
851 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
852 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
853 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
856 if (a
->mdns_ptr_rr
) {
857 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
858 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
859 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
860 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
864 dns_resource_record_unref(a
->llmnr_address_rr
);
865 dns_resource_record_unref(a
->llmnr_ptr_rr
);
866 dns_resource_record_unref(a
->mdns_address_rr
);
867 dns_resource_record_unref(a
->mdns_ptr_rr
);
872 void link_address_add_rrs(LinkAddress
*a
, bool force_remove
) {
877 if (a
->family
== AF_INET
) {
880 link_address_relevant(a
, true) &&
881 a
->link
->llmnr_ipv4_scope
&&
882 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
883 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
885 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
886 a
->link
->manager
->llmnr_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->llmnr_hostname
);
887 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
893 if (!a
->llmnr_address_rr
) {
894 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv4_key
);
895 if (!a
->llmnr_address_rr
) {
900 a
->llmnr_address_rr
->a
.in_addr
= a
->in_addr
.in
;
901 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
904 if (!a
->llmnr_ptr_rr
) {
905 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
909 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
912 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_address_rr
, true);
914 log_warning_errno(r
, "Failed to add A record to LLMNR zone: %m");
916 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_ptr_rr
, false);
918 log_warning_errno(r
, "Failed to add IPv4 PTR record to LLMNR zone: %m");
920 if (a
->llmnr_address_rr
) {
921 if (a
->link
->llmnr_ipv4_scope
)
922 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
923 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
926 if (a
->llmnr_ptr_rr
) {
927 if (a
->link
->llmnr_ipv4_scope
)
928 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
929 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
934 link_address_relevant(a
, true) &&
935 a
->link
->mdns_ipv4_scope
&&
936 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
937 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
938 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
939 a
->link
->manager
->mdns_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->mdns_hostname
);
940 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
946 if (!a
->mdns_address_rr
) {
947 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv4_key
);
948 if (!a
->mdns_address_rr
) {
953 a
->mdns_address_rr
->a
.in_addr
= a
->in_addr
.in
;
954 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
957 if (!a
->mdns_ptr_rr
) {
958 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
962 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
965 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_address_rr
, true);
967 log_warning_errno(r
, "Failed to add A record to MDNS zone: %m");
969 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_ptr_rr
, false);
971 log_warning_errno(r
, "Failed to add IPv4 PTR record to MDNS zone: %m");
973 if (a
->mdns_address_rr
) {
974 if (a
->link
->mdns_ipv4_scope
)
975 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
976 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
979 if (a
->mdns_ptr_rr
) {
980 if (a
->link
->mdns_ipv4_scope
)
981 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
982 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
987 if (a
->family
== AF_INET6
) {
990 link_address_relevant(a
, true) &&
991 a
->link
->llmnr_ipv6_scope
&&
992 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
993 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
995 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
996 a
->link
->manager
->llmnr_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->llmnr_hostname
);
997 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
1003 if (!a
->llmnr_address_rr
) {
1004 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv6_key
);
1005 if (!a
->llmnr_address_rr
) {
1010 a
->llmnr_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
1011 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
1014 if (!a
->llmnr_ptr_rr
) {
1015 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
1019 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
1022 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_address_rr
, true);
1024 log_warning_errno(r
, "Failed to add AAAA record to LLMNR zone: %m");
1026 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_ptr_rr
, false);
1028 log_warning_errno(r
, "Failed to add IPv6 PTR record to LLMNR zone: %m");
1030 if (a
->llmnr_address_rr
) {
1031 if (a
->link
->llmnr_ipv6_scope
)
1032 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
1033 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
1036 if (a
->llmnr_ptr_rr
) {
1037 if (a
->link
->llmnr_ipv6_scope
)
1038 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
1039 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
1043 if (!force_remove
&&
1044 link_address_relevant(a
, true) &&
1045 a
->link
->mdns_ipv6_scope
&&
1046 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
1047 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
1049 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
1050 a
->link
->manager
->mdns_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->mdns_hostname
);
1051 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
1057 if (!a
->mdns_address_rr
) {
1058 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv6_key
);
1059 if (!a
->mdns_address_rr
) {
1064 a
->mdns_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
1065 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
1068 if (!a
->mdns_ptr_rr
) {
1069 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
1073 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
1076 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_address_rr
, true);
1078 log_warning_errno(r
, "Failed to add AAAA record to MDNS zone: %m");
1080 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_ptr_rr
, false);
1082 log_warning_errno(r
, "Failed to add IPv6 PTR record to MDNS zone: %m");
1084 if (a
->mdns_address_rr
) {
1085 if (a
->link
->mdns_ipv6_scope
)
1086 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
1087 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
1090 if (a
->mdns_ptr_rr
) {
1091 if (a
->link
->mdns_ipv6_scope
)
1092 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
1093 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
1101 log_debug_errno(r
, "Failed to update address RRs: %m");
1104 int link_address_update_rtnl(LinkAddress
*a
, sd_netlink_message
*m
) {
1109 r
= sd_rtnl_message_addr_get_flags(m
, &a
->flags
);
1113 sd_rtnl_message_addr_get_scope(m
, &a
->scope
);
1115 link_allocate_scopes(a
->link
);
1116 link_add_rrs(a
->link
, false);
1121 bool link_address_relevant(LinkAddress
*a
, bool local_multicast
) {
1124 if (a
->flags
& (IFA_F_DEPRECATED
|IFA_F_TENTATIVE
))
1127 if (a
->scope
>= (local_multicast
? RT_SCOPE_HOST
: RT_SCOPE_LINK
))
1133 static bool link_needs_save(Link
*l
) {
1136 /* Returns true if any of the settings where set different from the default */
1141 if (l
->llmnr_support
!= RESOLVE_SUPPORT_YES
||
1142 l
->mdns_support
!= RESOLVE_SUPPORT_NO
||
1143 l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
||
1144 l
->dns_over_tls_mode
!= _DNS_OVER_TLS_MODE_INVALID
)
1147 if (l
->dns_servers
||
1151 if (!set_isempty(l
->dnssec_negative_trust_anchors
))
1154 if (l
->default_route
>= 0)
1160 int link_save_user(Link
*l
) {
1161 _cleanup_free_
char *temp_path
= NULL
;
1162 _cleanup_fclose_
FILE *f
= NULL
;
1167 assert(l
->state_file
);
1169 if (!link_needs_save(l
)) {
1170 (void) unlink(l
->state_file
);
1174 r
= mkdir_parents(l
->state_file
, 0700);
1178 r
= fopen_temporary(l
->state_file
, &f
, &temp_path
);
1182 (void) fchmod(fileno(f
), 0644);
1184 fputs("# This is private data. Do not parse.\n", f
);
1186 v
= resolve_support_to_string(l
->llmnr_support
);
1188 fprintf(f
, "LLMNR=%s\n", v
);
1190 v
= resolve_support_to_string(l
->mdns_support
);
1192 fprintf(f
, "MDNS=%s\n", v
);
1194 v
= dnssec_mode_to_string(l
->dnssec_mode
);
1196 fprintf(f
, "DNSSEC=%s\n", v
);
1198 if (l
->default_route
>= 0)
1199 fprintf(f
, "DEFAULT_ROUTE=%s\n", yes_no(l
->default_route
));
1201 if (l
->dns_servers
) {
1204 fputs("SERVERS=", f
);
1205 LIST_FOREACH(servers
, server
, l
->dns_servers
) {
1207 if (server
!= l
->dns_servers
)
1210 v
= dns_server_string(server
);
1221 if (l
->search_domains
) {
1222 DnsSearchDomain
*domain
;
1224 fputs("DOMAINS=", f
);
1225 LIST_FOREACH(domains
, domain
, l
->search_domains
) {
1227 if (domain
!= l
->search_domains
)
1230 if (domain
->route_only
)
1233 fputs(DNS_SEARCH_DOMAIN_NAME(domain
), f
);
1238 if (!set_isempty(l
->dnssec_negative_trust_anchors
)) {
1244 SET_FOREACH(nta
, l
->dnssec_negative_trust_anchors
, i
) {
1255 r
= fflush_and_check(f
);
1259 if (rename(temp_path
, l
->state_file
) < 0) {
1267 (void) unlink(l
->state_file
);
1270 (void) unlink(temp_path
);
1272 return log_error_errno(r
, "Failed to save link data %s: %m", l
->state_file
);
1275 int link_load_user(Link
*l
) {
1283 *default_route
= NULL
;
1290 assert(l
->state_file
);
1292 /* Try to load only a single time */
1298 return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */
1300 r
= parse_env_file(NULL
, l
->state_file
,
1304 "SERVERS", &servers
,
1305 "DOMAINS", &domains
,
1307 "DEFAULT_ROUTE", &default_route
);
1313 link_flush_settings(l
);
1315 /* If we can't recognize the LLMNR or MDNS setting we don't override the default */
1316 s
= resolve_support_from_string(llmnr
);
1318 l
->llmnr_support
= s
;
1320 s
= resolve_support_from_string(mdns
);
1322 l
->mdns_support
= s
;
1324 r
= parse_boolean(default_route
);
1326 l
->default_route
= r
;
1328 /* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
1329 l
->dnssec_mode
= dnssec_mode_from_string(dnssec
);
1331 for (p
= servers
;;) {
1332 _cleanup_free_
char *word
= NULL
;
1334 r
= extract_first_word(&p
, &word
, NULL
, 0);
1340 r
= link_update_dns_server_one(l
, word
);
1342 log_debug_errno(r
, "Failed to load DNS server '%s', ignoring: %m", word
);
1347 for (p
= domains
;;) {
1348 _cleanup_free_
char *word
= NULL
;
1352 r
= extract_first_word(&p
, &word
, NULL
, 0);
1358 is_route
= word
[0] == '~';
1359 n
= is_route
? word
+ 1 : word
;
1361 r
= link_update_search_domain_one(l
, n
, is_route
);
1363 log_debug_errno(r
, "Failed to load search domain '%s', ignoring: %m", word
);
1369 _cleanup_set_free_free_ Set
*ns
= NULL
;
1371 ns
= set_new(&dns_name_hash_ops
);
1377 r
= set_put_strsplit(ns
, ntas
, NULL
, 0);
1381 l
->dnssec_negative_trust_anchors
= TAKE_PTR(ns
);
1387 return log_error_errno(r
, "Failed to load link data %s: %m", l
->state_file
);
1390 void link_remove_user(Link
*l
) {
1392 assert(l
->state_file
);
1394 (void) unlink(l
->state_file
);