From: Yu Watanabe Date: Sun, 26 Jan 2025 20:15:48 +0000 (+0900) Subject: network/route: adjust configuration source based on Gateway= setting X-Git-Tag: v258-rc1~1419^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e92f40c6b0b92dbde9f08f24ceb17f50249cf2c1;p=thirdparty%2Fsystemd.git network/route: adjust configuration source based on Gateway= setting 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. --- diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 30abef49a23..0dfb1737e8e 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -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) { diff --git a/src/network/networkd-ndisc.c b/src/network/networkd-ndisc.c index 42bed0d642a..9c579db4458 100644 --- a/src/network/networkd-ndisc.c +++ b/src/network/networkd-ndisc.c @@ -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) diff --git a/src/network/networkd-route-nexthop.c b/src/network/networkd-route-nexthop.c index bf0271807bf..9482b25bb8e 100644 --- a/src/network/networkd-route-nexthop.c +++ b/src/network/networkd-route-nexthop.c @@ -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. */ diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index f6386e0426a..ff93c1d27de 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -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)