mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 01:47:58 +02:00
l3cfg: add nm_l3_config_data_get_blacklisted_ip4_routes() util
We will need to prune routes that kernel adds (and we don't want).
This commit is contained in:
parent
0ab341b9e6
commit
e89a095673
3 changed files with 94 additions and 29 deletions
|
|
@ -1380,16 +1380,101 @@ _data_get_direct_route_for_host (const NML3ConfigData *self,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Kernel likes to add device routes for all addresses. Normally, we want to suppress that
|
||||
* with IFA_F_NOPREFIXROUTE. But we also want to support kernels that don't support that
|
||||
* flag. So, we collect here all those routes that kernel might add but we don't want.
|
||||
* If the route shows up within a certain timeout of us configuring the address, we assume
|
||||
* that it was (undesirably) added by kernel and we remove it.
|
||||
*
|
||||
* The most common reason is that for each IPv4 address we want to add a corresponding device
|
||||
* route with the right ipv4.route-metric. The route that kernel adds has metric 0, so it is
|
||||
* undesired.
|
||||
*
|
||||
* FIXME(l3cfg): implement handling blacklisted routes.
|
||||
*
|
||||
* For IPv6, IFA_F_NOPREFIXROUTE is supported for a longer time and we don't do such a hack.
|
||||
*/
|
||||
GPtrArray *
|
||||
nm_l3_config_data_get_blacklisted_ip4_routes (const NML3ConfigData *self,
|
||||
gboolean is_vrf)
|
||||
{
|
||||
gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL;
|
||||
const NMPObject *my_addr_obj;
|
||||
NMDedupMultiIter iter;
|
||||
|
||||
nm_assert (_NM_IS_L3_CONFIG_DATA (self, FALSE));
|
||||
|
||||
/* For IPv6 slaac, we explicitly add the device-routes (onlink).
|
||||
* As we don't do that for IPv4 and manual IPv6 addresses. Add them here
|
||||
* as dependent routes. */
|
||||
|
||||
nm_l3_config_data_iter_obj_for_each (&iter, self, &my_addr_obj, NMP_OBJECT_TYPE_IP4_ADDRESS) {
|
||||
const NMPlatformIP4Address *const my_addr = NMP_OBJECT_CAST_IP4_ADDRESS (my_addr_obj);
|
||||
in_addr_t network_4;
|
||||
NMPlatformIPXRoute rx;
|
||||
|
||||
if (my_addr->external)
|
||||
continue;
|
||||
|
||||
nm_assert (my_addr->plen <= 32);
|
||||
if (my_addr->plen == 0)
|
||||
continue;
|
||||
|
||||
network_4 = nm_utils_ip4_address_clear_host_address (my_addr->peer_address,
|
||||
my_addr->plen);
|
||||
|
||||
if (nm_utils_ip4_address_is_zeronet (network_4)) {
|
||||
/* Kernel doesn't add device-routes for destinations that
|
||||
* start with 0.x.y.z. Skip them. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( my_addr->plen == 32
|
||||
&& my_addr->address == my_addr->peer_address) {
|
||||
/* Kernel doesn't add device-routes for /32 addresses unless
|
||||
* they have a peer. */
|
||||
continue;
|
||||
}
|
||||
|
||||
rx.r4 = (NMPlatformIP4Route) {
|
||||
.ifindex = self->ifindex,
|
||||
.rt_source = NM_IP_CONFIG_SOURCE_KERNEL,
|
||||
.network = network_4,
|
||||
.plen = my_addr->plen,
|
||||
.pref_src = my_addr->address,
|
||||
.table_coerced = nm_platform_route_table_coerce (RT_TABLE_MAIN),
|
||||
.metric = NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE,
|
||||
.scope_inv = nm_platform_route_scope_inv (NM_RT_SCOPE_LINK),
|
||||
};
|
||||
nm_platform_ip_route_normalize (AF_INET, &rx.rx);
|
||||
|
||||
if (nm_l3_config_data_lookup_route (self,
|
||||
AF_INET,
|
||||
&rx.rx)) {
|
||||
/* we track such a route explicitly. Don't blacklist it. */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ip4_dev_route_blacklist)
|
||||
ip4_dev_route_blacklist = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
|
||||
|
||||
g_ptr_array_add (ip4_dev_route_blacklist,
|
||||
nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, &rx));
|
||||
}
|
||||
|
||||
return g_steal_pointer (&ip4_dev_route_blacklist);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void
|
||||
nm_l3_config_data_add_dependent_routes (NML3ConfigData *self,
|
||||
int addr_family,
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
gboolean is_vrf,
|
||||
GPtrArray **out_ip4_dev_route_blacklist)
|
||||
gboolean is_vrf)
|
||||
{
|
||||
const gboolean IS_IPv4 = NM_IS_IPv4 (addr_family);
|
||||
gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL;
|
||||
gs_unref_ptrarray GPtrArray *extra_onlink_routes = NULL;
|
||||
const NMPObject *my_addr_obj;
|
||||
const NMPObject *my_route_obj;
|
||||
|
|
@ -1490,28 +1575,6 @@ nm_l3_config_data_add_dependent_routes (NML3ConfigData *self,
|
|||
};
|
||||
nm_platform_ip_route_normalize (addr_family, &rx.rx);
|
||||
nm_l3_config_data_add_route (self, addr_family, NULL, &rx.rx);
|
||||
|
||||
if ( IS_IPv4
|
||||
&& out_ip4_dev_route_blacklist
|
||||
&& ( route_table != RT_TABLE_MAIN
|
||||
|| route_metric != NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE)) {
|
||||
|
||||
rx.r4.table_coerced = nm_platform_route_table_coerce (RT_TABLE_MAIN);
|
||||
rx.r4.metric = NM_PLATFORM_ROUTE_METRIC_IP4_DEVICE_ROUTE;
|
||||
nm_platform_ip_route_normalize (addr_family, &rx.rx);
|
||||
|
||||
if (nm_l3_config_data_lookup_route (self,
|
||||
addr_family,
|
||||
&rx.rx)) {
|
||||
/* we track such a route explicitly. Don't blacklist it. */
|
||||
} else {
|
||||
if (!ip4_dev_route_blacklist)
|
||||
ip4_dev_route_blacklist = g_ptr_array_new_with_free_func ((GDestroyNotify) nmp_object_unref);
|
||||
|
||||
g_ptr_array_add (ip4_dev_route_blacklist,
|
||||
nmp_object_new (NMP_OBJECT_TYPE_IP4_ROUTE, &rx));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const gboolean has_peer = !IN6_IS_ADDR_UNSPECIFIED (&my_addr->a6.peer_address);
|
||||
int routes_i;
|
||||
|
|
@ -1602,8 +1665,6 @@ nm_l3_config_data_add_dependent_routes (NML3ConfigData *self,
|
|||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
NM_SET_OUT (out_ip4_dev_route_blacklist, g_steal_pointer (&ip4_dev_route_blacklist));
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -105,12 +105,14 @@ void nm_l3_config_data_merge (NML3ConfigData *self,
|
|||
NML3ConfigMergeHookAddObj hook_add_addr,
|
||||
gpointer hook_user_data);
|
||||
|
||||
GPtrArray *nm_l3_config_data_get_blacklisted_ip4_routes (const NML3ConfigData *self,
|
||||
gboolean is_vrf);
|
||||
|
||||
void nm_l3_config_data_add_dependent_routes (NML3ConfigData *self,
|
||||
int addr_family,
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
gboolean is_vrf,
|
||||
GPtrArray **out_ip4_dev_route_blacklist);
|
||||
gboolean is_vrf);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -309,6 +309,8 @@ typedef enum {
|
|||
\
|
||||
guint8 plen; \
|
||||
\
|
||||
/* FIXME(l3cfg): the external marker won't be necessary anymore, because we only
|
||||
* merge addresses we care about, and ignore (don't remove) external addresses. */ \
|
||||
bool external:1; \
|
||||
\
|
||||
bool use_ip4_broadcast_address:1; \
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue