network/route: split out route_section_verify_nexthops()

No effective functional change, just refactoring and preparation for
later commits.
This commit is contained in:
Yu Watanabe
2024-01-13 10:10:32 +09:00
parent b9f29e9f52
commit 0db96961b4
3 changed files with 144 additions and 106 deletions
+117
View File
@@ -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,
+4
View File
@@ -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);
+23 -106
View File
@@ -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;
}
r = route_section_verify_nexthops(route);
if (r < 0)
return r;
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);
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,55 +2276,17 @@ 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->priority == 0)
route->priority = IP6_RT_PRIO_USER;
}
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);
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);
}