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.
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;
k = route_remove(route, manager, NULL, NULL);
if (k < 0 && r >= 0)
r = k;
+
+ route->removing = true;
}
return r;
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;