diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 795e4680cd..2a743401b6 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2419,7 +2419,6 @@ static struct nl_msg * _nl_msg_new_route (int nlmsg_type, int nlmsg_flags, const NMPObject *obj, - unsigned char scope, gconstpointer gateway, guint32 mss, gconstpointer pref_src, @@ -2440,7 +2439,9 @@ _nl_msg_new_route (int nlmsg_type, .rtm_tos = obj->ip_route.tos, .rtm_table = RT_TABLE_MAIN, /* omit setting RTA_TABLE attribute */ .rtm_protocol = nmp_utils_ip_config_source_coerce_to_rtprot (obj->ip_route.rt_source), - .rtm_scope = scope, + .rtm_scope = is_v4 + ? nm_platform_route_scope_inv (obj->ip4_route.scope_inv) + : RT_SCOPE_NOWHERE, .rtm_type = RTN_UNICAST, .rtm_flags = 0, .rtm_dst_len = obj->ip_route.plen, @@ -5695,11 +5696,12 @@ ip4_route_add (NMPlatform *platform, const NMPlatformIP4Route *route) r = NMP_OBJECT_CAST_IP4_ROUTE (&obj); r->network = nm_utils_ip4_address_clear_host_address (r->network, r->plen); r->rt_source = nmp_utils_ip_config_source_round_trip_rtprot (r->rt_source), + r->scope_inv = nm_platform_route_scope_inv (!r->gateway + ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE); nlmsg = _nl_msg_new_route (RTM_NEWROUTE, NLM_F_CREATE | NLM_F_REPLACE, &obj, - route->gateway ? RT_SCOPE_UNIVERSE : RT_SCOPE_LINK, &route->gateway, route->mss, route->pref_src ? &route->pref_src : NULL, @@ -5729,7 +5731,6 @@ ip6_route_add (NMPlatform *platform, const NMPlatformIP6Route *route) nlmsg = _nl_msg_new_route (RTM_NEWROUTE, NLM_F_CREATE | NLM_F_REPLACE, &obj, - IN6_IS_ADDR_UNSPECIFIED (&route->gateway) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE, &route->gateway, route->mss, !IN6_IS_ADDR_UNSPECIFIED (&route->pref_src) ? &route->pref_src : NULL, @@ -5791,7 +5792,6 @@ ip_route_delete (NMPlatform *platform, nlmsg = _nl_msg_new_route (RTM_DELROUTE, 0, obj, - RT_SCOPE_NOWHERE, NULL, 0, NULL, diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index b8443ccf1f..c8b3e160c1 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -4752,6 +4752,7 @@ nm_platform_ip4_route_hash (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpT if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { h = NM_HASH_COMBINE (h, obj->ifindex); h = NM_HASH_COMBINE (h, obj->rt_source); + h = NM_HASH_COMBINE (h, obj->scope_inv); } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: @@ -4805,6 +4806,7 @@ nm_platform_ip4_route_cmp (const NMPlatformIP4Route *a, const NMPlatformIP4Route if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) { NM_CMP_FIELD (a, b, ifindex); NM_CMP_FIELD (a, b, rt_source); + NM_CMP_FIELD (a, b, scope_inv); } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 7f14626d8f..326abcdf21 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -379,13 +379,22 @@ struct _NMPlatformIP4Route { in_addr_t network; in_addr_t gateway; - /* The bitwise inverse of the route scope. It is inverted so that the - * default value (RT_SCOPE_NOWHERE) is nul. */ - guint8 scope_inv; - /* RTA_PREFSRC/rtnl_route_get_pref_src(). A value of zero means that * no pref-src is set. */ in_addr_t pref_src; + + /* The bitwise inverse of the route scope rtm_scope. It is inverted so that the + * default value (RT_SCOPE_NOWHERE) is zero. Use nm_platform_route_scope_inv() + * to convert back and forth between the inverese representation and the + * real value. + * + * rtm_scope is part of the primary key for IPv4 routes. When deleting a route, + * the scope must match, unless it is left at RT_SCOPE_NOWHERE, in which case the first + * matching route is deleted. + * + * For IPv6 routes, the scope is ignored and kernel always assumes global scope. + * Hence, this field is only in NMPlatformIP4Route. */ + guint8 scope_inv; }; struct _NMPlatformIP6Route {