nm-netns: add onlink routes for ECMP routes

When adding a static route, kernel enforce that the gateway is
reachable. To solve this, NetworkManager generates onlink routes for
each static route. As ECMP routes does not follow the same logic than
singlehop routes, we need to add the onlink route for each hop of ECMP
routes once merged.

NML3Cfg will take ownership of the onlink route added and will purge it
when it is not needed anymore.
This commit is contained in:
Fernando Fernandez Mancera 2022-12-22 11:36:58 +01:00
parent 5b5ce42682
commit 737cb5d424

View file

@ -771,6 +771,8 @@ _netns_ip_route_ecmp_update_mh(NMNetns *self,
const NMPObject *obj = mhrts_add->pdata[i];
nm_auto_nmpobj const NMPObject *obj_old = NULL;
gpointer unused;
const NMPlatformIP4Route *route_src;
guint j;
if (g_hash_table_steal_extended(priv->ecmp_routes,
obj,
@ -783,6 +785,35 @@ _netns_ip_route_ecmp_update_mh(NMNetns *self,
if (!g_hash_table_add(priv->ecmp_routes, (gpointer) nmp_object_ref(obj)))
nm_assert_not_reached();
/* for each nexthop we need to configure the onlink route for the gateway */
route_src = NMP_OBJECT_CAST_IP4_ROUTE(obj);
for (j = 0; j < route_src->n_nexthops; j++) {
NMPObject *new_onlink_obj;
NMPlatformIP4Route *new_onlink_route;
in_addr_t gateway;
int ifindex;
new_onlink_obj = nmp_object_clone(obj, TRUE);
new_onlink_route = NMP_OBJECT_CAST_IP4_ROUTE(new_onlink_obj);
if (j == 0) {
gateway = route_src->gateway;
ifindex = route_src->ifindex;
} else {
gateway = obj->_ip4_route.extra_nexthops[j - 1].gateway;
ifindex = obj->_ip4_route.extra_nexthops[j - 1].ifindex;
}
new_onlink_route->network = gateway;
new_onlink_route->plen = 32;
new_onlink_route->gateway = 0;
new_onlink_route->ifindex = ifindex;
new_onlink_route->weight = 0;
new_onlink_route->n_nexthops = 0;
/* we configure the onlink route and l3cfg will take the ownership and remove it if not needed */
nm_platform_ip_route_add(priv->platform, NMP_NLM_FLAG_APPEND, new_onlink_obj);
}
nm_platform_ip_route_add(priv->platform, NMP_NLM_FLAG_APPEND, obj);
}
}