]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/route: introduce route_remove_and_cancel()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 9 Jan 2024 06:49:20 +0000 (15:49 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 25 Jan 2024 07:43:44 +0000 (16:43 +0900)
Then, replace route_remove_and_drop() with it.

If a route is requested, and the request is already called,
we may not received its reply and notification from the kernel, and
the corresponding Route object may not be remembered. Even in such
case, we need to remove the route, otherwise the route will come
later after the function called.

This is the version for route of f22b586a215962416bdbd692aabb89b1ac2999d0.

src/network/networkd-dhcp-prefix-delegation.c
src/network/networkd-dhcp4.c
src/network/networkd-dhcp6.c
src/network/networkd-ndisc.c
src/network/networkd-route.c
src/network/networkd-route.h

index b8b03f6d3b94882d0cf11c10091aa7c92e0dab6d..d8f9a2c053c38bf8e37e46d0e41dacf418bc5eac 100644 (file)
@@ -176,8 +176,7 @@ int dhcp_pd_remove(Link *link, bool only_marked) {
 
                         link_remove_dhcp_pd_subnet_prefix(link, &route->dst.in6);
 
-                        RET_GATHER(ret, route_remove(route));
-                        route_cancel_request(route, link);
+                        RET_GATHER(ret, route_remove_and_cancel(route, link->manager));
                 }
         } else {
                 Address *address;
@@ -612,9 +611,7 @@ void dhcp_pd_prefix_lost(Link *uplink) {
                                           .address = route->dst }))
                         continue;
 
-                (void) route_remove(route);
-
-                route_cancel_request(route, uplink);
+                (void) route_remove_and_cancel(route, uplink->manager);
         }
 
         set_clear(uplink->dhcp_pd_prefixes);
index be7abcf6f3849f53e166cfc1cc878bd74b2f7952..1a1836cf6669e290bc7455e3ede6f6352fa92986 100644 (file)
@@ -256,8 +256,7 @@ static int dhcp4_remove_address_and_routes(Link *link, bool only_marked) {
                 if (only_marked && !route_is_marked(route))
                         continue;
 
-                RET_GATHER(ret, route_remove(route));
-                route_cancel_request(route, link);
+                RET_GATHER(ret, route_remove_and_cancel(route, link->manager));
         }
 
         SET_FOREACH(address, link->addresses) {
index 26ed034bbeae03243782198d64f3a3d601980b72..eb1420be5c0691314bc45b174eb18e30466fbc29 100644 (file)
@@ -62,8 +62,7 @@ static int dhcp6_remove(Link *link, bool only_marked) {
                 if (only_marked && !route_is_marked(route))
                         continue;
 
-                RET_GATHER(ret, route_remove(route));
-                route_cancel_request(route, link);
+                RET_GATHER(ret, route_remove_and_cancel(route, link->manager));
         }
 
         SET_FOREACH(address, link->addresses) {
index 7186187fd828f379247a31cbc595dea4840b11cc..488c8c02948a9ed443c7b8fe9b383e6491917d0b 100644 (file)
@@ -1173,7 +1173,7 @@ static int ndisc_drop_outdated(Link *link, usec_t timestamp_usec) {
                 if (route->lifetime_usec >= timestamp_usec)
                         continue; /* the route is still valid */
 
-                r = route_remove_and_drop(route);
+                r = route_remove_and_cancel(route, link->manager);
                 if (r < 0)
                         RET_GATHER(ret, log_link_warning_errno(link, r, "Failed to remove outdated SLAAC route, ignoring: %m"));
         }
index 3a33769f8b5094bb0d4aa822852e434a0f59e959..efb121cb82f44a320a44695280ecc143d9f7c28d 100644 (file)
@@ -510,13 +510,13 @@ static int route_remove_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *l
         return 1;
 }
 
-int route_remove(Route *route) {
+int route_remove(Route *route, Manager *manager) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
         Link *link = NULL;
         int r;
 
         assert(route);
-        Manager *manager = ASSERT_PTR(route->manager);
+        assert(manager);
 
         log_route_debug(route, "Removing", manager);
 
@@ -541,17 +541,27 @@ int route_remove(Route *route) {
         return 0;
 }
 
-int route_remove_and_drop(Route *route) {
-        if (!route)
-                return 0;
+int route_remove_and_cancel(Route *route, Manager *manager) {
+        bool waiting = false;
+        Request *req;
 
-        route_cancel_request(route, NULL);
+        assert(route);
+        assert(manager);
+
+        /* If the route is remembered by the manager, then use the remembered object. */
+        (void) route_get(manager, route, &route);
 
-        if (route_exists(route))
-                return route_remove(route);
+        /* Cancel the request for the route. If the request is already called but we have not received the
+         * notification about the request, then explicitly remove the route. */
+        if (route_get_request(manager, route, &req) >= 0) {
+                waiting = req->waiting_reply;
+                request_detach(req);
+                route_cancel_requesting(route);
+        }
 
-        if (route->state == 0)
-                route_free(route);
+        /* If we know that the route will come or already exists, remove it. */
+        if (waiting || (route->manager && route_exists(route)))
+                return route_remove(route, manager);
 
         return 0;
 }
@@ -562,7 +572,7 @@ static int route_expire_handler(sd_event_source *s, uint64_t usec, void *userdat
 
         assert(route->manager);
 
-        r = route_remove(route);
+        r = route_remove(route, route->manager);
         if (r < 0) {
                 Link *link = NULL;
                 (void) route_get_link(route->manager, route, &link);
@@ -944,20 +954,6 @@ int link_request_static_routes(Link *link, bool only_ipv4) {
         return 0;
 }
 
-void route_cancel_request(Route *route, Link *link) {
-        assert(route);
-        Manager *manager = ASSERT_PTR(route->manager ?: ASSERT_PTR(link)->manager);
-
-        if (!route_is_requesting(route))
-                return;
-
-        Request *req;
-        if (route_get_request(manager, route, &req) >= 0)
-                request_detach(req);
-
-        route_cancel_requesting(route);
-}
-
 static int process_route_one(
                 Manager *manager,
                 uint16_t type,
@@ -1376,7 +1372,7 @@ int link_drop_routes(Link *link, bool foreign) {
                 if (!route_is_marked(route))
                         continue;
 
-                RET_GATHER(r, route_remove(route));
+                RET_GATHER(r, route_remove(route, link->manager));
         }
 
         return r;
index 090bf34a61aadf34f4f028ae37169ef23e053c45..51a06dd0f14c0e7e9ee7c78fa5e21f3a5e7ed5ab 100644 (file)
@@ -88,8 +88,8 @@ int route_new_static(Network *network, const char *filename, unsigned section_li
 int route_dup(const Route *src, const RouteNextHop *nh, Route **ret);
 
 int route_configure_handler_internal(sd_netlink *rtnl, sd_netlink_message *m, Link *link, Route *route, const char *error_msg);
-int route_remove(Route *route);
-int route_remove_and_drop(Route *route);
+int route_remove(Route *route, Manager *manager);
+int route_remove_and_cancel(Route *route, Manager *manager);
 
 int route_get(Manager *manager, const Route *route, Route **ret);
 
@@ -102,7 +102,6 @@ static inline int link_drop_foreign_routes(Link *link) {
 }
 int link_foreignize_routes(Link *link);
 
-void route_cancel_request(Route *route, Link *link);
 int link_request_route(
                 Link *link,
                 const Route *route,