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.
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user