merge: branch 'ih/rt-leftover'
l3cfg: remove routes added by NM on reapply https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2080
This commit is contained in:
@@ -3919,15 +3919,18 @@ _l3cfg_routed_dns(NML3Cfg *self, NML3ConfigData *l3cd)
|
||||
* table sync mode to FULL, to clear the DNS routes added
|
||||
* previously. */
|
||||
self->priv.dns_route_added_x[IS_IPv4] = FALSE;
|
||||
nm_l3_config_data_set_route_table_sync(l3cd,
|
||||
addr_family,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_FULL);
|
||||
nm_l3_config_data_set_route_table_sync(
|
||||
l3cd,
|
||||
addr_family,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
nameservers = nm_l3_config_data_get_nameservers(l3cd, addr_family, &len);
|
||||
nm_l3_config_data_set_route_table_sync(l3cd, addr_family, NM_IP_ROUTE_TABLE_SYNC_MODE_FULL);
|
||||
nm_l3_config_data_set_route_table_sync(l3cd,
|
||||
addr_family,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL);
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
nm_auto_nmpobj NMPObject *obj = NULL;
|
||||
@@ -3977,9 +3980,10 @@ _l3cfg_routed_dns(NML3Cfg *self, NML3ConfigData *l3cd)
|
||||
nm_platform_ip4_route_to_string(&route_new.r4, route_buf, sizeof(route_buf)));
|
||||
|
||||
nm_l3_config_data_add_route_4(l3cd, &route_new.r4);
|
||||
nm_l3_config_data_set_route_table_sync(l3cd,
|
||||
AF_INET,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_FULL);
|
||||
nm_l3_config_data_set_route_table_sync(
|
||||
l3cd,
|
||||
AF_INET,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL);
|
||||
route_added = TRUE;
|
||||
} else {
|
||||
route_new.r6 = (NMPlatformIP6Route) {
|
||||
@@ -5129,7 +5133,7 @@ _l3_commit_one(NML3Cfg *self,
|
||||
}
|
||||
|
||||
if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_NONE)
|
||||
route_table_sync = NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN;
|
||||
route_table_sync = NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES;
|
||||
|
||||
if (any_dirty)
|
||||
_obj_states_track_prune_dirty(self, TRUE);
|
||||
@@ -5158,6 +5162,8 @@ _l3_commit_one(NML3Cfg *self,
|
||||
}
|
||||
|
||||
if (c_list_is_empty(&self->priv.p->blocked_lst_head_x[IS_IPv4])) {
|
||||
gs_unref_ptrarray GPtrArray *routes_old = NULL;
|
||||
|
||||
addresses_prune =
|
||||
nm_platform_ip_address_get_prune_list(self->priv.platform,
|
||||
addr_family,
|
||||
@@ -5165,10 +5171,28 @@ _l3_commit_one(NML3Cfg *self,
|
||||
nm_g_array_data(ipv6_temp_addrs_keep),
|
||||
nm_g_array_len(ipv6_temp_addrs_keep));
|
||||
|
||||
if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES) {
|
||||
GHashTableIter h_iter;
|
||||
ObjStateData *obj_state;
|
||||
|
||||
/* Get list of all the routes that were configured by us */
|
||||
routes_old = g_ptr_array_new_with_free_func((GDestroyNotify) nmp_object_unref);
|
||||
g_hash_table_iter_init(&h_iter, self->priv.p->obj_state_hash);
|
||||
while (g_hash_table_iter_next(&h_iter, (gpointer *) &obj_state, NULL)) {
|
||||
if (NMP_OBJECT_GET_TYPE(obj_state->obj) == NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4)
|
||||
&& obj_state->os_nm_configured)
|
||||
g_ptr_array_add(routes_old, (gpointer) nmp_object_ref(obj_state->obj));
|
||||
}
|
||||
|
||||
nm_platform_route_objs_sort(routes_old, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY);
|
||||
}
|
||||
|
||||
routes_prune = nm_platform_ip_route_get_prune_list(self->priv.platform,
|
||||
addr_family,
|
||||
self->priv.ifindex,
|
||||
route_table_sync);
|
||||
route_table_sync,
|
||||
routes_old);
|
||||
|
||||
_obj_state_zombie_lst_prune_all(self, addr_family);
|
||||
}
|
||||
} else {
|
||||
|
@@ -462,21 +462,24 @@ static GVariant *
|
||||
_version_info_get(void)
|
||||
{
|
||||
const guint32 arr[] = {
|
||||
/* The array contains as first element NM_VERSION, which can be
|
||||
* used to numerically compare the version (see also NM_ENCODE_VERSION,
|
||||
* nm_utils_version(), nm_encode_version() and nm_decode_version(). */
|
||||
NM_VERSION,
|
||||
};
|
||||
|
||||
/* The array contains as first element NM_VERSION, which can be
|
||||
* used to numerically compare the version (see also NM_ENCODE_VERSION,
|
||||
* nm_utils_version(), nm_encode_version() and nm_decode_version().
|
||||
*
|
||||
* The following elements of the array are a bitfield of capabilities.
|
||||
* These capabilities should only depend on compile-time abilities
|
||||
* (unlike NM_MANAGER_CAPABILITIES, NMCapability). The supported values
|
||||
* are from NMVersionInfoCapability enum. This way to expose capabilities
|
||||
* is more cumbersome but more efficient compared to NM_MANAGER_CAPABILITIES.
|
||||
* As such, it is cheap to add capabilities for something, where you would
|
||||
* avoid it as NM_MANAGER_CAPABILITIES due to the overhead.
|
||||
*/
|
||||
/* The following elements of the array are a bitfield of capabilities.
|
||||
* These capabilities should only depend on compile-time abilities
|
||||
* (unlike NM_MANAGER_CAPABILITIES, NMCapability). The supported values
|
||||
* are from NMVersionInfoCapability enum. This way to expose capabilities
|
||||
* is more cumbersome but more efficient compared to NM_MANAGER_CAPABILITIES.
|
||||
* As such, it is cheap to add capabilities for something, where you would
|
||||
* avoid it as NM_MANAGER_CAPABILITIES due to the overhead.
|
||||
*
|
||||
* Each of the array's elements has 32 bits. This means that capabilities
|
||||
* with index 0-31 goes to element #1, with index 32-63 to element #2,
|
||||
* with index 64-95 to element #3 and so on. */
|
||||
1 << NM_VERSION_INFO_CAPABILITY_SYNC_ROUTE_WITH_TABLE,
|
||||
};
|
||||
|
||||
return nm_g_variant_new_au(arr, G_N_ELEMENTS(arr));
|
||||
}
|
||||
|
@@ -169,14 +169,11 @@ nmc_client_has_version_info_capability(NMClient *nmc, NMVersionInfoCapability ca
|
||||
len--;
|
||||
ver++;
|
||||
|
||||
idx = (gsize) capability;
|
||||
if (idx >= G_MAXSIZE - 31u)
|
||||
return FALSE;
|
||||
idx = (gsize) capability;
|
||||
idx_hi = idx / 32u;
|
||||
idx_lo = idx % 32u;
|
||||
|
||||
idx_hi = ((idx + 31u) / 32u);
|
||||
idx_lo = (idx % 32u);
|
||||
|
||||
if (idx_hi > len)
|
||||
if (idx_hi >= len)
|
||||
return FALSE;
|
||||
|
||||
return NM_FLAGS_ANY(ver[idx_hi], (1ull << idx_lo));
|
||||
|
@@ -6316,7 +6316,7 @@ nm_client_get_capabilities(NMClient *client, gsize *length)
|
||||
*
|
||||
* If available, the first element in the array is NM_VERSION which
|
||||
* encodes the daemon version as "(major << 16 | minor << 8 | micro)".
|
||||
* The following elements are a bitfield of %NMVersionInfoCapabilities
|
||||
* The following elements are a bitfield of %NMVersionInfoCapability
|
||||
* that indicate that the daemon supports a certain capability.
|
||||
*
|
||||
* Returns: (transfer none) (array length=length): the
|
||||
@@ -8313,7 +8313,7 @@ nm_client_class_init(NMClientClass *client_class)
|
||||
* Expose version info and capabilities of NetworkManager. If non-empty,
|
||||
* the first element is NM_VERSION, which encodes the version of the
|
||||
* daemon as "(major << 16 | minor << 8 | micro)". The following elements
|
||||
* is a bitfields of %NMVersionInfoCapabilities. If a bit is set, then
|
||||
* is a bitfields of %NMVersionInfoCapability. If a bit is set, then
|
||||
* the running NetworkManager has the respective capability.
|
||||
*
|
||||
* Since: 1.42
|
||||
|
@@ -94,16 +94,19 @@
|
||||
|
||||
/**
|
||||
* NMVersionInfoCapability:
|
||||
* %_NM_VERSION_INFO_CAPABILITY_UNUSED: a dummy capability. It has no meaning,
|
||||
* don't use it.
|
||||
* @NM_VERSION_INFO_CAPABILITY_SYNC_ROUTE_WITH_TABLE: Contains the fix to a bug that
|
||||
* caused that routes in table other than main were not removed on reapply nor
|
||||
* on connection down.
|
||||
* https://issues.redhat.com/browse/RHEL-66262
|
||||
* https://issues.redhat.com/browse/RHEL-67324
|
||||
*
|
||||
* Currently no enum values are defined. These capabilities are exposed
|
||||
* on D-Bus in the "VersionInfo" bit field.
|
||||
* The numeric values represent the bit index of the capability. These capabilities
|
||||
* can be queried in the "VersionInfo" D-Bus property.
|
||||
*
|
||||
* Since: 1.42
|
||||
*/
|
||||
typedef enum {
|
||||
_NM_VERSION_INFO_CAPABILITY_UNUSED = 0x7FFFFFFFu,
|
||||
NM_VERSION_INFO_CAPABILITY_SYNC_ROUTE_WITH_TABLE = 0,
|
||||
} NMVersionInfoCapability;
|
||||
|
||||
/**
|
||||
|
@@ -61,6 +61,8 @@ G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_address.data) == _NM_UTILS_H
|
||||
G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_perm_address.data) == _NM_UTILS_HWADDR_LEN_MAX);
|
||||
G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_broadcast.data) == _NM_UTILS_HWADDR_LEN_MAX);
|
||||
|
||||
static int _route_objs_cmp_values(gconstpointer a, gconstpointer b, gpointer user_data);
|
||||
|
||||
static const char *
|
||||
_nmp_link_port_data_to_string(NMPortKind port_kind,
|
||||
const NMPlatformLinkPortData *port_data,
|
||||
@@ -4904,11 +4906,24 @@ nm_platform_ip_address_get_prune_list(NMPlatform *self,
|
||||
return result;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_route_obj_find_bsearch(GPtrArray *sorted_routes_objs, const NMPObject *route_obj)
|
||||
{
|
||||
gssize pos =
|
||||
nm_ptrarray_find_bsearch((gconstpointer *) sorted_routes_objs->pdata,
|
||||
sorted_routes_objs->len,
|
||||
route_obj,
|
||||
_route_objs_cmp_values,
|
||||
GINT_TO_POINTER((int) NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY));
|
||||
return pos >= 0;
|
||||
}
|
||||
|
||||
GPtrArray *
|
||||
nm_platform_ip_route_get_prune_list(NMPlatform *self,
|
||||
int addr_family,
|
||||
int ifindex,
|
||||
NMIPRouteTableSyncMode route_table_sync)
|
||||
NMIPRouteTableSyncMode route_table_sync,
|
||||
GPtrArray *sorted_old_routes_objs)
|
||||
{
|
||||
NMPLookup lookup;
|
||||
GPtrArray *routes_prune = NULL;
|
||||
@@ -4922,10 +4937,21 @@ nm_platform_ip_route_get_prune_list(NMPlatform *self,
|
||||
nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6));
|
||||
nm_assert(NM_IN_SET(route_table_sync,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_FULL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE));
|
||||
|
||||
if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES) {
|
||||
nm_assert(sorted_old_routes_objs);
|
||||
nm_assert(nm_utils_ptrarray_is_sorted(
|
||||
(gconstpointer *) sorted_old_routes_objs->pdata,
|
||||
sorted_old_routes_objs->len,
|
||||
FALSE,
|
||||
_route_objs_cmp_values,
|
||||
GINT_TO_POINTER((int) NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)));
|
||||
}
|
||||
|
||||
nmp_lookup_init_object_by_ifindex(&lookup,
|
||||
NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family)),
|
||||
ifindex);
|
||||
@@ -4947,7 +4973,12 @@ nm_platform_ip_route_get_prune_list(NMPlatform *self,
|
||||
if (!nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&rt->rx)))
|
||||
continue;
|
||||
break;
|
||||
case NM_IP_ROUTE_TABLE_SYNC_MODE_FULL:
|
||||
case NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES:
|
||||
if (!nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&rt->rx))
|
||||
&& !_route_obj_find_bsearch(sorted_old_routes_objs, obj))
|
||||
continue;
|
||||
break;
|
||||
case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL:
|
||||
if (nm_platform_ip_route_get_effective_table(&rt->rx) == RT_TABLE_LOCAL)
|
||||
continue;
|
||||
break;
|
||||
@@ -5316,7 +5347,8 @@ nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex)
|
||||
routes_prune = nm_platform_ip_route_get_prune_list(self,
|
||||
AF_INET,
|
||||
ifindex,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE);
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE,
|
||||
NULL);
|
||||
success &= nm_platform_ip_route_sync(self, AF_INET, ifindex, NULL, routes_prune, NULL);
|
||||
}
|
||||
if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) {
|
||||
@@ -5325,7 +5357,8 @@ nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex)
|
||||
routes_prune = nm_platform_ip_route_get_prune_list(self,
|
||||
AF_INET6,
|
||||
ifindex,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE);
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE,
|
||||
NULL);
|
||||
success &= nm_platform_ip_route_sync(self, AF_INET6, ifindex, NULL, routes_prune, NULL);
|
||||
}
|
||||
return success;
|
||||
@@ -8833,6 +8866,45 @@ nm_platform_lnk_wireguard_cmp(const NMPlatformLnkWireGuard *a, const NMPlatformL
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
_route_objs_cmp_values(gconstpointer a, gconstpointer b, gpointer user_data)
|
||||
{
|
||||
const NMPObject *a_obj = a;
|
||||
const NMPObject *b_obj = b;
|
||||
NMPlatformIPRouteCmpType cmp_type = GPOINTER_TO_INT(user_data);
|
||||
|
||||
nm_assert(a_obj && b_obj);
|
||||
nm_assert(NMP_OBJECT_CAST_IP_ROUTE(a_obj) && NMP_OBJECT_CAST_IP_ROUTE(b_obj));
|
||||
|
||||
if (NMP_OBJECT_GET_ADDR_FAMILY(a_obj) != NMP_OBJECT_GET_ADDR_FAMILY(b_obj)) {
|
||||
return NMP_OBJECT_GET_ADDR_FAMILY(a_obj) == AF_INET ? 1 : -1;
|
||||
} else if (NMP_OBJECT_GET_ADDR_FAMILY(a_obj) == AF_INET) {
|
||||
return nm_platform_ip4_route_cmp(NMP_OBJECT_CAST_IP4_ROUTE(a_obj),
|
||||
NMP_OBJECT_CAST_IP4_ROUTE(b_obj),
|
||||
cmp_type);
|
||||
} else {
|
||||
return nm_platform_ip6_route_cmp(NMP_OBJECT_CAST_IP6_ROUTE(a_obj),
|
||||
NMP_OBJECT_CAST_IP6_ROUTE(b_obj),
|
||||
cmp_type);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
_route_objs_cmp(gconstpointer a, gconstpointer b, gpointer user_data)
|
||||
{
|
||||
nm_assert(a && b);
|
||||
|
||||
return _route_objs_cmp_values(*((const NMPObject **) a), *((const NMPObject **) b), user_data);
|
||||
}
|
||||
|
||||
void
|
||||
nm_platform_route_objs_sort(GPtrArray *routes_objs, NMPlatformIPRouteCmpType cmp_type)
|
||||
{
|
||||
nm_assert(routes_objs);
|
||||
|
||||
g_ptr_array_sort_with_data(routes_objs, _route_objs_cmp, GINT_TO_POINTER((int) cmp_type));
|
||||
}
|
||||
|
||||
void
|
||||
nm_platform_ip4_rt_nexthop_hash_update(const NMPlatformIP4RtNextHop *obj,
|
||||
gboolean for_id,
|
||||
|
@@ -2419,7 +2419,8 @@ int nm_platform_ip6_route_add(NMPlatform *self, NMPNlmFlags flags, const NMPlatf
|
||||
GPtrArray *nm_platform_ip_route_get_prune_list(NMPlatform *self,
|
||||
int addr_family,
|
||||
int ifindex,
|
||||
NMIPRouteTableSyncMode route_table_sync);
|
||||
NMIPRouteTableSyncMode route_table_sync,
|
||||
GPtrArray *old_routes_objs);
|
||||
|
||||
gboolean nm_platform_ip_route_sync(NMPlatform *self,
|
||||
int addr_family,
|
||||
@@ -2528,6 +2529,8 @@ int nm_platform_lnk_wireguard_cmp(const NMPlatformLnkWireGuard *a, const NMPlatf
|
||||
|
||||
GHashTable *nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex);
|
||||
|
||||
void nm_platform_route_objs_sort(GPtrArray *routes_objs, NMPlatformIPRouteCmpType cmp_type);
|
||||
|
||||
int nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a,
|
||||
const NMPlatformIP4Route *b,
|
||||
NMPlatformIPRouteCmpType cmp_type);
|
||||
|
@@ -212,8 +212,11 @@ nmp_object_type_to_flags(NMPObjectType obj_type)
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_NONE: indicate an invalid setting.
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN: only the main table is synced. For all
|
||||
* other tables, NM won't delete any extra routes.
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_FULL: NM will sync all tables, except the
|
||||
* local table (255).
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES: only the main table is synced,
|
||||
* plus individual routes in other tables added by NM, leaving routes that
|
||||
* were not added by NM untouched.
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL: NM will sync all tables, except
|
||||
* the local table (255).
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL: NM will sync all tables, including the
|
||||
* local table (255).
|
||||
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE: NM will sync all tables (including
|
||||
@@ -223,7 +226,8 @@ nmp_object_type_to_flags(NMPObjectType obj_type)
|
||||
typedef enum {
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_FULL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE,
|
||||
} NMIPRouteTableSyncMode;
|
||||
|
Reference in New Issue
Block a user