core: add dependent local routes configured by kernel
Pre-generate routes in the local table that are configured by kernel when an ip-address is assigned to an interface. This helps NM taking into account routes that are not to be deleted when a connection is reapplied (or deactivated) on an interface instead of only ignoring (when pruning) IPv6 routes having metric 0 and routes belonging to the local table having 'kernel' as proto. https://bugzilla.redhat.com/show_bug.cgi?id=1821787
This commit is contained in:
@@ -671,6 +671,28 @@ nm_ip4_config_update_routes_metric (NMIP4Config *self, gint64 metric)
|
|||||||
g_object_thaw_notify (G_OBJECT (self));
|
g_object_thaw_notify (G_OBJECT (self));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_add_local_route_from_addr4 (NMIP4Config *self,
|
||||||
|
const NMPlatformIP4Address *addr,
|
||||||
|
int ifindex)
|
||||||
|
{
|
||||||
|
nm_auto_nmpobj NMPObject *r = NULL;
|
||||||
|
NMPlatformIP4Route *route;
|
||||||
|
|
||||||
|
r = nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, NULL);
|
||||||
|
route = NMP_OBJECT_CAST_IP4_ROUTE (r);
|
||||||
|
route->ifindex = ifindex;
|
||||||
|
route->rt_source = NM_IP_CONFIG_SOURCE_KERNEL;
|
||||||
|
route->network = addr->address;
|
||||||
|
route->plen = 32;
|
||||||
|
route->pref_src = addr->address;
|
||||||
|
route->table_coerced = nm_platform_route_table_coerce (RT_TABLE_LOCAL);
|
||||||
|
route->type_coerced = nm_platform_route_type_coerce (RTN_LOCAL);
|
||||||
|
route->scope_inv = nm_platform_route_scope_inv (RT_SCOPE_HOST);
|
||||||
|
|
||||||
|
_add_route (self, r, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nm_ip4_config_add_dependent_routes (NMIP4Config *self,
|
nm_ip4_config_add_dependent_routes (NMIP4Config *self,
|
||||||
guint32 route_table,
|
guint32 route_table,
|
||||||
@@ -707,6 +729,8 @@ nm_ip4_config_add_dependent_routes (NMIP4Config *self,
|
|||||||
if (my_addr->external)
|
if (my_addr->external)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
_add_local_route_from_addr4 (self, my_addr, ifindex);
|
||||||
|
|
||||||
if (_ipv4_is_zeronet (network)) {
|
if (_ipv4_is_zeronet (network)) {
|
||||||
/* Kernel doesn't add device-routes for destinations that
|
/* Kernel doesn't add device-routes for destinations that
|
||||||
* start with 0.x.y.z. Skip them. */
|
* start with 0.x.y.z. Skip them. */
|
||||||
|
@@ -474,6 +474,24 @@ _add_multicast_route6 (NMIP6Config *self, int ifindex)
|
|||||||
_add_route (self, r, NULL, NULL);
|
_add_route (self, r, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_add_local_route_from_addr6 (NMIP6Config *self, const NMPlatformIP6Address *addr, int ifindex)
|
||||||
|
{
|
||||||
|
nm_auto_nmpobj NMPObject *r = NULL;
|
||||||
|
NMPlatformIP6Route *route;
|
||||||
|
|
||||||
|
r = nmp_object_new (NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
|
||||||
|
route = NMP_OBJECT_CAST_IP6_ROUTE (r);
|
||||||
|
route->ifindex = ifindex;
|
||||||
|
route->network = addr->address;
|
||||||
|
route->plen = 128;
|
||||||
|
route->table_coerced = nm_platform_route_table_coerce (RT_TABLE_LOCAL);
|
||||||
|
route->type_coerced = nm_platform_route_type_coerce (RTN_LOCAL);
|
||||||
|
route->metric = 0;
|
||||||
|
|
||||||
|
_add_route (self, r, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nm_ip6_config_add_dependent_routes (NMIP6Config *self,
|
nm_ip6_config_add_dependent_routes (NMIP6Config *self,
|
||||||
guint32 route_table,
|
guint32 route_table,
|
||||||
@@ -504,6 +522,10 @@ nm_ip6_config_add_dependent_routes (NMIP6Config *self,
|
|||||||
|
|
||||||
if (my_addr->external)
|
if (my_addr->external)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
/* Pre-generate local route added by kernel */
|
||||||
|
_add_local_route_from_addr6 (self, my_addr, ifindex);
|
||||||
|
|
||||||
if (NM_FLAGS_HAS (my_addr->n_ifa_flags, IFA_F_NOPREFIXROUTE))
|
if (NM_FLAGS_HAS (my_addr->n_ifa_flags, IFA_F_NOPREFIXROUTE))
|
||||||
continue;
|
continue;
|
||||||
if (my_addr->plen == 0)
|
if (my_addr->plen == 0)
|
||||||
|
@@ -4230,18 +4230,9 @@ nm_platform_ip_route_get_prune_list (NMPlatform *self,
|
|||||||
} else if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN) {
|
} else if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN) {
|
||||||
if (!nm_platform_route_table_is_main (NMP_OBJECT_CAST_IP_ROUTE (obj)->table_coerced))
|
if (!nm_platform_route_table_is_main (NMP_OBJECT_CAST_IP_ROUTE (obj)->table_coerced))
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else
|
||||||
nm_assert (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_ALL);
|
nm_assert (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_ALL);
|
||||||
|
|
||||||
/* IPv6 routes having metric 0 and routes having rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL
|
|
||||||
* are entirely managed by kernel, let's not touch them */
|
|
||||||
if (addr_family == AF_INET6 && NMP_OBJECT_CAST_IP6_ROUTE (obj)->metric == 0)
|
|
||||||
continue;
|
|
||||||
if ( nm_platform_route_table_uncoerce (NMP_OBJECT_CAST_IP_ROUTE (obj)->table_coerced, TRUE) == RT_TABLE_LOCAL
|
|
||||||
&& NMP_OBJECT_CAST_IP_ROUTE (obj)->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_ptr_array_add (routes_prune, (gpointer) nmp_object_ref (obj));
|
g_ptr_array_add (routes_prune, (gpointer) nmp_object_ref (obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user