]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network/route: adjust configuration source based on Gateway= setting
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 26 Jan 2025 20:15:48 +0000 (05:15 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 26 Jan 2025 21:29:26 +0000 (06:29 +0900)
If Gateway=_dhcp4/_ra, the route will be anyway configured with
NETWORK_CONFIG_SOURCE_DHCP4/_NDISC. See dhcp4_request_route() and
ndisc_route_prepare().

This is mostly for avoiding link_drop_routes(), which drops unnecessary static
and/or foreign routes, unexpectedly filtering an existing route with the
route specified with Gateway=_dhcp4/_ra.

src/network/networkd-dhcp4.c
src/network/networkd-ndisc.c
src/network/networkd-route-nexthop.c
src/network/networkd-route.c

index 30abef49a23a46a12a157f5d0a2b5c809357d01e..0dfb1737e8e807442a2e0d6253386c2051056c19 100644 (file)
@@ -643,13 +643,11 @@ static int dhcp4_request_semi_static_routes(Link *link) {
                 _cleanup_(route_unrefp) Route *route = NULL;
                 struct in_addr gw;
 
-                if (!rt->gateway_from_dhcp_or_ra)
-                        continue;
-
-                if (rt->nexthop.family != AF_INET)
+                if (rt->source != NETWORK_CONFIG_SOURCE_DHCP4)
                         continue;
 
                 assert(rt->family == AF_INET);
+                assert(rt->nexthop.family == AF_INET);
 
                 r = dhcp4_find_gateway_for_destination(link, &rt->dst.in, rt->dst_prefixlen, &gw);
                 if (r == -EHOSTUNREACH) {
index 42bed0d642ad025eb81110fcc9cff0bffffb93d1..9c579db44589b5fa614f75e2c30d111328a8fb80 100644 (file)
@@ -1083,11 +1083,10 @@ static int ndisc_router_drop_default(Link *link, sd_ndisc_router *rt) {
         HASHMAP_FOREACH(route_gw, link->network->routes_by_section) {
                 _cleanup_(route_unrefp) Route *tmp = NULL;
 
-                if (!route_gw->gateway_from_dhcp_or_ra)
+                if (route_gw->source != NETWORK_CONFIG_SOURCE_NDISC)
                         continue;
 
-                if (route_gw->nexthop.family != AF_INET6)
-                        continue;
+                assert(route_gw->nexthop.family == AF_INET6);
 
                 r = route_dup(route_gw, NULL, &tmp);
                 if (r < 0)
@@ -1158,11 +1157,10 @@ static int ndisc_router_process_default(Link *link, sd_ndisc_router *rt) {
         HASHMAP_FOREACH(route_gw, link->network->routes_by_section) {
                 _cleanup_(route_unrefp) Route *route = NULL;
 
-                if (!route_gw->gateway_from_dhcp_or_ra)
+                if (route_gw->source != NETWORK_CONFIG_SOURCE_NDISC)
                         continue;
 
-                if (route_gw->nexthop.family != AF_INET6)
-                        continue;
+                assert(route_gw->nexthop.family == AF_INET6);
 
                 r = route_dup(route_gw, NULL, &route);
                 if (r < 0)
index bf0271807bf48596a4ea4bfe03cb6bbb349ac543..9482b25bb8e1b84ea699ac0bab6083a90887a000 100644 (file)
@@ -844,11 +844,24 @@ int route_section_verify_nexthops(Route *route) {
                                 return log_route_section(route, "Invalid route family.");
                         }
 
-                if (route->nexthop.family == AF_INET && !FLAGS_SET(route->network->dhcp, ADDRESS_FAMILY_IPV4))
-                        return log_route_section(route, "Gateway=\"_dhcp4\" is specified but DHCPv4 client is disabled.");
+                switch (route->nexthop.family) {
+                case AF_INET:
+                        if (!FLAGS_SET(route->network->dhcp, ADDRESS_FAMILY_IPV4))
+                                return log_route_section(route, "Gateway=\"_dhcp4\" is specified but DHCPv4 client is disabled.");
 
-                if (route->nexthop.family == AF_INET6 && route->network->ndisc == 0)
-                        return log_route_section(route, "Gateway=\"_ipv6ra\" is specified but IPv6AcceptRA= is disabled.");
+                        route->source = NETWORK_CONFIG_SOURCE_DHCP4;
+                        break;
+
+                case AF_INET6:
+                        if (route->network->ndisc == 0)
+                                return log_route_section(route, "Gateway=\"_ipv6ra\" is specified but IPv6AcceptRA= is disabled.");
+
+                        route->source = NETWORK_CONFIG_SOURCE_NDISC;
+                        break;
+
+                default:
+                        assert_not_reached();
+                }
         }
 
         /* When only Gateway= is specified, assume the route family based on the Gateway address. */
index f6386e0426ad2fd99099696d3198f3a756e4a19d..ff93c1d27de08403298133bc7ae58d8eff9f568c 100644 (file)
@@ -1065,7 +1065,7 @@ int link_request_static_routes(Link *link, bool only_ipv4) {
         link->static_routes_configured = false;
 
         HASHMAP_FOREACH(route, link->network->routes_by_section) {
-                if (route->gateway_from_dhcp_or_ra)
+                if (route->source != NETWORK_CONFIG_SOURCE_STATIC)
                         continue;
 
                 if (only_ipv4 && route->family != AF_INET)
@@ -1519,6 +1519,9 @@ int link_drop_routes(Link *link, bool only_static) {
                         continue;
 
                 HASHMAP_FOREACH(route, other->network->routes_by_section) {
+                        if (route->source != NETWORK_CONFIG_SOURCE_STATIC)
+                                continue;
+
                         if (route->family == AF_INET || ordered_set_isempty(route->nexthops)) {
                                 r = link_unmark_route(other, route, NULL);
                                 if (r < 0)