From: Yu Watanabe Date: Tue, 9 Jan 2024 06:49:20 +0000 (+0900) Subject: network/route: introduce route_remove_and_cancel() X-Git-Tag: v256-rc1~1041^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3caed9ea0830b811ba0e5222e57c5d7deda204e3;p=thirdparty%2Fsystemd.git 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. --- diff --git a/src/network/networkd-dhcp-prefix-delegation.c b/src/network/networkd-dhcp-prefix-delegation.c index b8b03f6d3b9..d8f9a2c053c 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 be7abcf6f38..1a1836cf666 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 26ed034bbea..eb1420be5c0 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 7186187fd82..488c8c02948 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 3a33769f8b5..efb121cb82f 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 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; diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 090bf34a61a..51a06dd0f14 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,