]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/route: save if the route expiration is managed by the kernel
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 9 Jan 2024 04:44:15 +0000 (13:44 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 12 Jan 2024 00:46:09 +0000 (09:46 +0900)
Otherwise, our own expiration timer will be setup on updating a route.
See comment in link_request_route().

src/network/networkd-route.c
src/network/networkd-route.h

index 78774f60ed8219c829033ecb5386ef92b9c94f6d..83dfea1392c957db3999164aef4994bd021b798d 100644 (file)
@@ -1014,26 +1014,26 @@ static int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdat
 }
 
 static int route_setup_timer(Route *route, const struct rta_cacheinfo *cacheinfo) {
-        Manager *manager;
         int r;
 
         assert(route);
-        assert(route->manager || (route->link && route->link->manager));
-
-        manager = route->manager ?: route->link->manager;
-
-        if (route->lifetime_usec == USEC_INFINITY)
-                return 0;
 
         if (cacheinfo && cacheinfo->rta_expires != 0)
-                /* Assume that non-zero rta_expires means kernel will handle the route expiration. */
+                route->expiration_managed_by_kernel = true;
+
+        if (route->lifetime_usec == USEC_INFINITY || /* We do not request expiration for the route. */
+            route->expiration_managed_by_kernel) {   /* We have received nonzero expiration previously. The expiration is managed by the kernel. */
+                route->expire = sd_event_source_disable_unref(route->expire);
                 return 0;
+        }
 
+        Manager *manager = ASSERT_PTR(route->manager ?: ASSERT_PTR(route->link)->manager);
         r = event_reset_time(manager->event, &route->expire, CLOCK_BOOTTIME,
                              route->lifetime_usec, 0, route_expire_handler, route, 0, "route-expiration", true);
         if (r < 0)
-                return r;
+                return log_link_warning_errno(route->link, r, "Failed to configure expiration timer for route, ignoring: %m");
 
+        log_route_debug(route, "Configured expiration timer for", route->link, manager);
         return 1;
 }
 
@@ -1379,15 +1379,10 @@ int link_request_route(
                 if (consume_object)
                         route_free(route);
 
-                if (existing->expire) {
+                if (existing->expire)
                         /* When re-configuring an existing route, kernel does not send RTM_NEWROUTE
                          * message, so we need to update the timer here. */
-                        r = route_setup_timer(existing, NULL);
-                        if (r < 0)
-                                log_link_warning_errno(link, r, "Failed to update expiration timer for route, ignoring: %m");
-                        if (r > 0)
-                                log_route_debug(existing, "Updated expiration timer for", link, link->manager);
-                }
+                        (void) route_setup_timer(existing, NULL);
         }
 
         log_route_debug(existing, "Requesting", link, link->manager);
@@ -1573,11 +1568,7 @@ static int process_route_one(
                 route_enter_configured(route);
                 log_route_debug(route, is_new ? "Received new" : "Received remembered", link, manager);
 
-                r = route_setup_timer(route, cacheinfo);
-                if (r < 0)
-                        log_link_warning_errno(link, r, "Failed to configure expiration timer for route, ignoring: %m");
-                if (r > 0)
-                        log_route_debug(route, "Configured expiration timer for", link, manager);
+                (void) route_setup_timer(route, cacheinfo);
 
                 break;
 
index 33d1e643cc49e92ae6cf36045d8bbedf028a44d7..0baf199ddbd925de16b3607c488b9ec7295cf097 100644 (file)
@@ -53,6 +53,14 @@ struct Route {
         /* metrics (RTA_METRICS) */
         RouteMetric metric;
 
+        /* This is an absolute point in time, and NOT a timespan/duration.
+         * Must be specified with clock_boottime_or_monotonic(). */
+        usec_t lifetime_usec; /* RTA_EXPIRES (IPv6 only) */
+        /* Used when kernel does not support RTA_EXPIRES attribute. */
+        sd_event_source *expire;
+        bool expiration_managed_by_kernel:1; /* RTA_CACHEINFO has nonzero rta_expires */
+
+        /* Only used by conf persers and route_section_verify(). */
         bool scope_set:1;
         bool table_set:1;
         bool priority_set:1;
@@ -65,12 +73,6 @@ struct Route {
         union in_addr_union src;
         union in_addr_union prefsrc;
         OrderedSet *multipath_routes;
-
-        /* This is an absolute point in time, and NOT a timespan/duration.
-         * Must be specified with clock_boottime_or_monotonic(). */
-        usec_t lifetime_usec;
-        /* Used when kernel does not support RTA_EXPIRES attribute. */
-        sd_event_source *expire;
 };
 
 extern const struct hash_ops route_hash_ops;