mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-25 04:04:36 +00:00
core: fix generation of dependent local routes for VRFs
When using VRF devices we must pre-generate dependent local
routes in the VRF's table otherwise they will be incorrectly added
to the local table instead.
https://bugzilla.redhat.com/show_bug.cgi?id=1857133
Fixes: a199cd2a7d
('core: add dependent local routes configured by kernel')
This commit is contained in:
parent
f0a39b517e
commit
d342af1925
|
@ -68,6 +68,7 @@
|
|||
|
||||
#include "nm-device-generic.h"
|
||||
#include "nm-device-vlan.h"
|
||||
#include "nm-device-vrf.h"
|
||||
#include "nm-device-wireguard.h"
|
||||
|
||||
#include "nm-device-logging.h"
|
||||
|
@ -8097,15 +8098,21 @@ ip_config_merge_and_apply (NMDevice *self,
|
|||
}
|
||||
|
||||
if (commit) {
|
||||
gboolean is_vrf;
|
||||
|
||||
is_vrf = priv->master && nm_device_get_device_type (priv->master) == NM_DEVICE_TYPE_VRF;
|
||||
|
||||
if (IS_IPv4) {
|
||||
nm_ip4_config_add_dependent_routes (NM_IP4_CONFIG (composite),
|
||||
nm_device_get_route_table (self, addr_family),
|
||||
nm_device_get_route_metric (self, addr_family),
|
||||
is_vrf,
|
||||
&ip4_dev_route_blacklist);
|
||||
} else {
|
||||
nm_ip6_config_add_dependent_routes (NM_IP6_CONFIG (composite),
|
||||
nm_device_get_route_table (self, addr_family),
|
||||
nm_device_get_route_metric (self, addr_family));
|
||||
nm_device_get_route_metric (self, addr_family),
|
||||
is_vrf);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,11 +41,13 @@
|
|||
static struct {
|
||||
GMainLoop *main_loop;
|
||||
int ifindex;
|
||||
gboolean is_vrf_device;
|
||||
|
||||
guint dad_failed_id;
|
||||
CList dad_failed_lst_head;
|
||||
} gl/*obal*/ = {
|
||||
.ifindex = -1,
|
||||
.is_vrf_device = FALSE,
|
||||
};
|
||||
|
||||
static struct {
|
||||
|
@ -120,6 +122,7 @@ dhcp4_state_changed (NMDhcpClient *client,
|
|||
nm_ip4_config_add_dependent_routes (existing,
|
||||
RT_TABLE_MAIN,
|
||||
global_opt.priority_v4,
|
||||
gl.is_vrf_device,
|
||||
&ip4_dev_route_blacklist);
|
||||
if (!nm_ip4_config_commit (existing,
|
||||
NM_PLATFORM_GET,
|
||||
|
@ -236,7 +239,8 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
|
|||
nm_ip6_config_merge (existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
|
||||
nm_ip6_config_add_dependent_routes (existing,
|
||||
RT_TABLE_MAIN,
|
||||
global_opt.priority_v6);
|
||||
global_opt.priority_v6,
|
||||
gl.is_vrf_device);
|
||||
if (!nm_ip6_config_commit (existing,
|
||||
NM_PLATFORM_GET,
|
||||
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
||||
|
@ -480,6 +484,11 @@ main (int argc, char *argv[])
|
|||
if (pllink) {
|
||||
hwaddr = nmp_link_address_get_as_bytes (&pllink->l_address);
|
||||
bcast_hwaddr = nmp_link_address_get_as_bytes (&pllink->l_broadcast);
|
||||
|
||||
if (pllink->master > 0) {
|
||||
gl.is_vrf_device
|
||||
= nm_platform_link_get_type (NM_PLATFORM_GET, pllink->master) == NM_LINK_TYPE_VRF;
|
||||
}
|
||||
}
|
||||
|
||||
if (global_opt.iid_str) {
|
||||
|
|
|
@ -672,9 +672,11 @@ nm_ip4_config_update_routes_metric (NMIP4Config *self, gint64 metric)
|
|||
}
|
||||
|
||||
static void
|
||||
_add_local_route_from_addr4 (NMIP4Config *self,
|
||||
const NMPlatformIP4Address *addr,
|
||||
int ifindex)
|
||||
_add_local_route_from_addr4 (NMIP4Config * self,
|
||||
const NMPlatformIP4Address *addr,
|
||||
int ifindex,
|
||||
guint32 route_table,
|
||||
gboolean is_vrf)
|
||||
{
|
||||
nm_auto_nmpobj NMPObject *r = NULL;
|
||||
NMPlatformIP4Route *route;
|
||||
|
@ -686,18 +688,19 @@ _add_local_route_from_addr4 (NMIP4Config *self,
|
|||
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);
|
||||
route->table_coerced = nm_platform_route_table_coerce (is_vrf ? route_table : RT_TABLE_LOCAL);
|
||||
|
||||
_add_route (self, r, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip4_config_add_dependent_routes (NMIP4Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
GPtrArray **out_ip4_dev_route_blacklist)
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
gboolean is_vrf,
|
||||
GPtrArray ** out_ip4_dev_route_blacklist)
|
||||
{
|
||||
GPtrArray *ip4_dev_route_blacklist = NULL;
|
||||
const NMPlatformIP4Address *my_addr;
|
||||
|
@ -729,7 +732,7 @@ nm_ip4_config_add_dependent_routes (NMIP4Config *self,
|
|||
if (my_addr->external)
|
||||
continue;
|
||||
|
||||
_add_local_route_from_addr4 (self, my_addr, ifindex);
|
||||
_add_local_route_from_addr4 (self, my_addr, ifindex, route_table, is_vrf);
|
||||
|
||||
if (_ipv4_is_zeronet (network)) {
|
||||
/* Kernel doesn't add device-routes for destinations that
|
||||
|
|
|
@ -157,9 +157,10 @@ NMDedupMultiIndex *nm_ip4_config_get_multi_idx (const NMIP4Config *self);
|
|||
NMIP4Config *nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex);
|
||||
|
||||
void nm_ip4_config_add_dependent_routes (NMIP4Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
GPtrArray **out_ip4_dev_route_blacklist);
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
gboolean is_vrf,
|
||||
GPtrArray ** out_ip4_dev_route_blacklist);
|
||||
|
||||
gboolean nm_ip4_config_commit (const NMIP4Config *self,
|
||||
NMPlatform *platform,
|
||||
|
|
|
@ -475,27 +475,32 @@ _add_multicast_route6 (NMIP6Config *self, int ifindex)
|
|||
}
|
||||
|
||||
static void
|
||||
_add_local_route_from_addr6 (NMIP6Config *self, const NMPlatformIP6Address *addr, int ifindex)
|
||||
_add_local_route_from_addr6 (NMIP6Config * self,
|
||||
const NMPlatformIP6Address *addr,
|
||||
int ifindex,
|
||||
guint32 route_table,
|
||||
gboolean is_vrf)
|
||||
{
|
||||
nm_auto_nmpobj NMPObject *r = NULL;
|
||||
NMPlatformIP6Route *route;
|
||||
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;
|
||||
route->table_coerced = nm_platform_route_table_coerce (is_vrf ? route_table : RT_TABLE_LOCAL);
|
||||
|
||||
_add_route (self, r, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_config_add_dependent_routes (NMIP6Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric)
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
gboolean is_vrf)
|
||||
{
|
||||
const NMPlatformIP6Address *my_addr;
|
||||
const NMPlatformIP6Route *my_route;
|
||||
|
@ -524,7 +529,7 @@ nm_ip6_config_add_dependent_routes (NMIP6Config *self,
|
|||
continue;
|
||||
|
||||
/* Pre-generate local route added by kernel */
|
||||
_add_local_route_from_addr6 (self, my_addr, ifindex);
|
||||
_add_local_route_from_addr6 (self, my_addr, ifindex, route_table, is_vrf);
|
||||
|
||||
if (NM_FLAGS_HAS (my_addr->n_ifa_flags, IFA_F_NOPREFIXROUTE))
|
||||
continue;
|
||||
|
|
|
@ -93,8 +93,9 @@ NMIP6Config *nm_ip6_config_capture (struct _NMDedupMultiIndex *multi_idx, NMPlat
|
|||
NMSettingIP6ConfigPrivacy use_temporary);
|
||||
|
||||
void nm_ip6_config_add_dependent_routes (NMIP6Config *self,
|
||||
guint32 route_table,
|
||||
guint32 route_metric);
|
||||
guint32 route_table,
|
||||
guint32 route_metric,
|
||||
gboolean is_vrf);
|
||||
|
||||
gboolean nm_ip6_config_commit (const NMIP6Config *self,
|
||||
NMPlatform *platform,
|
||||
|
|
|
@ -1447,6 +1447,20 @@ get_route_table (NMVpnConnection *self,
|
|||
return route_table ?: (fallback_main ? RT_TABLE_MAIN : 0);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_is_device_vrf (NMVpnConnection *self)
|
||||
{
|
||||
NMDevice *parent;
|
||||
NMDevice *master;
|
||||
|
||||
parent = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self));
|
||||
if (!parent)
|
||||
return FALSE;
|
||||
|
||||
master = nm_device_get_master (parent);
|
||||
return master && nm_device_get_link_type (master) == NM_LINK_TYPE_VRF;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
||||
{
|
||||
|
@ -1646,6 +1660,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
|
|||
nm_ip4_config_add_dependent_routes (config,
|
||||
route_table,
|
||||
nm_vpn_connection_get_ip4_route_metric (self),
|
||||
_is_device_vrf (self),
|
||||
&priv->ip4_dev_route_blacklist);
|
||||
|
||||
if (priv->ip4_config) {
|
||||
|
@ -1840,9 +1855,7 @@ next:
|
|||
nm_ip6_config_add_route (config, &r, NULL);
|
||||
}
|
||||
|
||||
nm_ip6_config_add_dependent_routes (config,
|
||||
route_table,
|
||||
route_metric);
|
||||
nm_ip6_config_add_dependent_routes (config, route_table, route_metric, _is_device_vrf (self));
|
||||
|
||||
if (priv->ip6_config) {
|
||||
nm_ip6_config_replace (priv->ip6_config, config, NULL);
|
||||
|
|
Loading…
Reference in a new issue