mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-28 09:50:09 +01:00
platform: improve workaround for deleting IPv4 route with libnl guessing route scope
Previously, we always lookup the cache for libnl objects and used those for delete_object(). This was necessary, because libnl guesses and overwrites the IPv4 route scope. Newer libnl no longer overwrites the scope if set explicitly to RT_SCOPE_NOWHERE. So, this workaround is no longer needed. Indeed there might be cases, where it is harmful, because we might guess the wrong scope. This was fixed in libnl3 in commits85ec9c7ad8015c4ee59bhttps://bugzilla.gnome.org/show_bug.cgi?id=726273 Signed-off-by: Thomas Haller <thaller@redhat.com>
This commit is contained in:
parent
ff801bcafc
commit
019bf7512d
1 changed files with 32 additions and 21 deletions
|
|
@ -1494,17 +1494,13 @@ delete_object (NMPlatform *platform, struct nl_object *obj)
|
|||
{
|
||||
NMLinuxPlatformPrivate *priv = NM_LINUX_PLATFORM_GET_PRIVATE (platform);
|
||||
auto_nl_object struct nl_object *obj_cleanup = obj;
|
||||
auto_nl_object struct nl_object *cached_object = NULL;
|
||||
struct nl_object *object;
|
||||
struct nl_object *object = obj;
|
||||
int object_type;
|
||||
int nle;
|
||||
|
||||
object_type = object_type_from_nl_object (obj);
|
||||
g_return_val_if_fail (object_type != OBJECT_TYPE_UNKNOWN, FALSE);
|
||||
|
||||
cached_object = nm_nl_cache_search (choose_cache_by_type (platform, object_type), obj);
|
||||
object = cached_object ? cached_object : obj;
|
||||
|
||||
switch (object_type) {
|
||||
case OBJECT_TYPE_LINK:
|
||||
nle = rtnl_link_delete (priv->nlh, (struct rtnl_link *) object);
|
||||
|
|
@ -3327,25 +3323,40 @@ ip4_route_delete (NMPlatform *platform, int ifindex, in_addr_t network, int plen
|
|||
{
|
||||
in_addr_t gateway = 0;
|
||||
struct nl_object *route = build_rtnl_route (AF_INET, ifindex, &network, plen, &gateway, metric, 0);
|
||||
uint8_t scope = RT_SCOPE_NOWHERE;
|
||||
|
||||
g_return_val_if_fail (route, FALSE);
|
||||
|
||||
/* When searching for a matching IPv4 route to delete, the kernel
|
||||
* searches for a matching scope, unless the RTM_DELROUTE message
|
||||
* specifies RT_SCOPE_NOWHERE (see fib_table_delete()).
|
||||
*
|
||||
* However, if we set the scope of @rtnlroute to RT_SCOPE_NOWHERE (or
|
||||
* leave it unset), rtnl_route_build_msg() will reset the scope to
|
||||
* rtnl_route_guess_scope() -- which might be the wrong scope.
|
||||
*
|
||||
* As a workaround, we set the scope to RT_SCOPE_UNIVERSE, so libnl
|
||||
* will not overwrite it. But this only works if we guess correctly.
|
||||
*
|
||||
* As a better workaround, we don't use @rtnlroute as argument for
|
||||
* rtnl_route_delete(), but we look into our cache, if we already have
|
||||
* this route ready.
|
||||
**/
|
||||
rtnl_route_set_scope ((struct rtnl_route *) route, RT_SCOPE_UNIVERSE);
|
||||
if (!_nl_has_capability (1 /* NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE */)) {
|
||||
/* When searching for a matching IPv4 route to delete, the kernel
|
||||
* searches for a matching scope, unless the RTM_DELROUTE message
|
||||
* specifies RT_SCOPE_NOWHERE (see fib_table_delete()).
|
||||
*
|
||||
* However, if we set the scope of @rtnlroute to RT_SCOPE_NOWHERE (or
|
||||
* leave it unset), rtnl_route_build_msg() will reset the scope to
|
||||
* rtnl_route_guess_scope() -- which probably guesses wrong.
|
||||
*
|
||||
* As a workaround, we look at the cached route and use that scope.
|
||||
*
|
||||
* Newer versions of libnl, no longer reset the scope if explicitly set to RT_SCOPE_NOWHERE.
|
||||
* So, this workaround is only needed unless we have NL_CAPABILITY_ROUTE_BUILD_MSG_SET_SCOPE.
|
||||
**/
|
||||
struct nl_object *cached_object;
|
||||
|
||||
cached_object = nm_nl_cache_search (choose_cache_by_type (platform, OBJECT_TYPE_IP4_ROUTE), route);
|
||||
if (cached_object) {
|
||||
scope = rtnl_route_get_scope ((struct rtnl_route *) cached_object);
|
||||
nl_object_put (cached_object);
|
||||
}
|
||||
|
||||
if (scope == RT_SCOPE_NOWHERE) {
|
||||
/* If we would set the scope to RT_SCOPE_NOWHERE, libnl would guess the scope.
|
||||
* But probably it will guess 'link' because we don't set the next hop
|
||||
* of the route we are about to delete. A better guess is 'global'. */
|
||||
scope = RT_SCOPE_UNIVERSE;
|
||||
}
|
||||
}
|
||||
rtnl_route_set_scope ((struct rtnl_route *) route, scope);
|
||||
|
||||
return delete_object (platform, route);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue