From 796273775c917b3e987abcdcb0eaa2b2f031dd8d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 21 Oct 2021 05:47:16 +0900 Subject: [PATCH 1/3] network: dhcp6pd: not necessary to drop routes when Assign=yes --- src/network/networkd-dhcp6.c | 64 +++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 10a4496d48..b0ce0187f6 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -150,8 +150,6 @@ static int dhcp6_pd_get_assigned_prefix(Link *link, const struct in6_addr *pd_pr } int dhcp6_pd_remove(Link *link, bool only_marked) { - Address *address; - Route *route; int k, r = 0; assert(link); @@ -163,45 +161,51 @@ int dhcp6_pd_remove(Link *link, bool only_marked) { if (!only_marked) link->dhcp6_pd_configured = false; - SET_FOREACH(route, link->routes) { - if (route->source != NETWORK_CONFIG_SOURCE_DHCP6PD) - continue; - if (only_marked && !route_is_marked(route)) - continue; + if (!link->network->dhcp6_pd_assign) { + Route *route; - if (link->radv) - (void) sd_radv_remove_prefix(link->radv, &route->dst.in6, 64); + SET_FOREACH(route, link->routes) { + if (route->source != NETWORK_CONFIG_SOURCE_DHCP6PD) + continue; + if (only_marked && !route_is_marked(route)) + continue; - link_remove_dhcp6_pd_prefix(link, &route->dst.in6); + if (link->radv) + (void) sd_radv_remove_prefix(link->radv, &route->dst.in6, 64); - k = route_remove(route); - if (k < 0) - r = k; + link_remove_dhcp6_pd_prefix(link, &route->dst.in6); - route_cancel_request(route); - } + k = route_remove(route); + if (k < 0) + r = k; - SET_FOREACH(address, link->addresses) { - struct in6_addr prefix; + route_cancel_request(route); + } + } else { + Address *address; - if (address->source != NETWORK_CONFIG_SOURCE_DHCP6PD) - continue; - if (only_marked && !address_is_marked(address)) - continue; + SET_FOREACH(address, link->addresses) { + struct in6_addr prefix; - prefix = address->in_addr.in6; - in6_addr_mask(&prefix, 64); + if (address->source != NETWORK_CONFIG_SOURCE_DHCP6PD) + continue; + if (only_marked && !address_is_marked(address)) + continue; - if (link->radv) - (void) sd_radv_remove_prefix(link->radv, &prefix, 64); + prefix = address->in_addr.in6; + in6_addr_mask(&prefix, 64); - link_remove_dhcp6_pd_prefix(link, &prefix); + if (link->radv) + (void) sd_radv_remove_prefix(link->radv, &prefix, 64); - k = address_remove(address); - if (k < 0) - r = k; + link_remove_dhcp6_pd_prefix(link, &prefix); - address_cancel_request(address); + k = address_remove(address); + if (k < 0) + r = k; + + address_cancel_request(address); + } } return r; From a3ad6acf7b7a1cbec077e777ca603f0eb0ee5157 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 21 Oct 2021 17:54:06 +0900 Subject: [PATCH 2/3] network: dhcp6pd: also call dhcp6_pd_prepare() and dhcp6_pd_finalize() for upstream interface As now the subnet prefix may be assigned to the upstream interface. --- src/network/networkd-dhcp6.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index b0ce0187f6..fb13027337 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -844,12 +844,17 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) { return log_link_warning_errno(dhcp6_link, r, "Failed to get timestamp of DHCPv6 lease: %m"); HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) { - if (link == dhcp6_link) - continue; - r = dhcp6_pd_prepare(link); - if (r < 0) + if (r < 0) { + /* When failed on the upstream interface (i.e., the case link == dhcp6_link), + * immediately abort the assignment of the prefixes. As, the all assigned + * prefixes will be dropped soon in link_enter_failed(), and it is meaningless + * to continue the assignment. */ + if (link == dhcp6_link) + return r; + link_enter_failed(link); + } } for (sd_dhcp6_lease_reset_pd_prefix_iter(dhcp6_link->dhcp6_lease);;) { @@ -921,12 +926,13 @@ static int dhcp6_pd_prefix_acquired(Link *dhcp6_link) { } HASHMAP_FOREACH(link, dhcp6_link->manager->links_by_index) { - if (link == dhcp6_link) - continue; - r = dhcp6_pd_finalize(link); - if (r < 0) + if (r < 0) { + if (link == dhcp6_link) + return r; + link_enter_failed(link); + } } return 0; From b7f7c7879321131793ac7d465632823cc1cafb65 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Thu, 21 Oct 2021 16:09:44 +0900 Subject: [PATCH 3/3] network: dhcp6pd: check link state earlier before assigning prefixes to downstream Also, narrow the acceptable range of the states. --- src/network/networkd-dhcp6.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index fb13027337..a92394554a 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -547,15 +547,15 @@ static int dhcp6_pd_prefix_distribute( _cleanup_free_ char *buf = NULL; struct in6_addr assigned_prefix; + if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) + continue; + if (!link_dhcp6_pd_is_enabled(link)) continue; if (link == dhcp6_link && !link->network->dhcp6_pd_assign) continue; - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) - continue; - if (assign_preferred_subnet_id != link_has_preferred_subnet_id(link)) continue; @@ -581,7 +581,7 @@ static int dhcp6_pd_prefix_distribute( } static int dhcp6_pd_prepare(Link *link) { - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) + if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) return 0; if (!link_dhcp6_pd_is_enabled(link)) @@ -596,7 +596,7 @@ static int dhcp6_pd_prepare(Link *link) { static int dhcp6_pd_finalize(Link *link) { int r; - if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) + if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) return 0; if (!link_dhcp6_pd_is_enabled(link))