diff options
author | Lennart Poettering <lennart@poettering.net> | 2017-10-23 18:39:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-10-23 18:39:07 +0200 |
commit | d3aa0a1c4265aa48c6565c34eb7aa2b7bb255be7 (patch) | |
tree | 092e78cc5d74f7986cdf65b5a58109cd55a75a74 | |
parent | hwdb: invert the USB touchpad integration assumption (#7161) (diff) | |
parent | man: Add EmitDNS= and EmitDomains= to the IPv6PrefixDelegation section (diff) | |
download | systemd-d3aa0a1c4265aa48c6565c34eb7aa2b7bb255be7.tar.xz systemd-d3aa0a1c4265aa48c6565c34eb7aa2b7bb255be7.zip |
Merge pull request #6948 from pfl/radv_emit_dns
Add EmitDNS= and EmitDomains= network file configuration options
-rw-r--r-- | man/systemd.network.xml | 27 | ||||
-rw-r--r-- | src/libsystemd-network/radv-internal.h | 2 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 2 | ||||
-rw-r--r-- | src/network/networkd-network.c | 3 | ||||
-rw-r--r-- | src/network/networkd-network.h | 2 | ||||
-rw-r--r-- | src/network/networkd-radv.c | 152 | ||||
-rw-r--r-- | src/network/networkd-radv.h | 1 | ||||
-rw-r--r-- | src/systemd/sd-radv.h | 5 |
8 files changed, 167 insertions, 27 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml index b1759677f9..2fb5886b79 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1452,19 +1452,36 @@ </varlistentry> <varlistentry> + <term><varname>EmitDNS=</varname></term> <term><varname>DNS=</varname></term> - <listitem><para>A list of recursive DNS server IPv6 addresses - distributed via Router Advertisement messages. + <listitem><para><varname>DNS=</varname> specifies a list of recursive + DNS server IPv6 addresses that distributed via Router Advertisement + messages when <varname>EmitDNS=</varname> is true. If <varname>DNS= + </varname> is empty, DNS servers are read from the + <literal>[Network]</literal> section. If the + <literal>[Network]</literal> section does not contain any DNS servers + either, DNS servers from the uplink with the highest priority default + route are used. When <varname>EmitDNS=</varname> is false, no DNS server + information is sent in Router Advertisement messages. + <varname>EmitDNS=</varname> defaults to true. </para></listitem> </varlistentry> <varlistentry> + <term><varname>EmitDomains=</varname></term> <term><varname>Domains=</varname></term> - <listitem><para>A list of DNS search domains distributed via - Router Advertisement messages. Defaults to empty, i.e. no search - domains are sent.</para></listitem> + <listitem><para>A list of DNS search domains distributed via Router + Advertisement messages when <varname>EmitDomains=</varname> is true. If + <varname>Domains=</varname> is empty, DNS search domains are read from the + <literal>[Network]</literal> section. If the <literal>[Network]</literal> + section does not contain any DNS search domains either, DNS search + domains from the uplink with the highest priority default route are + used. When <varname>EmitDomains=</varname> is false, no DNS search domain + information is sent in Router Advertisement messages. + <varname>EmitDomains=</varname> defaults to true. + </para></listitem> </varlistentry> <varlistentry> diff --git a/src/libsystemd-network/radv-internal.h b/src/libsystemd-network/radv-internal.h index 5601be844d..b4d0becdd1 100644 --- a/src/libsystemd-network/radv-internal.h +++ b/src/libsystemd-network/radv-internal.h @@ -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) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index af39d77ce9..ca0d67e3d2 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -152,7 +152,9 @@ IPv6PrefixDelegation.RouterLifetimeSec, config_parse_sec, IPv6PrefixDelegation.Managed, config_parse_bool, 0, offsetof(Network, router_managed) IPv6PrefixDelegation.OtherInformation, config_parse_bool, 0, offsetof(Network, router_other_information) IPv6PrefixDelegation.RouterPreference, config_parse_router_preference, 0, 0 +IPv6PrefixDelegation.EmitDNS, config_parse_bool, 0, offsetof(Network, router_emit_dns) IPv6PrefixDelegation.DNS, config_parse_radv_dns, 0, 0 +IPv6PrefixDelegation.EmitDomains, config_parse_bool, 0, offsetof(Network, router_emit_domains) IPv6PrefixDelegation.Domains, config_parse_radv_search_domains, 0, 0 IPv6PrefixDelegation.DNSLifetimeSec, config_parse_sec, 0, offsetof(Network, router_dns_lifetime_usec) IPv6Prefix.Prefix, config_parse_prefix, 0, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 3a7eb2c2a8..bf54a57f3b 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -233,6 +233,9 @@ static int network_load_one(Manager *manager, const char *filename) { network->dhcp_server_emit_router = true; network->dhcp_server_emit_timezone = true; + network->router_emit_dns = true; + network->router_emit_domains = true; + network->use_bpdu = true; network->allow_port_to_be_root = true; network->unicast_flood = true; diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 9fb0eae380..500325fbd0 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -167,6 +167,8 @@ struct Network { uint8_t router_preference; bool router_managed; bool router_other_information; + bool router_emit_dns; + bool router_emit_domains; usec_t router_dns_lifetime_usec; struct in6_addr *router_dns; unsigned n_router_dns; diff --git a/src/network/networkd-radv.c b/src/network/networkd-radv.c index 6768208cfa..5c807b887a 100644 --- a/src/network/networkd-radv.c +++ b/src/network/networkd-radv.c @@ -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); } diff --git a/src/network/networkd-radv.h b/src/network/networkd-radv.h index a186b111a1..d59373df9f 100644 --- a/src/network/networkd-radv.h +++ b/src/network/networkd-radv.h @@ -21,4 +21,5 @@ #include "networkd-link.h" +int radv_emit_dns(Link *link); int radv_configure(Link *link); diff --git a/src/systemd/sd-radv.h b/src/systemd/sd-radv.h index 0cc1d670b9..9805e3f24d 100644 --- a/src/systemd/sd-radv.h +++ b/src/systemd/sd-radv.h @@ -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; |