From: Yu Watanabe Date: Sat, 13 Jan 2024 01:06:21 +0000 (+0900) Subject: network/route: split out route_section_verify_nexthops() X-Git-Tag: v256-rc1~1163^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0db96961b4795f7fcdc5e067741482660e5f4733;p=thirdparty%2Fsystemd.git network/route: split out route_section_verify_nexthops() No effective functional change, just refactoring and preparation for later commits. --- diff --git a/src/network/networkd-route-nexthop.c b/src/network/networkd-route-nexthop.c index f1d81f2014f..4dc86d3b76d 100644 --- a/src/network/networkd-route-nexthop.c +++ b/src/network/networkd-route-nexthop.c @@ -5,11 +5,128 @@ #include "alloc-util.h" #include "extract-word.h" #include "netlink-util.h" +#include "networkd-network.h" #include "networkd-route.h" #include "networkd-route-nexthop.h" +#include "networkd-route-util.h" #include "parse-util.h" #include "string-util.h" +int route_section_verify_nexthops(Route *route) { + assert(route); + assert(route->section); + assert(route->network); + + if (route->gateway_from_dhcp_or_ra) { + if (route->gw_family == AF_UNSPEC) + /* When deprecated Gateway=_dhcp is set, then assume gateway family based on other settings. */ + switch (route->family) { + case AF_UNSPEC: + log_warning("%s: Deprecated value \"_dhcp\" is specified for Gateway= in [Route] section from line %u. " + "Please use \"_dhcp4\" or \"_ipv6ra\" instead. Assuming \"_dhcp4\".", + route->section->filename, route->section->line); + + route->gw_family = route->family = AF_INET; + break; + case AF_INET: + case AF_INET6: + log_warning("%s: Deprecated value \"_dhcp\" is specified for Gateway= in [Route] section from line %u. " + "Assuming \"%s\" based on Destination=, Source=, or PreferredSource= setting.", + route->section->filename, route->section->line, route->family == AF_INET ? "_dhcp4" : "_ipv6ra"); + + route->gw_family = route->family; + break; + default: + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: Invalid route family. Ignoring [Route] section from line %u.", + route->section->filename, route->section->line); + } + + if (route->gw_family == AF_INET && !FLAGS_SET(route->network->dhcp, ADDRESS_FAMILY_IPV4)) + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: Gateway=\"_dhcp4\" is specified but DHCPv4 client is disabled. " + "Ignoring [Route] section from line %u.", + route->section->filename, route->section->line); + + if (route->gw_family == AF_INET6 && !route->network->ipv6_accept_ra) + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: Gateway=\"_ipv6ra\" is specified but IPv6AcceptRA= is disabled. " + "Ignoring [Route] section from line %u.", + route->section->filename, route->section->line); + } + + /* When only Gateway= is specified, assume the route family based on the Gateway address. */ + if (route->family == AF_UNSPEC) + route->family = route->gw_family; + + if (route->family == AF_UNSPEC) { + assert(route->section); + + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: Route section without Gateway=, Destination=, Source=, " + "or PreferredSource= field configured. " + "Ignoring [Route] section from line %u.", + route->section->filename, route->section->line); + } + + if (route->gateway_onlink < 0 && in_addr_is_set(route->gw_family, &route->gw) && + ordered_hashmap_isempty(route->network->addresses_by_section)) { + /* If no address is configured, in most cases the gateway cannot be reachable. + * TODO: we may need to improve the condition above. */ + log_warning("%s: Gateway= without static address configured. " + "Enabling GatewayOnLink= option.", + route->section->filename); + route->gateway_onlink = true; + } + + if (route->gateway_onlink >= 0) + SET_FLAG(route->flags, RTNH_F_ONLINK, route->gateway_onlink); + + if (route->family == AF_INET6) { + if (route->gw_family == AF_INET) + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: IPv4 gateway is configured for IPv6 route. " + "Ignoring [Route] section from line %u.", + route->section->filename, route->section->line); + + MultipathRoute *m; + ORDERED_SET_FOREACH(m, route->multipath_routes) + if (m->gateway.family == AF_INET) + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: IPv4 multipath route is specified for IPv6 route. " + "Ignoring [Route] section from line %u.", + route->section->filename, route->section->line); + } + + if (route->nexthop_id != 0 && + (route->gateway_from_dhcp_or_ra || + in_addr_is_set(route->gw_family, &route->gw) || + !ordered_set_isempty(route->multipath_routes))) + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: NextHopId= cannot be specified with Gateway= or MultiPathRoute=. " + "Ignoring [Route] section from line %u.", + route->section->filename, route->section->line); + + if (route_type_is_reject(route) && + (route->gateway_from_dhcp_or_ra || + in_addr_is_set(route->gw_family, &route->gw) || + !ordered_set_isempty(route->multipath_routes))) + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: reject type route cannot be specified with Gateway= or MultiPathRoute=. " + "Ignoring [Route] section from line %u.", + route->section->filename, route->section->line); + + if ((route->gateway_from_dhcp_or_ra || + in_addr_is_set(route->gw_family, &route->gw)) && + !ordered_set_isempty(route->multipath_routes)) + return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), + "%s: Gateway= cannot be specified with MultiPathRoute=. " + "Ignoring [Route] section from line %u.", + route->section->filename, route->section->line); + + return 0; +} + int config_parse_gateway( const char *unit, const char *filename, diff --git a/src/network/networkd-route-nexthop.h b/src/network/networkd-route-nexthop.h index df5265c5082..fb935749865 100644 --- a/src/network/networkd-route-nexthop.h +++ b/src/network/networkd-route-nexthop.h @@ -3,6 +3,10 @@ #include "conf-parser.h" +typedef struct Route Route; + +int route_section_verify_nexthops(Route *route); + CONFIG_PARSER_PROTOTYPE(config_parse_gateway); CONFIG_PARSER_PROTOTYPE(config_parse_route_gateway_onlink); CONFIG_PARSER_PROTOTYPE(config_parse_route_nexthop); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index e890d0a2e96..04b63805137 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -2236,79 +2236,34 @@ int config_parse_route_type( return 0; } -static int route_section_verify(Route *route, Network *network) { +static int route_section_verify(Route *route) { + int r; + + assert(route); + assert(route->section); + assert(route->network); + if (section_is_invalid(route->section)) return -EINVAL; /* Currently, we do not support static route with finite lifetime. */ assert(route->lifetime_usec == USEC_INFINITY); - if (route->gateway_from_dhcp_or_ra) { - if (route->gw_family == AF_UNSPEC) { - /* When deprecated Gateway=_dhcp is set, then assume gateway family based on other settings. */ - switch (route->family) { - case AF_UNSPEC: - log_warning("%s: Deprecated value \"_dhcp\" is specified for Gateway= in [Route] section from line %u. " - "Please use \"_dhcp4\" or \"_ipv6ra\" instead. Assuming \"_dhcp4\".", - route->section->filename, route->section->line); - route->family = AF_INET; - break; - case AF_INET: - case AF_INET6: - log_warning("%s: Deprecated value \"_dhcp\" is specified for Gateway= in [Route] section from line %u. " - "Assuming \"%s\" based on Destination=, Source=, or PreferredSource= setting.", - route->section->filename, route->section->line, route->family == AF_INET ? "_dhcp4" : "_ipv6ra"); - break; - default: - return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: Invalid route family. Ignoring [Route] section from line %u.", - route->section->filename, route->section->line); - } - route->gw_family = route->family; - } - - if (route->gw_family == AF_INET && !FLAGS_SET(network->dhcp, ADDRESS_FAMILY_IPV4)) - return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: Gateway=\"_dhcp4\" is specified but DHCPv4 client is disabled. " - "Ignoring [Route] section from line %u.", - route->section->filename, route->section->line); - - if (route->gw_family == AF_INET6 && !network->ipv6_accept_ra) - return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: Gateway=\"_ipv6ra\" is specified but IPv6AcceptRA= is disabled. " - "Ignoring [Route] section from line %u.", - route->section->filename, route->section->line); - } - - /* When only Gateway= is specified, assume the route family based on the Gateway address. */ - if (route->family == AF_UNSPEC) - route->family = route->gw_family; - - if (route->family == AF_UNSPEC) { - assert(route->section); - - return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: Route section without Gateway=, Destination=, Source=, " - "or PreferredSource= field configured. " - "Ignoring [Route] section from line %u.", - route->section->filename, route->section->line); - } - - if (route->family == AF_INET6 && route->gw_family == AF_INET) - return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: IPv4 gateway is configured for IPv6 route. " - "Ignoring [Route] section from line %u.", - route->section->filename, route->section->line); + r = route_section_verify_nexthops(route); + if (r < 0) + return r; - if (!route->table_set && network->vrf) { - route->table = VRF(network->vrf)->table; + /* table */ + if (!route->table_set && route->network->vrf) { + route->table = VRF(route->network->vrf)->table; route->table_set = true; } if (!route->table_set && IN_SET(route->type, RTN_LOCAL, RTN_BROADCAST, RTN_ANYCAST, RTN_NAT)) route->table = RT_TABLE_LOCAL; - if (!route->scope_set && route->family != AF_INET6) { + /* scope */ + if (!route->scope_set && route->family == AF_INET) { if (IN_SET(route->type, RTN_LOCAL, RTN_NAT)) route->scope = RT_SCOPE_HOST; else if (IN_SET(route->type, RTN_BROADCAST, RTN_ANYCAST, RTN_MULTICAST)) @@ -2321,54 +2276,16 @@ static int route_section_verify(Route *route, Network *network) { route->scope = RT_SCOPE_LINK; } - if (route->scope != RT_SCOPE_UNIVERSE && route->family == AF_INET6) { - log_warning("%s: Scope= is specified for IPv6 route. It will be ignored.", route->section->filename); - route->scope = RT_SCOPE_UNIVERSE; - } - - if (route->family == AF_INET6 && route->priority == 0) - route->priority = IP6_RT_PRIO_USER; - - if (route->gateway_onlink < 0 && in_addr_is_set(route->gw_family, &route->gw) && - ordered_hashmap_isempty(network->addresses_by_section)) { - /* If no address is configured, in most cases the gateway cannot be reachable. - * TODO: we may need to improve the condition above. */ - log_warning("%s: Gateway= without static address configured. " - "Enabling GatewayOnLink= option.", - network->filename); - route->gateway_onlink = true; - } - - if (route->gateway_onlink >= 0) - SET_FLAG(route->flags, RTNH_F_ONLINK, route->gateway_onlink); - + /* IPv6 route */ if (route->family == AF_INET6) { - MultipathRoute *m; + if (route->scope != RT_SCOPE_UNIVERSE) { + log_warning("%s: Scope= is specified for IPv6 route. It will be ignored.", route->section->filename); + route->scope = RT_SCOPE_UNIVERSE; + } - ORDERED_SET_FOREACH(m, route->multipath_routes) - if (m->gateway.family == AF_INET) - return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: IPv4 multipath route is specified for IPv6 route. " - "Ignoring [Route] section from line %u.", - route->section->filename, route->section->line); - } - - if ((route->gateway_from_dhcp_or_ra || - in_addr_is_set(route->gw_family, &route->gw)) && - !ordered_set_isempty(route->multipath_routes)) - return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: Gateway= cannot be specified with MultiPathRoute=. " - "Ignoring [Route] section from line %u.", - route->section->filename, route->section->line); - - if (route->nexthop_id > 0 && - (route->gateway_from_dhcp_or_ra || - in_addr_is_set(route->gw_family, &route->gw) || - !ordered_set_isempty(route->multipath_routes))) - return log_warning_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: NextHopId= cannot be specified with Gateway= or MultiPathRoute=. " - "Ignoring [Route] section from line %u.", - route->section->filename, route->section->line); + if (route->priority == 0) + route->priority = IP6_RT_PRIO_USER; + } return 0; } @@ -2379,6 +2296,6 @@ void network_drop_invalid_routes(Network *network) { assert(network); HASHMAP_FOREACH(route, network->routes_by_section) - if (route_section_verify(route, network) < 0) + if (route_section_verify(route) < 0) route_free(route); }