74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/***
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2014 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering***/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include <net/if.h>
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "sd-network.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering#include "missing.h"
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering#include "parse-util.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "resolved-link.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "string-util.h"
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering#include "strv.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint link_new(Manager *m, Link **ret, int ifindex) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_(link_freep) Link *l = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(ifindex > 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt r = hashmap_ensure_allocated(&m->links, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering l = new0(Link, 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!l)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering l->ifindex = ifindex;
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->llmnr_support = RESOLVE_SUPPORT_YES;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering l->mdns_support = RESOLVE_SUPPORT_NO;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering l->dnssec_mode = _DNSSEC_MODE_INVALID;
6955a3ba9dc5d36487724878333a5745987e6656Lennart Poettering l->operstate = IF_OPER_UNKNOWN;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = hashmap_put(m->links, INT_TO_PTR(ifindex), l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering l->manager = m;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (ret)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *ret = l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering l = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringvoid link_flush_settings(Link *l) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering assert(l);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering l->llmnr_support = RESOLVE_SUPPORT_YES;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering l->mdns_support = RESOLVE_SUPPORT_NO;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering l->dnssec_mode = _DNSSEC_MODE_INVALID;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering dns_server_unlink_all(l->dns_servers);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering dns_search_domain_unlink_all(l->search_domains);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering l->dnssec_negative_trust_anchors = set_free_free(l->dnssec_negative_trust_anchors);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering}
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringLink *link_free(Link *l) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!l)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering link_flush_settings(l);
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering while (l->addresses)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering (void) link_address_free(l->addresses);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (l->manager)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dns_scope_free(l->unicast_scope);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering dns_scope_free(l->llmnr_ipv4_scope);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering dns_scope_free(l->llmnr_ipv6_scope);
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack dns_scope_free(l->mdns_ipv4_scope);
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack dns_scope_free(l->mdns_ipv6_scope);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering}
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringvoid link_allocate_scopes(Link *l) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering int r;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(l);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering if (link_relevant(l, AF_UNSPEC, false) &&
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering l->dns_servers) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!l->unicast_scope) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = dns_scope_new(l->manager, &l->unicast_scope, l, DNS_PROTOCOL_DNS, AF_UNSPEC);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to allocate DNS scope: %m");
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } else
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering l->unicast_scope = dns_scope_free(l->unicast_scope);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering if (link_relevant(l, AF_INET, true) &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->llmnr_support != RESOLVE_SUPPORT_NO &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->manager->llmnr_support != RESOLVE_SUPPORT_NO) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!l->llmnr_ipv4_scope) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = dns_scope_new(l->manager, &l->llmnr_ipv4_scope, l, DNS_PROTOCOL_LLMNR, AF_INET);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to allocate LLMNR IPv4 scope: %m");
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } else
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering l->llmnr_ipv4_scope = dns_scope_free(l->llmnr_ipv4_scope);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering if (link_relevant(l, AF_INET6, true) &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->llmnr_support != RESOLVE_SUPPORT_NO &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->manager->llmnr_support != RESOLVE_SUPPORT_NO &&
db97a66aa69925f7403ba3c433e86320d136567dLennart Poettering socket_ipv6_is_supported()) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (!l->llmnr_ipv6_scope) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering r = dns_scope_new(l->manager, &l->llmnr_ipv6_scope, l, DNS_PROTOCOL_LLMNR, AF_INET6);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to allocate LLMNR IPv6 scope: %m");
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering } else
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering l->llmnr_ipv6_scope = dns_scope_free(l->llmnr_ipv6_scope);
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering if (link_relevant(l, AF_INET, true) &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->mdns_support != RESOLVE_SUPPORT_NO &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->manager->mdns_support != RESOLVE_SUPPORT_NO) {
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack if (!l->mdns_ipv4_scope) {
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack r = dns_scope_new(l->manager, &l->mdns_ipv4_scope, l, DNS_PROTOCOL_MDNS, AF_INET);
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack if (r < 0)
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack log_warning_errno(r, "Failed to allocate mDNS IPv4 scope: %m");
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack }
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack } else
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack l->mdns_ipv4_scope = dns_scope_free(l->mdns_ipv4_scope);
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering if (link_relevant(l, AF_INET6, true) &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->mdns_support != RESOLVE_SUPPORT_NO &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->manager->mdns_support != RESOLVE_SUPPORT_NO) {
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack if (!l->mdns_ipv6_scope) {
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack r = dns_scope_new(l->manager, &l->mdns_ipv6_scope, l, DNS_PROTOCOL_MDNS, AF_INET6);
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack if (r < 0)
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack log_warning_errno(r, "Failed to allocate mDNS IPv6 scope: %m");
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack }
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack } else
b4f1862df2e45aba90386887d685b8bf3c840e10Daniel Mack l->mdns_ipv6_scope = dns_scope_free(l->mdns_ipv6_scope);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poetteringvoid link_add_rrs(Link *l, bool force_remove) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering LinkAddress *a;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering LIST_FOREACH(addresses, a, l->addresses)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering link_address_add_rrs(a, force_remove);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenint link_update_rtnl(Link *l, sd_netlink_message *m) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering const char *n = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_rtnl_message_link_get_flags(m, &l->flags);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
6955a3ba9dc5d36487724878333a5745987e6656Lennart Poettering (void) sd_netlink_message_read_u32(m, IFLA_MTU, &l->mtu);
6955a3ba9dc5d36487724878333a5745987e6656Lennart Poettering (void) sd_netlink_message_read_u8(m, IFLA_OPERSTATE, &l->operstate);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersen if (sd_netlink_message_read_string(m, IFLA_IFNAME, &n) >= 0) {
cc7844e78751916acb639443c119763cafe2c684Lennart Poettering strncpy(l->name, n, sizeof(l->name)-1);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering char_array_0(l->name);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering }
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering link_allocate_scopes(l);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering link_add_rrs(l, false);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
6073b6f26ab9fc6bf335faa7073ec443eef093fdTom Gundersenstatic int link_update_dns_servers(Link *l) {
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen _cleanup_strv_free_ char **nameservers = NULL;
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen char **nameserver;
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersen r = sd_network_link_get_dns(l->ifindex, &nameservers);
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering if (r == -ENODATA) {
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering r = 0;
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering goto clear;
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering }
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto clear;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering dns_server_mark_all(l->dns_servers);
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen STRV_FOREACH(nameserver, nameservers) {
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen union in_addr_union a;
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering DnsServer *s;
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen int family;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen r = in_addr_from_string_auto(*nameserver, &family, &a);
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen if (r < 0)
6f4dedb250f2d607eceefaa491f338becbeee7c0Tom Gundersen goto clear;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering s = dns_server_find(l->dns_servers, family, &a);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (s)
0b58db658b5c3f586ac3a837427f1f7fec2abb2eLennart Poettering dns_server_move_back_and_unmark(s);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else {
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto clear;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering dns_server_unlink_marked(l->dns_servers);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringclear:
4b95f1798f22c1bb75295f448188560cb6ec9eceLennart Poettering dns_server_unlink_all(l->dns_servers);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poetteringstatic int link_update_llmnr_support(Link *l) {
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering _cleanup_free_ char *b = NULL;
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering int r;
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering assert(l);
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
d6731e4c7964ee2860d4f5abdb0b52acd7a66960Tom Gundersen r = sd_network_link_get_llmnr(l->ifindex, &b);
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering if (r == -ENODATA) {
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering r = 0;
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering goto clear;
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering }
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering if (r < 0)
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering goto clear;
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->llmnr_support = resolve_support_from_string(b);
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering if (l->llmnr_support < 0) {
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering r = -EINVAL;
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering goto clear;
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering }
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering return 0;
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poetteringclear:
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering l->llmnr_support = RESOLVE_SUPPORT_YES;
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering return r;
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering}
19b50b5ba7ee8c1bfb330377309e4bab7a7531d8Lennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poetteringstatic int link_update_mdns_support(Link *l) {
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering _cleanup_free_ char *b = NULL;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering int r;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering assert(l);
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering r = sd_network_link_get_mdns(l->ifindex, &b);
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering if (r == -ENODATA) {
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering r = 0;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering goto clear;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering }
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering if (r < 0)
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering goto clear;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering l->mdns_support = resolve_support_from_string(b);
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering if (l->mdns_support < 0) {
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering r = -EINVAL;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering goto clear;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering }
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering return 0;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering
aaa297d4e5401fd4466632555432774863457f1dLennart Poetteringclear:
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering l->mdns_support = RESOLVE_SUPPORT_NO;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering return r;
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering}
aaa297d4e5401fd4466632555432774863457f1dLennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringvoid link_set_dnssec_mode(Link *l, DnssecMode mode) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering assert(l);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (l->dnssec_mode == mode)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if ((l->dnssec_mode == _DNSSEC_MODE_INVALID) ||
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering (l->dnssec_mode == DNSSEC_NO && mode != DNSSEC_NO) ||
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering (l->dnssec_mode == DNSSEC_ALLOW_DOWNGRADE && mode == DNSSEC_YES)) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* When switching from non-DNSSEC mode to DNSSEC mode, flush the cache. Also when switching from the
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering * allow-downgrade mode to full DNSSEC mode, flush it too. */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (l->unicast_scope)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering dns_cache_flush(&l->unicast_scope->cache);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering l->dnssec_mode = mode;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering}
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poetteringstatic int link_update_dnssec_mode(Link *l) {
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering _cleanup_free_ char *m = NULL;
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering DnssecMode mode;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering int r;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering assert(l);
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering r = sd_network_link_get_dnssec(l->ifindex, &m);
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering if (r == -ENODATA) {
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering r = 0;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering goto clear;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering }
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering if (r < 0)
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering goto clear;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering mode = dnssec_mode_from_string(m);
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering if (mode < 0) {
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering r = -EINVAL;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering goto clear;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering }
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering link_set_dnssec_mode(l, mode);
2e1bab34bdb1a5e849060afa8361b865ce39f87fLennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering return 0;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poetteringclear:
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering l->dnssec_mode = _DNSSEC_MODE_INVALID;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering return r;
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering}
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poetteringstatic int link_update_dnssec_negative_trust_anchors(Link *l) {
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering _cleanup_strv_free_ char **ntas = NULL;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering _cleanup_set_free_free_ Set *ns = NULL;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering char **i;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering int r;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering assert(l);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering r = sd_network_link_get_dnssec_negative_trust_anchors(l->ifindex, &ntas);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (r == -ENODATA) {
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering r = 0;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering goto clear;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering }
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (r < 0)
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering goto clear;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering ns = set_new(&dns_name_hash_ops);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (!ns)
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering return -ENOMEM;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering STRV_FOREACH(i, ntas) {
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering r = set_put_strdup(ns, *i);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (r < 0)
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering return r;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering }
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering set_free_free(l->dnssec_negative_trust_anchors);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering l->dnssec_negative_trust_anchors = ns;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering ns = NULL;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering return 0;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poetteringclear:
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering l->dnssec_negative_trust_anchors = set_free_free(l->dnssec_negative_trust_anchors);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering return r;
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering}
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poetteringstatic int link_update_search_domain_one(Link *l, const char *name, bool route_only) {
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering DnsSearchDomain *d;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering int r;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering r = dns_search_domain_find(l->search_domains, name, &d);
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering if (r < 0)
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering return r;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering if (r > 0)
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering dns_search_domain_move_back_and_unmark(d);
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering else {
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering r = dns_search_domain_new(l->manager, &d, DNS_SEARCH_DOMAIN_LINK, l, name);
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering if (r < 0)
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering return r;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering }
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering d->route_only = route_only;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering return 0;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering}
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poetteringstatic int link_update_search_domains(Link *l) {
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering _cleanup_strv_free_ char **sdomains = NULL, **rdomains = NULL;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering char **i;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering int r, q;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering assert(l);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering r = sd_network_link_get_search_domains(l->ifindex, &sdomains);
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering if (r < 0 && r != -ENODATA)
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering goto clear;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering q = sd_network_link_get_route_domains(l->ifindex, &rdomains);
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering if (q < 0 && q != -ENODATA) {
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering r = q;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering goto clear;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering }
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering if (r == -ENODATA && q == -ENODATA) {
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering /* networkd knows nothing about this interface, and that's fine. */
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering r = 0;
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering goto clear;
1ade96e980d3c0855a04140f4728b3ffd429bbeaLennart Poettering }
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering dns_search_domain_mark_all(l->search_domains);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering STRV_FOREACH(i, sdomains) {
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering r = link_update_search_domain_one(l, *i, false);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering if (r < 0)
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering goto clear;
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering }
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering STRV_FOREACH(i, rdomains) {
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering r = link_update_search_domain_one(l, *i, true);
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering if (r < 0)
ad44b56b0f4a12a8811b3867f42df7370f2fa8e0Lennart Poettering goto clear;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering }
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering dns_search_domain_unlink_marked(l->search_domains);
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen return 0;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poetteringclear:
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering dns_search_domain_unlink_all(l->search_domains);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering return r;
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen}
bda2c408f8a739c19161818bcc842107f60652a2Tom Gundersen
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringstatic int link_is_unmanaged(Link *l) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering _cleanup_free_ char *state = NULL;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering int r;
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering r = sd_network_link_get_setup_state(l->ifindex, &state);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (r == -ENODATA)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return 1;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (r < 0)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return r;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return STR_IN_SET(state, "pending", "unmanaged");
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering}
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringstatic void link_read_settings(Link *l) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering int r;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering assert(l);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* Read settings from networkd, except when networkd is not managing this interface. */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering r = link_is_unmanaged(l);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (r < 0) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering log_warning_errno(r, "Failed to determine whether interface %s is managed: %m", l->name);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (r > 0) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering /* If this link used to be managed, but is now unmanaged, flush all our settings -- but only once. */
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering if (l->is_managed)
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering link_flush_settings(l);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering l->is_managed = false;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering return;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering }
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering l->is_managed = true;
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering r = link_update_dns_servers(l);
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering if (r < 0)
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering log_warning_errno(r, "Failed to read DNS servers for interface %s, ignoring: %m", l->name);
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering r = link_update_llmnr_support(l);
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering if (r < 0)
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering log_warning_errno(r, "Failed to read LLMNR support for interface %s, ignoring: %m", l->name);
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering r = link_update_mdns_support(l);
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering if (r < 0)
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering log_warning_errno(r, "Failed to read mDNS support for interface %s, ignoring: %m", l->name);
125ae29d1bc3a6362c9bb1acddbe09fe1b274cfcLennart Poettering
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering r = link_update_dnssec_mode(l);
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering if (r < 0)
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering log_warning_errno(r, "Failed to read DNSSEC mode for interface %s, ignoring: %m", l->name);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering r = link_update_dnssec_negative_trust_anchors(l);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering if (r < 0)
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering log_warning_errno(r, "Failed to read DNSSEC negative trust anchors for interface %s, ignoring: %m", l->name);
8a516214c4412e8a40544bd725a6d499a30cbbbfLennart Poettering
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering r = link_update_search_domains(l);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering if (r < 0)
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering log_warning_errno(r, "Failed to read search domains for interface %s, ignoring: %m", l->name);
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering}
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poetteringint link_update_monitor(Link *l) {
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering assert(l);
a51c10485af349eb15faa4d1a63b9818bcf3e589Lennart Poettering
97e5d693c04e50605d438af1c8a965fd2963bbe9Lennart Poettering link_read_settings(l);
ad6c04756115809d615dede330213d73edf732a8Lennart Poettering link_allocate_scopes(l);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering link_add_rrs(l, false);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
011696f76233486bc56c266b18a328924f70269cLennart Poetteringbool link_relevant(Link *l, int family, bool local_multicast) {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering _cleanup_free_ char *state = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LinkAddress *a;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
011696f76233486bc56c266b18a328924f70269cLennart Poettering /* A link is relevant for local multicast traffic if it isn't a loopback or pointopoint device, has a link
011696f76233486bc56c266b18a328924f70269cLennart Poettering * beat, can do multicast and has at least one link-local (or better) IP address.
011696f76233486bc56c266b18a328924f70269cLennart Poettering *
011696f76233486bc56c266b18a328924f70269cLennart Poettering * A link is relevant for non-multicast traffic if it isn't a loopback device, has a link beat, and has at
011696f76233486bc56c266b18a328924f70269cLennart Poettering * least one routable address.*/
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering if (l->flags & (IFF_LOOPBACK|IFF_DORMANT))
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering if ((l->flags & (IFF_UP|IFF_LOWER_UP)) != (IFF_UP|IFF_LOWER_UP))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
011696f76233486bc56c266b18a328924f70269cLennart Poettering if (local_multicast) {
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering if (l->flags & IFF_POINTOPOINT)
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering return false;
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering if ((l->flags & IFF_MULTICAST) != IFF_MULTICAST)
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering return false;
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering }
dfc1091b2f5f21f69e0aa6d3c4536b8990d4b100Lennart Poettering
6955a3ba9dc5d36487724878333a5745987e6656Lennart Poettering /* Check kernel operstate
6955a3ba9dc5d36487724878333a5745987e6656Lennart Poettering * https://www.kernel.org/doc/Documentation/networking/operstates.txt */
6955a3ba9dc5d36487724878333a5745987e6656Lennart Poettering if (!IN_SET(l->operstate, IF_OPER_UNKNOWN, IF_OPER_UP))
6955a3ba9dc5d36487724878333a5745987e6656Lennart Poettering return false;
6955a3ba9dc5d36487724878333a5745987e6656Lennart Poettering
6955a3ba9dc5d36487724878333a5745987e6656Lennart Poettering (void) sd_network_link_get_operational_state(l->ifindex, &state);
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (state && !STR_IN_SET(state, "unknown", "degraded", "routable"))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_FOREACH(addresses, a, l->addresses)
011696f76233486bc56c266b18a328924f70269cLennart Poettering if ((family == AF_UNSPEC || a->family == family) && link_address_relevant(a, local_multicast))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart PoetteringLinkAddress *link_find_address(Link *l, int family, const union in_addr_union *in_addr) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LinkAddress *a;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering LIST_FOREACH(addresses, a, l->addresses)
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering if (a->family == family && in_addr_equal(family, &a->in_addr, in_addr))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return a;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
2c27fbca2d88214bd305272308a370a962818f1eLennart PoetteringDnsServer* link_set_dns_server(Link *l, DnsServer *s) {
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering assert(l);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering if (l->current_dns_server == s)
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering return s;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering if (s)
6cb08a8930bdaca950b152b1e8b82466ed59511cLennart Poettering log_info("Switching to DNS server %s for interface %s.", dns_server_string(s), l->name);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering dns_server_unref(l->current_dns_server);
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering l->current_dns_server = dns_server_ref(s);
2c27fbca2d88214bd305272308a370a962818f1eLennart Poettering
2c27fbca2d88214bd305272308a370a962818f1eLennart Poettering if (l->unicast_scope)
2c27fbca2d88214bd305272308a370a962818f1eLennart Poettering dns_cache_flush(&l->unicast_scope->cache);
2c27fbca2d88214bd305272308a370a962818f1eLennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering return s;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering}
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringDnsServer *link_get_dns_server(Link *l) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!l->current_dns_server)
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering link_set_dns_server(l, l->dns_servers);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return l->current_dns_server;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringvoid link_next_dns_server(Link *l) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!l->current_dns_server)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering /* Change to the next one, but make sure to follow the linked
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering * list only if this server is actually still linked. */
0eac462399c8e87bcce252cf058eba9f2678f2bdLennart Poettering if (l->current_dns_server->linked && l->current_dns_server->servers_next) {
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering link_set_dns_server(l, l->current_dns_server->servers_next);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering link_set_dns_server(l, l->dns_servers);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart PoetteringDnssecMode link_get_dnssec_mode(Link *l) {
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering assert(l);
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering if (l->dnssec_mode != _DNSSEC_MODE_INVALID)
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return l->dnssec_mode;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return manager_get_dnssec_mode(l->manager);
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering}
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poetteringbool link_dnssec_supported(Link *l) {
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering DnsServer *server;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering assert(l);
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering if (link_get_dnssec_mode(l) == DNSSEC_NO)
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return false;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering server = link_get_dns_server(l);
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering if (server)
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return dns_server_dnssec_supported(server);
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering return true;
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering}
c69fa7e3c44240bedc0ee1bd89fecf954783ac85Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringint link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr_union *in_addr) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LinkAddress *a;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(l);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(in_addr);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a = new0(LinkAddress, 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!a)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->family = family;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->in_addr = *in_addr;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering a->link = l;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_PREPEND(addresses, l->addresses, a);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (ret)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering *ret = a;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart PoetteringLinkAddress *link_address_free(LinkAddress *a) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!a)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (a->link) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering LIST_REMOVE(addresses, a->link->addresses, a);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (a->llmnr_address_rr) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (a->llmnr_ptr_rr) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering dns_resource_record_unref(a->llmnr_address_rr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering dns_resource_record_unref(a->llmnr_ptr_rr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering free(a);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poetteringvoid link_address_add_rrs(LinkAddress *a, bool force_remove) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering int r;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering assert(a);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a->family == AF_INET) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering if (!force_remove &&
011696f76233486bc56c266b18a328924f70269cLennart Poettering link_address_relevant(a, true) &&
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering a->link->llmnr_ipv4_scope &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering a->link->llmnr_support == RESOLVE_SUPPORT_YES &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering a->link->manager->llmnr_support == RESOLVE_SUPPORT_YES) {
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!a->link->manager->llmnr_host_ipv4_key) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering a->link->manager->llmnr_host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->llmnr_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!a->link->manager->llmnr_host_ipv4_key) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering r = -ENOMEM;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering goto fail;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!a->llmnr_address_rr) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering a->llmnr_address_rr = dns_resource_record_new(a->link->manager->llmnr_host_ipv4_key);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (!a->llmnr_address_rr) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering r = -ENOMEM;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering goto fail;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a->llmnr_address_rr->a.in_addr = a->in_addr.in;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (!a->llmnr_ptr_rr) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->llmnr_hostname);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (r < 0)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering goto fail;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_address_rr, true);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to add A record to LLMNR zone: %m");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_ptr_rr, false);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to add IPv6 PTR record to LLMNR zone: %m");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering } else {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a->llmnr_address_rr) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a->link->llmnr_ipv4_scope)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a->llmnr_address_rr = dns_resource_record_unref(a->llmnr_address_rr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a->llmnr_ptr_rr) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a->link->llmnr_ipv4_scope)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a->family == AF_INET6) {
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering if (!force_remove &&
011696f76233486bc56c266b18a328924f70269cLennart Poettering link_address_relevant(a, true) &&
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering a->link->llmnr_ipv6_scope &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering a->link->llmnr_support == RESOLVE_SUPPORT_YES &&
af49ca27ffd790d78dbbb465b978266dfd5c93daLennart Poettering a->link->manager->llmnr_support == RESOLVE_SUPPORT_YES) {
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!a->link->manager->llmnr_host_ipv6_key) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering a->link->manager->llmnr_host_ipv6_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, a->link->manager->llmnr_hostname);
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (!a->link->manager->llmnr_host_ipv6_key) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering r = -ENOMEM;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering goto fail;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (!a->llmnr_address_rr) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering a->llmnr_address_rr = dns_resource_record_new(a->link->manager->llmnr_host_ipv6_key);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (!a->llmnr_address_rr) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering r = -ENOMEM;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering goto fail;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a->llmnr_address_rr->aaaa.in6_addr = a->in_addr.in6;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (!a->llmnr_ptr_rr) {
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->llmnr_hostname);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (r < 0)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering goto fail;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering r = dns_zone_put(&a->link->llmnr_ipv6_scope->zone, a->link->llmnr_ipv6_scope, a->llmnr_address_rr, true);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to add AAAA record to LLMNR zone: %m");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering r = dns_zone_put(&a->link->llmnr_ipv6_scope->zone, a->link->llmnr_ipv6_scope, a->llmnr_ptr_rr, false);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_warning_errno(r, "Failed to add IPv6 PTR record to LLMNR zone: %m");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering } else {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a->llmnr_address_rr) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a->link->llmnr_ipv6_scope)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a->llmnr_address_rr = dns_resource_record_unref(a->llmnr_address_rr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a->llmnr_ptr_rr) {
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (a->link->llmnr_ipv6_scope)
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering }
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering return;
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poetteringfail:
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_debug_errno(r, "Failed to update address RRs: %m");
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
1c4baffc1895809bae9ac36b670af90a4cb9cd7dTom Gundersenint link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(a);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_rtnl_message_addr_get_flags(m, &a->flags);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering sd_rtnl_message_addr_get_scope(m, &a->scope);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering link_allocate_scopes(a->link);
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering link_add_rrs(a->link, false);
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
011696f76233486bc56c266b18a328924f70269cLennart Poetteringbool link_address_relevant(LinkAddress *a, bool local_multicast) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(a);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
7b85d72f824cdf34554b349712b6b8e39095dbd4Lennart Poettering if (a->flags & (IFA_F_DEPRECATED|IFA_F_TENTATIVE))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
011696f76233486bc56c266b18a328924f70269cLennart Poettering if (a->scope >= (local_multicast ? RT_SCOPE_HOST : RT_SCOPE_LINK))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return true;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}