]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: check lifetime of address and route before configure
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 12 Jul 2023 01:50:53 +0000 (10:50 +0900)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 14 Jul 2023 08:01:20 +0000 (10:01 +0200)
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.

src/network/networkd-address.c
src/network/networkd-route-util.c

index 221f5c9efe7f87b08352e24c877b1b54b3a8a46d..21d08c8f377d3c89584821463a5cae49b8972cce 100644 (file)
@@ -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) {
index e497f059965786c46537ea4bf48138f244b7decc..51514f2cd428b2cf7aa342db9e984af2a21f7b94 100644 (file)
@@ -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;