From 790736e42e39476409be55113a796132f041d256 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 2 Jul 2021 20:13:32 +0900 Subject: [PATCH 1/4] network: fix log message --- src/network/networkd-link.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index a939f55731..c1ab14ebec 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -519,7 +519,8 @@ void link_check_ready(Link *link) { /* When DHCP[46], NDisc, or IPv4LL is enabled, at least one protocol must be finished. */ return (void) log_link_debug(link, "%s(): dynamic addresses or routes are not configured.", __func__); - log_link_debug(link, "%s(): dhcp4:%s ipv4ll:%s dhcp6_addresses:%s dhcp_routes:%s dhcp_pd_addresses:%s dhcp_pd_routes:%s ndisc_addresses:%s ndisc_routes:%s", + log_link_debug(link, "%s(): dhcp4:%s ipv4ll:%s dhcp6_addresses:%s dhcp6_routes:%s " + "dhcp6_pd_addresses:%s dhcp6_pd_routes:%s ndisc_addresses:%s ndisc_routes:%s", __func__, yes_no(link->dhcp4_configured), yes_no(link->ipv4ll_address_configured), From fe139e8ef9bcd985b9df495edf4f97e40d5332ea Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 2 Jul 2021 20:15:10 +0900 Subject: [PATCH 2/4] network: drop old ndisc configurations after new ones are configured Previously, `ndisc_remove_old_one()` checked `ndisc_{addresses,routes}_configured` flags, but they are not unset when all addresses or routes are already assigned. After the request queue is implemented, the address or route requests are not processed within the same event of ndisc handler is called, but will processed later when they are ready. So, calling `ndisc_remove_old()` in the event of ndisc handler will remove all addresses and routes previously assigned even they are requested to be updated. This makes `ndisc_remove_old()` do nothing when there exist some requests to configure addresses and routes, thus previously assigned addresses and routes are kept until all requests are processed. Fixes #20050. --- src/network/networkd-ndisc.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 444147c305..eebcea1a69 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -128,9 +128,6 @@ static int ndisc_remove_old_one(Link *link, const struct in6_addr *router, bool if (!force) { bool set_callback = false; - if (!link->ndisc_addresses_configured || !link->ndisc_routes_configured) - return 0; - SET_FOREACH(na, link->ndisc_addresses) if (!na->marked && in6_addr_equal(&na->router, router)) { set_callback = true; @@ -212,6 +209,10 @@ static int ndisc_remove_old(Link *link) { assert(link); + if (link->ndisc_addresses_messages > 0 || + link->ndisc_routes_messages > 0) + return 0; + routers = set_new(&in6_addr_hash_ops); if (!routers) return -ENOMEM; From e95ec7cd1e363e1d55f59787c1e85f8f6c97e86c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 2 Jul 2021 20:19:17 +0900 Subject: [PATCH 3/4] network: drop old dhcp6 addresses or routes after new ones are configured Fixes the issue similar to #20050 but for DHCP6. --- src/network/networkd-dhcp6.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index e850e595e3..2b72b618fc 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -145,7 +145,7 @@ static int dhcp6_pd_remove_old(Link *link, bool force) { assert(link); assert(link->manager); - if (!force && (link->dhcp6_pd_address_messages != 0 || link->dhcp6_pd_route_messages != 0)) + if (!force && (link->dhcp6_pd_address_messages > 0 || link->dhcp6_pd_route_messages > 0)) return 0; if (set_isempty(link->dhcp6_pd_addresses_old) && set_isempty(link->dhcp6_pd_routes_old)) @@ -740,7 +740,7 @@ static int dhcp6_remove_old(Link *link, bool force) { assert(link); - if (!force && (!link->dhcp6_address_configured || !link->dhcp6_route_configured)) + if (!force && (link->dhcp6_address_messages > 0 || link->dhcp6_route_messages > 0)) return 0; if (set_isempty(link->dhcp6_addresses_old) && set_isempty(link->dhcp6_routes_old)) From 899034ba8167bd16e802cfbea29a9ee85dee5be5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 2 Jul 2021 22:26:04 +0900 Subject: [PATCH 4/4] network: fix overflow issue in address lifetime calculation Fixes another issue reported in #20050. See https://github.com/systemd/systemd/issues/20050#issuecomment-872967337. --- src/network/networkd-ndisc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index eebcea1a69..efc4707855 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -819,8 +819,10 @@ static int ndisc_router_process_autonomous_prefix(Link *link, sd_ndisc_router *r r = address_get(link, address, &e); if (r > 0) { /* If the address is already assigned, but not valid anymore, then refuse to - * update the address. */ - if (e->cinfo.tstamp / 100 + e->cinfo.ifa_valid < time_now / USEC_PER_SEC) + * update the address, and it will be removed. */ + if (e->cinfo.ifa_valid != CACHE_INFO_INFINITY_LIFE_TIME && + usec_add(e->cinfo.tstamp / 100 * USEC_PER_SEC, + e->cinfo.ifa_valid * USEC_PER_SEC) < time_now) continue; }