]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: do not remove static routes on other interfaces that are currently in the...
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 15 Mar 2025 00:38:09 +0000 (09:38 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 15 Mar 2025 01:26:20 +0000 (10:26 +0900)
Otherwise, even if .network file has KeepConfiguration=yes, routes on
an interfaces may be removed on restart.

Fixes a bug introduced by 8d01e44c1f0e00b414d36bd1b46ecff548242208.

src/network/networkd-route.c

index 11fa624d14ee44a69a3fdf0678ac5c1d827b32b8..67c5d5ae8e8a5832517c6f20a040fff7a9b0bb0e 100644 (file)
@@ -1538,15 +1538,22 @@ int link_drop_routes(Link *link, bool only_static) {
                 if (!link_should_mark_config(link, only_static, route->source, route->protocol))
                         continue;
 
-                /* When we also mark foreign routes, do not mark routes assigned to other interfaces.
-                 * Otherwise, routes assigned to unmanaged interfaces will be dropped.
-                 * Note, route_get_link() does not provide assigned link for routes with an unreachable type
-                 * or IPv4 multipath routes. So, the current implementation does not support managing such
-                 * routes by other daemon or so, unless ManageForeignRoutes=no. */
-                if (!only_static) {
-                        Link *route_link;
+                Link *route_link = NULL;
+                if (route_get_link(link->manager, route, &route_link) >= 0 && route_link != link) {
+                        /* When we also mark foreign routes, do not mark routes assigned to other interfaces.
+                         * Otherwise, routes assigned to unmanaged interfaces will be dropped.
+                         * Note, route_get_link() does not provide assigned link for routes with an
+                         * unreachable type or IPv4 multipath routes. So, the current implementation does not
+                         * support managing such routes by other daemon or so, unless ManageForeignRoutes=no. */
+                        if (!only_static)
+                                continue;
 
-                        if (route_get_link(link->manager, route, &route_link) >= 0 && route_link != link)
+                        /* When we mark only static routes, do not mark routes assigned to links that we do
+                         * not know the assignment of .network files to the interfaces. Otherwise, if an
+                         * interface is in the pending state, even if the .network file to be assigned to the
+                         * interface has KeepConfiguration=yes, routes on the interface will be removed.
+                         * This is especially important when systemd-networkd is restarted. */
+                        if (!IN_SET(route_link->state, LINK_STATE_UNMANAGED, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
                                 continue;
                 }