1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-05 13:18:06 +03:00

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 f22b586a21.
This commit is contained in:
Yu Watanabe 2024-01-09 15:49:20 +09:00
parent 6b7309b6fb
commit 3caed9ea08
6 changed files with 29 additions and 39 deletions

View 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);

View 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) {

View 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) {

View 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"));
}

View 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 (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;

View 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,