resolved-link.c revision 07630cea1f3a845c09309f197ac7c4f11edd3b62
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering/***
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering This file is part of systemd.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering Copyright 2014 Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering systemd is free software; you can redistribute it and/or modify it
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering under the terms of the GNU Lesser General Public License as published by
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering (at your option) any later version.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering systemd is distributed in the hope that it will be useful, but
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering Lesser General Public License for more details.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering You should have received a copy of the GNU Lesser General Public License
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering***/
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include <net/if.h>
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include "sd-network.h"
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering#include "missing.h"
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering#include "resolved-link.h"
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include "string-util.h"
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering#include "strv.h"
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringint link_new(Manager *m, Link **ret, int ifindex) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering _cleanup_(link_freep) Link *l = NULL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering assert(m);
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering assert(ifindex > 0);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = hashmap_ensure_allocated(&m->links, NULL);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = new0(Link, 1);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!l)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return -ENOMEM;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l->ifindex = ifindex;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l->llmnr_support = SUPPORT_YES;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = hashmap_put(m->links, INT_TO_PTR(ifindex), l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l->manager = m;
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering if (ret)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering *ret = l;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l = NULL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart PoetteringLink *link_free(Link *l) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!l)
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering return NULL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering while (l->addresses)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_address_free(l->addresses);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering if (l->manager)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering while (l->dns_servers) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering DnsServer *s = l->dns_servers;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering LIST_REMOVE(servers, l->dns_servers, s);
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering dns_server_unref(s);
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering }
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering dns_scope_free(l->unicast_scope);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering dns_scope_free(l->llmnr_ipv4_scope);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering dns_scope_free(l->llmnr_ipv6_scope);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering free(l);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return NULL;
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering}
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic void link_allocate_scopes(Link *l) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (l->dns_servers) {
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering if (!l->unicast_scope) {
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering r = dns_scope_new(l->manager, &l->unicast_scope, l, DNS_PROTOCOL_DNS, AF_UNSPEC);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering log_warning_errno(r, "Failed to allocate DNS scope: %m");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering } else
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering l->unicast_scope = dns_scope_free(l->unicast_scope);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (link_relevant(l, AF_INET) &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering l->llmnr_support != SUPPORT_NO &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering l->manager->llmnr_support != SUPPORT_NO) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!l->llmnr_ipv4_scope) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = dns_scope_new(l->manager, &l->llmnr_ipv4_scope, l, DNS_PROTOCOL_LLMNR, AF_INET);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering log_warning_errno(r, "Failed to allocate LLMNR IPv4 scope: %m");
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering } else
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering l->llmnr_ipv4_scope = dns_scope_free(l->llmnr_ipv4_scope);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (link_relevant(l, AF_INET6) &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering l->llmnr_support != SUPPORT_NO &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering l->manager->llmnr_support != SUPPORT_NO &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering socket_ipv6_is_supported()) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!l->llmnr_ipv6_scope) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = dns_scope_new(l->manager, &l->llmnr_ipv6_scope, l, DNS_PROTOCOL_LLMNR, AF_INET6);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_warning_errno(r, "Failed to allocate LLMNR IPv6 scope: %m");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering } else
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l->llmnr_ipv6_scope = dns_scope_free(l->llmnr_ipv6_scope);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringvoid link_add_rrs(Link *l, bool force_remove) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering LinkAddress *a;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering LIST_FOREACH(addresses, a, l->addresses)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_address_add_rrs(a, force_remove);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringint link_update_rtnl(Link *l, sd_netlink_message *m) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering const char *n = NULL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(m);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = sd_rtnl_message_link_get_flags(m, &l->flags);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering sd_netlink_message_read_u32(m, IFLA_MTU, &l->mtu);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (sd_netlink_message_read_string(m, IFLA_IFNAME, &n) >= 0) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering strncpy(l->name, n, sizeof(l->name)-1);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering char_array_0(l->name);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering link_allocate_scopes(l);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering link_add_rrs(l, false);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return 0;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering}
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringstatic int link_update_dns_servers(Link *l) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering _cleanup_strv_free_ char **nameservers = NULL;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering char **nameserver;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering DnsServer *s, *nx;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering int r;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering assert(l);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = sd_network_link_get_dns(l->ifindex, &nameservers);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering goto clear;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering LIST_FOREACH(servers, s, l->dns_servers)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering s->marked = true;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering STRV_FOREACH(nameserver, nameservers) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering union in_addr_union a;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int family;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = in_addr_from_string_auto(*nameserver, &family, &a);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering goto clear;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering s = link_find_dns_server(l, family, &a);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (s)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering s->marked = false;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering else {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a);
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering if (r < 0)
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering goto clear;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering LIST_FOREACH_SAFE(servers, s, nx, l->dns_servers)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (s->marked) {
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering LIST_REMOVE(servers, l->dns_servers, s);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering dns_server_unref(s);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering }
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return 0;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poetteringclear:
9058851be7821edac08c1fa7ecafe5cba9ab9022Lennart Poettering while (l->dns_servers) {
9058851be7821edac08c1fa7ecafe5cba9ab9022Lennart Poettering s = l->dns_servers;
9058851be7821edac08c1fa7ecafe5cba9ab9022Lennart Poettering
9058851be7821edac08c1fa7ecafe5cba9ab9022Lennart Poettering LIST_REMOVE(servers, l->dns_servers, s);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering dns_server_unref(s);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return r;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic int link_update_llmnr_support(Link *l) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering _cleanup_free_ char *b = NULL;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = sd_network_link_get_llmnr(l->ifindex, &b);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering goto clear;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = parse_boolean(b);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (streq(b, "resolve"))
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering l->llmnr_support = SUPPORT_RESOLVE;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering else
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto clear;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering } else if (r > 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering l->llmnr_support = SUPPORT_YES;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering else
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l->llmnr_support = SUPPORT_NO;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return 0;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringclear:
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering l->llmnr_support = SUPPORT_YES;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic int link_update_domains(Link *l) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!l->unicast_scope)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l->unicast_scope->domains = strv_free(l->unicast_scope->domains);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = sd_network_link_get_domains(l->ifindex,
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering &l->unicast_scope->domains);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringint link_update_monitor(Link *l) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_update_dns_servers(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_update_llmnr_support(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_allocate_scopes(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_update_domains(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_add_rrs(l, false);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringbool link_relevant(Link *l, int family) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering _cleanup_free_ char *state = NULL;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering LinkAddress *a;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
5ba081b0fb02380cee4c2ff5bc7e05f869eb8415Lennart Poettering /* A link is relevant if it isn't a loopback or pointopoint
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * device, has a link beat, can do multicast and has at least
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering * one relevant IP address */
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (l->flags & (IFF_LOOPBACK|IFF_POINTOPOINT|IFF_DORMANT))
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return false;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if ((l->flags & (IFF_UP|IFF_LOWER_UP|IFF_MULTICAST)) != (IFF_UP|IFF_LOWER_UP|IFF_MULTICAST))
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return false;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering sd_network_link_get_operational_state(l->ifindex, &state);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (state && !STR_IN_SET(state, "unknown", "degraded", "routable"))
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return false;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering LIST_FOREACH(addresses, a, l->addresses)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (a->family == family && link_address_relevant(a))
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return true;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return false;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering}
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart PoetteringLinkAddress *link_find_address(Link *l, int family, const union in_addr_union *in_addr) {
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering LinkAddress *a;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering assert(l);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering LIST_FOREACH(addresses, a, l->addresses)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (a->family == family && in_addr_equal(family, &a->in_addr, in_addr))
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return a;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return NULL;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering}
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart PoetteringDnsServer* link_find_dns_server(Link *l, int family, const union in_addr_union *in_addr) {
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering DnsServer *s;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering assert(l);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering LIST_FOREACH(servers, s, l->dns_servers)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (s->family == family && in_addr_equal(family, &s->address, in_addr))
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return s;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return NULL;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering}
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart PoetteringDnsServer* link_set_dns_server(Link *l, DnsServer *s) {
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering assert(l);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering if (l->current_dns_server == s)
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return s;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering if (s) {
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering _cleanup_free_ char *ip = NULL;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering in_addr_to_string(s->family, &s->address, &ip);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering log_info("Switching to DNS server %s for interface %s.", strna(ip), l->name);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering }
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering l->current_dns_server = s;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering if (l->unicast_scope)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering dns_cache_flush(&l->unicast_scope->cache);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return s;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering}
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart PoetteringDnsServer *link_get_dns_server(Link *l) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering assert(l);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!l->current_dns_server)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_set_dns_server(l, l->dns_servers);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return l->current_dns_server;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringvoid link_next_dns_server(Link *l) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(l);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!l->current_dns_server)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (l->current_dns_server->servers_next) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering link_set_dns_server(l, l->current_dns_server->servers_next);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering link_set_dns_server(l, l->dns_servers);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poetteringint link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr_union *in_addr) {
259d2e762041d8d50c2a17bfea90b1a96f6b880bLennart Poettering LinkAddress *a;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(l);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering assert(in_addr);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering a = new0(LinkAddress, 1);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!a)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return -ENOMEM;
86b9b8e70d54e79db3ff4f67bbd5280ecfc82537Lennart Poettering
86b9b8e70d54e79db3ff4f67bbd5280ecfc82537Lennart Poettering a->family = family;
86b9b8e70d54e79db3ff4f67bbd5280ecfc82537Lennart Poettering a->in_addr = *in_addr;
86b9b8e70d54e79db3ff4f67bbd5280ecfc82537Lennart Poettering
86b9b8e70d54e79db3ff4f67bbd5280ecfc82537Lennart Poettering a->link = l;
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering LIST_PREPEND(addresses, l->addresses, a);
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering if (ret)
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering *ret = a;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering return 0;
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart PoetteringLinkAddress *link_address_free(LinkAddress *a) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!a)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return NULL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering if (a->link) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering LIST_REMOVE(addresses, a->link->addresses, a);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (a->llmnr_address_rr) {
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (a->llmnr_ptr_rr) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering dns_resource_record_unref(a->llmnr_address_rr);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering dns_resource_record_unref(a->llmnr_ptr_rr);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering free(a);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return NULL;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering}
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringvoid link_address_add_rrs(LinkAddress *a, bool force_remove) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering int r;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering assert(a);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (a->family == AF_INET) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!force_remove &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering link_address_relevant(a) &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->link->llmnr_ipv4_scope &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->link->llmnr_support == SUPPORT_YES &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->link->manager->llmnr_support == SUPPORT_YES) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!a->link->manager->llmnr_host_ipv4_key) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->link->manager->llmnr_host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->llmnr_hostname);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!a->link->manager->llmnr_host_ipv4_key) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = -ENOMEM;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto fail;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!a->llmnr_address_rr) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->llmnr_address_rr = dns_resource_record_new(a->link->manager->llmnr_host_ipv4_key);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!a->llmnr_address_rr) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = -ENOMEM;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto fail;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->llmnr_address_rr->a.in_addr = a->in_addr.in;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!a->llmnr_ptr_rr) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->llmnr_hostname);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto fail;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_address_rr, true);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering log_warning_errno(r, "Failed to add A record to LLMNR zone: %m");
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = dns_zone_put(&a->link->llmnr_ipv4_scope->zone, a->link->llmnr_ipv4_scope, a->llmnr_ptr_rr, false);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering log_warning_errno(r, "Failed to add IPv6 PTR record to LLMNR zone: %m");
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering } else {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (a->llmnr_address_rr) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (a->link->llmnr_ipv4_scope)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->llmnr_address_rr = dns_resource_record_unref(a->llmnr_address_rr);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (a->llmnr_ptr_rr) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (a->link->llmnr_ipv4_scope)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (a->family == AF_INET6) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!force_remove &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering link_address_relevant(a) &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->link->llmnr_ipv6_scope &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->link->llmnr_support == SUPPORT_YES &&
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->link->manager->llmnr_support == SUPPORT_YES) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!a->link->manager->llmnr_host_ipv6_key) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->link->manager->llmnr_host_ipv6_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, a->link->manager->llmnr_hostname);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!a->link->manager->llmnr_host_ipv6_key) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = -ENOMEM;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto fail;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!a->llmnr_address_rr) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->llmnr_address_rr = dns_resource_record_new(a->link->manager->llmnr_host_ipv6_key);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!a->llmnr_address_rr) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = -ENOMEM;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto fail;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->llmnr_address_rr->aaaa.in6_addr = a->in_addr.in6;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (!a->llmnr_ptr_rr) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->llmnr_hostname);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto fail;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = dns_zone_put(&a->link->llmnr_ipv6_scope->zone, a->link->llmnr_ipv6_scope, a->llmnr_address_rr, true);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering log_warning_errno(r, "Failed to add AAAA record to LLMNR zone: %m");
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = dns_zone_put(&a->link->llmnr_ipv6_scope->zone, a->link->llmnr_ipv6_scope, a->llmnr_ptr_rr, false);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering log_warning_errno(r, "Failed to add IPv6 PTR record to LLMNR zone: %m");
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering } else {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (a->llmnr_address_rr) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (a->link->llmnr_ipv6_scope)
dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
a->llmnr_address_rr = dns_resource_record_unref(a->llmnr_address_rr);
}
if (a->llmnr_ptr_rr) {
if (a->link->llmnr_ipv6_scope)
dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
}
}
}
return;
fail:
log_debug_errno(r, "Failed to update address RRs: %m");
}
int link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m) {
int r;
assert(a);
assert(m);
r = sd_rtnl_message_addr_get_flags(m, &a->flags);
if (r < 0)
return r;
sd_rtnl_message_addr_get_scope(m, &a->scope);
link_allocate_scopes(a->link);
link_add_rrs(a->link, false);
return 0;
}
bool link_address_relevant(LinkAddress *a) {
assert(a);
if (a->flags & (IFA_F_DEPRECATED|IFA_F_TENTATIVE))
return false;
if (IN_SET(a->scope, RT_SCOPE_HOST, RT_SCOPE_NOWHERE))
return false;
return true;
}