diff options
Diffstat (limited to 'src/network/networkd-state-file.c')
-rw-r--r-- | src/network/networkd-state-file.c | 321 |
1 files changed, 212 insertions, 109 deletions
diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c index 85c9d21082..03146c62c7 100644 --- a/src/network/networkd-state-file.c +++ b/src/network/networkd-state-file.c @@ -21,88 +21,250 @@ #include "strv.h" #include "tmpfile-util.h" -static int ordered_set_put_dns_server(OrderedSet **s, int ifindex, struct in_addr_full *dns) { - const char *p; +static int ordered_set_put_dns_servers(OrderedSet **s, int ifindex, struct in_addr_full **dns, unsigned n) { int r; assert(s); - assert(dns); + assert(dns || n == 0); - if (dns->ifindex != 0 && dns->ifindex != ifindex) - return 0; + FOREACH_ARRAY(a, dns, n) { + const char *p; - p = in_addr_full_to_string(dns); - if (!p) - return 0; + if ((*a)->ifindex != 0 && (*a)->ifindex != ifindex) + return 0; - r = ordered_set_put_strdup(s, p); - if (r == -EEXIST) - return 0; + p = in_addr_full_to_string(*a); + if (!p) + return 0; + + r = ordered_set_put_strdup(s, p); + if (r < 0) + return r; + } - return r; + return 0; } -static int ordered_set_put_dns_servers(OrderedSet **s, int ifindex, struct in_addr_full **dns, unsigned n) { - int r, c = 0; +static int ordered_set_put_in4_addrv( + OrderedSet **s, + const struct in_addr *addresses, + size_t n, + bool (*predicate)(const struct in_addr *addr)) { + + int r; assert(s); - assert(dns || n == 0); + assert(n == 0 || addresses); + + FOREACH_ARRAY(a, addresses, n) { + if (predicate && !predicate(a)) + continue; - for (unsigned i = 0; i < n; i++) { - r = ordered_set_put_dns_server(s, ifindex, dns[i]); + r = ordered_set_put_strdup(s, IN4_ADDR_TO_STRING(a)); if (r < 0) return r; + } + + return 0; +} - c += r; +static int ordered_set_put_in6_addrv( + OrderedSet **s, + const struct in6_addr *addresses, + size_t n) { + + int r; + + assert(s); + assert(n == 0 || addresses); + + FOREACH_ARRAY(a, addresses, n) { + r = ordered_set_put_strdup(s, IN6_ADDR_TO_STRING(a)); + if (r < 0) + return r; } - return c; + return 0; } -static int ordered_set_put_in4_addr(OrderedSet **s, const struct in_addr *address) { - _cleanup_free_ char *p = NULL; +static int link_put_dns(Link *link, OrderedSet **s) { int r; + assert(link); + assert(link->network); assert(s); - assert(address); - r = in_addr_to_string(AF_INET, (const union in_addr_union*) address, &p); + if (link->n_dns != UINT_MAX) + return ordered_set_put_dns_servers(s, link->ifindex, link->dns, link->n_dns); + + r = ordered_set_put_dns_servers(s, link->ifindex, link->network->dns, link->network->n_dns); if (r < 0) return r; - r = ordered_set_ensure_allocated(s, &string_hash_ops_free); + if (link->dhcp_lease && link->network->dhcp_use_dns) { + const struct in_addr *addresses; + + r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses); + if (r >= 0) { + r = ordered_set_put_in4_addrv(s, addresses, r, in4_addr_is_non_local); + if (r < 0) + return r; + } + } + + if (link->dhcp6_lease && link->network->dhcp6_use_dns) { + const struct in6_addr *addresses; + + r = sd_dhcp6_lease_get_dns(link->dhcp6_lease, &addresses); + if (r >= 0) { + r = ordered_set_put_in6_addrv(s, addresses, r); + if (r < 0) + return r; + } + } + + if (link->network->ipv6_accept_ra_use_dns) { + NDiscRDNSS *a; + + SET_FOREACH(a, link->ndisc_rdnss) { + r = ordered_set_put_in6_addrv(s, &a->router, 1); + if (r < 0) + return r; + } + } + + return 0; +} + +static int link_put_ntp(Link *link, OrderedSet **s) { + int r; + + assert(link); + assert(link->network); + assert(s); + + if (link->ntp) + return ordered_set_put_strdupv(s, link->ntp); + + r = ordered_set_put_strdupv(s, link->network->ntp); if (r < 0) return r; - r = ordered_set_consume(*s, TAKE_PTR(p)); - if (r == -EEXIST) - return 0; + if (link->dhcp_lease && link->network->dhcp_use_ntp) { + const struct in_addr *addresses; - return r; + r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses); + if (r >= 0) { + r = ordered_set_put_in4_addrv(s, addresses, r, in4_addr_is_non_local); + if (r < 0) + return r; + } + } + + if (link->dhcp6_lease && link->network->dhcp6_use_ntp) { + const struct in6_addr *addresses; + char **fqdn; + + r = sd_dhcp6_lease_get_ntp_addrs(link->dhcp6_lease, &addresses); + if (r >= 0) { + r = ordered_set_put_in6_addrv(s, addresses, r); + if (r < 0) + return r; + } + + r = sd_dhcp6_lease_get_ntp_fqdn(link->dhcp6_lease, &fqdn); + if (r >= 0) { + r = ordered_set_put_strdupv(s, fqdn); + if (r < 0) + return r; + } + } + + return 0; } -static int ordered_set_put_in4_addrv( - OrderedSet **s, - const struct in_addr *addresses, - size_t n, - bool (*predicate)(const struct in_addr *addr)) { +static int link_put_sip(Link *link, OrderedSet **s) { + int r; + + assert(link); + assert(link->network); + assert(s); + + if (link->dhcp_lease && link->network->dhcp_use_ntp) { + const struct in_addr *addresses; - int r, c = 0; + r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses); + if (r >= 0) { + r = ordered_set_put_in4_addrv(s, addresses, r, in4_addr_is_non_local); + if (r < 0) + return r; + } + } + return 0; +} + +static int link_put_domains(Link *link, bool is_route, OrderedSet **s) { + OrderedSet *link_domains, *network_domains; + DHCPUseDomains use_domains; + int r; + + assert(link); + assert(link->network); assert(s); - assert(n == 0 || addresses); - for (size_t i = 0; i < n; i++) { - if (predicate && !predicate(&addresses[i])) - continue; - r = ordered_set_put_in4_addr(s, addresses+i); - if (r < 0) - return r; + link_domains = is_route ? link->route_domains : link->search_domains; + network_domains = is_route ? link->network->route_domains : link->network->search_domains; + use_domains = is_route ? DHCP_USE_DOMAINS_ROUTE : DHCP_USE_DOMAINS_YES; + + if (link_domains) + return ordered_set_put_string_set(s, link_domains); - c += r; + r = ordered_set_put_string_set(s, network_domains); + if (r < 0) + return r; + + if (link->dhcp_lease && link->network->dhcp_use_domains == use_domains) { + const char *domainname; + char **domains; + + r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname); + if (r >= 0) { + r = ordered_set_put_strdup(s, domainname); + if (r < 0) + return r; + } + + r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains); + if (r >= 0) { + r = ordered_set_put_strdupv(s, domains); + if (r < 0) + return r; + } + } + + if (link->dhcp6_lease && link->network->dhcp6_use_domains == use_domains) { + char **domains; + + r = sd_dhcp6_lease_get_domains(link->dhcp6_lease, &domains); + if (r >= 0) { + r = ordered_set_put_strdupv(s, domains); + if (r < 0) + return r; + } } - return c; + if (link->network->ipv6_accept_ra_use_domains == use_domains) { + NDiscDNSSL *a; + + SET_FOREACH(a, link->ndisc_dnssl) { + r = ordered_set_put_strdup(s, NDISC_DNSSL_DOMAIN(a)); + if (r < 0) + return r; + } + } + + return 0; } int manager_save(Manager *m) { @@ -126,8 +288,6 @@ int manager_save(Manager *m) { return 0; /* Do not update state file when running in test mode. */ HASHMAP_FOREACH(link, m->links_by_index) { - const struct in_addr *addresses; - if (link->flags & IFF_LOOPBACK) continue; @@ -147,82 +307,25 @@ int manager_save(Manager *m) { links_online++; } - /* First add the static configured entries */ - if (link->n_dns != UINT_MAX) - r = ordered_set_put_dns_servers(&dns, link->ifindex, link->dns, link->n_dns); - else - r = ordered_set_put_dns_servers(&dns, link->ifindex, link->network->dns, link->network->n_dns); + r = link_put_dns(link, &dns); if (r < 0) return r; - r = ordered_set_put_strdupv(&ntp, link->ntp ?: link->network->ntp); + r = link_put_ntp(link, &ntp); if (r < 0) return r; - r = ordered_set_put_string_set(&search_domains, link->search_domains ?: link->network->search_domains); + r = link_put_sip(link, &sip); if (r < 0) return r; - r = ordered_set_put_string_set(&route_domains, link->route_domains ?: link->network->route_domains); + r = link_put_domains(link, /* is_route = */ false, &search_domains); if (r < 0) return r; - if (!link->dhcp_lease) - continue; - - /* Secondly, add the entries acquired via DHCP */ - if (link->network->dhcp_use_dns) { - r = sd_dhcp_lease_get_dns(link->dhcp_lease, &addresses); - if (r > 0) { - r = ordered_set_put_in4_addrv(&dns, addresses, r, in4_addr_is_non_local); - if (r < 0) - return r; - } else if (r < 0 && r != -ENODATA) - return r; - } - - if (link->network->dhcp_use_ntp) { - r = sd_dhcp_lease_get_ntp(link->dhcp_lease, &addresses); - if (r > 0) { - r = ordered_set_put_in4_addrv(&ntp, addresses, r, in4_addr_is_non_local); - if (r < 0) - return r; - } else if (r < 0 && r != -ENODATA) - return r; - } - - if (link->network->dhcp_use_sip) { - r = sd_dhcp_lease_get_sip(link->dhcp_lease, &addresses); - if (r > 0) { - r = ordered_set_put_in4_addrv(&sip, addresses, r, in4_addr_is_non_local); - if (r < 0) - return r; - } else if (r < 0 && r != -ENODATA) - return r; - } - - if (link->network->dhcp_use_domains != DHCP_USE_DOMAINS_NO) { - OrderedSet **target_domains; - const char *domainname; - char **domains = NULL; - - target_domains = link->network->dhcp_use_domains == DHCP_USE_DOMAINS_YES ? &search_domains : &route_domains; - r = sd_dhcp_lease_get_domainname(link->dhcp_lease, &domainname); - if (r >= 0) { - r = ordered_set_put_strdup(target_domains, domainname); - if (r < 0) - return r; - } else if (r != -ENODATA) - return r; - - r = sd_dhcp_lease_get_search_domains(link->dhcp_lease, &domains); - if (r >= 0) { - r = ordered_set_put_strdupv(target_domains, domains); - if (r < 0) - return r; - } else if (r != -ENODATA) - return r; - } + r = link_put_domains(link, /* is_route = */ true, &route_domains); + if (r < 0) + return r; } if (carrier_state >= LINK_CARRIER_STATE_ENSLAVED) |