mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-27 07:00:34 +01:00
core: fix nm_netns_ip_route_ecmp_commit() to return regular single-hop route
nm_netns_ip_route_ecmp_commit() returns the ECMP routes that didn't find
a merge-partner. It expects NML3Cfg to configure such routes in
platform.
Note that these routes have a positive "weight", which was used for
tracking the ECMP information in NML3Cfg and NMNetns.
But in kernel, single-hop routes don't have a weight. All routes in
NMPlatform will have a zero weight. While it somewhat works to call
nm_platform_ip_route_add() with a single-hop route of non-zero weight,
the result will be a different(!) route. This means for example that
nm_platform_ip_route_sync() will search the NMPlatform cache for whether
the routes exist, but in the cache single-hop routes with positive weight
never exist.
The proper solution is that nm_netns_ip_route_ecmp_commit() does not
tell NML3Cfg to add a route, that cannot be added. Instead, it must
first normalize the weight to zero, to have a "regular" single-hop
route.
Fixes: 5b5ce42682 ('nm-netns: track ECMP routes')
This commit is contained in:
parent
389ac096e3
commit
ca7cbf6fea
1 changed files with 26 additions and 1 deletions
|
|
@ -916,6 +916,8 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self,
|
|||
}
|
||||
|
||||
if (route->n_nexthops <= 1) {
|
||||
NMPObject *route_clone;
|
||||
|
||||
/* This is a single hop route. Return it to the caller. */
|
||||
if (!*out_singlehop_routes) {
|
||||
/* Note that the returned array does not own a reference. This
|
||||
|
|
@ -924,7 +926,30 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self,
|
|||
*out_singlehop_routes =
|
||||
g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
|
||||
}
|
||||
g_ptr_array_add(*out_singlehop_routes, (gpointer) nmp_object_ref(route_obj));
|
||||
|
||||
/* We have here a IPv4 single-hop route. For internal tracking purposes,
|
||||
* this route has a positive "weight" (which was used to mark it as a candidate
|
||||
* for ECMP merging). Now we want to return this route to NML3Cfg and add it
|
||||
* as regular single-hop routes.
|
||||
*
|
||||
* A single-hop route in kernel always has a "weight" of zero. This route
|
||||
* cannot be added as-is. Well, if we would, then the result would be
|
||||
* a different(!) route (with a zero "weight").
|
||||
*
|
||||
* Anticipate that and normalize the route now to be a regular single-hop
|
||||
* route (with weight zero). nm_platform_ip_route_normalize() does that.
|
||||
* We really want to return a regular route here, not the route with a positive
|
||||
* weight that exists for internal tracking purposes.
|
||||
*/
|
||||
nm_assert(route_obj->ip4_route.weight > 0u);
|
||||
nm_assert(NMP_OBJECT_GET_TYPE(route_obj) == NMP_OBJECT_TYPE_IP4_ROUTE);
|
||||
|
||||
route_clone = nmp_object_clone(route_obj, FALSE);
|
||||
nm_platform_ip_route_normalize(AF_INET,
|
||||
NMP_OBJECT_CAST_IP_ROUTE(route_clone),
|
||||
NMP_IP_ROUTE_NORMALIZE_FLAGS_NONE);
|
||||
g_ptr_array_add(*out_singlehop_routes, route_clone);
|
||||
|
||||
if (changed) {
|
||||
_LOGT("ecmp-route: single-hop %s",
|
||||
nmp_object_to_string(route_obj,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue