diff options
author | Luca Boccassi <bluca@debian.org> | 2023-10-08 23:46:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-08 23:46:44 +0200 |
commit | 00dd4e78f60c75bb35385087b37ce080307019c1 (patch) | |
tree | 84082256d6d2f4f0491dd5bdfaa0b3157d67e17c /src | |
parent | Merge pull request #29490 from yuwata/network-tc-fixes (diff) | |
parent | test-network: add test for DHCPv6 information requesting mode (diff) | |
download | systemd-00dd4e78f60c75bb35385087b37ce080307019c1.tar.xz systemd-00dd4e78f60c75bb35385087b37ce080307019c1.zip |
Merge pull request #29495 from yuwata/network-manager-state-file
network: fixlets for manager state file
Diffstat (limited to 'src')
-rw-r--r-- | src/network/networkd-dhcp6.c | 29 | ||||
-rw-r--r-- | src/network/networkd-state-file.c | 321 |
2 files changed, 228 insertions, 122 deletions
diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 5c5dff9413..6044411a75 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -341,7 +341,17 @@ static int dhcp6_lease_ip_acquired(sd_dhcp6_client *client, Link *link) { } static int dhcp6_lease_information_acquired(sd_dhcp6_client *client, Link *link) { - return 0; + sd_dhcp6_lease *lease; + int r; + + assert(client); + assert(link); + + r = sd_dhcp6_client_get_lease(client, &lease); + if (r < 0) + return log_link_error_errno(link, r, "Failed to get DHCPv6 lease: %m"); + + return unref_and_replace_full(link->dhcp6_lease, lease, sd_dhcp6_lease_ref, sd_dhcp6_lease_unref); } static int dhcp6_lease_lost(Link *link) { @@ -366,7 +376,7 @@ static int dhcp6_lease_lost(Link *link) { static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) { Link *link = ASSERT_PTR(userdata); - int r; + int r = 0; assert(link->network); @@ -378,31 +388,24 @@ static void dhcp6_handler(sd_dhcp6_client *client, int event, void *userdata) { case SD_DHCP6_CLIENT_EVENT_RESEND_EXPIRE: case SD_DHCP6_CLIENT_EVENT_RETRANS_MAX: r = dhcp6_lease_lost(link); - if (r < 0) - link_enter_failed(link); break; case SD_DHCP6_CLIENT_EVENT_IP_ACQUIRE: r = dhcp6_lease_ip_acquired(client, link); - if (r < 0) { - link_enter_failed(link); - return; - } + break; - _fallthrough_; case SD_DHCP6_CLIENT_EVENT_INFORMATION_REQUEST: r = dhcp6_lease_information_acquired(client, link); - if (r < 0) - link_enter_failed(link); break; default: if (event < 0) - log_link_warning_errno(link, event, "DHCPv6 error: %m"); + log_link_warning_errno(link, event, "DHCPv6 error, ignoring: %m"); else log_link_warning(link, "DHCPv6 unknown event: %d", event); - return; } + if (r < 0) + link_enter_failed(link); } int dhcp6_start_on_ra(Link *link, bool information_request) { 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) |