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.
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user