]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: do not remove reject type routes more than once
authorYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 28 Apr 2021 17:42:42 +0000 (02:42 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 29 Apr 2021 00:11:36 +0000 (09:11 +0900)
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.

src/network/networkd-route.c
src/network/networkd-route.h

index 22e19cc146689b5dcc0b9853d0f9ed03f00f5d83..c1e5f6b4b8240d6dae0f8569ee4a684d1a22ec51 100644 (file)
@@ -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;
index 331f1f9ea2e0f113bb2a6c41b6cd5bb406ee1ff7..ddb433817a9f3035002fd734e34fefc1cef76925 100644 (file)
@@ -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;