From: Yu Watanabe Date: Wed, 28 Apr 2021 17:42:42 +0000 (+0900) Subject: network: do not remove reject type routes more than once X-Git-Tag: v249-rc1~323^2~1 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8a9ce525d1d5830c074451dd2b62865958ac7308;p=thirdparty%2Fsystemd.git network: do not remove reject type routes more than once Usually, removing non-existing addresses, routes, and etc, are safe. However, when multiple interfaces lost their carriers simultaneously, then manager_drop_routes() and manager_drop_nexthop() are called multiple times. If a route with a blackhole nexthop is removed in that process, the later removal requests of the route fail with -EINVAL, rathar than -ESRCH, as the corresponding nexthop does not exist anymore. So, let's not remove routes which managed by Manager more than once. --- diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 22e19cc1466..c1e5f6b4b82 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -854,6 +854,9 @@ static int manager_drop_routes_internal(Manager *manager, bool foreign, const Li routes = foreign ? manager->routes_foreign : manager->routes; SET_FOREACH(route, routes) { + if (route->removing) + continue; + /* Do not touch routes managed by the kernel. */ if (route->protocol == RTPROT_KERNEL) continue; @@ -867,6 +870,8 @@ static int manager_drop_routes_internal(Manager *manager, bool foreign, const Li k = route_remove(route, manager, NULL, NULL); if (k < 0 && r >= 0) r = k; + + route->removing = true; } return r; diff --git a/src/network/networkd-route.h b/src/network/networkd-route.h index 331f1f9ea2e..ddb433817a9 100644 --- a/src/network/networkd-route.h +++ b/src/network/networkd-route.h @@ -52,6 +52,7 @@ typedef struct Route { bool protocol_set:1; bool pref_set:1; bool gateway_from_dhcp_or_ra:1; + bool removing:1; union in_addr_union gw; union in_addr_union dst;