Blame SOURCES/1001-core-fix-generation-of-dependent-rh1857133.patch

146a1d
From 7fadadb8f33675d0a12c94f5c0f5c6ecef4a98cf Mon Sep 17 00:00:00 2001
146a1d
From: Antonio Cardace <acardace@redhat.com>
146a1d
Date: Tue, 14 Jul 2020 11:35:35 +0200
146a1d
Subject: [PATCH] core: fix generation of dependent local routes for VRFs
146a1d
146a1d
When using VRF devices we must pre-generate dependent local
146a1d
routes in the VRF's table otherwise they will be incorrectly added
146a1d
to the local table instead.
146a1d
146a1d
https://bugzilla.redhat.com/show_bug.cgi?id=1857133
146a1d
146a1d
Fixes: a199cd2a7d92 ('core: add dependent local routes configured by kernel')
146a1d
(cherry picked from commit d342af1925223cf8d117750c91f35f3041f05570)
146a1d
(cherry picked from commit ad64da5e85757eeb729fea377bb92ac41c8b92bd)
146a1d
---
146a1d
 src/devices/nm-device.c     |  9 ++++++++-
146a1d
 src/nm-iface-helper.c       | 11 ++++++++++-
146a1d
 src/nm-ip4-config.c         | 19 +++++++++++--------
146a1d
 src/nm-ip4-config.h         |  7 ++++---
146a1d
 src/nm-ip6-config.c         | 17 +++++++++++------
146a1d
 src/nm-ip6-config.h         |  5 +++--
146a1d
 src/vpn/nm-vpn-connection.c | 19 ++++++++++++++++---
146a1d
 7 files changed, 63 insertions(+), 24 deletions(-)
146a1d
146a1d
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
146a1d
index de09e4807..57c32cef8 100644
146a1d
--- a/src/devices/nm-device.c
146a1d
+++ b/src/devices/nm-device.c
146a1d
@@ -68,6 +68,7 @@
146a1d
 
146a1d
 #include "nm-device-generic.h"
146a1d
 #include "nm-device-vlan.h"
146a1d
+#include "nm-device-vrf.h"
146a1d
 #include "nm-device-wireguard.h"
146a1d
 
146a1d
 #include "nm-device-logging.h"
146a1d
@@ -8097,15 +8098,21 @@ ip_config_merge_and_apply (NMDevice *self,
146a1d
 	}
146a1d
 
146a1d
 	if (commit) {
146a1d
+		gboolean is_vrf;
146a1d
+
146a1d
+		is_vrf = priv->master && nm_device_get_device_type (priv->master) == NM_DEVICE_TYPE_VRF;
146a1d
+
146a1d
 		if (IS_IPv4) {
146a1d
 			nm_ip4_config_add_dependent_routes (NM_IP4_CONFIG (composite),
146a1d
 			                                    nm_device_get_route_table (self, addr_family),
146a1d
 			                                    nm_device_get_route_metric (self, addr_family),
146a1d
+			                                    is_vrf,
146a1d
 			                                    &ip4_dev_route_blacklist);
146a1d
 		} else {
146a1d
 			nm_ip6_config_add_dependent_routes (NM_IP6_CONFIG (composite),
146a1d
 			                                    nm_device_get_route_table (self, addr_family),
146a1d
-			                                    nm_device_get_route_metric (self, addr_family));
146a1d
+			                                    nm_device_get_route_metric (self, addr_family),
146a1d
+			                                    is_vrf);
146a1d
 		}
146a1d
 	}
146a1d
 
146a1d
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
146a1d
index 6320e722c..c7d65d2a6 100644
146a1d
--- a/src/nm-iface-helper.c
146a1d
+++ b/src/nm-iface-helper.c
146a1d
@@ -41,11 +41,13 @@
146a1d
 static struct {
146a1d
 	GMainLoop *main_loop;
146a1d
 	int ifindex;
146a1d
+	gboolean is_vrf_device;
146a1d
 
146a1d
 	guint dad_failed_id;
146a1d
 	CList dad_failed_lst_head;
146a1d
 } gl/*obal*/ = {
146a1d
 	.ifindex = -1,
146a1d
+	.is_vrf_device = FALSE,
146a1d
 };
