NetworkManager/SOURCES/1004-fix-handling-generated-local-routes-rh1907661.patch
2021-09-09 22:46:30 +00:00

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