resolved-link.c revision 0eac462399c8e87bcce252cf058eba9f2678f2bd
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 "alloc-util.h"
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering#include "missing.h"
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering#include "parse-util.h"
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering#include "resolved-link.h"
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering#include "string-util.h"
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering#include "strv.h"
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringint link_new(Manager *m, Link **ret, int ifindex) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering _cleanup_(link_freep) Link *l = NULL;
a09abc4ae0bdc0200324eaa0416f23ff2170ec4eLennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering assert(m);
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering assert(ifindex > 0);
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering r = hashmap_ensure_allocated(&m->links, NULL);
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering if (r < 0)
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering return r;
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering l = new0(Link, 1);
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering if (!l)
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering return -ENOMEM;
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering l->ifindex = ifindex;
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart 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;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart 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)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return NULL;
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering link_flush_dns_servers(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering while (l->addresses)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_address_free(l->addresses);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (l->manager)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering hashmap_remove(l->manager->links, INT_TO_PTR(l->ifindex));
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering dns_scope_free(l->unicast_scope);
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering dns_scope_free(l->llmnr_ipv4_scope);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering dns_scope_free(l->llmnr_ipv6_scope);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering free(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return NULL;
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic void link_allocate_scopes(Link *l) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(l);
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (l->dns_servers) {
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (!l->unicast_scope) {
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering r = dns_scope_new(l->manager, &l->unicast_scope, l, DNS_PROTOCOL_DNS, AF_UNSPEC);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (r < 0)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering log_warning_errno(r, "Failed to allocate DNS scope: %m");
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering }
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen } else
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen l->unicast_scope = dns_scope_free(l->unicast_scope);
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (link_relevant(l, AF_INET) &&
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering l->llmnr_support != SUPPORT_NO &&
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering l->manager->llmnr_support != SUPPORT_NO) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (!l->llmnr_ipv4_scope) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = dns_scope_new(l->manager, &l->llmnr_ipv4_scope, l, DNS_PROTOCOL_LLMNR, AF_INET);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_warning_errno(r, "Failed to allocate LLMNR IPv4 scope: %m");
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering } else
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering l->llmnr_ipv4_scope = dns_scope_free(l->llmnr_ipv4_scope);
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (link_relevant(l, AF_INET6) &&
d0bbc21caa6e68693a47db60c93e99422bf2a858Lennart Poettering l->llmnr_support != SUPPORT_NO &&
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering l->manager->llmnr_support != SUPPORT_NO &&
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering socket_ipv6_is_supported()) {
44b601bc79e46722bc0f0862ee0ce34a2284ef11Lennart Poettering if (!l->llmnr_ipv6_scope) {
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering r = dns_scope_new(l->manager, &l->llmnr_ipv6_scope, l, DNS_PROTOCOL_LLMNR, AF_INET6);
25d042e81516246b1ebf706a57c47ac19abb0b8aLennart Poettering if (r < 0)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering log_warning_errno(r, "Failed to allocate LLMNR IPv6 scope: %m");
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering } else
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering l->llmnr_ipv6_scope = dns_scope_free(l->llmnr_ipv6_scope);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering}
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringvoid link_add_rrs(Link *l, bool force_remove) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering LinkAddress *a;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering LIST_FOREACH(addresses, a, l->addresses)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering link_address_add_rrs(a, force_remove);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering}
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
25d042e81516246b1ebf706a57c47ac19abb0b8aLennart 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);
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart 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
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering sd_netlink_message_read_u32(m, IFLA_MTU, &l->mtu);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (sd_netlink_message_read_string(m, IFLA_IFNAME, &n) >= 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering strncpy(l->name, n, sizeof(l->name)-1);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering char_array_0(l->name);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering link_allocate_scopes(l);
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering link_add_rrs(l, false);
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poetteringstatic int link_update_dns_servers(Link *l) {
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering _cleanup_strv_free_ char **nameservers = NULL;
72f1d5a2880d103dc1c1746f5c02e192e054705eLennart Poettering char **nameserver;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = sd_network_link_get_dns(l->ifindex, &nameservers);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto clear;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering link_mark_dns_servers(l);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering STRV_FOREACH(nameserver, nameservers) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering union in_addr_union a;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering DnsServer *s;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering int family;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = in_addr_from_string_auto(*nameserver, &family, &a);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto clear;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering s = link_find_dns_server(l, family, &a);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (s)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering s->marked = false;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering else {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = dns_server_new(l->manager, NULL, DNS_SERVER_LINK, l, family, &a);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering goto clear;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering }
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering link_flush_marked_dns_servers(l);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return 0;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringclear:
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_flush_dns_servers(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return r;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringstatic int link_update_llmnr_support(Link *l) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering _cleanup_free_ char *b = NULL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int r;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering r = sd_network_link_get_llmnr(l->ifindex, &b);
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering if (r < 0)
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering goto clear;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek r = parse_boolean(b);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (r < 0) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (streq(b, "resolve"))
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering l->llmnr_support = SUPPORT_RESOLVE;
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek else
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek goto clear;
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek } else if (r > 0)
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek l->llmnr_support = SUPPORT_YES;
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek else
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek l->llmnr_support = SUPPORT_NO;
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return 0;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poetteringclear:
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering l->llmnr_support = SUPPORT_YES;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return r;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering}
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poetteringstatic int link_update_domains(Link *l) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering int r;
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen if (!l->unicast_scope)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return 0;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart 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)
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering return r;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering
a5344d2c3b0f14e954ce1c0ef905c5b44bc5bf0aLennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poetteringint link_update_monitor(Link *l) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(l);
29abad107f8610e73b2fc091216040b579c75453Zbigniew Jędrzejewski-Szmek
29abad107f8610e73b2fc091216040b579c75453Zbigniew Jędrzejewski-Szmek link_update_dns_servers(l);
2a0e0692565f0435657c93498e09cbb2d3517152Shawn Landden link_update_llmnr_support(l);
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering link_allocate_scopes(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_update_domains(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering link_add_rrs(l, false);
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering return 0;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringbool link_relevant(Link *l, int family) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering _cleanup_free_ char *state = NULL;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering LinkAddress *a;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering assert(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart 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))
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return false;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering sd_network_link_get_operational_state(l->ifindex, &state);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (state && !STR_IN_SET(state, "unknown", "degraded", "routable"))
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return false;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering LIST_FOREACH(addresses, a, l->addresses)
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering if (a->family == family && link_address_relevant(a))
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return true;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering return false;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart PoetteringLinkAddress *link_find_address(Link *l, int family, const union in_addr_union *in_addr) {
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering LinkAddress *a;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering assert(l);
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering LIST_FOREACH(addresses, a, l->addresses)
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering if (a->family == family && in_addr_equal(family, &a->in_addr, in_addr))
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering return a;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering return NULL;
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering}
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poetteringvoid link_flush_dns_servers(Link *l) {
ee55db41442ad8055f5a84a339b1e0e22bc037c4Lennart Poettering assert(l);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering while (l->dns_servers)
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering dns_server_unlink(l->dns_servers);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poetteringvoid link_flush_marked_dns_servers(Link *l) {
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering DnsServer *s, *next;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering assert(l);
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering LIST_FOREACH_SAFE(servers, s, next, l->dns_servers) {
6c045c0b4c49c88a1d3b9360c05efa5084796d2dZbigniew Jędrzejewski-Szmek if (!s->marked)
6c045c0b4c49c88a1d3b9360c05efa5084796d2dZbigniew Jędrzejewski-Szmek continue;
6c045c0b4c49c88a1d3b9360c05efa5084796d2dZbigniew Jędrzejewski-Szmek
6c045c0b4c49c88a1d3b9360c05efa5084796d2dZbigniew Jędrzejewski-Szmek dns_server_unlink(s);
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering }
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering}
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poetteringvoid link_mark_dns_servers(Link *l) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering DnsServer *s;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
8e33886ec582336564ae11b80023abe93d7599c0Zbigniew Jędrzejewski-Szmek assert(l);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering LIST_FOREACH(servers, s, l->dns_servers)
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering s->marked = true;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering}
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart PoetteringDnsServer* link_find_dns_server(Link *l, int family, const union in_addr_union *in_addr) {
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering DnsServer *s;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering assert(l);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering assert(in_addr);
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering LIST_FOREACH(servers, s, l->dns_servers)
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (s->family == family && in_addr_equal(family, &s->address, in_addr))
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering return s;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering return NULL;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering}
87b0284327e34a4b96c22085fa2cdb3219294991Zbigniew Jędrzejewski-Szmek
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-SzmekDnsServer* link_set_dns_server(Link *l, DnsServer *s) {
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering assert(l);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering if (l->current_dns_server == s)
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering return s;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering
73843b52585d42cc1a970a1c664818ece6942e9eLennart Poettering if (s) {
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart Poettering _cleanup_free_ char *ip = NULL;
c79e98eadd3056a36a662699fa650db5b1bca0c3Lennart 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 dns_server_unref(l->current_dns_server);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering l->current_dns_server = dns_server_ref(s);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering if (l->unicast_scope)
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering dns_cache_flush(&l->unicast_scope->cache);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering return s;
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering}
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
0dad12c190b7493955cd60d2a1625199b1709f69Lennart PoetteringDnsServer *link_get_dns_server(Link *l) {
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering assert(l);
0dad12c190b7493955cd60d2a1625199b1709f69Lennart Poettering
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering if (!l->current_dns_server)
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering link_set_dns_server(l, l->dns_servers);
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering return l->current_dns_server;
7f3e62571a63ac90de6ac5eefeeb8d3e9aa6f49eLennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poetteringvoid link_next_dns_server(Link *l) {
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering assert(l);
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (!l->current_dns_server)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering /* Change to the next one, but make sure to follow the linked
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering * list only if this server is actually still linked. */
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (l->current_dns_server->linked && l->current_dns_server->servers_next) {
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering link_set_dns_server(l, l->current_dns_server->servers_next);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering }
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering link_set_dns_server(l, l->dns_servers);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering}
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poetteringint link_address_new(Link *l, LinkAddress **ret, int family, const union in_addr_union *in_addr) {
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering LinkAddress *a;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering assert(l);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering assert(in_addr);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering a = new0(LinkAddress, 1);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (!a)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return -ENOMEM;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering a->family = family;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering a->in_addr = *in_addr;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering a->link = l;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering LIST_PREPEND(addresses, l->addresses, a);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (ret)
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering *ret = a;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return 0;
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering}
5c0aa72a4999bdcf03fe93ed5c8213c2b4c681f0Lennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart PoetteringLinkAddress *link_address_free(LinkAddress *a) {
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (!a)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return NULL;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (a->link) {
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering LIST_REMOVE(addresses, a->link->addresses, a);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (a->llmnr_address_rr) {
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_address_rr);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering else if (a->family == AF_INET6 && a->link->llmnr_ipv6_scope)
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_address_rr);
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek }
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek if (a->llmnr_ptr_rr) {
6e5abe1564070a760196b97031eca9cf5e95e8a2Zbigniew Jędrzejewski-Szmek if (a->family == AF_INET && a->link->llmnr_ipv4_scope)
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek 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);
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen dns_resource_record_unref(a->llmnr_address_rr);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering dns_resource_record_unref(a->llmnr_ptr_rr);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering free(a);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering return NULL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering}
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmekvoid link_address_add_rrs(LinkAddress *a, bool force_remove) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering int r;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek assert(a);
86b9b8e70d54e79db3ff4f67bbd5280ecfc82537Lennart Poettering
86b9b8e70d54e79db3ff4f67bbd5280ecfc82537Lennart Poettering if (a->family == AF_INET) {
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering
bb99a35a873c35e80b0b47fe045081022660374dLennart Poettering if (!force_remove &&
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering link_address_relevant(a) &&
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering a->link->llmnr_ipv4_scope &&
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering a->link->llmnr_support == SUPPORT_YES &&
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering a->link->manager->llmnr_support == SUPPORT_YES) {
8b38f3cc3eb73adf9536cb73d0f319e60d42ea0cLennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!a->link->manager->llmnr_host_ipv4_key) {
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering a->link->manager->llmnr_host_ipv4_key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, a->link->manager->llmnr_hostname);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!a->link->manager->llmnr_host_ipv4_key) {
a6e87e90ede66815989ba2db92a07102a69906feLennart Poettering r = -ENOMEM;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering goto fail;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering }
4cd9a9d9ecf3a8835e21930f3215a5f5b74144beLennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (!a->llmnr_address_rr) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering a->llmnr_address_rr = dns_resource_record_new(a->link->manager->llmnr_host_ipv4_key);
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering if (!a->llmnr_address_rr) {
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering r = -ENOMEM;
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering goto fail;
224f2ee221e77c326d1d7761abb6e812432b2163Lennart Poettering }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek a->llmnr_address_rr->a.in_addr = a->in_addr.in;
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek a->llmnr_address_rr->ttl = LLMNR_DEFAULT_TTL;
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek }
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek if (!a->llmnr_ptr_rr) {
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering r = dns_resource_record_new_reverse(&a->llmnr_ptr_rr, a->family, &a->in_addr, a->link->manager->llmnr_hostname);
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart Poettering if (r < 0)
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek goto fail;
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek
61c024b328d5493a334242a4d01ba923582093faZbigniew Jędrzejewski-Szmek a->llmnr_ptr_rr->ttl = LLMNR_DEFAULT_TTL;
fe6521272ba203ec8f0d5a94f0729960b3f90525Lennart 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)
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen dns_zone_remove_rr(&a->link->llmnr_ipv4_scope->zone, a->llmnr_ptr_rr);
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen }
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
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart 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
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart 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)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv6_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_ipv6_scope)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering dns_zone_remove_rr(&a->link->llmnr_ipv6_scope->zone, a->llmnr_ptr_rr);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering a->llmnr_ptr_rr = dns_resource_record_unref(a->llmnr_ptr_rr);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering }
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering }
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering }
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringfail:
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen log_debug_errno(r, "Failed to update address RRs: %m");
1ae464e09376853c52075ec4d8a6bfc4b4036d0cThomas Hindoe Paaboel Andersen}
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poetteringint link_address_update_rtnl(LinkAddress *a, sd_netlink_message *m) {
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering int r;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering assert(a);
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering assert(m);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering r = sd_rtnl_message_addr_get_flags(m, &a->flags);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering if (r < 0)
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering return r;
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering sd_rtnl_message_addr_get_scope(m, &a->scope);
b070e7f3c9ed680c821bd89d42506695f2438506Lennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering link_allocate_scopes(a->link);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering link_add_rrs(a->link, false);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return 0;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering}
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poetteringbool link_address_relevant(LinkAddress *a) {
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering assert(a);
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
3ed08c446cfaaae2b234fdfeb0c34ab6b4748c3eLennart Poettering if (a->flags & (IFA_F_DEPRECATED|IFA_F_TENTATIVE))
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return false;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering if (IN_SET(a->scope, RT_SCOPE_HOST, RT_SCOPE_NOWHERE))
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return false;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering return true;
18c7ed186be28800a2eeb37ad31c9c44480d3d9cLennart Poettering}