From: Yu Watanabe Date: Wed, 12 Jul 2023 01:50:53 +0000 (+0900) Subject: network: check lifetime of address and route before configure X-Git-Tag: v254-rc2~24 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=dc32de392466c3cadab313abbc636e341047049b;p=thirdparty%2Fsystemd.git network: check lifetime of address and route before configure Otherwise, we may configure a route that depends on the existence of an address or another route, and may fail when lifetime of one of them are already zero. Hopefully fixes #28358. --- diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 221f5c9efe7..21d08c8f377 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -143,6 +143,14 @@ Address *address_free(Address *address) { return mfree(address); } +static bool address_lifetime_is_valid(const Address *a) { + assert(a); + + return + a->lifetime_valid_usec == USEC_INFINITY || + a->lifetime_valid_usec > now(CLOCK_BOOTTIME); +} + bool address_is_ready(const Address *a) { assert(a); @@ -158,7 +166,7 @@ bool address_is_ready(const Address *a) { if (!FLAGS_SET(a->state, NETWORK_CONFIG_STATE_CONFIGURED)) return false; - return true; + return address_lifetime_is_valid(a); } bool link_check_addresses_ready(Link *link, NetworkConfigSource source) { @@ -707,7 +715,7 @@ bool manager_has_address(Manager *manager, int family, const union in_addr_union if (manager_get_address(manager, family, address, 0, &a) < 0) return false; - return check_ready ? address_is_ready(a) : address_exists(a); + return check_ready ? address_is_ready(a) : (address_exists(a) && address_lifetime_is_valid(a)); } const char* format_lifetime(char *buf, size_t l, usec_t lifetime_usec) { diff --git a/src/network/networkd-route-util.c b/src/network/networkd-route-util.c index e497f059965..51514f2cd42 100644 --- a/src/network/networkd-route-util.c +++ b/src/network/networkd-route-util.c @@ -39,6 +39,14 @@ unsigned routes_max(void) { return cached; } +static bool route_lifetime_is_valid(const Route *route) { + assert(route); + + return + route->lifetime_usec == USEC_INFINITY || + route->lifetime_usec > now(CLOCK_BOOTTIME); +} + static Route *link_find_default_gateway(Link *link, int family, Route *gw) { Route *route; @@ -123,6 +131,8 @@ bool gateway_is_ready(Link *link, bool onlink, int family, const union in_addr_u SET_FOREACH(route, link->routes) { if (!route_exists(route)) continue; + if (!route_lifetime_is_valid(route)) + continue; if (route->family != family) continue; if (!in_addr_is_set(route->family, &route->dst) && route->dst_prefixlen == 0) @@ -169,6 +179,9 @@ static int link_address_is_reachable_internal( if (!route_exists(route)) continue; + if (!route_lifetime_is_valid(route)) + continue; + if (route->type != RTN_UNICAST) continue;