2 This file is part of systemd.
4 Copyright 2014 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "sd-network.h"
24 #include "alloc-util.h"
29 #include "parse-util.h"
30 #include "resolved-link.h"
31 #include "string-util.h"
34 int link_new(Manager
*m
, Link
**ret
, int ifindex
) {
35 _cleanup_(link_freep
) Link
*l
= NULL
;
41 r
= hashmap_ensure_allocated(&m
->links
, NULL
);
50 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
51 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
52 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
53 l
->operstate
= IF_OPER_UNKNOWN
;
55 if (asprintf(&l
->state_file
, "/run/systemd/resolve/netif/%i", ifindex
) < 0)
58 r
= hashmap_put(m
->links
, INT_TO_PTR(ifindex
), l
);
71 void link_flush_settings(Link
*l
) {
74 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
75 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
76 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
78 dns_server_unlink_all(l
->dns_servers
);
79 dns_search_domain_unlink_all(l
->search_domains
);
81 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
84 Link
*link_free(Link
*l
) {
88 /* Send goodbye messages. */
89 dns_scope_announce(l
->mdns_ipv4_scope
, true);
90 dns_scope_announce(l
->mdns_ipv6_scope
, true);
92 link_flush_settings(l
);
95 (void) link_address_free(l
->addresses
);
98 hashmap_remove(l
->manager
->links
, INT_TO_PTR(l
->ifindex
));
100 dns_scope_free(l
->unicast_scope
);
101 dns_scope_free(l
->llmnr_ipv4_scope
);
102 dns_scope_free(l
->llmnr_ipv6_scope
);
103 dns_scope_free(l
->mdns_ipv4_scope
);
104 dns_scope_free(l
->mdns_ipv6_scope
);
111 void link_allocate_scopes(Link
*l
) {
116 if (link_relevant(l
, AF_UNSPEC
, false) &&
118 if (!l
->unicast_scope
) {
119 r
= dns_scope_new(l
->manager
, &l
->unicast_scope
, l
, DNS_PROTOCOL_DNS
, AF_UNSPEC
);
121 log_warning_errno(r
, "Failed to allocate DNS scope: %m");
124 l
->unicast_scope
= dns_scope_free(l
->unicast_scope
);
126 if (link_relevant(l
, AF_INET
, true) &&
127 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
128 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
) {
129 if (!l
->llmnr_ipv4_scope
) {
130 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv4_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET
);
132 log_warning_errno(r
, "Failed to allocate LLMNR IPv4 scope: %m");
135 l
->llmnr_ipv4_scope
= dns_scope_free(l
->llmnr_ipv4_scope
);
137 if (link_relevant(l
, AF_INET6
, true) &&
138 l
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
139 l
->manager
->llmnr_support
!= RESOLVE_SUPPORT_NO
&&
140 socket_ipv6_is_supported()) {
141 if (!l
->llmnr_ipv6_scope
) {
142 r
= dns_scope_new(l
->manager
, &l
->llmnr_ipv6_scope
, l
, DNS_PROTOCOL_LLMNR
, AF_INET6
);
144 log_warning_errno(r
, "Failed to allocate LLMNR IPv6 scope: %m");
147 l
->llmnr_ipv6_scope
= dns_scope_free(l
->llmnr_ipv6_scope
);
149 if (link_relevant(l
, AF_INET
, true) &&
150 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
151 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
152 if (!l
->mdns_ipv4_scope
) {
153 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv4_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET
);
155 log_warning_errno(r
, "Failed to allocate mDNS IPv4 scope: %m");
158 l
->mdns_ipv4_scope
= dns_scope_free(l
->mdns_ipv4_scope
);
160 if (link_relevant(l
, AF_INET6
, true) &&
161 l
->mdns_support
!= RESOLVE_SUPPORT_NO
&&
162 l
->manager
->mdns_support
!= RESOLVE_SUPPORT_NO
) {
163 if (!l
->mdns_ipv6_scope
) {
164 r
= dns_scope_new(l
->manager
, &l
->mdns_ipv6_scope
, l
, DNS_PROTOCOL_MDNS
, AF_INET6
);
166 log_warning_errno(r
, "Failed to allocate mDNS IPv6 scope: %m");
169 l
->mdns_ipv6_scope
= dns_scope_free(l
->mdns_ipv6_scope
);
172 void link_add_rrs(Link
*l
, bool force_remove
) {
175 LIST_FOREACH(addresses
, a
, l
->addresses
)
176 link_address_add_rrs(a
, force_remove
);
179 int link_process_rtnl(Link
*l
, sd_netlink_message
*m
) {
180 const char *n
= NULL
;
186 r
= sd_rtnl_message_link_get_flags(m
, &l
->flags
);
190 (void) sd_netlink_message_read_u32(m
, IFLA_MTU
, &l
->mtu
);
191 (void) sd_netlink_message_read_u8(m
, IFLA_OPERSTATE
, &l
->operstate
);
193 if (sd_netlink_message_read_string(m
, IFLA_IFNAME
, &n
) >= 0) {
194 strncpy(l
->name
, n
, sizeof(l
->name
)-1);
195 char_array_0(l
->name
);
198 link_allocate_scopes(l
);
199 link_add_rrs(l
, false);
204 static int link_update_dns_server_one(Link
*l
, const char *name
) {
205 union in_addr_union a
;
212 r
= in_addr_from_string_auto(name
, &family
, &a
);
216 s
= dns_server_find(l
->dns_servers
, family
, &a
, 0);
218 dns_server_move_back_and_unmark(s
);
222 return dns_server_new(l
->manager
, NULL
, DNS_SERVER_LINK
, l
, family
, &a
, 0);
225 static int link_update_dns_servers(Link
*l
) {
226 _cleanup_strv_free_
char **nameservers
= NULL
;
232 r
= sd_network_link_get_dns(l
->ifindex
, &nameservers
);
240 dns_server_mark_all(l
->dns_servers
);
242 STRV_FOREACH(nameserver
, nameservers
) {
243 r
= link_update_dns_server_one(l
, *nameserver
);
248 dns_server_unlink_marked(l
->dns_servers
);
252 dns_server_unlink_all(l
->dns_servers
);
256 static int link_update_llmnr_support(Link
*l
) {
257 _cleanup_free_
char *b
= NULL
;
262 r
= sd_network_link_get_llmnr(l
->ifindex
, &b
);
270 l
->llmnr_support
= resolve_support_from_string(b
);
271 if (l
->llmnr_support
< 0) {
279 l
->llmnr_support
= RESOLVE_SUPPORT_YES
;
283 static int link_update_mdns_support(Link
*l
) {
284 _cleanup_free_
char *b
= NULL
;
289 r
= sd_network_link_get_mdns(l
->ifindex
, &b
);
297 l
->mdns_support
= resolve_support_from_string(b
);
298 if (l
->mdns_support
< 0) {
306 l
->mdns_support
= RESOLVE_SUPPORT_NO
;
310 void link_set_dnssec_mode(Link
*l
, DnssecMode mode
) {
314 if (l
->dnssec_mode
== mode
)
317 if ((l
->dnssec_mode
== _DNSSEC_MODE_INVALID
) ||
318 (l
->dnssec_mode
== DNSSEC_NO
&& mode
!= DNSSEC_NO
) ||
319 (l
->dnssec_mode
== DNSSEC_ALLOW_DOWNGRADE
&& mode
== DNSSEC_YES
)) {
321 /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
322 * allow-downgrade mode to full DNSSEC mode, flush it too. */
323 if (l
->unicast_scope
)
324 dns_cache_flush(&l
->unicast_scope
->cache
);
327 l
->dnssec_mode
= mode
;
330 static int link_update_dnssec_mode(Link
*l
) {
331 _cleanup_free_
char *m
= NULL
;
337 r
= sd_network_link_get_dnssec(l
->ifindex
, &m
);
345 mode
= dnssec_mode_from_string(m
);
351 link_set_dnssec_mode(l
, mode
);
356 l
->dnssec_mode
= _DNSSEC_MODE_INVALID
;
360 static int link_update_dnssec_negative_trust_anchors(Link
*l
) {
361 _cleanup_strv_free_
char **ntas
= NULL
;
362 _cleanup_set_free_free_ Set
*ns
= NULL
;
367 r
= sd_network_link_get_dnssec_negative_trust_anchors(l
->ifindex
, &ntas
);
375 ns
= set_new(&dns_name_hash_ops
);
379 r
= set_put_strdupv(ns
, ntas
);
383 set_free_free(l
->dnssec_negative_trust_anchors
);
384 l
->dnssec_negative_trust_anchors
= ns
;
390 l
->dnssec_negative_trust_anchors
= set_free_free(l
->dnssec_negative_trust_anchors
);
394 static int link_update_search_domain_one(Link
*l
, const char *name
, bool route_only
) {
401 r
= dns_search_domain_find(l
->search_domains
, name
, &d
);
405 dns_search_domain_move_back_and_unmark(d
);
407 r
= dns_search_domain_new(l
->manager
, &d
, DNS_SEARCH_DOMAIN_LINK
, l
, name
);
412 d
->route_only
= route_only
;
416 static int link_update_search_domains(Link
*l
) {
417 _cleanup_strv_free_
char **sdomains
= NULL
, **rdomains
= NULL
;
423 r
= sd_network_link_get_search_domains(l
->ifindex
, &sdomains
);
424 if (r
< 0 && r
!= -ENODATA
)
427 q
= sd_network_link_get_route_domains(l
->ifindex
, &rdomains
);
428 if (q
< 0 && q
!= -ENODATA
) {
433 if (r
== -ENODATA
&& q
== -ENODATA
) {
434 /* networkd knows nothing about this interface, and that's fine. */
439 dns_search_domain_mark_all(l
->search_domains
);
441 STRV_FOREACH(i
, sdomains
) {
442 r
= link_update_search_domain_one(l
, *i
, false);
447 STRV_FOREACH(i
, rdomains
) {
448 r
= link_update_search_domain_one(l
, *i
, true);
453 dns_search_domain_unlink_marked(l
->search_domains
);
457 dns_search_domain_unlink_all(l
->search_domains
);
461 static int link_is_managed(Link
*l
) {
462 _cleanup_free_
char *state
= NULL
;
467 r
= sd_network_link_get_setup_state(l
->ifindex
, &state
);
473 return !STR_IN_SET(state
, "pending", "unmanaged");
476 static void link_read_settings(Link
*l
) {
481 /* Read settings from networkd, except when networkd is not managing this interface. */
483 r
= link_is_managed(l
);
485 log_warning_errno(r
, "Failed to determine whether interface %s is managed: %m", l
->name
);
490 /* If this link used to be managed, but is now unmanaged, flush all our settings — but only once. */
492 link_flush_settings(l
);
494 l
->is_managed
= false;
498 l
->is_managed
= true;
500 r
= link_update_dns_servers(l
);
502 log_warning_errno(r
, "Failed to read DNS servers for interface %s, ignoring: %m", l
->name
);
504 r
= link_update_llmnr_support(l
);
506 log_warning_errno(r
, "Failed to read LLMNR support for interface %s, ignoring: %m", l
->name
);
508 r
= link_update_mdns_support(l
);
510 log_warning_errno(r
, "Failed to read mDNS support for interface %s, ignoring: %m", l
->name
);
512 r
= link_update_dnssec_mode(l
);
514 log_warning_errno(r
, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l
->name
);
516 r
= link_update_dnssec_negative_trust_anchors(l
);
518 log_warning_errno(r
, "Failed to read DNSSEC negative trust anchors for interface %s, ignoring: %m", l
->name
);
520 r
= link_update_search_domains(l
);
522 log_warning_errno(r
, "Failed to read search domains for interface %s, ignoring: %m", l
->name
);
525 int link_update(Link
*l
) {
528 link_read_settings(l
);
530 link_allocate_scopes(l
);
531 link_add_rrs(l
, false);
536 bool link_relevant(Link
*l
, int family
, bool local_multicast
) {
537 _cleanup_free_
char *state
= NULL
;
542 /* A link is relevant for local multicast traffic if it isn't a loopback or pointopoint device, has a link
543 * beat, can do multicast and has at least one link-local (or better) IP address.
545 * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
546 * least one routable address.*/
548 if (l
->flags
& (IFF_LOOPBACK
|IFF_DORMANT
))
551 if ((l
->flags
& (IFF_UP
|IFF_LOWER_UP
)) != (IFF_UP
|IFF_LOWER_UP
))
554 if (local_multicast
) {
555 if (l
->flags
& IFF_POINTOPOINT
)
558 if ((l
->flags
& IFF_MULTICAST
) != IFF_MULTICAST
)
562 /* Check kernel operstate
563 * https://www.kernel.org/doc/Documentation/networking/operstates.txt */
564 if (!IN_SET(l
->operstate
, IF_OPER_UNKNOWN
, IF_OPER_UP
))
567 (void) sd_network_link_get_operational_state(l
->ifindex
, &state
);
568 if (state
&& !STR_IN_SET(state
, "unknown", "degraded", "routable"))
571 LIST_FOREACH(addresses
, a
, l
->addresses
)
572 if ((family
== AF_UNSPEC
|| a
->family
== family
) && link_address_relevant(a
, local_multicast
))
578 LinkAddress
*link_find_address(Link
*l
, int family
, const union in_addr_union
*in_addr
) {
583 LIST_FOREACH(addresses
, a
, l
->addresses
)
584 if (a
->family
== family
&& in_addr_equal(family
, &a
->in_addr
, in_addr
))
590 DnsServer
* link_set_dns_server(Link
*l
, DnsServer
*s
) {
593 if (l
->current_dns_server
== s
)
597 log_info("Switching to DNS server %s for interface %s.", dns_server_string(s
), l
->name
);
599 dns_server_unref(l
->current_dns_server
);
600 l
->current_dns_server
= dns_server_ref(s
);
602 if (l
->unicast_scope
)
603 dns_cache_flush(&l
->unicast_scope
->cache
);
608 DnsServer
*link_get_dns_server(Link
*l
) {
611 if (!l
->current_dns_server
)
612 link_set_dns_server(l
, l
->dns_servers
);
614 return l
->current_dns_server
;
617 void link_next_dns_server(Link
*l
) {
620 if (!l
->current_dns_server
)
623 /* Change to the next one, but make sure to follow the linked
624 * list only if this server is actually still linked. */
625 if (l
->current_dns_server
->linked
&& l
->current_dns_server
->servers_next
) {
626 link_set_dns_server(l
, l
->current_dns_server
->servers_next
);
630 link_set_dns_server(l
, l
->dns_servers
);
633 DnssecMode
link_get_dnssec_mode(Link
*l
) {
636 if (l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
637 return l
->dnssec_mode
;
639 return manager_get_dnssec_mode(l
->manager
);
642 bool link_dnssec_supported(Link
*l
) {
647 if (link_get_dnssec_mode(l
) == DNSSEC_NO
)
650 server
= link_get_dns_server(l
);
652 return dns_server_dnssec_supported(server
);
657 int link_address_new(Link
*l
, LinkAddress
**ret
, int family
, const union in_addr_union
*in_addr
) {
663 a
= new0(LinkAddress
, 1);
668 a
->in_addr
= *in_addr
;
671 LIST_PREPEND(addresses
, l
->addresses
, a
);
679 LinkAddress
*link_address_free(LinkAddress
*a
) {
684 LIST_REMOVE(addresses
, a
->link
->addresses
, a
);
686 if (a
->llmnr_address_rr
) {
687 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
688 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
689 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
690 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
693 if (a
->llmnr_ptr_rr
) {
694 if (a
->family
== AF_INET
&& a
->link
->llmnr_ipv4_scope
)
695 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
696 else if (a
->family
== AF_INET6
&& a
->link
->llmnr_ipv6_scope
)
697 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
700 if (a
->mdns_address_rr
) {
701 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
702 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
703 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
704 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
707 if (a
->mdns_ptr_rr
) {
708 if (a
->family
== AF_INET
&& a
->link
->mdns_ipv4_scope
)
709 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
710 else if (a
->family
== AF_INET6
&& a
->link
->mdns_ipv6_scope
)
711 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
715 dns_resource_record_unref(a
->llmnr_address_rr
);
716 dns_resource_record_unref(a
->llmnr_ptr_rr
);
717 dns_resource_record_unref(a
->mdns_address_rr
);
718 dns_resource_record_unref(a
->mdns_ptr_rr
);
723 void link_address_add_rrs(LinkAddress
*a
, bool force_remove
) {
728 if (a
->family
== AF_INET
) {
731 link_address_relevant(a
, true) &&
732 a
->link
->llmnr_ipv4_scope
&&
733 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
734 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
736 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
737 a
->link
->manager
->llmnr_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->llmnr_hostname
);
738 if (!a
->link
->manager
->llmnr_host_ipv4_key
) {
744 if (!a
->llmnr_address_rr
) {
745 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv4_key
);
746 if (!a
->llmnr_address_rr
) {
751 a
->llmnr_address_rr
->a
.in_addr
= a
->in_addr
.in
;
752 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
755 if (!a
->llmnr_ptr_rr
) {
756 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
760 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
763 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_address_rr
, true);
765 log_warning_errno(r
, "Failed to add A record to LLMNR zone: %m");
767 r
= dns_zone_put(&a
->link
->llmnr_ipv4_scope
->zone
, a
->link
->llmnr_ipv4_scope
, a
->llmnr_ptr_rr
, false);
769 log_warning_errno(r
, "Failed to add IPv4 PTR record to LLMNR zone: %m");
771 if (a
->llmnr_address_rr
) {
772 if (a
->link
->llmnr_ipv4_scope
)
773 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_address_rr
);
774 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
777 if (a
->llmnr_ptr_rr
) {
778 if (a
->link
->llmnr_ipv4_scope
)
779 dns_zone_remove_rr(&a
->link
->llmnr_ipv4_scope
->zone
, a
->llmnr_ptr_rr
);
780 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
785 link_address_relevant(a
, true) &&
786 a
->link
->mdns_ipv4_scope
&&
787 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
788 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
789 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
790 a
->link
->manager
->mdns_host_ipv4_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_A
, a
->link
->manager
->mdns_hostname
);
791 if (!a
->link
->manager
->mdns_host_ipv4_key
) {
797 if (!a
->mdns_address_rr
) {
798 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv4_key
);
799 if (!a
->mdns_address_rr
) {
804 a
->mdns_address_rr
->a
.in_addr
= a
->in_addr
.in
;
805 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
808 if (!a
->mdns_ptr_rr
) {
809 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
813 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
816 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_address_rr
, true);
818 log_warning_errno(r
, "Failed to add A record to MDNS zone: %m");
820 r
= dns_zone_put(&a
->link
->mdns_ipv4_scope
->zone
, a
->link
->mdns_ipv4_scope
, a
->mdns_ptr_rr
, false);
822 log_warning_errno(r
, "Failed to add IPv4 PTR record to MDNS zone: %m");
824 if (a
->mdns_address_rr
) {
825 if (a
->link
->mdns_ipv4_scope
)
826 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_address_rr
);
827 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
830 if (a
->mdns_ptr_rr
) {
831 if (a
->link
->mdns_ipv4_scope
)
832 dns_zone_remove_rr(&a
->link
->mdns_ipv4_scope
->zone
, a
->mdns_ptr_rr
);
833 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
838 if (a
->family
== AF_INET6
) {
841 link_address_relevant(a
, true) &&
842 a
->link
->llmnr_ipv6_scope
&&
843 a
->link
->llmnr_support
== RESOLVE_SUPPORT_YES
&&
844 a
->link
->manager
->llmnr_support
== RESOLVE_SUPPORT_YES
) {
846 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
847 a
->link
->manager
->llmnr_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->llmnr_hostname
);
848 if (!a
->link
->manager
->llmnr_host_ipv6_key
) {
854 if (!a
->llmnr_address_rr
) {
855 a
->llmnr_address_rr
= dns_resource_record_new(a
->link
->manager
->llmnr_host_ipv6_key
);
856 if (!a
->llmnr_address_rr
) {
861 a
->llmnr_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
862 a
->llmnr_address_rr
->ttl
= LLMNR_DEFAULT_TTL
;
865 if (!a
->llmnr_ptr_rr
) {
866 r
= dns_resource_record_new_reverse(&a
->llmnr_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->llmnr_hostname
);
870 a
->llmnr_ptr_rr
->ttl
= LLMNR_DEFAULT_TTL
;
873 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_address_rr
, true);
875 log_warning_errno(r
, "Failed to add AAAA record to LLMNR zone: %m");
877 r
= dns_zone_put(&a
->link
->llmnr_ipv6_scope
->zone
, a
->link
->llmnr_ipv6_scope
, a
->llmnr_ptr_rr
, false);
879 log_warning_errno(r
, "Failed to add IPv6 PTR record to LLMNR zone: %m");
881 if (a
->llmnr_address_rr
) {
882 if (a
->link
->llmnr_ipv6_scope
)
883 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_address_rr
);
884 a
->llmnr_address_rr
= dns_resource_record_unref(a
->llmnr_address_rr
);
887 if (a
->llmnr_ptr_rr
) {
888 if (a
->link
->llmnr_ipv6_scope
)
889 dns_zone_remove_rr(&a
->link
->llmnr_ipv6_scope
->zone
, a
->llmnr_ptr_rr
);
890 a
->llmnr_ptr_rr
= dns_resource_record_unref(a
->llmnr_ptr_rr
);
895 link_address_relevant(a
, true) &&
896 a
->link
->mdns_ipv6_scope
&&
897 a
->link
->mdns_support
== RESOLVE_SUPPORT_YES
&&
898 a
->link
->manager
->mdns_support
== RESOLVE_SUPPORT_YES
) {
900 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
901 a
->link
->manager
->mdns_host_ipv6_key
= dns_resource_key_new(DNS_CLASS_IN
, DNS_TYPE_AAAA
, a
->link
->manager
->mdns_hostname
);
902 if (!a
->link
->manager
->mdns_host_ipv6_key
) {
908 if (!a
->mdns_address_rr
) {
909 a
->mdns_address_rr
= dns_resource_record_new(a
->link
->manager
->mdns_host_ipv6_key
);
910 if (!a
->mdns_address_rr
) {
915 a
->mdns_address_rr
->aaaa
.in6_addr
= a
->in_addr
.in6
;
916 a
->mdns_address_rr
->ttl
= MDNS_DEFAULT_TTL
;
919 if (!a
->mdns_ptr_rr
) {
920 r
= dns_resource_record_new_reverse(&a
->mdns_ptr_rr
, a
->family
, &a
->in_addr
, a
->link
->manager
->mdns_hostname
);
924 a
->mdns_ptr_rr
->ttl
= MDNS_DEFAULT_TTL
;
927 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_address_rr
, true);
929 log_warning_errno(r
, "Failed to add AAAA record to MDNS zone: %m");
931 r
= dns_zone_put(&a
->link
->mdns_ipv6_scope
->zone
, a
->link
->mdns_ipv6_scope
, a
->mdns_ptr_rr
, false);
933 log_warning_errno(r
, "Failed to add IPv6 PTR record to MDNS zone: %m");
935 if (a
->mdns_address_rr
) {
936 if (a
->link
->mdns_ipv6_scope
)
937 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_address_rr
);
938 a
->mdns_address_rr
= dns_resource_record_unref(a
->mdns_address_rr
);
941 if (a
->mdns_ptr_rr
) {
942 if (a
->link
->mdns_ipv6_scope
)
943 dns_zone_remove_rr(&a
->link
->mdns_ipv6_scope
->zone
, a
->mdns_ptr_rr
);
944 a
->mdns_ptr_rr
= dns_resource_record_unref(a
->mdns_ptr_rr
);
952 log_debug_errno(r
, "Failed to update address RRs: %m");
955 int link_address_update_rtnl(LinkAddress
*a
, sd_netlink_message
*m
) {
960 r
= sd_rtnl_message_addr_get_flags(m
, &a
->flags
);
964 sd_rtnl_message_addr_get_scope(m
, &a
->scope
);
966 link_allocate_scopes(a
->link
);
967 link_add_rrs(a
->link
, false);
972 bool link_address_relevant(LinkAddress
*a
, bool local_multicast
) {
975 if (a
->flags
& (IFA_F_DEPRECATED
|IFA_F_TENTATIVE
))
978 if (a
->scope
>= (local_multicast
? RT_SCOPE_HOST
: RT_SCOPE_LINK
))
984 static bool link_needs_save(Link
*l
) {
987 /* Returns true if any of the settings where set different from the default */
992 if (l
->llmnr_support
!= RESOLVE_SUPPORT_YES
||
993 l
->mdns_support
!= RESOLVE_SUPPORT_NO
||
994 l
->dnssec_mode
!= _DNSSEC_MODE_INVALID
)
997 if (l
->dns_servers
||
1001 if (!set_isempty(l
->dnssec_negative_trust_anchors
))
1007 int link_save_user(Link
*l
) {
1008 _cleanup_free_
char *temp_path
= NULL
;
1009 _cleanup_fclose_
FILE *f
= NULL
;
1014 assert(l
->state_file
);
1016 if (!link_needs_save(l
)) {
1017 (void) unlink(l
->state_file
);
1021 r
= mkdir_parents(l
->state_file
, 0700);
1025 r
= fopen_temporary(l
->state_file
, &f
, &temp_path
);
1029 fputs("# This is private data. Do not parse.\n", f
);
1031 v
= resolve_support_to_string(l
->llmnr_support
);
1033 fprintf(f
, "LLMNR=%s\n", v
);
1035 v
= resolve_support_to_string(l
->mdns_support
);
1037 fprintf(f
, "MDNS=%s\n", v
);
1039 v
= dnssec_mode_to_string(l
->dnssec_mode
);
1041 fprintf(f
, "DNSSEC=%s\n", v
);
1043 if (l
->dns_servers
) {
1046 fputs("SERVERS=", f
);
1047 LIST_FOREACH(servers
, server
, l
->dns_servers
) {
1049 if (server
!= l
->dns_servers
)
1052 v
= dns_server_string(server
);
1063 if (l
->search_domains
) {
1064 DnsSearchDomain
*domain
;
1066 fputs("DOMAINS=", f
);
1067 LIST_FOREACH(domains
, domain
, l
->search_domains
) {
1069 if (domain
!= l
->search_domains
)
1072 if (domain
->route_only
)
1075 fputs(DNS_SEARCH_DOMAIN_NAME(domain
), f
);
1080 if (!set_isempty(l
->dnssec_negative_trust_anchors
)) {
1086 SET_FOREACH(nta
, l
->dnssec_negative_trust_anchors
, i
) {
1097 r
= fflush_and_check(f
);
1101 if (rename(temp_path
, l
->state_file
) < 0) {
1109 (void) unlink(l
->state_file
);
1112 (void) unlink(temp_path
);
1114 return log_error_errno(r
, "Failed to save link data %s: %m", l
->state_file
);
1117 int link_load_user(Link
*l
) {
1131 assert(l
->state_file
);
1133 /* Try to load only a single time */
1139 return 0; /* if the device is managed, then networkd is our configuration source, not the bus API */
1141 r
= parse_env_file(l
->state_file
, NEWLINE
,
1145 "SERVERS", &servers
,
1146 "DOMAINS", &domains
,
1154 link_flush_settings(l
);
1156 /* If we can't recognize the LLMNR or MDNS setting we don't override the default */
1157 s
= resolve_support_from_string(llmnr
);
1159 l
->llmnr_support
= s
;
1161 s
= resolve_support_from_string(mdns
);
1163 l
->mdns_support
= s
;
1165 /* If we can't recognize the DNSSEC setting, then set it to invalid, so that the daemon default is used. */
1166 l
->dnssec_mode
= dnssec_mode_from_string(dnssec
);
1168 for (p
= servers
;;) {
1169 _cleanup_free_
char *word
= NULL
;
1171 r
= extract_first_word(&p
, &word
, NULL
, 0);
1177 r
= link_update_dns_server_one(l
, word
);
1179 log_debug_errno(r
, "Failed to load DNS server '%s', ignoring: %m", word
);
1184 for (p
= domains
;;) {
1185 _cleanup_free_
char *word
= NULL
;
1189 r
= extract_first_word(&p
, &word
, NULL
, 0);
1195 is_route
= word
[0] == '~';
1196 n
= is_route
? word
+ 1 : word
;
1198 r
= link_update_search_domain_one(l
, n
, is_route
);
1200 log_debug_errno(r
, "Failed to load search domain '%s', ignoring: %m", word
);
1206 _cleanup_set_free_free_ Set
*ns
= NULL
;
1208 ns
= set_new(&dns_name_hash_ops
);
1214 r
= set_put_strsplit(ns
, ntas
, NULL
, 0);
1218 l
->dnssec_negative_trust_anchors
= ns
;
1225 return log_error_errno(r
, "Failed to load link data %s: %m", l
->state_file
);
1228 void link_remove_user(Link
*l
) {
1230 assert(l
->state_file
);
1232 (void) unlink(l
->state_file
);