From 3caed9ea0830b811ba0e5222e57c5d7deda204e3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 9 Jan 2024 15:49:20 +0900 Subject: [PATCH] network/route: introduce route_remove_and_cancel() 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 | 7 +-- src/network/networkd-dhcp4.c | 3 +- src/network/networkd-dhcp6.c | 3 +- src/network/networkd-ndisc.c | 2 +- src/network/networkd-route.c | 48 +++++++++---------- src/network/networkd-route.h | 5 +- 6 files changed, 29 insertions(+), 39 deletions(-) diff --git a/src/network/networkd-dhcp-prefix-delegation.c b/src/network/networkd-dhcp-prefix-delegation.c index b8b03f6d3b..d8f9a2c053 100644 --- a/src/network/networkd-dhcp-prefix-delegation.c +++ b/src/network/networkd-dhcp-prefix-delegation.c @@ -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); diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index be7abcf6f3..1a1836cf66 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -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) { diff --git a/src/network/networkd-dhcp6.c b/src/network/networkd-dhcp6.c index 26ed034bbe..eb1420be5c 100644 --- a/src/network/networkd-dhcp6.c +++ b/src/network/networkd-dhcp6.c @@ -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) { diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 7186187fd8..488c8c0294 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -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")); } diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 3a33769f8b..efb121cb82 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -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 (route_exists(route)) - return route_remove(route); + /* If the route is remembered by the manager, then use the remembered object. */ + (void) route_get(manager, route, &route); - if (route->state == 0) - route_free(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 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; diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 090bf34a61..51a06dd0f1 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -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,