network: do not set nexthop ID, gateway, and multipath routes simultaneously
See kernel's rtm_to_fib_config() in net/ipv4/fib_frontend.c and rtm_to_fib6_config() in net/ipv6/route.c. Note that if both gateway and multipath routes are specified, then kernel ignores gateway. So, strictly speaking, setting both gateway and multipath routes is allowed by kernel. But such situation is mostly user's misconfiguration. Let's refuse it. Note that the conditions newly added in route_configure() are redundant, as all static configurations are already verified in route_section_verify(), and dynamic configurations do not set nexthop_id or multipath routes. Just for safety.
This commit is contained in:
@@ -645,7 +645,7 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req
|
||||
|
||||
/* link may be NULL */
|
||||
|
||||
if (in_addr_is_set(route->gw_family, &route->gw)) {
|
||||
if (in_addr_is_set(route->gw_family, &route->gw) && route->nexthop_id == 0) {
|
||||
if (route->gw_family == route->family) {
|
||||
r = netlink_message_append_in_addr_union(req, RTA_GATEWAY, route->gw_family, &route->gw);
|
||||
if (r < 0)
|
||||
@@ -1100,8 +1100,8 @@ int route_configure(
|
||||
Route **ret) {
|
||||
|
||||
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
|
||||
int r, k = 0;
|
||||
Route *nr;
|
||||
int r, k;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
@@ -1188,19 +1188,22 @@ int route_configure(
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_METRICS attribute: %m");
|
||||
|
||||
r = append_nexthops(route, req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
|
||||
|
||||
if (ordered_set_isempty(route->multipath_routes)) {
|
||||
if (route->nexthop_id != 0 ||
|
||||
in_addr_is_set(route->gw_family, &route->gw) ||
|
||||
ordered_set_isempty(route->multipath_routes)) {
|
||||
k = route_add_and_setup_timer(link, route, NULL, &nr);
|
||||
if (k < 0)
|
||||
return k;
|
||||
} else {
|
||||
MultipathRoute *m;
|
||||
|
||||
r = append_nexthops(route, req);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m");
|
||||
|
||||
assert(!ret);
|
||||
|
||||
k = 0;
|
||||
ORDERED_SET_FOREACH(m, route->multipath_routes) {
|
||||
r = route_add_and_setup_timer(link, route, m, NULL);
|
||||
if (r < 0)
|
||||
@@ -2766,8 +2769,17 @@ static int route_section_verify(Route *route, Network *network) {
|
||||
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 &&
|
||||
(in_addr_is_set(route->gw_family, &route->gw) ||
|
||||
(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=. "
|
||||
|
||||
Reference in New Issue
Block a user