networkd: Automatically set DNS and search domain information
When EmitDNS or EmitDomains is set, automatically look up values for Router Advertisement DNS and DNS search domain options starting with the values in the IPv6PrefixDelegationsection, if any. If none are found, use the values set for the network, and as a last resort try with the preferred upstream network. The default DNS lifetime and therefore Router Advertisement interval is added to the public sd_radv.h header as the DNS lifetime depends on the maximum advertisement interval.
This commit is contained in:
parent
9e25315caa
commit
c555a358ce
|
@ -25,8 +25,6 @@
|
|||
#include "list.h"
|
||||
#include "sparse-endian.h"
|
||||
|
||||
#define SD_RADV_DEFAULT_MIN_TIMEOUT_USEC (200*USEC_PER_SEC)
|
||||
#define SD_RADV_DEFAULT_MAX_TIMEOUT_USEC (600*USEC_PER_SEC)
|
||||
assert_cc(SD_RADV_DEFAULT_MIN_TIMEOUT_USEC <= SD_RADV_DEFAULT_MAX_TIMEOUT_USEC)
|
||||
|
||||
#define SD_RADV_MAX_INITIAL_RTR_ADVERT_INTERVAL_USEC (16*USEC_PER_SEC)
|
||||
|
|
|
@ -21,9 +21,140 @@
|
|||
#include <arpa/inet.h>
|
||||
|
||||
#include "networkd-address.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-radv.h"
|
||||
#include "sd-radv.h"
|
||||
|
||||
static int radv_get_ip6dns(Network *network, struct in6_addr **dns,
|
||||
size_t *n_dns) {
|
||||
_cleanup_free_ struct in6_addr *addresses = NULL;
|
||||
size_t i, n_addresses = 0, n_allocated = 0;
|
||||
|
||||
assert(network);
|
||||
assert(dns);
|
||||
assert(n_dns);
|
||||
|
||||
for (i = 0; i < network->n_dns; i++) {
|
||||
union in_addr_union *addr;
|
||||
|
||||
if (network->dns[i].family != AF_INET6)
|
||||
continue;
|
||||
|
||||
addr = &network->dns[i].address;
|
||||
|
||||
if (in_addr_is_null(AF_INET6, addr) ||
|
||||
in_addr_is_link_local(AF_INET6, addr) ||
|
||||
in_addr_is_localhost(AF_INET6, addr))
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(addresses, n_allocated, n_addresses + 1))
|
||||
return -ENOMEM;
|
||||
|
||||
addresses[n_addresses++] = addr->in6;
|
||||
}
|
||||
|
||||
if (addresses) {
|
||||
*dns = addresses;
|
||||
addresses = NULL;
|
||||
|
||||
*n_dns = n_addresses;
|
||||
}
|
||||
|
||||
return n_addresses;
|
||||
}
|
||||
|
||||
static int radv_set_dns(Link *link, Link *uplink) {
|
||||
_cleanup_free_ struct in6_addr *dns = NULL;
|
||||
size_t n_dns;
|
||||
usec_t lifetime_usec;
|
||||
int r;
|
||||
|
||||
if (!link->network->router_emit_dns)
|
||||
return 0;
|
||||
|
||||
if (link->network->router_dns) {
|
||||
dns = newdup(struct in6_addr, link->network->router_dns,
|
||||
link->network->n_router_dns);
|
||||
if (dns == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
n_dns = link->network->n_router_dns;
|
||||
lifetime_usec = link->network->router_dns_lifetime_usec;
|
||||
|
||||
goto set_dns;
|
||||
}
|
||||
|
||||
lifetime_usec = SD_RADV_DEFAULT_DNS_LIFETIME_USEC;
|
||||
|
||||
r = radv_get_ip6dns(link->network, &dns, &n_dns);
|
||||
if (r > 0)
|
||||
goto set_dns;
|
||||
|
||||
if (uplink) {
|
||||
r = radv_get_ip6dns(uplink->network, &dns, &n_dns);
|
||||
if (r > 0)
|
||||
goto set_dns;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
set_dns:
|
||||
return sd_radv_set_rdnss(link->radv,
|
||||
DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
|
||||
dns, n_dns);
|
||||
}
|
||||
|
||||
static int radv_set_domains(Link *link, Link *uplink) {
|
||||
char **search_domains;
|
||||
usec_t lifetime_usec;
|
||||
|
||||
if (!link->network->router_emit_domains)
|
||||
return 0;
|
||||
|
||||
search_domains = link->network->router_search_domains;
|
||||
lifetime_usec = link->network->router_dns_lifetime_usec;
|
||||
|
||||
if (search_domains)
|
||||
goto set_domains;
|
||||
|
||||
lifetime_usec = SD_RADV_DEFAULT_DNS_LIFETIME_USEC;
|
||||
|
||||
search_domains = link->network->search_domains;
|
||||
if (search_domains)
|
||||
goto set_domains;
|
||||
|
||||
if (uplink) {
|
||||
search_domains = uplink->network->search_domains;
|
||||
if (search_domains)
|
||||
goto set_domains;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
set_domains:
|
||||
return sd_radv_set_dnssl(link->radv,
|
||||
DIV_ROUND_UP(lifetime_usec, USEC_PER_SEC),
|
||||
search_domains);
|
||||
|
||||
}
|
||||
|
||||
int radv_emit_dns(Link *link) {
|
||||
Link *uplink;
|
||||
int r;
|
||||
|
||||
uplink = manager_find_uplink(link->manager, link);
|
||||
|
||||
r = radv_set_dns(link, uplink);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Could not set RA DNS: %m");
|
||||
|
||||
r = radv_set_domains(link, uplink);
|
||||
if (r < 0)
|
||||
log_link_warning_errno(link, r, "Could not set RA Domains: %m");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int radv_configure(Link *link) {
|
||||
int r;
|
||||
Prefix *p;
|
||||
|
@ -75,24 +206,5 @@ int radv_configure(Link *link) {
|
|||
return r;
|
||||
}
|
||||
|
||||
if (link->network->router_dns) {
|
||||
r = sd_radv_set_rdnss(link->radv,
|
||||
DIV_ROUND_UP(link->network->router_dns_lifetime_usec,
|
||||
USEC_PER_SEC),
|
||||
link->network->router_dns,
|
||||
link->network->n_router_dns);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (link->network->router_search_domains) {
|
||||
r = sd_radv_set_dnssl(link->radv,
|
||||
DIV_ROUND_UP(link->network->router_dns_lifetime_usec,
|
||||
USEC_PER_SEC),
|
||||
link->network->router_search_domains);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return radv_emit_dns(link);
|
||||
}
|
||||
|
|
|
@ -21,4 +21,5 @@
|
|||
|
||||
#include "networkd-link.h"
|
||||
|
||||
int radv_emit_dns(Link *link);
|
||||
int radv_configure(Link *link);
|
||||
|
|
|
@ -33,6 +33,11 @@
|
|||
|
||||
_SD_BEGIN_DECLARATIONS;
|
||||
|
||||
#define SD_RADV_DEFAULT_MIN_TIMEOUT_USEC (200*USEC_PER_SEC)
|
||||
#define SD_RADV_DEFAULT_MAX_TIMEOUT_USEC (600*USEC_PER_SEC)
|
||||
|
||||
#define SD_RADV_DEFAULT_DNS_LIFETIME_USEC (3*SD_RADV_DEFAULT_MAX_TIMEOUT_USEC)
|
||||
|
||||
typedef struct sd_radv sd_radv;
|
||||
typedef struct sd_radv_prefix sd_radv_prefix;
|
||||
|
||||
|
|
Loading…
Reference in a new issue