146a1d
 
146a1d
 static struct {
146a1d
@@ -120,6 +122,7 @@ dhcp4_state_changed (NMDhcpClient *client,
146a1d
 		nm_ip4_config_add_dependent_routes (existing,
146a1d
 		                                    RT_TABLE_MAIN,
146a1d
 		                                    global_opt.priority_v4,
146a1d
+		                                    gl.is_vrf_device,
146a1d
 		                                    &ip4_dev_route_blacklist);
146a1d
 		if (!nm_ip4_config_commit (existing,
146a1d
 		                           NM_PLATFORM_GET,
146a1d
@@ -236,7 +239,8 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in
146a1d
 	nm_ip6_config_merge (existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT, 0);
146a1d
 	nm_ip6_config_add_dependent_routes (existing,
146a1d
 	                                    RT_TABLE_MAIN,
146a1d
-	                                    global_opt.priority_v6);
146a1d
+	                                    global_opt.priority_v6,
146a1d
+	                                    gl.is_vrf_device);
146a1d
 	if (!nm_ip6_config_commit (existing,
146a1d
 	                           NM_PLATFORM_GET,
146a1d
 	                           NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
146a1d
@@ -480,6 +484,11 @@ main (int argc, char *argv[])
146a1d
 	if (pllink) {
146a1d
 		hwaddr = nmp_link_address_get_as_bytes (&pllink->l_address);
146a1d
 		bcast_hwaddr = nmp_link_address_get_as_bytes (&pllink->l_broadcast);
146a1d
+
146a1d
+		if (pllink->master > 0) {
146a1d
+			gl.is_vrf_device
146a1d
+			    = nm_platform_link_get_type (NM_PLATFORM_GET, pllink->master) == NM_LINK_TYPE_VRF;
146a1d
+		}
146a1d
 	}
146a1d
 
146a1d
 	if (global_opt.iid_str) {
146a1d
diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c
146a1d
index 490296c8d..f017a3e80 100644
146a1d
--- a/src/nm-ip4-config.c
146a1d
+++ b/src/nm-ip4-config.c
146a1d
@@ -672,9 +672,11 @@ nm_ip4_config_update_routes_metric (NMIP4Config *self, gint64 metric)
146a1d
 }
146a1d
 
146a1d
 static void
146a1d
-_add_local_route_from_addr4 (NMIP4Config *self,
146a1d
-                            const NMPlatformIP4Address *addr,
146a1d
-                            int ifindex)
146a1d
+_add_local_route_from_addr4 (NMIP4Config *               self,
146a1d
+                             const NMPlatformIP4Address *addr,
146a1d
+                             int                         ifindex,
146a1d
+                             guint32                     route_table,
146a1d
+                             gboolean                    is_vrf)
146a1d
 {
146a1d
 	nm_auto_nmpobj NMPObject *r = NULL;
146a1d
 	NMPlatformIP4Route *route;
146a1d
@@ -686,18 +688,19 @@ _add_local_route_from_addr4 (NMIP4Config *self,
146a1d
 	route->network = addr->address;
146a1d
 	route->plen = 32;
146a1d
 	route->pref_src = addr->address;
146a1d
-	route->table_coerced = nm_platform_route_table_coerce (RT_TABLE_LOCAL);
146a1d
 	route->type_coerced = nm_platform_route_type_coerce (RTN_LOCAL);
146a1d
 	route->scope_inv = nm_platform_route_scope_inv (RT_SCOPE_HOST);
146a1d
+	route->table_coerced = nm_platform_route_table_coerce (is_vrf ? route_table : RT_TABLE_LOCAL);
146a1d
 
146a1d
 	_add_route (self, r, NULL, NULL);
146a1d
 }
146a1d
 
146a1d
 void
146a1d
 nm_ip4_config_add_dependent_routes (NMIP4Config *self,
146a1d
-                                    guint32 route_table,
146a1d
-                                    guint32 route_metric,
146a1d
-                                    GPtrArray **out_ip4_dev_route_blacklist)
146a1d
+                                    guint32      route_table,
146a1d
+                                    guint32      route_metric,
146a1d
+                                    gboolean     is_vrf,
146a1d
+                                    GPtrArray ** out_ip4_dev_route_blacklist)
146a1d
 {
146a1d
 	GPtrArray *ip4_dev_route_blacklist = NULL;
146a1d
 	const NMPlatformIP4Address *my_addr;
146a1d
@@ -729,7 +732,7 @@ nm_ip4_config_add_dependent_routes (NMIP4Config *self,
146a1d
 		if (my_addr->external)
146a1d
 			continue;
146a1d
 
146a1d
-		_add_local_route_from_addr4 (self, my_addr, ifindex);
146a1d
+		_add_local_route_from_addr4 (self, my_addr, ifindex, route_table, is_vrf);
146a1d
 
146a1d
 		if (_ipv4_is_zeronet (network)) {
146a1d
 			/* Kernel doesn't add device-routes for destinations that
146a1d
diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h
146a1d
index d4694d936..dc8222fd5 100644
146a1d
--- a/src/nm-ip4-config.h
146a1d
+++ b/src/nm-ip4-config.h
146a1d
@@ -157,9 +157,10 @@ NMDedupMultiIndex *nm_ip4_config_get_multi_idx (const NMIP4Config *self);
146a1d
 NMIP4Config *nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int ifindex);
146a1d
 
146a1d
 void nm_ip4_config_add_dependent_routes (NMIP4Config *self,
146a1d
-                                         guint32 route_table,
146a1d
-                                         guint32 route_metric,
146a1d
-                                         GPtrArray **out_ip4_dev_route_blacklist);
146a1d
+                                         guint32      route_table,
146a1d
+                                         guint32      route_metric,
146a1d
+                                         gboolean     is_vrf,
146a1d
+                                         GPtrArray ** out_ip4_dev_route_blacklist);
146a1d
 
146a1d
 gboolean nm_ip4_config_commit (const NMIP4Config *self,
146a1d
                                NMPlatform *platform,
146a1d
diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c
146a1d
index 4911ec1d1..1589cad00 100644
146a1d
--- a/src/nm-ip6-config.c
146a1d
+++ b/src/nm-ip6-config.c
146a1d
@@ -475,27 +475,32 @@ _add_multicast_route6 (NMIP6Config *self, int ifindex)
146a1d
 }
146a1d
 
146a1d
 static void
146a1d
-_add_local_route_from_addr6 (NMIP6Config *self, const NMPlatformIP6Address *addr, int ifindex)
146a1d
+_add_local_route_from_addr6 (NMIP6Config *               self,
146a1d
+                             const NMPlatformIP6Address *addr,
146a1d
+                             int                         ifindex,
146a1d
+                             guint32                     route_table,
146a1d
+                             gboolean                    is_vrf)
146a1d
 {
146a1d
 	nm_auto_nmpobj NMPObject *r = NULL;
146a1d
-	NMPlatformIP6Route *route;
146a1d
+	NMPlatformIP6Route *      route;
146a1d
 
146a1d
 	r = nmp_object_new (NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
146a1d
 	route = NMP_OBJECT_CAST_IP6_ROUTE (r);
146a1d
 	route->ifindex = ifindex;
146a1d
 	route->network = addr->address;
146a1d
 	route->plen = 128;
146a1d
-	route->table_coerced = nm_platform_route_table_coerce (RT_TABLE_LOCAL);
146a1d
 	route->type_coerced = nm_platform_route_type_coerce (RTN_LOCAL);
146a1d
 	route->metric = 0;
146a1d
+	route->table_coerced = nm_platform_route_table_coerce (is_vrf ? route_table : RT_TABLE_LOCAL);
146a1d
 
146a1d
 	_add_route (self, r, NULL, NULL);
146a1d
 }
146a1d
 
146a1d
 void
146a1d
 nm_ip6_config_add_dependent_routes (NMIP6Config *self,
146a1d
-                                    guint32 route_table,
146a1d
-                                    guint32 route_metric)
146a1d
+                                    guint32      route_table,
146a1d
+                                    guint32      route_metric,
146a1d
+                                    gboolean     is_vrf)
146a1d
 {
146a1d
 	const NMPlatformIP6Address *my_addr;
146a1d
 	const NMPlatformIP6Route *my_route;
146a1d
@@ -524,7 +529,7 @@ nm_ip6_config_add_dependent_routes (NMIP6Config *self,
146a1d
 			continue;
146a1d
 
146a1d
 		/* Pre-generate local route added by kernel */
146a1d
-		_add_local_route_from_addr6 (self, my_addr, ifindex);
146a1d
+		_add_local_route_from_addr6 (self, my_addr, ifindex, route_table, is_vrf);
146a1d
 
146a1d
 		if (NM_FLAGS_HAS (my_addr->n_ifa_flags, IFA_F_NOPREFIXROUTE))
146a1d
 			continue;
146a1d
diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h
146a1d
index 36e8518a8..b6f461b29 100644
146a1d
--- a/src/nm-ip6-config.h
146a1d
+++ b/src/nm-ip6-config.h
146a1d
@@ -93,8 +93,9 @@ NMIP6Config *nm_ip6_config_capture (struct _NMDedupMultiIndex *multi_idx, NMPlat
146a1d
                                     NMSettingIP6ConfigPrivacy use_temporary);
146a1d
 
146a1d
 void nm_ip6_config_add_dependent_routes (NMIP6Config *self,
146a1d
-                                         guint32 route_table,
146a1d
-                                         guint32 route_metric);
146a1d
+                                         guint32      route_table,
146a1d
+                                         guint32      route_metric,
146a1d
+                                         gboolean     is_vrf);
146a1d
 
146a1d
 gboolean nm_ip6_config_commit (const NMIP6Config *self,
146a1d
                                NMPlatform *platform,
146a1d
diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c
146a1d
index 6d995dc48..ff6b8e00c 100644
146a1d
--- a/src/vpn/nm-vpn-connection.c
146a1d
+++ b/src/vpn/nm-vpn-connection.c
146a1d
@@ -1447,6 +1447,20 @@ get_route_table (NMVpnConnection *self,
146a1d
 	return route_table ?: (fallback_main ? RT_TABLE_MAIN : 0);
146a1d
 }
146a1d
 
146a1d
+static gboolean
146a1d
+_is_device_vrf (NMVpnConnection *self)
146a1d
+{
146a1d
+	NMDevice *parent;
146a1d
+	NMDevice *master;
146a1d
+
146a1d
+	parent = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (self));
146a1d
+	if (!parent)
146a1d
+		return FALSE;
146a1d
+
146a1d
+	master = nm_device_get_master (parent);
146a1d
+	return master && nm_device_get_link_type (master) == NM_LINK_TYPE_VRF;
146a1d
+}
146a1d
+
146a1d
 static void
146a1d
 nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
146a1d
 {
146a1d
@@ -1646,6 +1660,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict)
146a1d
 	nm_ip4_config_add_dependent_routes (config,
146a1d
 	                                    route_table,
146a1d
 	                                    nm_vpn_connection_get_ip4_route_metric (self),
146a1d
+	                                    _is_device_vrf (self),
146a1d
 	                                    &priv->ip4_dev_route_blacklist);
146a1d
 
146a1d
 	if (priv->ip4_config) {
146a1d
@@ -1840,9 +1855,7 @@ next:
146a1d
 		nm_ip6_config_add_route (config, &r, NULL);
146a1d
 	}
146a1d
 
146a1d
-	nm_ip6_config_add_dependent_routes (config,
146a1d
-	                                    route_table,
146a1d
-	                                    route_metric);
146a1d
+	nm_ip6_config_add_dependent_routes (config, route_table, route_metric, _is_device_vrf (self));
146a1d
 
146a1d
 	if (priv->ip6_config) {
146a1d
 		nm_ip6_config_replace (priv->ip6_config, config, NULL);
146a1d
-- 
146a1d
2.26.2
146a1d