From 08c2fcdc0db98cc91d74c0dbdd203f5a86c3ce04 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 12 Jun 2021 05:34:49 +0900 Subject: [PATCH 1/2] network: route: set link ifindex when multi-path routes specified without interface name And do not set RTA_OIF attribute when multi-path routes are specified. See kernel's fib_get_nhs() in net/ipv4/fib_semantics.c. Fixes #19890. --- src/network/networkd-route.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 721d49af75..427856ac26 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -967,7 +967,9 @@ static int route_set_netlink_message(const Route *route, sd_netlink_message *req return log_link_error_errno(link, r, "Could not append RTA_TABLE attribute: %m"); } - if (!route_type_is_reject(route) && route->nexthop_id == 0) { + if (!route_type_is_reject(route) && + route->nexthop_id == 0 && + ordered_set_isempty(route->multipath_routes)) { assert(link); /* Those routes must be attached to a specific link */ r = sd_netlink_message_append_u32(req, RTA_OIF, link->ifindex); @@ -1358,7 +1360,7 @@ static int route_add_and_setup_timer(Link *link, const Route *route, unsigned *r return 0; } -static int append_nexthop_one(const Route *route, const MultipathRoute *m, struct rtattr **rta, size_t offset) { +static int append_nexthop_one(const Link *link, const Route *route, const MultipathRoute *m, struct rtattr **rta, size_t offset) { struct rtnexthop *rtnh; struct rtattr *new_rta; int r; @@ -1376,7 +1378,7 @@ static int append_nexthop_one(const Route *route, const MultipathRoute *m, struc rtnh = (struct rtnexthop *)((uint8_t *) *rta + offset); *rtnh = (struct rtnexthop) { .rtnh_len = sizeof(*rtnh), - .rtnh_ifindex = m->ifindex, + .rtnh_ifindex = m->ifindex > 0 ? m->ifindex : link->ifindex, .rtnh_hops = m->weight, }; @@ -1403,13 +1405,17 @@ clear: return r; } -static int append_nexthops(const Route *route, sd_netlink_message *req) { +static int append_nexthops(const Link *link, const Route *route, sd_netlink_message *req) { _cleanup_free_ struct rtattr *rta = NULL; struct rtnexthop *rtnh; MultipathRoute *m; size_t offset; int r; + assert(link); + assert(route); + assert(req); + if (ordered_set_isempty(route->multipath_routes)) return 0; @@ -1424,7 +1430,7 @@ static int append_nexthops(const Route *route, sd_netlink_message *req) { offset = (uint8_t *) RTA_DATA(rta) - (uint8_t *) rta; ORDERED_SET_FOREACH(m, route->multipath_routes) { - r = append_nexthop_one(route, m, &rta, offset); + r = append_nexthop_one(link, route, m, &rta, offset); if (r < 0) return r; @@ -1561,7 +1567,7 @@ static int route_configure( assert(route->nexthop_id == 0); assert(!in_addr_is_set(route->gw_family, &route->gw)); - r = append_nexthops(route, req); + r = append_nexthops(link, route, req); if (r < 0) return log_link_error_errno(link, r, "Could not append RTA_MULTIPATH attribute: %m"); } From 7a0fef86884b1f72d8a1d6dd1bebb97f2fdfcdfa Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 12 Jun 2021 05:37:57 +0900 Subject: [PATCH 2/2] test-network: add a testcase for MultiPathRoute= without interface name --- test/test-network/conf/25-route-static.network | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test-network/conf/25-route-static.network b/test/test-network/conf/25-route-static.network index a120daf10e..09aae8067a 100644 --- a/test/test-network/conf/25-route-static.network +++ b/test/test-network/conf/25-route-static.network @@ -82,8 +82,8 @@ Destination=149.10.123.4 [Route] Destination=192.168.10.1/32 -MultiPathRoute=149.10.124.59@dummy98 10 -MultiPathRoute=149.10.124.60@dummy98 5 +MultiPathRoute=149.10.124.59 10 +MultiPathRoute=149.10.124.60 5 [Route] Destination=2001:1234:5:7fff:ff:ff:ff:ff/128