571 lines
25 KiB
Diff
571 lines
25 KiB
Diff
|
From 549687f0202469289cef3ac322f81a04677873b6 Mon Sep 17 00:00:00 2001
|
||
|
From: Thomas Haller <thaller@redhat.com>
|
||
|
Date: Tue, 23 Mar 2021 17:48:43 +0100
|
||
|
Subject: [PATCH 1/6] core: avoid logging pointer value in
|
||
|
nm_device_set_ip_config()
|
||
|
|
||
|
(cherry picked from commit 5da8c073efd67f12292c1c5c67ada64b9c9f5a6c)
|
||
|
(cherry picked from commit c0e937c8b9a1077d1e77c3fe1f480b6e5b54c55b)
|
||
|
---
|
||
|
src/core/devices/nm-device.c | 4 ++--
|
||
|
1 file changed, 2 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
|
||
|
index 040dd0b4d367..44b87490c17e 100644
|
||
|
--- a/src/core/devices/nm-device.c
|
||
|
+++ b/src/core/devices/nm-device.c
|
||
|
@@ -13496,10 +13496,10 @@ nm_device_set_ip_config(NMDevice * self,
|
||
|
nm_assert(IS_IPv4 || !ip4_dev_route_blacklist);
|
||
|
|
||
|
_LOGD(LOGD_IPX(IS_IPv4),
|
||
|
- "ip%c-config: update (commit=%d, new-config=%p)",
|
||
|
+ "ip%c-config: update (commit=%d, new-config=" NM_HASH_OBFUSCATE_PTR_FMT")",
|
||
|
nm_utils_addr_family_to_char(addr_family),
|
||
|
commit,
|
||
|
- new_config);
|
||
|
+ NM_HASH_OBFUSCATE_PTR(new_config));
|
||
|
|
||
|
/* Always commit to nm-platform to update lifetimes */
|
||
|
if (commit && new_config) {
|
||
|
--
|
||
|
2.30.2
|
||
|
|
||
|
|
||
|
From a633a7855bb08afc9709a8dbed01fb5e4278d540 Mon Sep 17 00:00:00 2001
|
||
|
From: Thomas Haller <thaller@redhat.com>
|
||
|
Date: Tue, 23 Mar 2021 17:56:37 +0100
|
||
|
Subject: [PATCH 2/6] core: log route-table-sync-mode in
|
||
|
nm_device_set_ip_config()
|
||
|
|
||
|
(cherry picked from commit f6db2c6261b560ec34b56eeeb3766c9165f5619b)
|
||
|
(cherry picked from commit 2fb1a22e2be6d9e83bfc9e9873f93976286a55b0)
|
||
|
---
|
||
|
src/core/devices/nm-device.c | 28 ++++++++++++++++++----------
|
||
|
1 file changed, 18 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
|
||
|
index 44b87490c17e..5eaf8c23e7da 100644
|
||
|
--- a/src/core/devices/nm-device.c
|
||
|
+++ b/src/core/devices/nm-device.c
|
||
|
@@ -13478,12 +13478,13 @@ nm_device_set_ip_config(NMDevice * self,
|
||
|
gboolean commit,
|
||
|
GPtrArray * ip4_dev_route_blacklist)
|
||
|
{
|
||
|
- NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
|
||
|
- const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
||
|
- NMIPConfig * old_config;
|
||
|
- gboolean has_changes = FALSE;
|
||
|
- gboolean success = TRUE;
|
||
|
- NMSettingsConnection *settings_connection;
|
||
|
+ NMDevicePrivate * priv = NM_DEVICE_GET_PRIVATE(self);
|
||
|
+ const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
||
|
+ NMIPConfig * old_config;
|
||
|
+ gboolean has_changes = FALSE;
|
||
|
+ gboolean success = TRUE;
|
||
|
+ NMSettingsConnection * settings_connection;
|
||
|
+ NMIPRouteTableSyncMode route_table_sync_mode;
|
||
|
|
||
|
nm_assert_addr_family(addr_family);
|
||
|
nm_assert(!new_config || nm_ip_config_get_addr_family(new_config) == addr_family);
|
||
|
@@ -13495,11 +13496,18 @@ nm_device_set_ip_config(NMDevice * self,
|
||
|
})));
|
||
|
nm_assert(IS_IPv4 || !ip4_dev_route_blacklist);
|
||
|
|
||
|
+ if (commit && new_config)
|
||
|
+ route_table_sync_mode = _get_route_table_sync_mode_stateful(self, addr_family);
|
||
|
+ else
|
||
|
+ route_table_sync_mode = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE;
|
||
|
+
|
||
|
_LOGD(LOGD_IPX(IS_IPv4),
|
||
|
- "ip%c-config: update (commit=%d, new-config=" NM_HASH_OBFUSCATE_PTR_FMT")",
|
||
|
+ "ip%c-config: update (commit=%d, new-config=" NM_HASH_OBFUSCATE_PTR_FMT
|
||
|
+ ", route-table-sync-mode=%d)",
|
||
|
nm_utils_addr_family_to_char(addr_family),
|
||
|
commit,
|
||
|
- NM_HASH_OBFUSCATE_PTR(new_config));
|
||
|
+ NM_HASH_OBFUSCATE_PTR(new_config),
|
||
|
+ (int) route_table_sync_mode);
|
||
|
|
||
|
/* Always commit to nm-platform to update lifetimes */
|
||
|
if (commit && new_config) {
|
||
|
@@ -13508,7 +13516,7 @@ nm_device_set_ip_config(NMDevice * self,
|
||
|
if (IS_IPv4) {
|
||
|
success = nm_ip4_config_commit(NM_IP4_CONFIG(new_config),
|
||
|
nm_device_get_platform(self),
|
||
|
- _get_route_table_sync_mode_stateful(self, AF_INET));
|
||
|
+ route_table_sync_mode);
|
||
|
nm_platform_ip4_dev_route_blacklist_set(nm_device_get_platform(self),
|
||
|
nm_ip_config_get_ifindex(new_config),
|
||
|
ip4_dev_route_blacklist);
|
||
|
@@ -13517,7 +13525,7 @@ nm_device_set_ip_config(NMDevice * self,
|
||
|
|
||
|
success = nm_ip6_config_commit(NM_IP6_CONFIG(new_config),
|
||
|
nm_device_get_platform(self),
|
||
|
- _get_route_table_sync_mode_stateful(self, AF_INET6),
|
||
|
+ route_table_sync_mode,
|
||
|
&temporary_not_available);
|
||
|
|
||
|
if (!_rt6_temporary_not_available_set(self, temporary_not_available))
|
||
|
--
|
||
|
2.30.2
|
||
|
|
||
|
|
||
|
From a9aead98e4c2d5ce73ab6388360139489f677320 Mon Sep 17 00:00:00 2001
|
||
|
From: Thomas Haller <thaller@redhat.com>
|
||
|
Date: Mon, 22 Mar 2021 17:31:35 +0100
|
||
|
Subject: [PATCH 3/6] core: add NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE mode
|
||
|
|
||
|
When we deactivate a device, we flush all IP addresses and
|
||
|
routes. Thus, have yet another sync mode for that. It will sync more
|
||
|
than "ALL".
|
||
|
|
||
|
(cherry picked from commit e226b5eb829e5e8c623948e35d406e815cd05089)
|
||
|
(cherry picked from commit b263454f241ea944d87e13f935530d0539343bce)
|
||
|
---
|
||
|
src/core/nm-types.h | 12 ++++++++----
|
||
|
src/core/platform/nm-platform.c | 29 +++++++++++++++++++----------
|
||
|
2 files changed, 27 insertions(+), 14 deletions(-)
|
||
|
|
||
|
diff --git a/src/core/nm-types.h b/src/core/nm-types.h
|
||
|
index ab2314594d4a..8a32b7d20459 100644
|
||
|
--- a/src/core/nm-types.h
|
||
|
+++ b/src/core/nm-types.h
|
||
|
@@ -245,12 +245,16 @@ typedef enum {
|
||
|
* local table (255).
|
||
|
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL: NM will sync all tables, including the
|
||
|
* local table (255).
|
||
|
+ * @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE: NM will sync all tables (including
|
||
|
+ * the local table). It will thereby remove all addresses, that is during
|
||
|
+ * deactivation.
|
||
|
*/
|
||
|
typedef enum {
|
||
|
- NM_IP_ROUTE_TABLE_SYNC_MODE_NONE = 0,
|
||
|
- NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN = 1,
|
||
|
- NM_IP_ROUTE_TABLE_SYNC_MODE_FULL = 2,
|
||
|
- NM_IP_ROUTE_TABLE_SYNC_MODE_ALL = 3,
|
||
|
+ NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
|
||
|
+ NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
||
|
+ NM_IP_ROUTE_TABLE_SYNC_MODE_FULL,
|
||
|
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL,
|
||
|
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE,
|
||
|
} NMIPRouteTableSyncMode;
|
||
|
|
||
|
/* settings */
|
||
|
diff --git a/src/core/platform/nm-platform.c b/src/core/platform/nm-platform.c
|
||
|
index 0e5f8ab54806..8cfcf8bc6654 100644
|
||
|
--- a/src/core/platform/nm-platform.c
|
||
|
+++ b/src/core/platform/nm-platform.c
|
||
|
@@ -4363,7 +4363,8 @@ nm_platform_ip_route_get_prune_list(NMPlatform * self,
|
||
|
nm_assert(NM_IN_SET(route_table_sync,
|
||
|
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
|
||
|
NM_IP_ROUTE_TABLE_SYNC_MODE_FULL,
|
||
|
- NM_IP_ROUTE_TABLE_SYNC_MODE_ALL));
|
||
|
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL,
|
||
|
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE));
|
||
|
|
||
|
nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family)), ifindex);
|
||
|
head_entry = nm_platform_lookup(self, &lookup);
|
||
|
@@ -4375,16 +4376,24 @@ nm_platform_ip_route_get_prune_list(NMPlatform * self,
|
||
|
c_list_for_each (iter, &head_entry->lst_entries_head) {
|
||
|
const NMPObject *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj;
|
||
|
|
||
|
- if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_FULL) {
|
||
|
- if (nm_platform_ip_route_get_effective_table(NMP_OBJECT_CAST_IP_ROUTE(obj))
|
||
|
- == RT_TABLE_LOCAL)
|
||
|
- continue;
|
||
|
- } else if (route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN) {
|
||
|
+ switch (route_table_sync) {
|
||
|
+ case NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN:
|
||
|
if (!nm_platform_route_table_is_main(
|
||
|
nm_platform_ip_route_get_effective_table(NMP_OBJECT_CAST_IP_ROUTE(obj))))
|
||
|
continue;
|
||
|
- } else
|
||
|
- nm_assert(route_table_sync == NM_IP_ROUTE_TABLE_SYNC_MODE_ALL);
|
||
|
+ break;
|
||
|
+ case NM_IP_ROUTE_TABLE_SYNC_MODE_FULL:
|
||
|
+ if (nm_platform_ip_route_get_effective_table(NMP_OBJECT_CAST_IP_ROUTE(obj))
|
||
|
+ == RT_TABLE_LOCAL)
|
||
|
+ continue;
|
||
|
+ break;
|
||
|
+ case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL:
|
||
|
+ case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE:
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ nm_assert_not_reached();
|
||
|
+ break;
|
||
|
+ }
|
||
|
|
||
|
g_ptr_array_add(routes_prune, (gpointer) nmp_object_ref(obj));
|
||
|
}
|
||
|
@@ -4679,7 +4688,7 @@ nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex)
|
||
|
routes_prune = nm_platform_ip_route_get_prune_list(self,
|
||
|
AF_INET,
|
||
|
ifindex,
|
||
|
- NM_IP_ROUTE_TABLE_SYNC_MODE_ALL);
|
||
|
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE);
|
||
|
success &= nm_platform_ip_route_sync(self, AF_INET, ifindex, NULL, routes_prune, NULL);
|
||
|
}
|
||
|
if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) {
|
||
|
@@ -4688,7 +4697,7 @@ nm_platform_ip_route_flush(NMPlatform *self, int addr_family, int ifindex)
|
||
|
routes_prune = nm_platform_ip_route_get_prune_list(self,
|
||
|
AF_INET6,
|
||
|
ifindex,
|
||
|
- NM_IP_ROUTE_TABLE_SYNC_MODE_ALL);
|
||
|
+ NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE);
|
||
|
success &= nm_platform_ip_route_sync(self, AF_INET6, ifindex, NULL, routes_prune, NULL);
|
||
|
}
|
||
|
return success;
|
||
|
--
|
||
|
2.30.2
|
||
|
|
||
|
|
||
|
From 7e6bf896b89c6c51f3524fa26f1214f65e748843 Mon Sep 17 00:00:00 2001
|
||
|
From: Thomas Haller <thaller@redhat.com>
|
||
|
Date: Mon, 22 Mar 2021 21:43:47 +0100
|
||
|
Subject: [PATCH 4/6] core: don't add ff00::/8 unicast route to
|
||
|
nm_ip6_config_add_dependent_routes()
|
||
|
|
||
|
This effectively reverts commit cd89026c5f4f ('core: add dependent
|
||
|
multicast route configured by kernel for IPv6').
|
||
|
|
||
|
It's not clear to me why this was done or why it would be correct.
|
||
|
|
||
|
True, kernel automatically adds multicast route like
|
||
|
|
||
|
multicast ff00::/8 dev $IFACE table local proto kernel metric 256 pref medium
|
||
|
|
||
|
But NetworkManager ignores all multicast routes for now. So the dependent
|
||
|
routes cannot contain multicast routes as they are not handled. Also,
|
||
|
the code added a unicast route, so I don't understand why the comment
|
||
|
is talking about multicast.
|
||
|
|
||
|
This seems just wrong. Drop it.
|
||
|
|
||
|
(cherry picked from commit c29d995000a147cecbe1dbaa9607936c1844ba10)
|
||
|
(cherry picked from commit 40bc834176fbe8c17a22c7ea77f3cb8aa6c407b6)
|
||
|
---
|
||
|
src/core/nm-ip6-config.c | 17 -----------------
|
||
|
1 file changed, 17 deletions(-)
|
||
|
|
||
|
diff --git a/src/core/nm-ip6-config.c b/src/core/nm-ip6-config.c
|
||
|
index 1f7def346510..f498fc796a44 100644
|
||
|
--- a/src/core/nm-ip6-config.c
|
||
|
+++ b/src/core/nm-ip6-config.c
|
||
|
@@ -396,23 +396,6 @@ nm_ip6_config_add_dependent_routes(NMIP6Config *self,
|
||
|
*
|
||
|
* For manually added IPv6 routes, add the device routes explicitly. */
|
||
|
|
||
|
- /* Pre-generate multicast route */
|
||
|
- {
|
||
|
- 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.s6_addr[0] = 0xffu;
|
||
|
- route->plen = 8;
|
||
|
- route->table_coerced = nm_platform_route_table_coerce(RT_TABLE_LOCAL);
|
||
|
- route->type_coerced = nm_platform_route_type_coerce(RTN_UNICAST);
|
||
|
- route->metric = 256;
|
||
|
-
|
||
|
- _add_route(self, r, NULL, NULL);
|
||
|
- }
|
||
|
-
|
||
|
nm_ip_config_iter_ip6_address_for_each (&iter, self, &my_addr) {
|
||
|
NMPlatformIP6Route *route;
|
||
|
gboolean has_peer;
|
||
|
--
|
||
|
2.30.2
|
||
|
|
||
|
|
||
|
From 542388d6b508981656eb96e6940fdf3359ac1353 Mon Sep 17 00:00:00 2001
|
||
|
From: Thomas Haller <thaller@redhat.com>
|
||
|
Date: Tue, 23 Mar 2021 10:05:30 +0100
|
||
|
Subject: [PATCH 5/6] core: minor cleanup in
|
||
|
nm_platform_ip_route_get_prune_list()
|
||
|
|
||
|
(cherry picked from commit fe1bf4c907c29997cbc6a28bc0781bfc419cb07f)
|
||
|
(cherry picked from commit 087c7f394cbffcf4bc786a8e92825059d340dfc9)
|
||
|
---
|
||
|
src/core/platform/nm-platform.c | 10 +++++-----
|
||
|
1 file changed, 5 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/src/core/platform/nm-platform.c b/src/core/platform/nm-platform.c
|
||
|
index 8cfcf8bc6654..45636ea85ed3 100644
|
||
|
--- a/src/core/platform/nm-platform.c
|
||
|
+++ b/src/core/platform/nm-platform.c
|
||
|
@@ -4374,22 +4374,22 @@ nm_platform_ip_route_get_prune_list(NMPlatform * self,
|
||
|
routes_prune = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nm_dedup_multi_obj_unref);
|
||
|
|
||
|
c_list_for_each (iter, &head_entry->lst_entries_head) {
|
||
|
- const NMPObject *obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj;
|
||
|
+ const NMPObject * obj = c_list_entry(iter, NMDedupMultiEntry, lst_entries)->obj;
|
||
|
+ const NMPlatformIPXRoute *rt = NMP_OBJECT_CAST_IPX_ROUTE(obj);
|
||
|
|
||
|
switch (route_table_sync) {
|
||
|
case NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN:
|
||
|
- if (!nm_platform_route_table_is_main(
|
||
|
- nm_platform_ip_route_get_effective_table(NMP_OBJECT_CAST_IP_ROUTE(obj))))
|
||
|
+ if (!nm_platform_route_table_is_main(nm_platform_ip_route_get_effective_table(&rt->rx)))
|
||
|
continue;
|
||
|
break;
|
||
|
case NM_IP_ROUTE_TABLE_SYNC_MODE_FULL:
|
||
|
- if (nm_platform_ip_route_get_effective_table(NMP_OBJECT_CAST_IP_ROUTE(obj))
|
||
|
- == RT_TABLE_LOCAL)
|
||
|
+ if (nm_platform_ip_route_get_effective_table(&rt->rx) == RT_TABLE_LOCAL)
|
||
|
continue;
|
||
|
break;
|
||
|
case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL:
|
||
|
case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE:
|
||
|
break;
|
||
|
+
|
||
|
default:
|
||
|
nm_assert_not_reached();
|
||
|
break;
|
||
|
--
|
||
|
2.30.2
|
||
|
|
||
|
|
||
|
From 0a331bb0f4646e3590e30660ed5c4bf599275a8b Mon Sep 17 00:00:00 2001
|
||
|
From: Thomas Haller <thaller@redhat.com>
|
||
|
Date: Fri, 19 Mar 2021 21:20:52 +0100
|
||
|
Subject: [PATCH 6/6] core: don't add dependent local route for addresses
|
||
|
|
||
|
When adding an IPv4 address, kernel automatically adds a local route.
|
||
|
This is done by fib_add_ifaddr(). Note that if the address is
|
||
|
IFA_F_SECONDARY, then the "src" is the primary address. That means, with
|
||
|
|
||
|
nmcli connection add con-name t type ethernet ifname t autoconnect no \
|
||
|
ipv4.method manual ipv6.method disabled \
|
||
|
ipv4.addresses '192.168.77.10/24, 192.168.77.11/24'
|
||
|
|
||
|
we get two routes:
|
||
|
|
||
|
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
|
||
|
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.10"
|
||
|
|
||
|
Our code would only generate instead:
|
||
|
|
||
|
"local 192.168.77.10 dev t table local proto kernel scope host src 192.168.77.10"
|
||
|
"local 192.168.77.11 dev t table local proto kernel scope host src 192.168.77.11"
|
||
|
|
||
|
Afterwards, this artificial route will be leaked:
|
||
|
|
||
|
#!/bin/bash
|
||
|
|
||
|
set -vx
|
||
|
|
||
|
nmcli connection delete t || :
|
||
|
ip link delete t || :
|
||
|
|
||
|
ip link add name t type veth peer t-veth
|
||
|
|
||
|
nmcli connection add con-name t type ethernet ifname t autoconnect no ipv4.method manual ipv4.addresses '192.168.77.10/24, 192.168.77.11/24' ipv6.method disabled
|
||
|
|
||
|
nmcli connection up t
|
||
|
|
||
|
ip route show table all dev t | grep --color '^\|192.168.77.11'
|
||
|
|
||
|
sleep 1
|
||
|
|
||
|
nmcli device modify t -ipv4.addresses 192.168.77.11/24
|
||
|
|
||
|
ip route show table all dev t | grep --color '^\|192.168.77.11'
|
||
|
|
||
|
ip route show table all dev t | grep -q 192.168.77.11 && echo "the local route 192.168.77.11 is still there, because NM adds a local route with wrong pref-src"
|
||
|
|
||
|
It will also be leaked because in the example above ipv4.route-table is
|
||
|
unset, so we are not in full route sync mode and the local table is not
|
||
|
synced.
|
||
|
|
||
|
This was introduced by commit 3e5fc04df320 ('core: add dependent local
|
||
|
routes configured by kernel'), but it's unclear to me why we really need
|
||
|
this. Drop it again and effectively revert commit 3e5fc04df320 ('core:
|
||
|
add dependent local routes configured by kernel').
|
||
|
|
||
|
I think this "solution" is still bad. We need to improve our route sync
|
||
|
approach with L3Cfg rework. For now, it's probably good enough.
|
||
|
|
||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1907661
|
||
|
(cherry picked from commit 557644f5e03a77b3ebe09ceba672217959cf3bdc)
|
||
|
(cherry picked from commit eb1c607c7054ff6b60209ef3afb10db74e19305e)
|
||
|
---
|
||
|
src/core/nm-ip4-config.c | 15 ------
|
||
|
src/core/nm-ip6-config.c | 16 ------
|
||
|
src/core/platform/nm-platform.c | 91 +++++++++++++++++++++++++++++++++
|
||
|
3 files changed, 91 insertions(+), 31 deletions(-)
|
||
|
|
||
|
diff --git a/src/core/nm-ip4-config.c b/src/core/nm-ip4-config.c
|
||
|
index c49dfb4c34b8..608b7fc8b70c 100644
|
||
|
--- a/src/core/nm-ip4-config.c
|
||
|
+++ b/src/core/nm-ip4-config.c
|
||
|
@@ -649,21 +649,6 @@ nm_ip4_config_add_dependent_routes(NMIP4Config *self,
|
||
|
if (my_addr->external)
|
||
|
continue;
|
||
|
|
||
|
- /* Pre-generate local route added by kernel */
|
||
|
- 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 = my_addr->address;
|
||
|
- route->plen = 32;
|
||
|
- route->pref_src = my_addr->address;
|
||
|
- 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);
|
||
|
- nm_clear_pointer(&r, nmp_object_unref);
|
||
|
-
|
||
|
if (nm_utils_ip4_address_is_zeronet(network)) {
|
||
|
/* Kernel doesn't add device-routes for destinations that
|
||
|
* start with 0.x.y.z. Skip them. */
|
||
|
diff --git a/src/core/nm-ip6-config.c b/src/core/nm-ip6-config.c
|
||
|
index f498fc796a44..1e36050d9bff 100644
|
||
|
--- a/src/core/nm-ip6-config.c
|
||
|
+++ b/src/core/nm-ip6-config.c
|
||
|
@@ -404,22 +404,6 @@ nm_ip6_config_add_dependent_routes(NMIP6Config *self,
|
||
|
if (my_addr->external)
|
||
|
continue;
|
||
|
|
||
|
- {
|
||
|
- nm_auto_nmpobj NMPObject *r = NULL;
|
||
|
-
|
||
|
- /* Pre-generate local route added by kernel */
|
||
|
- r = nmp_object_new(NMP_OBJECT_TYPE_IP6_ROUTE, NULL);
|
||
|
- route = NMP_OBJECT_CAST_IP6_ROUTE(r);
|
||
|
- route->ifindex = ifindex;
|
||
|
- route->network = my_addr->address;
|
||
|
- route->plen = 128;
|
||
|
- 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);
|
||
|
- }
|
||
|
-
|
||
|
if (NM_FLAGS_HAS(my_addr->n_ifa_flags, IFA_F_NOPREFIXROUTE))
|
||
|
continue;
|
||
|
if (my_addr->plen == 0)
|
||
|
diff --git a/src/core/platform/nm-platform.c b/src/core/platform/nm-platform.c
|
||
|
index 45636ea85ed3..459a33071700 100644
|
||
|
--- a/src/core/platform/nm-platform.c
|
||
|
+++ b/src/core/platform/nm-platform.c
|
||
|
@@ -4357,6 +4357,11 @@ nm_platform_ip_route_get_prune_list(NMPlatform * self,
|
||
|
GPtrArray * routes_prune;
|
||
|
const NMDedupMultiHeadEntry *head_entry;
|
||
|
CList * iter;
|
||
|
+ NMPlatformIP4Route rt_local4;
|
||
|
+ NMPlatformIP6Route rt_local6;
|
||
|
+ const NMPlatformLink * pllink;
|
||
|
+ const NMPlatformLnkVrf * lnk_vrf;
|
||
|
+ guint32 local_table;
|
||
|
|
||
|
nm_assert(NM_IS_PLATFORM(self));
|
||
|
nm_assert(NM_IN_SET(addr_family, AF_INET, AF_INET6));
|
||
|
@@ -4371,6 +4376,14 @@ nm_platform_ip_route_get_prune_list(NMPlatform * self,
|
||
|
if (!head_entry)
|
||
|
return NULL;
|
||
|
|
||
|
+ lnk_vrf = nm_platform_link_get_lnk_vrf(self, ifindex, &pllink);
|
||
|
+ if (!lnk_vrf && pllink && pllink->master > 0)
|
||
|
+ lnk_vrf = nm_platform_link_get_lnk_vrf(self, pllink->master, NULL);
|
||
|
+ local_table = lnk_vrf ? lnk_vrf->table : RT_TABLE_LOCAL;
|
||
|
+
|
||
|
+ rt_local4.plen = 0;
|
||
|
+ rt_local6.plen = 0;
|
||
|
+
|
||
|
routes_prune = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nm_dedup_multi_obj_unref);
|
||
|
|
||
|
c_list_for_each (iter, &head_entry->lst_entries_head) {
|
||
|
@@ -4387,6 +4400,84 @@ nm_platform_ip_route_get_prune_list(NMPlatform * self,
|
||
|
continue;
|
||
|
break;
|
||
|
case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL:
|
||
|
+
|
||
|
+ /* FIXME: we should better handle routes that are automatically added by kernel.
|
||
|
+ *
|
||
|
+ * For now, make a good guess which are those routes and exclude them from
|
||
|
+ * pruning them. */
|
||
|
+
|
||
|
+ if (NM_IS_IPv4(addr_family)) {
|
||
|
+ /* for each IPv4 address kernel adds a route like
|
||
|
+ *
|
||
|
+ * local $ADDR dev $IFACE table local proto kernel scope host src $PRIMARY_ADDR
|
||
|
+ *
|
||
|
+ * Check whether route could be of that kind. */
|
||
|
+ if (nm_platform_ip_route_get_effective_table(&rt->rx) == local_table
|
||
|
+ && rt->rx.plen == 32 && rt->rx.rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL
|
||
|
+ && rt->rx.metric == 0
|
||
|
+ && rt->r4.scope_inv == nm_platform_route_scope_inv(RT_SCOPE_HOST)
|
||
|
+ && rt->r4.gateway == INADDR_ANY) {
|
||
|
+ if (rt_local4.plen == 0) {
|
||
|
+ rt_local4 = (NMPlatformIP4Route){
|
||
|
+ .ifindex = ifindex,
|
||
|
+ .type_coerced = nm_platform_route_type_coerce(RTN_LOCAL),
|
||
|
+ .plen = 32,
|
||
|
+ .rt_source = NM_IP_CONFIG_SOURCE_RTPROT_KERNEL,
|
||
|
+ .metric = 0,
|
||
|
+ .table_coerced = nm_platform_route_table_coerce(local_table),
|
||
|
+ .scope_inv = nm_platform_route_scope_inv(RT_SCOPE_HOST),
|
||
|
+ .gateway = INADDR_ANY,
|
||
|
+ };
|
||
|
+ }
|
||
|
+
|
||
|
+ /* the possible "network" depends on the addresses we have. We don't check that
|
||
|
+ * carefully. If the other parameters match, we assume that this route is the one
|
||
|
+ * generated by kernel. */
|
||
|
+ rt_local4.network = rt->r4.network;
|
||
|
+ rt_local4.pref_src = rt->r4.pref_src;
|
||
|
+
|
||
|
+ /* to be more confident about comparing the value, use our nm_platform_ip4_route_cmp()
|
||
|
+ * implementation. That will also consider parameters that we leave unspecified here. */
|
||
|
+ if (nm_platform_ip4_route_cmp(&rt->r4,
|
||
|
+ &rt_local4,
|
||
|
+ NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
||
|
+ == 0)
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ } else {
|
||
|
+ /* for each IPv6 address (that is no longer tentative) kernel adds a route like
|
||
|
+ *
|
||
|
+ * local $ADDR dev $IFACE table local proto kernel metric 0 pref medium
|
||
|
+ *
|
||
|
+ * Same as for the IPv4 case. */
|
||
|
+ if (nm_platform_ip_route_get_effective_table(&rt->rx) == local_table
|
||
|
+ && rt->rx.plen == 128 && rt->rx.rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL
|
||
|
+ && rt->rx.metric == 0 && rt->r6.rt_pref == NM_ICMPV6_ROUTER_PREF_MEDIUM
|
||
|
+ && IN6_IS_ADDR_UNSPECIFIED(&rt->r6.gateway)) {
|
||
|
+ if (rt_local6.plen == 0) {
|
||
|
+ rt_local6 = (NMPlatformIP6Route){
|
||
|
+ .ifindex = ifindex,
|
||
|
+ .type_coerced = nm_platform_route_type_coerce(RTN_LOCAL),
|
||
|
+ .plen = 128,
|
||
|
+ .rt_source = NM_IP_CONFIG_SOURCE_RTPROT_KERNEL,
|
||
|
+ .metric = 0,
|
||
|
+ .table_coerced = nm_platform_route_table_coerce(local_table),
|
||
|
+ .rt_pref = NM_ICMPV6_ROUTER_PREF_MEDIUM,
|
||
|
+ .gateway = IN6ADDR_ANY_INIT,
|
||
|
+ };
|
||
|
+ }
|
||
|
+
|
||
|
+ rt_local6.network = rt->r6.network;
|
||
|
+
|
||
|
+ if (nm_platform_ip6_route_cmp(&rt->r6,
|
||
|
+ &rt_local6,
|
||
|
+ NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY)
|
||
|
+ == 0)
|
||
|
+ continue;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ break;
|
||
|
+
|
||
|
case NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE:
|
||
|
break;
|
||
|
|
||
|
--
|
||
|
2.30.2
|
||
|
|