From c631aa48f034ade2b5cb97ccc4462d56d80174e7 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 17 Aug 2021 11:21:17 +0200 Subject: [PATCH] platform: capture NMIP[46]Config from platform with correct (reversed) order of IP addresses Fix the order of IP addresses when assuming devices (service restart). The order of IP addresses matters to kernel for selection of source IP address. If all other properties are equal ([1]), for IPv6, the address added *last* will be preferred. That is the address you see *first*` in `ip -6 addr show`. NMPlatform also preserves that order, so the address *first* is the most important one. On the other hand, in a connection profile, `ipv6.addresses` lists addresses in increasing priority (the last address is the primary one). That is for compatibility with initscripts, which iterates over the list of addresses and calls `ip addr add` (meaning, the last address will be added last and is thus preferred by kernel). As the priority order in the profile is reversed, also the priority order in NMIP[46]Config is reversed. Fix creating an NMIP[46]Config instance from platform addresses to honor the priority. This has real consequences. When restarting NetworkManager, the interface stays up with the addresses configured in the right order. After restart, the device gets assumed, which means that the NMIP[46]Config instance from the connection is not yet set, only the config from the platform gets synchronized. Previously the order was wrong, so during restart the order of IP addresses was reverted. [1] https://access.redhat.com/solutions/189153 https://bugzilla.redhat.com/show_bug.cgi?id=1988751 --- src/core/nm-ip4-config.c | 21 +-------------------- src/core/nm-ip6-config.c | 7 +------ 2 files changed, 2 insertions(+), 26 deletions(-) diff --git a/src/core/nm-ip4-config.c b/src/core/nm-ip4-config.c index 3d1e489a59..b9917ac95a 100644 --- a/src/core/nm-ip4-config.c +++ b/src/core/nm-ip4-config.c @@ -512,22 +512,6 @@ _notify_routes(NMIP4Config *self) /*****************************************************************************/ -static int -sort_captured_addresses(const CList *lst_a, const CList *lst_b, gconstpointer user_data) -{ - const NMPlatformIP4Address *addr_a = - NMP_OBJECT_CAST_IP4_ADDRESS(c_list_entry(lst_a, NMDedupMultiEntry, lst_entries)->obj); - const NMPlatformIP4Address *addr_b = - NMP_OBJECT_CAST_IP4_ADDRESS(c_list_entry(lst_b, NMDedupMultiEntry, lst_entries)->obj); - - nm_assert(addr_a); - nm_assert(addr_b); - - /* Primary addresses first */ - return NM_FLAGS_HAS(addr_a->n_ifa_flags, IFA_F_SECONDARY) - - NM_FLAGS_HAS(addr_b->n_ifa_flags, IFA_F_SECONDARY); -} - NMIP4Config * nm_ip4_config_clone(const NMIP4Config *self) { @@ -559,7 +543,7 @@ nm_ip4_config_capture(NMDedupMultiIndex *multi_idx, NMPlatform *platform, int if head_entry = nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex); if (head_entry) { - nmp_cache_iter_for_each (&iter, head_entry, &plobj) { + nmp_cache_iter_for_each_reverse (&iter, head_entry, &plobj) { if (!_nm_ip_config_add_obj(priv->multi_idx, &priv->idx_ip4_addresses_, ifindex, @@ -571,9 +555,6 @@ nm_ip4_config_capture(NMDedupMultiIndex *multi_idx, NMPlatform *platform, int if NULL)) nm_assert_not_reached(); } - head_entry = nm_ip4_config_lookup_addresses(self); - nm_assert(head_entry); - nm_dedup_multi_head_entry_sort(head_entry, sort_captured_addresses, NULL); _notify_addresses(self); } diff --git a/src/core/nm-ip6-config.c b/src/core/nm-ip6-config.c index d2ecf1759b..65e8473749 100644 --- a/src/core/nm-ip6-config.c +++ b/src/core/nm-ip6-config.c @@ -316,7 +316,7 @@ nm_ip6_config_capture(NMDedupMultiIndex * multi_idx, head_entry = nm_platform_lookup_object(platform, NMP_OBJECT_TYPE_IP6_ADDRESS, ifindex); if (head_entry) { - nmp_cache_iter_for_each (&iter, head_entry, &plobj) { + nmp_cache_iter_for_each_reverse (&iter, head_entry, &plobj) { if (!_nm_ip_config_add_obj(priv->multi_idx, &priv->idx_ip6_addresses_, ifindex, @@ -328,11 +328,6 @@ nm_ip6_config_capture(NMDedupMultiIndex * multi_idx, NULL)) nm_assert_not_reached(); } - head_entry = nm_ip6_config_lookup_addresses(self); - nm_assert(head_entry); - nm_dedup_multi_head_entry_sort(head_entry, - sort_captured_addresses, - GINT_TO_POINTER(use_temporary)); _notify_addresses(self); }