From: Yu Watanabe Date: Sun, 14 Jan 2024 05:50:19 +0000 (+0900) Subject: network/route-nexthop: introduce route_adjust_nexthops() and route_nexthops_needs_adj... X-Git-Tag: v256-rc1~1108^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=acc3fc9e5f08a95338f983321f98426dbf49585c;p=thirdparty%2Fsystemd.git network/route-nexthop: introduce route_adjust_nexthops() and route_nexthops_needs_adjust() These are not used in this commit, but will be used later. Preparation for later commits. --- diff --git a/src/network/networkd-route-nexthop.c b/src/network/networkd-route-nexthop.c index 6ea68afdc8a..9e14c695be1 100644 --- a/src/network/networkd-route-nexthop.c +++ b/src/network/networkd-route-nexthop.c @@ -200,6 +200,117 @@ int route_nexthops_copy(const Route *src, const RouteNextHop *nh, Route *dest) { return 0; } +static bool multipath_routes_needs_adjust(const Route *route) { + assert(route); + + RouteNextHop *nh; + ORDERED_SET_FOREACH(nh, route->nexthops) + if (route->nexthop.ifindex == 0) + return true; + + return false; +} + +bool route_nexthops_needs_adjust(const Route *route) { + assert(route); + + if (route->nexthop_id != 0) + /* At this stage, the nexthop may not be configured, or may be under reconfiguring. + * Hence, we cannot know if the nexthop is blackhole or not. */ + return route->type != RTN_BLACKHOLE; + + if (route_type_is_reject(route)) + return false; + + if (ordered_set_isempty(route->nexthops)) + return route->nexthop.ifindex == 0; + + return multipath_routes_needs_adjust(route); +} + +static bool route_nexthop_set_ifindex(RouteNextHop *nh, Link *link) { + assert(nh); + assert(link); + assert(link->manager); + + if (nh->ifindex > 0) { + nh->ifname = mfree(nh->ifname); + return false; + } + + /* If an interface name is specified, use it. Otherwise, use the interface that requests this route. */ + if (nh->ifname && link_get_by_name(link->manager, nh->ifname, &link) < 0) + return false; + + nh->ifindex = link->ifindex; + nh->ifname = mfree(nh->ifname); + return true; /* updated */ +} + +int route_adjust_nexthops(Route *route, Link *link) { + int r; + + assert(route); + assert(link); + assert(link->manager); + + /* When an IPv4 route has nexthop id and the nexthop type is blackhole, even though kernel sends + * RTM_NEWROUTE netlink message with blackhole type, kernel's internal route type fib_rt_info::type + * may not be blackhole. Thus, we cannot know the internal value. Moreover, on route removal, the + * matching is done with the hidden value if we set non-zero type in RTM_DELROUTE message. So, + * here let's set route type to BLACKHOLE when the nexthop is blackhole. */ + if (route->nexthop_id != 0) { + NextHop *nexthop; + + r = nexthop_is_ready(link->manager, route->nexthop_id, &nexthop); + if (r <= 0) + return r; /* r == 0 means the nexthop is under (re-)configuring. + * We cannot use the currently remembered information. */ + + if (!nexthop->blackhole) + return false; + + if (route->type == RTN_BLACKHOLE) + return false; + + route->type = RTN_BLACKHOLE; + return true; /* updated */ + } + + if (route_type_is_reject(route)) + return false; + + if (ordered_set_isempty(route->nexthops)) + return route_nexthop_set_ifindex(&route->nexthop, link); + + if (!multipath_routes_needs_adjust(route)) + return false; + + _cleanup_ordered_set_free_ OrderedSet *nexthops = NULL; + for (;;) { + _cleanup_(route_nexthop_freep) RouteNextHop *nh = NULL; + + nh = ordered_set_steal_first(route->nexthops); + if (!nh) + break; + + (void) route_nexthop_set_ifindex(nh, link); + + r = ordered_set_ensure_put(&nexthops, &route_nexthop_hash_ops, nh); + if (r == -EEXIST) + continue; /* Duplicated? Let's drop the nexthop. */ + if (r < 0) + return r; + assert(r > 0); + + TAKE_PTR(nh); + } + + ordered_set_free(route->nexthops); + route->nexthops = TAKE_PTR(nexthops); + return true; /* updated */ +} + int route_nexthop_get_link(Manager *manager, Link *link, const RouteNextHop *nh, Link **ret) { assert(manager); assert(nh); diff --git a/src/network/networkd-route-nexthop.h b/src/network/networkd-route-nexthop.h index 0d305c7231c..a63409c9e28 100644 --- a/src/network/networkd-route-nexthop.h +++ b/src/network/networkd-route-nexthop.h @@ -35,6 +35,8 @@ void route_nexthops_hash_func(const Route *route, struct siphash *state); int route_nexthops_compare_func(const Route *a, const Route *b); int route_nexthops_copy(const Route *src, const RouteNextHop *nh, Route *dest); +bool route_nexthops_needs_adjust(const Route *route); +int route_adjust_nexthops(Route *route, Link *link); int route_nexthop_get_link(Manager *manager, Link *link, const RouteNextHop *nh, Link **ret); int route_nexthops_is_ready_to_configure(const Route *route, Link *link);