From c5fa06036e050e540284c1be34c1d08da271493a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 28 Nov 2023 15:20:33 +0100 Subject: [PATCH] core: normalize the weight of routes in nm_netns_ip_route_ecmp_commit() This is useful, to avoid oddities. The receiver of this route is NML3Cfg, which tracks non-is-kernel routes. For those, the weight very much matters to indicate whether this is a ECMP route or single-hop. Here we clearly return single-hop route. Normalize the weight, to make that clear. Fixes: 5b5ce4268211 ('nm-netns: track ECMP routes') --- src/core/nm-netns.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/core/nm-netns.c b/src/core/nm-netns.c index 7c279cafc3..30aa7342f3 100644 --- a/src/core/nm-netns.c +++ b/src/core/nm-netns.c @@ -916,6 +916,8 @@ nm_netns_ip_route_ecmp_commit(NMNetns *self, } if (route->n_nexthops <= 1) { + NMPObject *rt; + /* 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,26 @@ 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)); + + /* The weight is odd. In single-hop objects received from kernel, it's + * always zero (and "is_kernel") is set. For NM-internal purposes, the weight + * is relevant. + * + * There is some special handling for comparing "is_kernel" routes with others. + * See _CMP_WEIGHT_SEMANTICALLY(). It still brings an odd asymmetry, and we would + * best avoid that. + * + * Here, we are going to return a route to NML3Cfg, which doesn't track "is_kernel" + * routes. But the route we are going to return, really should have weight zero, + * to avoid the oddity. + * + * Normalize the weight to zero. */ + nm_assert(route_obj->ip4_route.weight > 0u); + + rt = nmp_object_clone(route_obj, FALSE); + rt->ip4_route.weight = 0; + g_ptr_array_add(*out_singlehop_routes, rt); + if (changed) { _LOGT("ecmp-route: single-hop %s", nmp_object_to_string(route_obj,