diff options
-rw-r--r-- | src/libsystemd-network/radv-internal.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 |
4 files changed, 138 insertions, 22 deletions
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-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; |