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));
|
||||
}
|
||||
|
||||
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
|
||||
nm_ip4_config_add_dependent_routes (NMIP4Config *self,
|
||||
guint32 route_table,
|
||||
@@ -707,6 +729,8 @@ nm_ip4_config_add_dependent_routes (NMIP4Config *self,
|
||||
if (my_addr->external)
|
||||
continue;
|
||||
|
||||
_add_local_route_from_addr4 (self, my_addr, ifindex);
|
||||
|
||||
if (_ipv4_is_zeronet (network)) {
|
||||
/* Kernel doesn't add device-routes for destinations that
|
||||
* 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);
|
||||
}
|
||||
|
||||
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
|
||||
nm_ip6_config_add_dependent_routes (NMIP6Config *self,
|
||||
guint32 route_table,
|
||||
@@ -504,6 +522,10 @@ nm_ip6_config_add_dependent_routes (NMIP6Config *self,
|
||||
|
||||
if (my_addr->external)
|
||||
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))
|
||||
continue;
|
||||
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) {
|
||||
if (!nm_platform_route_table_is_main (NMP_OBJECT_CAST_IP_ROUTE (obj)->table_coerced))
|
||||
continue;
|
||||
} else {
|
||||
} else
|
||||
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));
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user