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.
This commit is contained in:
Yu Watanabe
2025-01-27 06:29:26 +09:00
parent 08570f2841
commit e92f40c6b0
4 changed files with 27 additions and 15 deletions
+2 -4
View 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) {
+4 -6
View 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)
+17 -4
View 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. */
+4 -1
View 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)