From 1b23d305e86cfa426689cfa27994cffc0bcadc74 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Tue, 10 May 2022 03:08:53 -0400 Subject: [PATCH] import NetworkManager-1.36.0-4.el8 --- .NetworkManager.metadata | 2 +- .gitignore | 2 +- ...-platform-for-assuming-after-restart.patch | 48 - ...-documentation-for-nm-settings-nmcli.patch | 59 - SOURCES/1001-wwan-dns-fix-rh2059138.patch | 62 + ...erve-external-bridge-ports-rh2035519.patch | 332 ++++ ...serve-IPv6-multicast-route-rh2004212.patch | 99 - ...better-handle-other-routes-rh1977984.patch | 1620 ----------------- ...-fix-ovsdb-removal-ports-rhbz1935026.patch | 52 + ...NAKs-from-other-servers-rhbz2059673.patch} | 2 +- SOURCES/9999-fix-pregen-doc.patch | 100 +- SPECS/NetworkManager.spec | 173 +- 12 files changed, 602 insertions(+), 1949 deletions(-) delete mode 100644 SOURCES/1000-platform-fix-capturing-addresses-from-platform-for-assuming-after-restart.patch delete mode 100644 SOURCES/1001-nmcli-docs-fix-address-order-in-ipv46-addresses-documentation-for-nm-settings-nmcli.patch create mode 100644 SOURCES/1001-wwan-dns-fix-rh2059138.patch create mode 100644 SOURCES/1002-checkpoint-preserve-external-bridge-ports-rh2035519.patch delete mode 100644 SOURCES/1002-preserve-IPv6-multicast-route-rh2004212.patch delete mode 100644 SOURCES/1003-cloud-setup-better-handle-other-routes-rh1977984.patch create mode 100644 SOURCES/1003-fix-ovsdb-removal-ports-rhbz1935026.patch rename SOURCES/{1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2065188.patch => 1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2059673.patch} (98%) diff --git a/.NetworkManager.metadata b/.NetworkManager.metadata index d295b56..95d4404 100644 --- a/.NetworkManager.metadata +++ b/.NetworkManager.metadata @@ -1 +1 @@ -d2b4c08e920b5c96c128041948e3092eedcbba80 SOURCES/NetworkManager-1.32.10.tar.xz +adbe8e9eef649ac73c4fbaefd71a1335d4d016cd SOURCES/NetworkManager-1.36.0.tar.xz diff --git a/.gitignore b/.gitignore index a02fac0..db48e32 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/NetworkManager-1.32.10.tar.xz +SOURCES/NetworkManager-1.36.0.tar.xz diff --git a/SOURCES/1000-platform-fix-capturing-addresses-from-platform-for-assuming-after-restart.patch b/SOURCES/1000-platform-fix-capturing-addresses-from-platform-for-assuming-after-restart.patch deleted file mode 100644 index cde533f..0000000 --- a/SOURCES/1000-platform-fix-capturing-addresses-from-platform-for-assuming-after-restart.patch +++ /dev/null @@ -1,48 +0,0 @@ -From af06ca8b1190240146f746f8aeca6fd11bfbe6ad Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 19 Aug 2021 13:35:27 +0200 -Subject: [PATCH] platform: fix capturing addresses from platform for assuming - after restart - -Commit c631aa48f034 ('platform: capture NMIP[46]Config from platform -with correct (reversed) order of IP addresses') changed this for IPv6 -and IPv4, but it's not correct for IPv4. - -For IPv6, later `ip addr add` calls adds a new primary address, which -is also listed in `ip addr show` first. Hence, as NMIP6Config tracks -addresses in increasing priority, while NMPlatform tracks them as -exposed by kernel, the order when appending addresses form platform -to NMIP6Config must be reversed. - -That is not the case for IPv4. For IPv4, later `ip addr add` calls -add a secondary IP address. Also, in `ip addr show` output they are -appended. Consequently, IPv4 addresses are tracked by NMPlatform with -decreasing priority (in the reverse order than for IPv6). - -Fix constructing the NMIP4Config by fixing the address order. This is -important, because during restart devices get assumed and our code would -configure the order of addresses as it finds them. - -Fixes: c631aa48f034 ('platform: capture NMIP[46]Config from platform with correct (reversed) order of IP addresses') -(cherry picked from commit c380893dc6757e30b429f968bc90bc1edda68998) -(cherry picked from commit 605373b38ab463826bd7eb80408fb2cfae07ee91) ---- - src/core/nm-ip4-config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/core/nm-ip4-config.c b/src/core/nm-ip4-config.c -index 90531d0291..52a8faa791 100644 ---- a/src/core/nm-ip4-config.c -+++ b/src/core/nm-ip4-config.c -@@ -543,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_reverse (&iter, head_entry, &plobj) { -+ nmp_cache_iter_for_each (&iter, head_entry, &plobj) { - if (!_nm_ip_config_add_obj(priv->multi_idx, - &priv->idx_ip4_addresses_, - ifindex, --- -2.26.3 - diff --git a/SOURCES/1001-nmcli-docs-fix-address-order-in-ipv46-addresses-documentation-for-nm-settings-nmcli.patch b/SOURCES/1001-nmcli-docs-fix-address-order-in-ipv46-addresses-documentation-for-nm-settings-nmcli.patch deleted file mode 100644 index 6e16cad..0000000 --- a/SOURCES/1001-nmcli-docs-fix-address-order-in-ipv46-addresses-documentation-for-nm-settings-nmcli.patch +++ /dev/null @@ -1,59 +0,0 @@ -From d0ba892917461659b5b1e429fb217218ff204379 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Thu, 19 Aug 2021 13:53:29 +0200 -Subject: [PATCH] nmcli/docs: fix address order in ipv46.addresses - documentation for `man nm-settings-nmcli` - -For IPv4, the order is not like for IPv6. Of course not. - -Fixes: 7aa4ad0fa22c ('nmcli/docs: better describe ipv[46].addresses in `man nm-settings-nmcli`') -(cherry picked from commit 2f3c2647d2263bf565fd21d14a3db56f6a063b91) -(cherry picked from commit dd8bc31fdb37acc2780f94defeb54e80bb1acf53) ---- - src/libnm-core-impl/nm-setting-ip4-config.c | 2 +- - src/libnmc-setting/settings-docs.h.in | 2 +- - src/nmcli/generate-docs-nm-settings-nmcli.xml.in | 2 +- - 3 files changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/libnm-core-impl/nm-setting-ip4-config.c b/src/libnm-core-impl/nm-setting-ip4-config.c -index b3a18bcae7..a24ebcfb5c 100644 ---- a/src/libnm-core-impl/nm-setting-ip4-config.c -+++ b/src/libnm-core-impl/nm-setting-ip4-config.c -@@ -967,7 +967,7 @@ nm_setting_ip4_config_class_init(NMSettingIP4ConfigClass *klass) - * format: a comma separated list of addresses - * description: A list of IPv4 addresses and their prefix length. Multiple addresses - * can be separated by comma. For example "192.168.1.5/24, 10.1.0.5/24". -- * The addresses are listed in increasing priority, meaning the last address will -+ * The addresses are listed in decreasing priority, meaning the first address will - * be the primary address. - * ---end--- - */ -diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in -index 12625d4459..85c5aca1e4 100644 ---- a/src/libnmc-setting/settings-docs.h.in -+++ b/src/libnmc-setting/settings-docs.h.in -@@ -226,7 +226,7 @@ - #define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_REMOTE N_("The remote endpoint of the tunnel; the value must contain an IPv4 or IPv6 address.") - #define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_TOS N_("The type of service (IPv4) or traffic class (IPv6) field to be set on tunneled packets.") - #define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_TTL N_("The TTL to assign to tunneled packets. 0 is a special value meaning that packets inherit the TTL value.") --#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ADDRESSES N_("A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example \"192.168.1.5/24, 10.1.0.5/24\". The addresses are listed in increasing priority, meaning the last address will be the primary address.") -+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ADDRESSES N_("A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example \"192.168.1.5/24, 10.1.0.5/24\". The addresses are listed in decreasing priority, meaning the first address will be the primary address.") - #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DAD_TIMEOUT N_("Timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4.") - #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID N_("A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values \"mac\" and \"perm-mac\" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value \"ipv6-duid\" uses the DUID from \"ipv6.dhcp-duid\" property as an RFC4361-compliant client identifier. As IAID it uses \"ipv4.dhcp-iaid\" and falls back to \"ipv6.dhcp-iaid\" if unset. The special value \"duid\" generates a RFC4361-compliant client identifier based on \"ipv4.dhcp-iaid\" and uses a DUID generated by hashing /etc/machine-id. The special value \"stable\" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the \"${DEVICE}\" or \"${MAC}\" specifier to get a per-device key. If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin.") - #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_FQDN N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-hostname\" are mutually exclusive and cannot be set at the same time.") -diff --git a/src/nmcli/generate-docs-nm-settings-nmcli.xml.in b/src/nmcli/generate-docs-nm-settings-nmcli.xml.in -index 88803094d6..ca5225ba28 100644 ---- a/src/nmcli/generate-docs-nm-settings-nmcli.xml.in -+++ b/src/nmcli/generate-docs-nm-settings-nmcli.xml.in -@@ -650,7 +650,7 @@ - description="DNS servers priority. The relative priority for DNS servers specified by this setting. A lower numerical value is better (higher priority). Negative values have the special effect of excluding other configurations with a greater numerical priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. To avoid all DNS leaks, set the priority of the profile that should be used to the most negative value of all active connections profiles. Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. Note that commonly the resolver tries name servers in /etc/resolv.conf in the order listed, proceeding with the next server in the list on failure. See for example the "rotate" option of the dns-options setting. If there are any negative DNS priorities, then only name servers from the devices with that lowest priority will be considered. When using a DNS resolver that supports Conditional Forwarding or Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection is used to query domains in its search list. The search domains determine which name servers to ask, and the DNS priority is used to prioritize name servers based on the domain. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the best priority (lowest numerical value) wins. If a sub domain is configured on another interface it will be accepted regardless the priority, unless parent domain on the other interface has a negative priority, which causes the sub domain to be shadowed. With Split DNS one can avoid undesired DNS leaks by properly configuring DNS priorities and the search domains, so that only name servers of the desired interface are configured." /> - -+ description="A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example "192.168.1.5/24, 10.1.0.5/24". The addresses are listed in decreasing priority, meaning the first address will be the primary address." /> - --- -2.26.3 - diff --git a/SOURCES/1001-wwan-dns-fix-rh2059138.patch b/SOURCES/1001-wwan-dns-fix-rh2059138.patch new file mode 100644 index 0000000..fbfcf88 --- /dev/null +++ b/SOURCES/1001-wwan-dns-fix-rh2059138.patch @@ -0,0 +1,62 @@ +From 7ba52fdcfeeb1e5400bcecb9fa93b3099dcccb47 Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Fri, 25 Feb 2022 10:06:48 +0100 +Subject: [PATCH] core: initialize l3cd dns-priority for ppp and wwan + +For devices that configure IP by themselves (by returning +"->ready_for_ip_config() = TRUE" and implementing +->act_stage3_ip_config()), we skip manual configuration. Currently, +manual configuration is the only one that sets flag HAS_DNS_PRIORITY +into the resulting l3cd. + +So, the merged l3cd for such devices misses a dns-priority and is +ignored by the DNS manager. + +Explicitly initialize the priority to 0; in this way, the default +value for the device will be set in the final l3cd during the merge. + +Fixes: 58287cbcc0c8 ('core: rework IP configuration in NetworkManager using layer 3 configuration') + +https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/931 +(cherry picked from commit b2e559fab2fa5adbf4e159fc1c2cadd3d965b01b) +(cherry picked from commit bfd3216584e9fe1eb0b6f3f81e3eb75a40877775) +--- + src/core/devices/wwan/nm-modem-broadband.c | 2 ++ + src/core/ppp/nm-ppp-manager.c | 1 + + 2 files changed, 3 insertions(+) + +diff --git a/src/core/devices/wwan/nm-modem-broadband.c b/src/core/devices/wwan/nm-modem-broadband.c +index f5336d3750..b585652e5d 100644 +--- a/src/core/devices/wwan/nm-modem-broadband.c ++++ b/src/core/devices/wwan/nm-modem-broadband.c +@@ -1032,6 +1032,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho + l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), + ifindex, + NM_IP_CONFIG_SOURCE_WWAN); ++ nm_l3_config_data_set_dns_priority(l3cd, AF_INET, 0); + + address = (NMPlatformIP4Address){ + .address = address_network, +@@ -1118,6 +1119,7 @@ stage3_ip_config_start(NMModem *modem, int addr_family, NMModemIPMethod ip_metho + l3cd = nm_l3_config_data_new(nm_platform_get_multi_idx(NM_PLATFORM_GET), + ifindex, + NM_IP_CONFIG_SOURCE_WWAN); ++ nm_l3_config_data_set_dns_priority(l3cd, AF_INET6, 0); + + do_auto = TRUE; + +diff --git a/src/core/ppp/nm-ppp-manager.c b/src/core/ppp/nm-ppp-manager.c +index dd6b1bc7f0..5761d59d39 100644 +--- a/src/core/ppp/nm-ppp-manager.c ++++ b/src/core/ppp/nm-ppp-manager.c +@@ -545,6 +545,7 @@ impl_ppp_manager_set_ip4_config(NMDBusObject *obj, + NM_IP_CONFIG_SOURCE_PPP); + + nm_l3_config_data_set_mtu(l3cd, mtu); ++ nm_l3_config_data_set_dns_priority(l3cd, AF_INET, 0); + + address = (NMPlatformIP4Address){ + .plen = 32, +-- +2.34.1 + diff --git a/SOURCES/1002-checkpoint-preserve-external-bridge-ports-rh2035519.patch b/SOURCES/1002-checkpoint-preserve-external-bridge-ports-rh2035519.patch new file mode 100644 index 0000000..5d5d9c4 --- /dev/null +++ b/SOURCES/1002-checkpoint-preserve-external-bridge-ports-rh2035519.patch @@ -0,0 +1,332 @@ +From b55842ac0803b59fe8675464191180e44634ce1f Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Tue, 22 Feb 2022 22:08:18 +0100 +Subject: [PATCH 1/2] core: reject unsupported flags for CheckpointCreate D-Bus + request + +(cherry picked from commit df6ee44fb2b96cf05aaeeee500c75d7d91b37404) +(cherry picked from commit 4cfc2245d382b0b869bd52238eecd17f1c10af1c) +--- + src/core/nm-manager.c | 34 +++++++++++++++++++++++++--------- + 1 file changed, 25 insertions(+), 9 deletions(-) + +diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c +index b440b22457f2..53ef1754bb72 100644 +--- a/src/core/nm-manager.c ++++ b/src/core/nm-manager.c +@@ -7453,15 +7453,30 @@ impl_manager_checkpoint_create(NMDBusObject *obj, + GDBusMethodInvocation *invocation, + GVariant *parameters) + { +- NMManager *self = NM_MANAGER(obj); +- NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); +- NMAuthChain *chain; +- char **devices; +- guint32 rollback_timeout; +- guint32 flags; ++ NMManager *self = NM_MANAGER(obj); ++ NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self); ++ NMAuthChain *chain; ++ gs_strfreev char **devices = NULL; ++ guint32 rollback_timeout; ++ guint32 flags; + + G_STATIC_ASSERT_EXPR(sizeof(flags) <= sizeof(NMCheckpointCreateFlags)); + ++ g_variant_get(parameters, "(^aouu)", &devices, &rollback_timeout, &flags); ++ ++ if ((NMCheckpointCreateFlags) flags != flags ++ || NM_FLAGS_ANY(flags, ++ ~((guint32) (NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL ++ | NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS ++ | NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES ++ | NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING)))) { ++ g_dbus_method_invocation_return_error_literal(invocation, ++ NM_MANAGER_ERROR, ++ NM_MANAGER_ERROR_INVALID_ARGUMENTS, ++ "Invalid flags"); ++ return; ++ } ++ + chain = nm_auth_chain_new_context(invocation, checkpoint_auth_done_cb, self); + if (!chain) { + g_dbus_method_invocation_return_error_literal(invocation, +@@ -7471,11 +7486,12 @@ impl_manager_checkpoint_create(NMDBusObject *obj, + return; + } + +- g_variant_get(parameters, "(^aouu)", &devices, &rollback_timeout, &flags); +- + c_list_link_tail(&priv->auth_lst_head, nm_auth_chain_parent_lst_list(chain)); + nm_auth_chain_set_data(chain, "audit-op", NM_AUDIT_OP_CHECKPOINT_CREATE, NULL); +- nm_auth_chain_set_data(chain, "devices", devices, (GDestroyNotify) g_strfreev); ++ nm_auth_chain_set_data(chain, ++ "devices", ++ g_steal_pointer(&devices), ++ (GDestroyNotify) g_strfreev); + nm_auth_chain_set_data(chain, "flags", GUINT_TO_POINTER(flags), NULL); + nm_auth_chain_set_data(chain, "timeout", GUINT_TO_POINTER(rollback_timeout), NULL); + nm_auth_chain_add_call(chain, NM_AUTH_PERMISSION_CHECKPOINT_ROLLBACK, TRUE); +-- +2.35.1 + + +From 3c417c8338bf44292d4869763587286c7d492c0c Mon Sep 17 00:00:00 2001 +From: Thomas Haller +Date: Tue, 22 Feb 2022 21:55:57 +0100 +Subject: [PATCH 2/2] core: preserve external ports during checkpoint rollback + +When we have a bridge interface with ports attached externally (that is, +not by NetworkManager itself), then it can make sense that during +checkpoint rollback we want to keep those ports attached. + +During rollback, we may need to deactivate the bridge device and +re-activate it. Implement this, by setting a flag before deactivating, +which prevents external ports to be detached. The flag gets cleared, +when the device state changes to activated (the following activation) +or unmanaged. + +This is an ugly solution, for several reasons. + +For one, NMDevice tracks its ports in the "slaves" list. But what +it does is ugly. There is no clear concept to understand what it +actually tacks. For example, it tracks externally added interfaces +(nm_device_sys_iface_state_is_external()) that are attached while +not being connected. But it also tracks interfaces that we want to attach +during activation (but which are not yet actually enslaved). It also tracks +slaves that have no actual netdev device (OVS). So it's not clear what this +list contains and what it should contain at any point in time. When we skip +the change of the slaves states during nm_device_master_release_slaves_all(), +it's not really clear what the effects are. It's ugly, but probably correct +enough. What would be better, if we had a clear purpose of what the +lists (or several lists) mean. E.g. a list of all ports that are +currently, physically attached vs. a list of ports we want to attach vs. +a list of OVS slaves that have no actual netdev device. + +Another problem is that we attach state on the device +("activation_state_preserve_external_ports"), which should linger there +during the deactivation and reactivation. How can we be sure that we don't +leave that flag dangling there, and that the desired following activation +is the one we cared about? If the follow-up activation fails short (e.g. an +unmanaged command comes first), will we properly disconnect the slaves? +Should we even? In practice, it might be correct enough. + +Also, we only implement this for bridges. I think this is where it makes +the most sense. And after all, it's an odd thing to preserve unknown, +external things during a rollback -- unknown, because we have no knowledge +about why these ports are attached and what to do with them. + +Also, the change doesn't remember the ports that were attached when the +checkpoint was created. Instead, we preserve all ports that are attached +during rollback. That seems more useful and easier to implement. So we +don't actually rollback to the configuration when the checkpoint was +created. Instead, we rollback, but keep external devices. + +Also, we do this now by default and introduce a flag to get the previous +behavior. + +https://bugzilla.redhat.com/show_bug.cgi?id=2035519 +https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/issues/ # 909 +(cherry picked from commit 98b3056604fc565f273c264b892086a75a4db0e9) +(cherry picked from commit 351ca13358f62f85af675672c3399141bec092cd) +--- + src/core/devices/nm-device.c | 71 ++++++++++++++++++++++- + src/core/devices/nm-device.h | 2 + + src/core/nm-checkpoint.c | 5 ++ + src/core/nm-manager.c | 3 +- + src/libnm-core-public/nm-dbus-interface.h | 16 +++-- + 5 files changed, 90 insertions(+), 7 deletions(-) + +diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c +index 35360ceebb7b..a11486d54be3 100644 +--- a/src/core/devices/nm-device.c ++++ b/src/core/devices/nm-device.c +@@ -76,6 +76,7 @@ + #include "nm-hostname-manager.h" + + #include "nm-device-generic.h" ++#include "nm-device-bridge.h" + #include "nm-device-vlan.h" + #include "nm-device-vrf.h" + #include "nm-device-wireguard.h" +@@ -483,9 +484,12 @@ typedef struct _NMDevicePrivate { + + NMUtilsStableType current_stable_id_type : 3; + ++ bool activation_state_preserve_external_ports : 1; ++ + bool nm_owned : 1; /* whether the device is a device owned and created by NM */ + +- bool assume_state_guess_assume : 1; ++ bool assume_state_guess_assume : 1; ++ + char *assume_state_connection_uuid; + + guint64 udi_id; +@@ -7666,8 +7670,19 @@ nm_device_master_release_slaves(NMDevice *self) + c_list_for_each_safe (iter, safe, &priv->slaves) { + SlaveInfo *info = c_list_entry(iter, SlaveInfo, lst_slave); + ++ if (priv->activation_state_preserve_external_ports ++ && nm_device_sys_iface_state_is_external(info->slave)) { ++ _LOGT(LOGD_DEVICE, ++ "master: preserve external port %s", ++ nm_device_get_iface(info->slave)); ++ continue; ++ } + nm_device_master_release_one_slave(self, info->slave, TRUE, FALSE, reason); + } ++ ++ /* We only need this flag for a short time. It served its purpose. Clear ++ * it again. */ ++ nm_device_activation_state_set_preserve_external_ports(self, FALSE); + } + + /** +@@ -15386,6 +15401,16 @@ _set_state_full(NMDevice *self, NMDeviceState state, NMDeviceStateReason reason, + if (state > NM_DEVICE_STATE_DISCONNECTED) + nm_device_assume_state_reset(self); + ++ if (state < NM_DEVICE_STATE_UNAVAILABLE ++ || (state >= NM_DEVICE_STATE_IP_CONFIG && state < NM_DEVICE_STATE_ACTIVATED)) { ++ /* preserve-external-ports is used by NMCheckpoint to activate a master ++ * device, and preserve already attached ports. This means, this state is only ++ * relevant during the deactivation and the following activation of the ++ * right profile. Once we are sufficiently far in the activation of the ++ * intended profile, we clear the state again. */ ++ nm_device_activation_state_set_preserve_external_ports(self, FALSE); ++ } ++ + if (state <= NM_DEVICE_STATE_UNAVAILABLE) { + if (available_connections_del_all(self)) + _notify(self, PROP_AVAILABLE_CONNECTIONS); +@@ -15790,6 +15815,50 @@ nm_device_get_state(NMDevice *self) + return NM_DEVICE_GET_PRIVATE(self)->state; + } + ++/*****************************************************************************/ ++ ++/** ++ * nm_device_activation_state_set_preserve_external_ports: ++ * @self: the NMDevice. ++ * @flag: whether to set or clear the the flag. ++ * ++ * This sets an internal flag to true, which does something specific. ++ * For non-master devices, it has no effect. For master devices, this ++ * will prevent to detach all external ports, until the next activation ++ * completes. ++ * ++ * This is used during checkpoint/rollback. We may want to preserve ++ * externally attached ports during the restore. NMCheckpoint will ++ * call this before doing a re-activation. By setting the flag, ++ * we basically preserve such ports. ++ * ++ * Once we reach again ACTIVATED state, the flag gets cleared. This ++ * only has effect for the next activation cycle. */ ++void ++nm_device_activation_state_set_preserve_external_ports(NMDevice *self, gboolean flag) ++{ ++ NMDevicePrivate *priv; ++ ++ g_return_if_fail(NM_IS_DEVICE(self)); ++ ++ priv = NM_DEVICE_GET_PRIVATE(self); ++ ++ if (!NM_IS_DEVICE_BRIDGE(self)) { ++ /* This is actually only implemented for bridge devices. While it might ++ * make sense for bond/team or OVS, it's not clear that it is actually ++ * useful or desirable. */ ++ return; ++ } ++ ++ if (priv->activation_state_preserve_external_ports == flag) ++ return; ++ ++ priv->activation_state_preserve_external_ports = flag; ++ _LOGD(LOGD_DEVICE, ++ "activation-state: preserve-external-ports %s", ++ flag ? "enabled" : "disabled"); ++} ++ + /*****************************************************************************/ + /* NMConfigDevice interface related stuff */ + +diff --git a/src/core/devices/nm-device.h b/src/core/devices/nm-device.h +index cfcd4ade6d80..a7badb861087 100644 +--- a/src/core/devices/nm-device.h ++++ b/src/core/devices/nm-device.h +@@ -444,6 +444,8 @@ NMDeviceType nm_device_get_device_type(NMDevice *dev); + NMLinkType nm_device_get_link_type(NMDevice *dev); + NMMetered nm_device_get_metered(NMDevice *dev); + ++void nm_device_activation_state_set_preserve_external_ports(NMDevice *self, gboolean flag); ++ + guint32 nm_device_get_route_table(NMDevice *self, int addr_family); + guint32 nm_device_get_route_metric(NMDevice *dev, int addr_family); + +diff --git a/src/core/nm-checkpoint.c b/src/core/nm-checkpoint.c +index 0153af970de7..5b48f91aa515 100644 +--- a/src/core/nm-checkpoint.c ++++ b/src/core/nm-checkpoint.c +@@ -282,6 +282,11 @@ restore_and_activate_connection(NMCheckpoint *self, DeviceCheckpoint *dev_checkp + * an internal subject. */ + if (nm_device_get_state(dev_checkpoint->device) > NM_DEVICE_STATE_DISCONNECTED + && nm_device_get_state(dev_checkpoint->device) < NM_DEVICE_STATE_DEACTIVATING) { ++ if (!NM_FLAGS_HAS(priv->flags, NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS)) { ++ nm_device_activation_state_set_preserve_external_ports(dev_checkpoint->device, ++ TRUE); ++ } ++ + nm_device_state_changed(dev_checkpoint->device, + NM_DEVICE_STATE_DEACTIVATING, + NM_DEVICE_STATE_REASON_NEW_ACTIVATION); +diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c +index 53ef1754bb72..6c73d237c845 100644 +--- a/src/core/nm-manager.c ++++ b/src/core/nm-manager.c +@@ -7469,7 +7469,8 @@ impl_manager_checkpoint_create(NMDBusObject *obj, + ~((guint32) (NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL + | NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS + | NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES +- | NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING)))) { ++ | NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING ++ | NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS)))) { + g_dbus_method_invocation_return_error_literal(invocation, + NM_MANAGER_ERROR, + NM_MANAGER_ERROR_INVALID_ARGUMENTS, +diff --git a/src/libnm-core-public/nm-dbus-interface.h b/src/libnm-core-public/nm-dbus-interface.h +index fe2a6c09db58..0d23c7d7a793 100644 +--- a/src/libnm-core-public/nm-dbus-interface.h ++++ b/src/libnm-core-public/nm-dbus-interface.h +@@ -959,17 +959,23 @@ typedef enum { + * overlapping younger checkpoints. This opts-in that the + * checkpoint can be automatically destroyed by the rollback + * of an older checkpoint. Since: 1.12. ++ * @NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS: during rollback, ++ * by default externally added ports attached to bridge devices are preserved. ++ * With this flag, the rollback detaches all external ports. ++ * This only has an effect for bridge ports. Before 1.38, 1.36.2, this was the default ++ * behavior. Since: 1.38, 1.36.2. + * + * The flags for CheckpointCreate call + * + * Since: 1.4 (gi flags generated since 1.12) + */ + typedef enum { /*< flags >*/ +- NM_CHECKPOINT_CREATE_FLAG_NONE = 0, +- NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL = 0x01, +- NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS = 0x02, +- NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES = 0x04, +- NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING = 0x08, ++ NM_CHECKPOINT_CREATE_FLAG_NONE = 0, ++ NM_CHECKPOINT_CREATE_FLAG_DESTROY_ALL = 0x01, ++ NM_CHECKPOINT_CREATE_FLAG_DELETE_NEW_CONNECTIONS = 0x02, ++ NM_CHECKPOINT_CREATE_FLAG_DISCONNECT_NEW_DEVICES = 0x04, ++ NM_CHECKPOINT_CREATE_FLAG_ALLOW_OVERLAPPING = 0x08, ++ NM_CHECKPOINT_CREATE_FLAG_NO_PRESERVE_EXTERNAL_PORTS = 0x10, + } NMCheckpointCreateFlags; + + /** +-- +2.35.1 + diff --git a/SOURCES/1002-preserve-IPv6-multicast-route-rh2004212.patch b/SOURCES/1002-preserve-IPv6-multicast-route-rh2004212.patch deleted file mode 100644 index cc87e0c..0000000 --- a/SOURCES/1002-preserve-IPv6-multicast-route-rh2004212.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 5f25baaba435aaa71e63350eac72afbf4d4513fd Mon Sep 17 00:00:00 2001 -From: Beniamino Galvani -Date: Fri, 17 Sep 2021 13:53:18 +0200 -Subject: [PATCH] platform: preserve IPv6 multicast route added by kernel - -Kernels < 5.11 add a route like: - - unicast ff00::/8 dev $IFACE proto boot scope global metric 256 pref medium - -to allow sending and receiving IPv6 multicast traffic. Ensure it's not -removed it when we do a route sync in mode ALL. - -In kernel 5.11 there were commits: - - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=ceed9038b2783d14e0422bdc6fd04f70580efb4c - https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a826b04303a40d52439aa141035fca5654ccaccd - -After those the route looks like - - multicast ff00::/8 dev $IFACE proto kernel metric 256 pref medium - -As NM ignores routes with rtm_type multicast, the code in this commit -is not needed on newer kernels. - -https://bugzilla.redhat.com/show_bug.cgi?id=2004212 -https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/984 -(cherry picked from commit 8003ca68f770c69e109c16f638abbcce44af9439) -(cherry picked from commit ce8eb446b4d9465a906bf8952c1b454dab8d0c7c) ---- - src/libnm-platform/nm-platform.c | 39 ++++++++++++++++++++++++++++++++ - 1 file changed, 39 insertions(+) - -diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c -index 6c0d0015d6..b7a65df597 100644 ---- a/src/libnm-platform/nm-platform.c -+++ b/src/libnm-platform/nm-platform.c -@@ -4304,6 +4304,7 @@ nm_platform_ip_route_get_prune_list(NMPlatform * self, - CList * iter; - NMPlatformIP4Route rt_local4; - NMPlatformIP6Route rt_local6; -+ NMPlatformIP6Route rt_mcast6; - const NMPlatformLink * pllink; - const NMPlatformLnkVrf * lnk_vrf; - guint32 local_table; -@@ -4328,6 +4329,7 @@ nm_platform_ip_route_get_prune_list(NMPlatform * self, - - rt_local4.plen = 0; - rt_local6.plen = 0; -+ rt_mcast6.plen = 0; - - routes_prune = g_ptr_array_new_full(head_entry->len, (GDestroyNotify) nm_dedup_multi_obj_unref); - -@@ -4420,6 +4422,43 @@ nm_platform_ip_route_get_prune_list(NMPlatform * self, - == 0) - continue; - } -+ -+ /* Kernels < 5.11 add a route like: -+ * -+ * unicast ff00::/8 dev $IFACE proto boot scope global metric 256 pref medium -+ * -+ * to allow sending and receiving IPv6 multicast traffic. Don't remove it. -+ * Since kernel 5.11 the route looks like: -+ * -+ * multicast ff00::/8 dev $IFACE proto kernel metric 256 pref medium -+ * -+ * As NM ignores routes with rtm_type multicast, there is no need for the code -+ * below on newer kernels. -+ */ -+ if (nm_platform_ip_route_get_effective_table(&rt->rx) == local_table -+ && rt->rx.plen == 8 && rt->rx.rt_source == NM_IP_CONFIG_SOURCE_RTPROT_BOOT -+ && rt->rx.metric == 256 && rt->r6.rt_pref == NM_ICMPV6_ROUTER_PREF_MEDIUM -+ && IN6_IS_ADDR_UNSPECIFIED(&rt->r6.gateway)) { -+ if (rt_mcast6.plen == 0) { -+ rt_mcast6 = (NMPlatformIP6Route){ -+ .ifindex = ifindex, -+ .type_coerced = nm_platform_route_type_coerce(RTN_UNICAST), -+ .plen = 8, -+ .rt_source = NM_IP_CONFIG_SOURCE_RTPROT_BOOT, -+ .metric = 256, -+ .table_coerced = nm_platform_route_table_coerce(local_table), -+ .rt_pref = NM_ICMPV6_ROUTER_PREF_MEDIUM, -+ .gateway = IN6ADDR_ANY_INIT, -+ .network = {{{0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}}}, -+ }; -+ } -+ -+ if (nm_platform_ip6_route_cmp(&rt->r6, -+ &rt_mcast6, -+ NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) -+ == 0) -+ continue; -+ } - } - break; - --- -2.31.1 - diff --git a/SOURCES/1003-cloud-setup-better-handle-other-routes-rh1977984.patch b/SOURCES/1003-cloud-setup-better-handle-other-routes-rh1977984.patch deleted file mode 100644 index 7c8e51b..0000000 --- a/SOURCES/1003-cloud-setup-better-handle-other-routes-rh1977984.patch +++ /dev/null @@ -1,1620 +0,0 @@ -From f79d5a903b769f45f084d81a732ec9b3dcc3f2a9 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 1 Sep 2021 09:30:29 +0200 -Subject: [PATCH 01/10] cloud-setup: return structure for get_config() result - instead of generic hash table - -Returning a struct seems easier to understand, because then the result -is typed. - -Also, we might return additional results, which are system wide and not -per-interface. - -(cherry picked from commit 323e18276894591712a5e29f6e907562c79c5216) -(cherry picked from commit c94b1c43d4b5c5b88d67d7966d23a005028e78d8) ---- - src/nm-cloud-setup/main.c | 54 ++++++++++++++++-------------- - src/nm-cloud-setup/nmcs-provider.c | 28 ++++++++++++++-- - src/nm-cloud-setup/nmcs-provider.h | 20 ++++++++++- - 3 files changed, 72 insertions(+), 30 deletions(-) - -diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c -index 8dc67851794c..04b29f8a4b74 100644 ---- a/src/nm-cloud-setup/main.c -+++ b/src/nm-cloud-setup/main.c -@@ -200,30 +200,30 @@ _nmc_get_device_by_hwaddr(NMClient *nmc, const char *hwaddr) - /*****************************************************************************/ - - typedef struct { -- GMainLoop * main_loop; -- GHashTable *config_dict; -+ GMainLoop * main_loop; -+ NMCSProviderGetConfigResult *result; - } GetConfigData; - - static void --_get_config_cb(GObject *source, GAsyncResult *result, gpointer user_data) -+_get_config_cb(GObject *source, GAsyncResult *res, gpointer user_data) - { -- GetConfigData * data = user_data; -- gs_unref_hashtable GHashTable *config_dict = NULL; -- gs_free_error GError *error = NULL; -+ GetConfigData * data = user_data; -+ nm_auto_free_nmcs_provider_get_config_result NMCSProviderGetConfigResult *result = NULL; -+ gs_free_error GError *error = NULL; - -- config_dict = nmcs_provider_get_config_finish(NMCS_PROVIDER(source), result, &error); -+ result = nmcs_provider_get_config_finish(NMCS_PROVIDER(source), res, &error); - -- if (!config_dict) { -+ if (!result) { - if (!nm_utils_error_is_cancelled(error)) - _LOGI("failure to get meta data: %s", error->message); - } else - _LOGD("meta data received"); - -- data->config_dict = g_steal_pointer(&config_dict); -+ data->result = g_steal_pointer(&result); - g_main_loop_quit(data->main_loop); - } - --static GHashTable * -+static NMCSProviderGetConfigResult * - _get_config(GCancellable *sigterm_cancellable, NMCSProvider *provider, NMClient *nmc) - { - nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new(NULL, FALSE); -@@ -243,7 +243,7 @@ _get_config(GCancellable *sigterm_cancellable, NMCSProvider *provider, NMClient - - g_main_loop_run(main_loop); - -- return data.config_dict; -+ return data.result; - } - - /*****************************************************************************/ -@@ -396,13 +396,13 @@ _nmc_mangle_connection(NMDevice * device, - /*****************************************************************************/ - - static guint --_config_data_get_num_valid(GHashTable *config_dict) -+_config_data_get_num_valid(const NMCSProviderGetConfigResult *result) - { - const NMCSProviderGetConfigIfaceData *config_data; - GHashTableIter h_iter; - guint n = 0; - -- g_hash_table_iter_init(&h_iter, config_dict); -+ g_hash_table_iter_init(&h_iter, result->iface_datas); - while (g_hash_table_iter_next(&h_iter, NULL, (gpointer *) &config_data)) { - if (nmcs_provider_get_config_iface_data_is_valid(config_data)) - n++; -@@ -525,7 +525,9 @@ try_again: - } - - static gboolean --_config_all(GCancellable *sigterm_cancellable, NMClient *nmc, GHashTable *config_dict) -+_config_all(GCancellable * sigterm_cancellable, -+ NMClient * nmc, -+ const NMCSProviderGetConfigResult *result) - { - GHashTableIter h_iter; - const NMCSProviderGetConfigIfaceData *c_config_data; -@@ -533,9 +535,9 @@ _config_all(GCancellable *sigterm_cancellable, NMClient *nmc, GHashTable *config - gboolean is_single_nic; - gboolean any_changes = FALSE; - -- is_single_nic = (_config_data_get_num_valid(config_dict) <= 1); -+ is_single_nic = (_config_data_get_num_valid(result) <= 1); - -- g_hash_table_iter_init(&h_iter, config_dict); -+ g_hash_table_iter_init(&h_iter, result->iface_datas); - while (g_hash_table_iter_next(&h_iter, (gpointer *) &c_hwaddr, (gpointer *) &c_config_data)) { - if (_config_one(sigterm_cancellable, nmc, is_single_nic, c_hwaddr, c_config_data)) - any_changes = TRUE; -@@ -564,12 +566,12 @@ sigterm_handler(gpointer user_data) - int - main(int argc, const char *const *argv) - { -- gs_unref_object GCancellable * sigterm_cancellable = NULL; -- nm_auto_destroy_and_unref_gsource GSource *sigterm_source = NULL; -- gs_unref_object NMCSProvider *provider = NULL; -- gs_unref_object NMClient *nmc = NULL; -- gs_unref_hashtable GHashTable *config_dict = NULL; -- gs_free_error GError *error = NULL; -+ gs_unref_object GCancellable * sigterm_cancellable = NULL; -+ nm_auto_destroy_and_unref_gsource GSource *sigterm_source = NULL; -+ gs_unref_object NMCSProvider *provider = NULL; -+ gs_unref_object NMClient * nmc = NULL; -+ nm_auto_free_nmcs_provider_get_config_result NMCSProviderGetConfigResult *result = NULL; -+ gs_free_error GError *error = NULL; - - _nm_logging_enabled_init(g_getenv(NMCS_ENV_VARIABLE("NM_CLOUD_SETUP_LOG"))); - -@@ -614,17 +616,17 @@ main(int argc, const char *const *argv) - goto done; - } - -- config_dict = _get_config(sigterm_cancellable, provider, nmc); -- if (!config_dict) -+ result = _get_config(sigterm_cancellable, provider, nmc); -+ if (!result) - goto done; - -- if (_config_all(sigterm_cancellable, nmc, config_dict)) -+ if (_config_all(sigterm_cancellable, nmc, result)) - _LOGI("some changes were applied for provider %s", nmcs_provider_get_name(provider)); - else - _LOGD("no changes were applied for provider %s", nmcs_provider_get_name(provider)); - - done: -- nm_clear_pointer(&config_dict, g_hash_table_unref); -+ nm_clear_pointer(&result, nmcs_provider_get_config_result_free); - g_clear_object(&nmc); - g_clear_object(&provider); - -diff --git a/src/nm-cloud-setup/nmcs-provider.c b/src/nm-cloud-setup/nmcs-provider.c -index 678152aa95e0..77f8090a8225 100644 ---- a/src/nm-cloud-setup/nmcs-provider.c -+++ b/src/nm-cloud-setup/nmcs-provider.c -@@ -49,6 +49,28 @@ nmcs_provider_get_main_context(NMCSProvider *self) - - return nm_http_client_get_main_context(NMCS_PROVIDER_GET_PRIVATE(self)->http_client); - } -+/*****************************************************************************/ -+ -+static NMCSProviderGetConfigResult * -+nmcs_provider_get_config_result_new(GHashTable *iface_datas) -+{ -+ NMCSProviderGetConfigResult *result; -+ -+ result = g_new(NMCSProviderGetConfigResult, 1); -+ *result = (NMCSProviderGetConfigResult){ -+ .iface_datas = g_hash_table_ref(iface_datas), -+ }; -+ return result; -+} -+ -+void -+nmcs_provider_get_config_result_free(NMCSProviderGetConfigResult *result) -+{ -+ if (result) { -+ nm_g_hash_table_unref(result->iface_datas); -+ g_free(result); -+ } -+} - - /*****************************************************************************/ - -@@ -137,8 +159,8 @@ _get_config_task_maybe_return(NMCSProviderGetConfigTaskData *get_config_data, GE - } else { - _LOGD("get-config: success"); - g_task_return_pointer(get_config_data->task, -- g_hash_table_ref(get_config_data->result_dict), -- (GDestroyNotify) g_hash_table_unref); -+ nmcs_provider_get_config_result_new(get_config_data->result_dict), -+ (GDestroyNotify) nmcs_provider_get_config_result_free); - } - - nm_clear_g_signal_handler(g_task_get_cancellable(get_config_data->task), -@@ -217,7 +239,7 @@ nmcs_provider_get_config(NMCSProvider * self, - NMCS_PROVIDER_GET_CLASS(self)->get_config(self, get_config_data); - } - --GHashTable * -+NMCSProviderGetConfigResult * - nmcs_provider_get_config_finish(NMCSProvider *self, GAsyncResult *result, GError **error) - { - g_return_val_if_fail(NMCS_IS_PROVIDER(self), FALSE); -diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h -index 13212b8e4cb4..730ddc9d8f09 100644 ---- a/src/nm-cloud-setup/nmcs-provider.h -+++ b/src/nm-cloud-setup/nmcs-provider.h -@@ -43,6 +43,24 @@ nmcs_provider_get_config_iface_data_is_valid(const NMCSProviderGetConfigIfaceDat - - NMCSProviderGetConfigIfaceData *nmcs_provider_get_config_iface_data_new(gboolean was_requested); - -+/*****************************************************************************/ -+ -+typedef struct { -+ /* A dictionary of (const char *) -> (NMCSProviderGetConfigIfaceData *). -+ * This is the per-interface result of get_config(). */ -+ GHashTable *iface_datas; -+} NMCSProviderGetConfigResult; -+ -+void nmcs_provider_get_config_result_free(NMCSProviderGetConfigResult *result); -+ -+NM_AUTO_DEFINE_FCN0(NMCSProviderGetConfigResult *, -+ _nm_auto_free_nmcs_provider_get_config_result, -+ nmcs_provider_get_config_result_free); -+#define nm_auto_free_nmcs_provider_get_config_result \ -+ nm_auto(_nm_auto_free_nmcs_provider_get_config_result) -+ -+/*****************************************************************************/ -+ - typedef struct { - GTask *task; - -@@ -124,7 +142,7 @@ void nmcs_provider_get_config(NMCSProvider * provider, - GAsyncReadyCallback callback, - gpointer user_data); - --GHashTable * -+NMCSProviderGetConfigResult * - nmcs_provider_get_config_finish(NMCSProvider *provider, GAsyncResult *result, GError **error); - - #endif /* __NMCS_PROVIDER_H__ */ --- -2.31.1 - - -From 165dd652446673c826ef0da33b865da359aa22ee Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 1 Sep 2021 09:42:37 +0200 -Subject: [PATCH 02/10] cloud-setup: cache number of valid interfaces in - get-config result - -Now that we return a struct from get_config(), we can have system-wide -properties returned. - -Let it count and cache the number of valid iface_datas. - -Currently that is not yet used, but it will be. - -(cherry picked from commit a3cd66d3fadcecab9b186cc7f634f6ec6a5a92ee) -(cherry picked from commit e74375fc3b68b07d1ed5f6ebca40cbe5b20ed47b) ---- - src/nm-cloud-setup/main.c | 22 +--------------------- - src/nm-cloud-setup/nmcs-provider.c | 15 +++++++++++++-- - src/nm-cloud-setup/nmcs-provider.h | 3 +++ - 3 files changed, 17 insertions(+), 23 deletions(-) - -diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c -index 04b29f8a4b74..686cd2fc0c84 100644 ---- a/src/nm-cloud-setup/main.c -+++ b/src/nm-cloud-setup/main.c -@@ -395,26 +395,9 @@ _nmc_mangle_connection(NMDevice * device, - - /*****************************************************************************/ - --static guint --_config_data_get_num_valid(const NMCSProviderGetConfigResult *result) --{ -- const NMCSProviderGetConfigIfaceData *config_data; -- GHashTableIter h_iter; -- guint n = 0; -- -- g_hash_table_iter_init(&h_iter, result->iface_datas); -- while (g_hash_table_iter_next(&h_iter, NULL, (gpointer *) &config_data)) { -- if (nmcs_provider_get_config_iface_data_is_valid(config_data)) -- n++; -- } -- -- return n; --} -- - static gboolean - _config_one(GCancellable * sigterm_cancellable, - NMClient * nmc, -- gboolean is_single_nic, - const char * hwaddr, - const NMCSProviderGetConfigIfaceData *config_data) - { -@@ -532,14 +515,11 @@ _config_all(GCancellable * sigterm_cancellable, - GHashTableIter h_iter; - const NMCSProviderGetConfigIfaceData *c_config_data; - const char * c_hwaddr; -- gboolean is_single_nic; - gboolean any_changes = FALSE; - -- is_single_nic = (_config_data_get_num_valid(result) <= 1); -- - g_hash_table_iter_init(&h_iter, result->iface_datas); - while (g_hash_table_iter_next(&h_iter, (gpointer *) &c_hwaddr, (gpointer *) &c_config_data)) { -- if (_config_one(sigterm_cancellable, nmc, is_single_nic, c_hwaddr, c_config_data)) -+ if (_config_one(sigterm_cancellable, nmc, c_hwaddr, c_config_data)) - any_changes = TRUE; - } - -diff --git a/src/nm-cloud-setup/nmcs-provider.c b/src/nm-cloud-setup/nmcs-provider.c -index 77f8090a8225..8f82ddb493ea 100644 ---- a/src/nm-cloud-setup/nmcs-provider.c -+++ b/src/nm-cloud-setup/nmcs-provider.c -@@ -54,12 +54,23 @@ nmcs_provider_get_main_context(NMCSProvider *self) - static NMCSProviderGetConfigResult * - nmcs_provider_get_config_result_new(GHashTable *iface_datas) - { -- NMCSProviderGetConfigResult *result; -+ const NMCSProviderGetConfigIfaceData *iface_data; -+ NMCSProviderGetConfigResult * result; -+ GHashTableIter h_iter; -+ guint num_valid_ifaces = 0; -+ -+ g_hash_table_iter_init(&h_iter, iface_datas); -+ while (g_hash_table_iter_next(&h_iter, NULL, (gpointer *) &iface_data)) { -+ if (nmcs_provider_get_config_iface_data_is_valid(iface_data)) -+ num_valid_ifaces++; -+ } - - result = g_new(NMCSProviderGetConfigResult, 1); - *result = (NMCSProviderGetConfigResult){ -- .iface_datas = g_hash_table_ref(iface_datas), -+ .iface_datas = g_hash_table_ref(iface_datas), -+ .num_valid_ifaces = num_valid_ifaces, - }; -+ - return result; - } - -diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h -index 730ddc9d8f09..2e4c8d167a73 100644 ---- a/src/nm-cloud-setup/nmcs-provider.h -+++ b/src/nm-cloud-setup/nmcs-provider.h -@@ -49,6 +49,9 @@ typedef struct { - /* A dictionary of (const char *) -> (NMCSProviderGetConfigIfaceData *). - * This is the per-interface result of get_config(). */ - GHashTable *iface_datas; -+ -+ /* The number of iface_datas that are nmcs_provider_get_config_iface_data_is_valid(). */ -+ guint num_valid_ifaces; - } NMCSProviderGetConfigResult; - - void nmcs_provider_get_config_result_free(NMCSProviderGetConfigResult *result); --- -2.31.1 - - -From 2e6d23ef2496b7a26f6406fab1d274eee66467af Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 1 Sep 2021 10:11:31 +0200 -Subject: [PATCH 03/10] cloud-setup: count numbers of valid IPv4 addresses in - get-config result - -Will be used next. - -(cherry picked from commit 7969ae1a82b90c3a9dbe33875d138c7b55cf6ac8) -(cherry picked from commit ae504433f11480fde2436d3a5acba026db6c47bd) ---- - src/nm-cloud-setup/nmcs-provider.c | 6 +++++- - src/nm-cloud-setup/nmcs-provider.h | 3 +++ - 2 files changed, 8 insertions(+), 1 deletion(-) - -diff --git a/src/nm-cloud-setup/nmcs-provider.c b/src/nm-cloud-setup/nmcs-provider.c -index 8f82ddb493ea..8901100378d0 100644 ---- a/src/nm-cloud-setup/nmcs-provider.c -+++ b/src/nm-cloud-setup/nmcs-provider.c -@@ -58,17 +58,21 @@ nmcs_provider_get_config_result_new(GHashTable *iface_datas) - NMCSProviderGetConfigResult * result; - GHashTableIter h_iter; - guint num_valid_ifaces = 0; -+ guint num_ipv4s = 0; - - g_hash_table_iter_init(&h_iter, iface_datas); - while (g_hash_table_iter_next(&h_iter, NULL, (gpointer *) &iface_data)) { -- if (nmcs_provider_get_config_iface_data_is_valid(iface_data)) -+ if (nmcs_provider_get_config_iface_data_is_valid(iface_data)) { - num_valid_ifaces++; -+ num_ipv4s += iface_data->ipv4s_len; -+ } - } - - result = g_new(NMCSProviderGetConfigResult, 1); - *result = (NMCSProviderGetConfigResult){ - .iface_datas = g_hash_table_ref(iface_datas), - .num_valid_ifaces = num_valid_ifaces, -+ .num_ipv4s = num_ipv4s, - }; - - return result; -diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h -index 2e4c8d167a73..31fec4449f9e 100644 ---- a/src/nm-cloud-setup/nmcs-provider.h -+++ b/src/nm-cloud-setup/nmcs-provider.h -@@ -52,6 +52,9 @@ typedef struct { - - /* The number of iface_datas that are nmcs_provider_get_config_iface_data_is_valid(). */ - guint num_valid_ifaces; -+ -+ /* the number of IPv4 addresses over all valid iface_datas. */ -+ guint num_ipv4s; - } NMCSProviderGetConfigResult; - - void nmcs_provider_get_config_result_free(NMCSProviderGetConfigResult *result); --- -2.31.1 - - -From d80ef34f9390eb2baecb863cbbeded3dbffa1d8e Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 1 Sep 2021 10:15:37 +0200 -Subject: [PATCH 04/10] cloud-setup: skip configuring policy routing if there - is only one interface/address - -nm-cloud-setup automatically configures the network. That may conflict -with what the user wants. In case the user configures some specific -setup, they are encouraged to disable nm-cloud-setup (and its -automatism). - -Still, what we do by default matters, and should play as well with -user's expectations. Configuring policy routing and a higher priority -table (30400+) that hijacks the traffic can cause problems. - -If the system only has one IPv4 address and one interface, then there -is no point in configuring policy routing at all. Detect that, and skip -the change in that case. - -Note that of course we need to handle the case where previously multiple -IP addresses were configured and an update gives only one address. In -that case we need to clear the previously configured rules/routes. The -patch achieves this. - -(cherry picked from commit 5f047968d7a48999d20001f83e2005caa43c80ce) -(cherry picked from commit 8bc8a0f56b97c28cf26fd678a549db41399adcb7) ---- - src/nm-cloud-setup/main.c | 41 +++++++++++++++++++++++++++++++-------- - 1 file changed, 33 insertions(+), 8 deletions(-) - -diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c -index 686cd2fc0c84..bb5c0d5ded9d 100644 ---- a/src/nm-cloud-setup/main.c -+++ b/src/nm-cloud-setup/main.c -@@ -269,7 +269,9 @@ _nmc_skip_connection(NMConnection *connection) - static gboolean - _nmc_mangle_connection(NMDevice * device, - NMConnection * connection, -+ const NMCSProviderGetConfigResult * result, - const NMCSProviderGetConfigIfaceData *config_data, -+ gboolean * out_skipped_single_addr, - gboolean * out_changed) - { - NMSettingIPConfig * s_ip; -@@ -288,6 +290,9 @@ _nmc_mangle_connection(NMDevice * device, - gs_unref_ptrarray GPtrArray *rules_new = NULL; - gs_unref_ptrarray GPtrArray *routes_new = NULL; - -+ NM_SET_OUT(out_skipped_single_addr, FALSE); -+ NM_SET_OUT(out_changed, FALSE); -+ - if (!nm_streq0(nm_connection_get_connection_type(connection), NM_SETTING_WIRED_SETTING_NAME)) - return FALSE; - -@@ -329,7 +334,11 @@ _nmc_mangle_connection(NMDevice * device, - } - } - -- if (config_data->has_ipv4s && config_data->has_cidr) { -+ if (result->num_valid_ifaces <= 1 && result->num_ipv4s <= 1) { -+ /* this setup only has one interface and one IPv4 address (or less). -+ * We don't need to configure policy routing in this case. */ -+ NM_SET_OUT(out_skipped_single_addr, TRUE); -+ } else if (config_data->has_ipv4s && config_data->has_cidr) { - for (i = 0; i < config_data->ipv4s_len; i++) { - NMIPAddress *entry; - -@@ -398,6 +407,7 @@ _nmc_mangle_connection(NMDevice * device, - static gboolean - _config_one(GCancellable * sigterm_cancellable, - NMClient * nmc, -+ const NMCSProviderGetConfigResult * result, - const char * hwaddr, - const NMCSProviderGetConfigIfaceData *config_data) - { -@@ -406,6 +416,7 @@ _config_one(GCancellable * sigterm_cancellable, - guint64 applied_version_id; - gs_free_error GError *error = NULL; - gboolean changed; -+ gboolean skipped_single_addr; - gboolean version_id_changed; - guint try_count; - gboolean any_changes = FALSE; -@@ -454,16 +465,30 @@ try_again: - return any_changes; - } - -- if (!_nmc_mangle_connection(device, applied_connection, config_data, &changed)) { -+ if (!_nmc_mangle_connection(device, -+ applied_connection, -+ result, -+ config_data, -+ &skipped_single_addr, -+ &changed)) { - _LOGD("config device %s: device has no suitable applied connection. Skip", hwaddr); - return any_changes; - } - - if (!changed) { -- _LOGD("config device %s: device needs no update to applied connection \"%s\" (%s). Skip", -- hwaddr, -- nm_connection_get_id(applied_connection), -- nm_connection_get_uuid(applied_connection)); -+ if (skipped_single_addr) { -+ _LOGD("config device %s: device needs no update to applied connection \"%s\" (%s) " -+ "because there are not multiple IP addresses. Skip", -+ hwaddr, -+ nm_connection_get_id(applied_connection), -+ nm_connection_get_uuid(applied_connection)); -+ } else { -+ _LOGD( -+ "config device %s: device needs no update to applied connection \"%s\" (%s). Skip", -+ hwaddr, -+ nm_connection_get_id(applied_connection), -+ nm_connection_get_uuid(applied_connection)); -+ } - return any_changes; - } - -@@ -472,7 +497,7 @@ try_again: - nm_connection_get_id(applied_connection), - nm_connection_get_uuid(applied_connection)); - -- /* we are about to call Reapply(). If if that fails, it counts as if we changed something. */ -+ /* we are about to call Reapply(). Even if that fails, it counts as if we changed something. */ - any_changes = TRUE; - - if (!nmcs_device_reapply(device, -@@ -519,7 +544,7 @@ _config_all(GCancellable * sigterm_cancellable, - - g_hash_table_iter_init(&h_iter, result->iface_datas); - while (g_hash_table_iter_next(&h_iter, (gpointer *) &c_hwaddr, (gpointer *) &c_config_data)) { -- if (_config_one(sigterm_cancellable, nmc, c_hwaddr, c_config_data)) -+ if (_config_one(sigterm_cancellable, nmc, result, c_hwaddr, c_config_data)) - any_changes = TRUE; - } - --- -2.31.1 - - -From 0042bff5e16e71f548dcb8d046a5dbd3f694de8f Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 1 Sep 2021 14:34:51 +0200 -Subject: [PATCH 05/10] cloud-setup: add "hwaddr" to - NMCSProviderGetConfigIfaceData struct - -get-config() gives a NMCSProviderGetConfigResult structure, and the -main part of data is the GHashTable of MAC addresses and -NMCSProviderGetConfigIfaceData instances. - -Let NMCSProviderGetConfigIfaceData also have a reference to the MAC -address. This way, I'll be able to create a (sorted) list of interface -datas, that also contain the MAC address. - -(cherry picked from commit ec56fe60fbf31768d0d1cae8bb325c1fdf7dbf07) -(cherry picked from commit cc289e53699872a3617aef321453ef6a885d0148) ---- - src/nm-cloud-setup/nmcs-provider-aliyun.c | 32 ++++++++++------------- - src/nm-cloud-setup/nmcs-provider-azure.c | 21 +++++++-------- - src/nm-cloud-setup/nmcs-provider-ec2.c | 27 ++++++++----------- - src/nm-cloud-setup/nmcs-provider-gcp.c | 20 +++++++------- - src/nm-cloud-setup/nmcs-provider.c | 22 +++++++++++----- - src/nm-cloud-setup/nmcs-provider.h | 12 +++++++-- - 6 files changed, 68 insertions(+), 66 deletions(-) - -diff --git a/src/nm-cloud-setup/nmcs-provider-aliyun.c b/src/nm-cloud-setup/nmcs-provider-aliyun.c -index 01a4af0ff5b8..126980fdfe44 100644 ---- a/src/nm-cloud-setup/nmcs-provider-aliyun.c -+++ b/src/nm-cloud-setup/nmcs-provider-aliyun.c -@@ -134,7 +134,6 @@ _get_config_fetch_done_cb(NMHttpClient * http_client, - GetConfigFetchDoneType fetch_type) - { - NMCSProviderGetConfigTaskData *get_config_data; -- const char * hwaddr = NULL; - gs_unref_bytes GBytes *response = NULL; - gs_free_error GError * error = NULL; - NMCSProviderGetConfigIfaceData *config_iface_data; -@@ -146,7 +145,7 @@ _get_config_fetch_done_cb(NMHttpClient * http_client, - gsize i; - gsize len; - -- nm_utils_user_data_unpack(user_data, &get_config_data, &hwaddr); -+ nm_utils_user_data_unpack(user_data, &get_config_data, &config_iface_data); - - nm_http_client_poll_get_finish(http_client, result, NULL, &response, &error); - -@@ -156,8 +155,6 @@ _get_config_fetch_done_cb(NMHttpClient * http_client, - if (error) - goto out; - -- config_iface_data = g_hash_table_lookup(get_config_data->result_dict, hwaddr); -- - switch (fetch_type) { - case GET_CONFIG_FETCH_DONE_TYPE_PRIVATE_IPV4S: - -@@ -300,22 +297,21 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us - gs_free char * uri2 = NULL; - gs_free char * uri3 = NULL; - gs_free char * uri4 = NULL; -- const char * hwaddr; - -- if (!g_hash_table_lookup_extended(get_config_data->result_dict, -- v_hwaddr, -- (gpointer *) &hwaddr, -- (gpointer *) &config_iface_data)) { -+ config_iface_data = g_hash_table_lookup(get_config_data->result_dict, v_hwaddr); -+ -+ if (!config_iface_data) { - if (!get_config_data->any) { - _LOGD("get-config: skip fetching meta data for %s (%s)", - v_hwaddr, - v_mac_data->path); - continue; - } -- config_iface_data = nmcs_provider_get_config_iface_data_new(FALSE); -- g_hash_table_insert(get_config_data->result_dict, -- (char *) (hwaddr = g_strdup(v_hwaddr)), -- config_iface_data); -+ -+ config_iface_data = -+ nmcs_provider_get_config_iface_data_create(get_config_data->result_dict, -+ FALSE, -+ v_hwaddr); - } - - nm_assert(config_iface_data->iface_idx == -1); -@@ -324,7 +320,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us - - _LOGD("get-config: start fetching meta data for #%" G_GSSIZE_FORMAT ", %s (%s)", - config_iface_data->iface_idx, -- hwaddr, -+ config_iface_data->hwaddr, - v_mac_data->path); - - get_config_data->n_pending++; -@@ -342,7 +338,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us - NULL, - NULL, - _get_config_fetch_done_cb_vpc_cidr_block, -- nm_utils_user_data_pack(get_config_data, hwaddr)); -+ nm_utils_user_data_pack(get_config_data, config_iface_data)); - - get_config_data->n_pending++; - nm_http_client_poll_get( -@@ -359,7 +355,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us - NULL, - NULL, - _get_config_fetch_done_cb_private_ipv4s, -- nm_utils_user_data_pack(get_config_data, hwaddr)); -+ nm_utils_user_data_pack(get_config_data, config_iface_data)); - - get_config_data->n_pending++; - nm_http_client_poll_get( -@@ -376,7 +372,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us - NULL, - NULL, - _get_config_fetch_done_cb_netmask, -- nm_utils_user_data_pack(get_config_data, hwaddr)); -+ nm_utils_user_data_pack(get_config_data, config_iface_data)); - - get_config_data->n_pending++; - nm_http_client_poll_get( -@@ -393,7 +389,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us - NULL, - NULL, - _get_config_fetch_done_cb_gateway, -- nm_utils_user_data_pack(get_config_data, hwaddr)); -+ nm_utils_user_data_pack(get_config_data, config_iface_data)); - } - - _nmcs_provider_get_config_task_maybe_return(get_config_data, NULL); -diff --git a/src/nm-cloud-setup/nmcs-provider-azure.c b/src/nm-cloud-setup/nmcs-provider-azure.c -index 69785d64a8ac..b3f0c68ba666 100644 ---- a/src/nm-cloud-setup/nmcs-provider-azure.c -+++ b/src/nm-cloud-setup/nmcs-provider-azure.c -@@ -97,7 +97,6 @@ typedef struct { - gssize intern_iface_idx; - gssize extern_iface_idx; - guint n_iface_data_pending; -- const char * hwaddr; - } AzureIfaceData; - - static void -@@ -378,25 +377,24 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data) - goto out_done; - } - -- if (!g_hash_table_lookup_extended(get_config_data->result_dict, -- v_hwaddr, -- (gpointer *) &iface_data->hwaddr, -- (gpointer *) &iface_data->iface_get_config)) { -+ iface_data->iface_get_config = g_hash_table_lookup(get_config_data->result_dict, v_hwaddr); -+ -+ if (!iface_data->iface_get_config) { - if (!get_config_data->any) { - _LOGD("get-config: skip fetching meta data for %s (%" G_GSSIZE_FORMAT ")", - v_hwaddr, - iface_data->intern_iface_idx); - goto out_done; - } -- iface_data->iface_get_config = nmcs_provider_get_config_iface_data_new(FALSE); -- g_hash_table_insert(get_config_data->result_dict, -- (char *) (iface_data->hwaddr = g_steal_pointer(&v_hwaddr)), -- iface_data->iface_get_config); -+ iface_data->iface_get_config = -+ nmcs_provider_get_config_iface_data_create(get_config_data->result_dict, -+ FALSE, -+ v_hwaddr); - } else { - if (iface_data->iface_get_config->iface_idx >= 0) { - _LOGI("interface[%" G_GSSIZE_FORMAT "]: duplicate MAC address %s returned", - iface_data->intern_iface_idx, -- iface_data->hwaddr); -+ iface_data->iface_get_config->hwaddr); - error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, - "duplicate MAC address for index %" G_GSSIZE_FORMAT, - iface_data->intern_iface_idx); -@@ -408,7 +406,7 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data) - - _LOGD("interface[%" G_GSSIZE_FORMAT "]: found a matching device with hwaddr %s", - iface_data->intern_iface_idx, -- iface_data->hwaddr); -+ iface_data->iface_get_config->hwaddr); - - nm_sprintf_buf(buf, "%" G_GSSIZE_FORMAT "/ipv4/ipAddress/", iface_data->intern_iface_idx); - -@@ -488,7 +486,6 @@ _get_net_ifaces_list_cb(GObject *source, GAsyncResult *result, gpointer user_dat - .intern_iface_idx = intern_iface_idx, - .extern_iface_idx = extern_iface_idx_cnt++, - .n_iface_data_pending = 0, -- .hwaddr = NULL, - }; - g_ptr_array_add(ifaces_arr, iface_data); - } -diff --git a/src/nm-cloud-setup/nmcs-provider-ec2.c b/src/nm-cloud-setup/nmcs-provider-ec2.c -index 6f83238d6871..9fe625182c35 100644 ---- a/src/nm-cloud-setup/nmcs-provider-ec2.c -+++ b/src/nm-cloud-setup/nmcs-provider-ec2.c -@@ -122,14 +122,13 @@ _get_config_fetch_done_cb(NMHttpClient *http_client, - gboolean is_local_ipv4) - { - NMCSProviderGetConfigTaskData *get_config_data; -- const char * hwaddr = NULL; - gs_unref_bytes GBytes *response = NULL; - gs_free_error GError * error = NULL; - NMCSProviderGetConfigIfaceData *config_iface_data; - in_addr_t tmp_addr; - int tmp_prefix; - -- nm_utils_user_data_unpack(user_data, &get_config_data, &hwaddr); -+ nm_utils_user_data_unpack(user_data, &get_config_data, &config_iface_data); - - nm_http_client_poll_get_finish(http_client, result, NULL, &response, &error); - -@@ -139,8 +138,6 @@ _get_config_fetch_done_cb(NMHttpClient *http_client, - if (error) - goto out; - -- config_iface_data = g_hash_table_lookup(get_config_data->result_dict, hwaddr); -- - if (is_local_ipv4) { - gs_free const char **s_addrs = NULL; - gsize i, len; -@@ -236,22 +233,20 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us - NMCSProviderGetConfigIfaceData *config_iface_data; - gs_free char * uri1 = NULL; - gs_free char * uri2 = NULL; -- const char * hwaddr; - -- if (!g_hash_table_lookup_extended(get_config_data->result_dict, -- v_hwaddr, -- (gpointer *) &hwaddr, -- (gpointer *) &config_iface_data)) { -+ config_iface_data = g_hash_table_lookup(get_config_data->result_dict, v_hwaddr); -+ -+ if (!config_iface_data) { - if (!get_config_data->any) { - _LOGD("get-config: skip fetching meta data for %s (%s)", - v_hwaddr, - v_mac_data->path); - continue; - } -- config_iface_data = nmcs_provider_get_config_iface_data_new(FALSE); -- g_hash_table_insert(get_config_data->result_dict, -- (char *) (hwaddr = g_strdup(v_hwaddr)), -- config_iface_data); -+ config_iface_data = -+ nmcs_provider_get_config_iface_data_create(get_config_data->result_dict, -+ FALSE, -+ v_hwaddr); - } - - nm_assert(config_iface_data->iface_idx == -1); -@@ -260,7 +255,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us - - _LOGD("get-config: start fetching meta data for #%" G_GSSIZE_FORMAT ", %s (%s)", - config_iface_data->iface_idx, -- hwaddr, -+ config_iface_data->hwaddr, - v_mac_data->path); - - get_config_data->n_pending++; -@@ -278,7 +273,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us - NULL, - NULL, - _get_config_fetch_done_cb_subnet_ipv4_cidr_block, -- nm_utils_user_data_pack(get_config_data, hwaddr)); -+ nm_utils_user_data_pack(get_config_data, config_iface_data)); - - get_config_data->n_pending++; - nm_http_client_poll_get( -@@ -295,7 +290,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us - NULL, - NULL, - _get_config_fetch_done_cb_local_ipv4s, -- nm_utils_user_data_pack(get_config_data, hwaddr)); -+ nm_utils_user_data_pack(get_config_data, config_iface_data)); - } - - _nmcs_provider_get_config_task_maybe_return(get_config_data, NULL); -diff --git a/src/nm-cloud-setup/nmcs-provider-gcp.c b/src/nm-cloud-setup/nmcs-provider-gcp.c -index eacfd5e24805..60425ad97868 100644 ---- a/src/nm-cloud-setup/nmcs-provider-gcp.c -+++ b/src/nm-cloud-setup/nmcs-provider-gcp.c -@@ -247,7 +247,6 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data) - GCPIfaceData * iface_data = user_data; - gs_free_error GError * error = NULL; - gs_free char * v_hwaddr = NULL; -- const char * hwaddr = NULL; - gs_free const char * uri = NULL; - char sbuf[100]; - NMCSProviderGetConfigTaskData *get_config_data; -@@ -273,26 +272,25 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data) - goto out_done; - } - -- if (!g_hash_table_lookup_extended(get_config_data->result_dict, -- v_hwaddr, -- (gpointer *) &hwaddr, -- (gpointer *) &iface_data->iface_get_config)) { -+ iface_data->iface_get_config = g_hash_table_lookup(get_config_data->result_dict, v_hwaddr); -+ -+ if (!iface_data->iface_get_config) { - if (!get_config_data->any) { - _LOGD("get-config: skip fetching meta data for %s (%" G_GSSIZE_FORMAT ")", - v_hwaddr, - iface_data->intern_iface_idx); - goto out_done; - } -- iface_data->iface_get_config = nmcs_provider_get_config_iface_data_new(FALSE); -- g_hash_table_insert(get_config_data->result_dict, -- (char *) (hwaddr = g_steal_pointer(&v_hwaddr)), -- iface_data->iface_get_config); -+ iface_data->iface_get_config = -+ nmcs_provider_get_config_iface_data_create(get_config_data->result_dict, -+ FALSE, -+ v_hwaddr); - is_requested = FALSE; - } else { - if (iface_data->iface_get_config->iface_idx >= 0) { - _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: duplicate MAC address %s returned", - iface_data->intern_iface_idx, -- hwaddr); -+ iface_data->iface_get_config->hwaddr); - error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, - "duplicate MAC address for index %" G_GSSIZE_FORMAT, - iface_data->intern_iface_idx); -@@ -306,7 +304,7 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data) - _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: found a %sdevice with hwaddr %s", - iface_data->intern_iface_idx, - is_requested ? "requested " : "", -- hwaddr); -+ iface_data->iface_get_config->hwaddr); - - nm_sprintf_buf(sbuf, "%" G_GSSIZE_FORMAT "/forwarded-ips/", iface_data->intern_iface_idx); - -diff --git a/src/nm-cloud-setup/nmcs-provider.c b/src/nm-cloud-setup/nmcs-provider.c -index 8901100378d0..56f36646bb8a 100644 ---- a/src/nm-cloud-setup/nmcs-provider.c -+++ b/src/nm-cloud-setup/nmcs-provider.c -@@ -127,15 +127,25 @@ nmcs_provider_detect_finish(NMCSProvider *self, GAsyncResult *result, GError **e - /*****************************************************************************/ - - NMCSProviderGetConfigIfaceData * --nmcs_provider_get_config_iface_data_new(gboolean was_requested) -+nmcs_provider_get_config_iface_data_create(GHashTable *iface_datas, -+ gboolean was_requested, -+ const char *hwaddr) - { - NMCSProviderGetConfigIfaceData *iface_data; - -+ nm_assert(hwaddr); -+ - iface_data = g_slice_new(NMCSProviderGetConfigIfaceData); - *iface_data = (NMCSProviderGetConfigIfaceData){ -+ .hwaddr = g_strdup(hwaddr), - .iface_idx = -1, - .was_requested = was_requested, - }; -+ -+ /* the has does not own the key (iface_datta->hwaddr), the lifetime of the -+ * key is associated with the iface_data instance. */ -+ g_hash_table_replace(iface_datas, (char *) iface_data->hwaddr, iface_data); -+ - return iface_data; - } - -@@ -146,6 +156,7 @@ _iface_data_free(gpointer data) - - g_free(iface_data->ipv4s_arr); - g_free(iface_data->iproutes_arr); -+ g_free((char *) iface_data->hwaddr); - - nm_g_slice_free(iface_data); - } -@@ -224,16 +235,13 @@ nmcs_provider_get_config(NMCSProvider * self, - *get_config_data = (NMCSProviderGetConfigTaskData){ - .task = nm_g_task_new(self, cancellable, nmcs_provider_get_config, callback, user_data), - .any = any, -- .result_dict = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, _iface_data_free), -+ .result_dict = g_hash_table_new_full(nm_str_hash, g_str_equal, NULL, _iface_data_free), - }; - - nmcs_wait_for_objects_register(get_config_data->task); - -- for (; hwaddrs && hwaddrs[0]; hwaddrs++) { -- g_hash_table_insert(get_config_data->result_dict, -- g_strdup(hwaddrs[0]), -- nmcs_provider_get_config_iface_data_new(TRUE)); -- } -+ for (; hwaddrs && hwaddrs[0]; hwaddrs++) -+ nmcs_provider_get_config_iface_data_create(get_config_data->result_dict, TRUE, hwaddrs[0]); - - if (cancellable) { - gulong cancelled_id; -diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h -index 31fec4449f9e..c67184679949 100644 ---- a/src/nm-cloud-setup/nmcs-provider.h -+++ b/src/nm-cloud-setup/nmcs-provider.h -@@ -10,6 +10,10 @@ - /*****************************************************************************/ - - typedef struct { -+ /* And it's exactly the same pointer that is also the key for the iface_datas -+ * dictionary. */ -+ const char *hwaddr; -+ - in_addr_t *ipv4s_arr; - gsize ipv4s_len; - -@@ -41,13 +45,17 @@ nmcs_provider_get_config_iface_data_is_valid(const NMCSProviderGetConfigIfaceDat - && ((config_data->has_ipv4s && config_data->has_cidr) || config_data->iproutes_len); - } - --NMCSProviderGetConfigIfaceData *nmcs_provider_get_config_iface_data_new(gboolean was_requested); -+NMCSProviderGetConfigIfaceData *nmcs_provider_get_config_iface_data_create(GHashTable *iface_datas, -+ gboolean was_requested, -+ const char *hwaddr); - - /*****************************************************************************/ - - typedef struct { - /* A dictionary of (const char *) -> (NMCSProviderGetConfigIfaceData *). -- * This is the per-interface result of get_config(). */ -+ * This is the per-interface result of get_config(). -+ * -+ * The key is the same pointer as NMCSProviderGetConfigIfaceData's hwaddr. */ - GHashTable *iface_datas; - - /* The number of iface_datas that are nmcs_provider_get_config_iface_data_is_valid(). */ --- -2.31.1 - - -From 351ff60c9fb34ac6010fd895ad290db536a756a7 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 1 Sep 2021 16:59:19 +0200 -Subject: [PATCH 06/10] cloud-setup: track sorted list of - NMCSProviderGetConfigIfaceData - -Sorted by iface_idx. The iface_idx is probably something useful and -stable, provided by the provider. E.g. it's the order in which -interfaces are exposed on the meta data. - -(cherry picked from commit 1c5cb9d3c2be5addd3b011873cfc6b99204955d1) -(cherry picked from commit 0a2ed627038349d838add8f3fd72e2d282e74693) ---- - src/nm-cloud-setup/nmcs-provider.c | 49 +++++++++++++++++++++++++++++- - src/nm-cloud-setup/nmcs-provider.h | 8 +++++ - 2 files changed, 56 insertions(+), 1 deletion(-) - -diff --git a/src/nm-cloud-setup/nmcs-provider.c b/src/nm-cloud-setup/nmcs-provider.c -index 56f36646bb8a..138e78d41b56 100644 ---- a/src/nm-cloud-setup/nmcs-provider.c -+++ b/src/nm-cloud-setup/nmcs-provider.c -@@ -51,6 +51,19 @@ nmcs_provider_get_main_context(NMCSProvider *self) - } - /*****************************************************************************/ - -+static int -+_result_new_sort_iface_data(gconstpointer pa, gconstpointer pb) -+{ -+ const NMCSProviderGetConfigIfaceData *a = *((const NMCSProviderGetConfigIfaceData *const *) pa); -+ const NMCSProviderGetConfigIfaceData *b = *((const NMCSProviderGetConfigIfaceData *const *) pb); -+ -+ /* negative iface_idx are sorted to the end. */ -+ NM_CMP_DIRECT((a->iface_idx < 0), (b->iface_idx < 0)); -+ -+ NM_CMP_FIELD(a, b, iface_idx); -+ return 0; -+} -+ - static NMCSProviderGetConfigResult * - nmcs_provider_get_config_result_new(GHashTable *iface_datas) - { -@@ -59,6 +72,12 @@ nmcs_provider_get_config_result_new(GHashTable *iface_datas) - GHashTableIter h_iter; - guint num_valid_ifaces = 0; - guint num_ipv4s = 0; -+ GPtrArray * ptrarr; -+ guint n_iface_datas; -+ -+ n_iface_datas = g_hash_table_size(iface_datas); -+ -+ ptrarr = g_ptr_array_sized_new(n_iface_datas + 1u); - - g_hash_table_iter_init(&h_iter, iface_datas); - while (g_hash_table_iter_next(&h_iter, NULL, (gpointer *) &iface_data)) { -@@ -66,15 +85,42 @@ nmcs_provider_get_config_result_new(GHashTable *iface_datas) - num_valid_ifaces++; - num_ipv4s += iface_data->ipv4s_len; - } -+ g_ptr_array_add(ptrarr, (gpointer) iface_data); - } - -+ g_ptr_array_sort(ptrarr, _result_new_sort_iface_data); -+ -+ nm_assert(n_iface_datas == ptrarr->len); -+ -+ g_ptr_array_add(ptrarr, NULL); -+ - result = g_new(NMCSProviderGetConfigResult, 1); - *result = (NMCSProviderGetConfigResult){ -- .iface_datas = g_hash_table_ref(iface_datas), -+ .iface_datas = g_hash_table_ref(iface_datas), -+ .n_iface_datas = n_iface_datas, -+ .iface_datas_arr = -+ (const NMCSProviderGetConfigIfaceData **) g_ptr_array_free(ptrarr, FALSE), - .num_valid_ifaces = num_valid_ifaces, - .num_ipv4s = num_ipv4s, - }; - -+#if NM_MORE_ASSERTS > 5 -+ { -+ gsize iface_idx_expected = 0; -+ guint i; -+ -+ for (i = 0; i < result->n_iface_datas; i++) { -+ if (result->iface_datas_arr[i]->iface_idx < 0) { -+ nm_assert(result->iface_datas_arr[i]->iface_idx == -1); -+ iface_idx_expected = -1; -+ continue; -+ } -+ nm_assert(result->iface_datas_arr[i]->iface_idx == iface_idx_expected); -+ iface_idx_expected++; -+ } -+ } -+#endif -+ - return result; - } - -@@ -83,6 +129,7 @@ nmcs_provider_get_config_result_free(NMCSProviderGetConfigResult *result) - { - if (result) { - nm_g_hash_table_unref(result->iface_datas); -+ g_free((gpointer) result->iface_datas_arr); - g_free(result); - } - } -diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h -index c67184679949..366320596492 100644 ---- a/src/nm-cloud-setup/nmcs-provider.h -+++ b/src/nm-cloud-setup/nmcs-provider.h -@@ -63,6 +63,14 @@ typedef struct { - - /* the number of IPv4 addresses over all valid iface_datas. */ - guint num_ipv4s; -+ -+ guint n_iface_datas; -+ -+ /* The sorted value of @iface_datas, sorted by iface_idx. -+ * -+ * Not found entries (iface_idx == -1) are sorted at the end. */ -+ const NMCSProviderGetConfigIfaceData *const *iface_datas_arr; -+ - } NMCSProviderGetConfigResult; - - void nmcs_provider_get_config_result_free(NMCSProviderGetConfigResult *result); --- -2.31.1 - - -From d6832b24cfdb07b3acd2d92dd1ca47df46eeaba4 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 1 Sep 2021 17:23:09 +0200 -Subject: [PATCH 07/10] cloud-setup: process iface-datas in sorted order - -The routes/rules that are configured are independent of the -order in which we process the devices. That is, because they -use the "iface_idx" for cases where there is ambiguity. - -Still, it feels nicer to always process them in a defined order. - -(cherry picked from commit a95ea0eb294d646f17b5e1cf4f17cb1540f8af3a) -(cherry picked from commit 6302cd416d92a8c2f5b4a6be9dded71af4cf7ced) ---- - src/nm-cloud-setup/main.c | 28 +++++++++++++--------------- - 1 file changed, 13 insertions(+), 15 deletions(-) - -diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c -index bb5c0d5ded9d..403c8d759794 100644 ---- a/src/nm-cloud-setup/main.c -+++ b/src/nm-cloud-setup/main.c -@@ -405,14 +405,15 @@ _nmc_mangle_connection(NMDevice * device, - /*****************************************************************************/ - - static gboolean --_config_one(GCancellable * sigterm_cancellable, -- NMClient * nmc, -- const NMCSProviderGetConfigResult * result, -- const char * hwaddr, -- const NMCSProviderGetConfigIfaceData *config_data) -+_config_one(GCancellable * sigterm_cancellable, -+ NMClient * nmc, -+ const NMCSProviderGetConfigResult *result, -+ guint idx) - { -- gs_unref_object NMDevice *device = NULL; -- gs_unref_object NMConnection *applied_connection = NULL; -+ const NMCSProviderGetConfigIfaceData *config_data = result->iface_datas_arr[idx]; -+ const char * hwaddr = config_data->hwaddr; -+ gs_unref_object NMDevice *device = NULL; -+ gs_unref_object NMConnection *applied_connection = NULL; - guint64 applied_version_id; - gs_free_error GError *error = NULL; - gboolean changed; -@@ -537,14 +538,11 @@ _config_all(GCancellable * sigterm_cancellable, - NMClient * nmc, - const NMCSProviderGetConfigResult *result) - { -- GHashTableIter h_iter; -- const NMCSProviderGetConfigIfaceData *c_config_data; -- const char * c_hwaddr; -- gboolean any_changes = FALSE; -- -- g_hash_table_iter_init(&h_iter, result->iface_datas); -- while (g_hash_table_iter_next(&h_iter, (gpointer *) &c_hwaddr, (gpointer *) &c_config_data)) { -- if (_config_one(sigterm_cancellable, nmc, result, c_hwaddr, c_config_data)) -+ gboolean any_changes = FALSE; -+ guint i; -+ -+ for (i = 0; i < result->n_iface_datas; i++) { -+ if (_config_one(sigterm_cancellable, nmc, result, i)) - any_changes = TRUE; - } - --- -2.31.1 - - -From 167faa59d23ab8b2db471169860c4387da625d21 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 1 Sep 2021 19:23:46 +0200 -Subject: [PATCH 08/10] cloud-setup: limit number of supported interfaces to - avoid overlapping table numbers - -The table number is chosen as 30400 + iface_idx. That is, the range is -limited and we shouldn't handle more than 100 devices. Add a check for -that and error out. - -(cherry picked from commit b68d694b78fd9b4b63b0592a2518f387aaa35f87) -(cherry picked from commit 292233e16ed1f60499c2676611d59c271352e2c3) ---- - src/nm-cloud-setup/main.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c -index 403c8d759794..6be8c145f3c9 100644 ---- a/src/nm-cloud-setup/main.c -+++ b/src/nm-cloud-setup/main.c -@@ -438,6 +438,14 @@ _config_one(GCancellable * sigterm_cancellable, - return FALSE; - } - -+ if (config_data->iface_idx >= 100) { -+ /* since we use the iface_idx to select a table number, the range is limited from -+ * 0 to 99. Note that the providers are required to provide increasing numbers, -+ * so this means we bail out after the first 100 devices. */ -+ _LOGD("config device %s: skip because number of supported interfaces reached", hwaddr); -+ return FALSE; -+ } -+ - _LOGD("config device %s: configuring \"%s\" (%s)...", - hwaddr, - nm_device_get_iface(device) ?: "/unknown/", --- -2.31.1 - - -From 5d8ac7f10fd9b4a467e8afd7e082acb4b2d33eed Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Mon, 6 Sep 2021 10:35:36 +0200 -Subject: [PATCH 09/10] cloud-setup: cleanup configuring addresses/routes/rules - in _nmc_mangle_connection() - -(cherry picked from commit 0978be5e43f142ec5c6062dcfe1c2f4aa834464b) -(cherry picked from commit ce24b4bca5d3fbad65d4065325cfa80ac05fbfdb) ---- - src/nm-cloud-setup/main.c | 52 +++++++++++++++++---------------------- - 1 file changed, 23 insertions(+), 29 deletions(-) - -diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c -index 6be8c145f3c9..260d111205f5 100644 ---- a/src/nm-cloud-setup/main.c -+++ b/src/nm-cloud-setup/main.c -@@ -279,10 +279,6 @@ _nmc_mangle_connection(NMDevice * device, - NMConnection * remote_connection; - NMSettingIPConfig * remote_s_ip = NULL; - gsize i; -- in_addr_t gateway; -- gint64 rt_metric; -- guint32 rt_table; -- NMIPRoute * route_entry; - gboolean addrs_changed = FALSE; - gboolean rules_changed = FALSE; - gboolean routes_changed = FALSE; -@@ -339,47 +335,45 @@ _nmc_mangle_connection(NMDevice * device, - * We don't need to configure policy routing in this case. */ - NM_SET_OUT(out_skipped_single_addr, TRUE); - } else if (config_data->has_ipv4s && config_data->has_cidr) { -+ NMIPAddress * addr_entry; -+ NMIPRoute * route_entry; -+ NMIPRoutingRule *rule_entry; -+ in_addr_t gateway; -+ char sbuf[NM_UTILS_INET_ADDRSTRLEN]; -+ - for (i = 0; i < config_data->ipv4s_len; i++) { -- NMIPAddress *entry; -- -- entry = nm_ip_address_new_binary(AF_INET, -- &config_data->ipv4s_arr[i], -- config_data->cidr_prefix, -- NULL); -- if (entry) -- g_ptr_array_add(addrs_new, entry); -+ addr_entry = nm_ip_address_new_binary(AF_INET, -+ &config_data->ipv4s_arr[i], -+ config_data->cidr_prefix, -+ NULL); -+ nm_assert(addr_entry); -+ g_ptr_array_add(addrs_new, addr_entry); - } -+ - if (config_data->has_gateway && config_data->gateway) { - gateway = config_data->gateway; - } else { - gateway = nm_utils_ip4_address_clear_host_address(config_data->cidr_addr, - config_data->cidr_prefix); -- ((guint8 *) &gateway)[3] += 1; -+ if (config_data->cidr_prefix < 32) -+ ((guint8 *) &gateway)[3] += 1; - } -- rt_metric = 10; -- rt_table = 30400 + config_data->iface_idx; - -- route_entry = -- nm_ip_route_new_binary(AF_INET, &nm_ip_addr_zero, 0, &gateway, rt_metric, NULL); -+ route_entry = nm_ip_route_new_binary(AF_INET, &nm_ip_addr_zero, 0, &gateway, 10, NULL); - nm_ip_route_set_attribute(route_entry, - NM_IP_ROUTE_ATTRIBUTE_TABLE, -- g_variant_new_uint32(rt_table)); -+ g_variant_new_uint32(30400 + config_data->iface_idx)); - g_ptr_array_add(routes_new, route_entry); - - for (i = 0; i < config_data->ipv4s_len; i++) { -- NMIPRoutingRule *entry; -- char sbuf[NM_UTILS_INET_ADDRSTRLEN]; -- -- entry = nm_ip_routing_rule_new(AF_INET); -- nm_ip_routing_rule_set_priority(entry, rt_table); -- nm_ip_routing_rule_set_from(entry, -+ rule_entry = nm_ip_routing_rule_new(AF_INET); -+ nm_ip_routing_rule_set_priority(rule_entry, 30400 + config_data->iface_idx); -+ nm_ip_routing_rule_set_from(rule_entry, - _nm_utils_inet4_ntop(config_data->ipv4s_arr[i], sbuf), - 32); -- nm_ip_routing_rule_set_table(entry, rt_table); -- -- nm_assert(nm_ip_routing_rule_validate(entry, NULL)); -- -- g_ptr_array_add(rules_new, entry); -+ nm_ip_routing_rule_set_table(rule_entry, 30400 + config_data->iface_idx); -+ nm_assert(nm_ip_routing_rule_validate(rule_entry, NULL)); -+ g_ptr_array_add(rules_new, rule_entry); - } - } - --- -2.31.1 - - -From c2402be45e2dec931690aef555de43292b015422 Mon Sep 17 00:00:00 2001 -From: Thomas Haller -Date: Wed, 1 Sep 2021 10:31:55 +0200 -Subject: [PATCH 10/10] cloud-setup: use suppress_prefixlength rule to honor - non-default-routes in the main table - -Background -========== - -Imagine you run a container on your machine. Then the routing table -might look like: - - default via 10.0.10.1 dev eth0 proto dhcp metric 100 - 10.0.10.0/28 dev eth0 proto kernel scope link src 10.0.10.5 metric 100 - [...] - 10.42.0.0/24 via 10.42.0.0 dev flannel.1 onlink - 10.42.1.2 dev cali02ad7e68ce1 scope link - 10.42.1.3 dev cali8fcecf5aaff scope link - 10.42.2.0/24 via 10.42.2.0 dev flannel.1 onlink - 10.42.3.0/24 via 10.42.3.0 dev flannel.1 onlink - -That is, there are another interfaces with subnets and specific routes. - -If nm-cloud-setup now configures rules: - - 0: from all lookup local - 30400: from 10.0.10.5 lookup 30400 - 32766: from all lookup main - 32767: from all lookup default - -and - - default via 10.0.10.1 dev eth0 table 30400 proto static metric 10 - 10.0.10.1 dev eth0 table 30400 proto static scope link metric 10 - -then these other subnets will also be reached via the default route. - -This container example is just one case where this is a problem. In -general, if you have specific routes on another interface, then the -default route in the 30400+ table will interfere badly. - -The idea of nm-cloud-setup is to automatically configure the network for -secondary IP addresses. When the user has special requirements, then -they should disable nm-cloud-setup and configure whatever they want. -But the container use case is popular and important. It is not something -where the user actively configures the network. This case needs to work better, -out of the box. In general, nm-cloud-setup should work better with the -existing network configuration. - -Change -====== - -Add new routing tables 30200+ with the individual subnets of the -interface: - - 10.0.10.0/24 dev eth0 table 30200 proto static metric 10 - [...] - default via 10.0.10.1 dev eth0 table 30400 proto static metric 10 - 10.0.10.1 dev eth0 table 30400 proto static scope link metric 10 - -Also add more important routing rules with priority 30200+, which select -these tables based on the source address: - - 30200: from 10.0.10.5 lookup 30200 - -These will do source based routing for the subnets on these -interfaces. - -Then, add a rule with priority 30350 - - 30350: lookup main suppress_prefixlength 0 - -which processes the routes from the main table, but ignores the default -routes. 30350 was chosen, because it's in between the rules 30200+ and -30400+, leaving a range for the user to configure their own rules. - -Then, as before, the rules 30400+ again look at the corresponding 30400+ -table, to find a default route. - -Finally, process the main table again, this time honoring the default -route. That is for packets that have a different source address. - -This change means that the source based routing is used for the -subnets that are configured on the interface and for the default route. -Whereas, if there are any more specific routes in the main table, they will -be preferred over the default route. - -Apparently Amazon Linux solves this differently, by not configuring a -routing table for addresses on interface "eth0". That might be an -alternative, but it's not clear to me what is special about eth0 to -warrant this treatment. It also would imply that we somehow recognize -this primary interface. In practise that would be doable by selecting -the interface with "iface_idx" zero. - -Instead choose this approach. This is remotely similar to what WireGuard does -for configuring the default route ([1]), however WireGuard uses fwmark to match -the packets instead of the source address. - -[1] https://www.wireguard.com/netns/#improved-rule-based-routing - -(cherry picked from commit fe80b2d1ecd94639573a944633a5d960db316f60) -(cherry picked from commit 58e58361bd1666e5af822a4bc970bebb8a44bd6e) ---- - man/nm-cloud-setup.xml | 66 +++++++++++++++------------------------ - src/nm-cloud-setup/main.c | 36 +++++++++++++++++++++ - 2 files changed, 62 insertions(+), 40 deletions(-) - -diff --git a/man/nm-cloud-setup.xml b/man/nm-cloud-setup.xml -index 7493cc1d7f26..976fc6472464 100644 ---- a/man/nm-cloud-setup.xml -+++ b/man/nm-cloud-setup.xml -@@ -256,7 +256,9 @@ ln -s /etc/systemd/system/timers.target.wants/nm-cloud-setup.timer /usr/lib/syst - Also, if the device is currently not activated in NetworkManager or if the currently - activated profile has a user-data org.freedesktop.nm-cloud-setup.skip=yes, - it is skipped. -- Then, the tool will change the runtime configuration of the device. -+ If only one interface and one address is configured, then the tool does nothing -+ and leaves the automatic configuration that was obtained via DHCP. -+ Otherwise, the tool will change the runtime configuration of the device. - - - Add static IPv4 addresses for all the configured addresses from local-ipv4s with -@@ -267,15 +269,25 @@ ln -s /etc/systemd/system/timers.target.wants/nm-cloud-setup.timer /usr/lib/syst - Choose a route table 30400 + the index of the interface and - add a default route 0.0.0.0/0. The gateway - is the first IP address in the CIDR subnet block. For -- example, we might get a route "0.0.0.0/0 172.16.5.1 10 table=30401". -+ example, we might get a route "0.0.0.0/0 172.16.5.1 10 table=30400". -+ Also choose a route table 30200 + the interface index. This -+ contains a direct routes to the subnets of this interface. - - - Finally, add a policy routing rule for each address. For example -- "priority 30401 from 172.16.5.3/32 table 30401, priority 30401 from 172.16.5.4/32 table 30401". -+ "priority 30200 from 172.16.5.3/32 table 30200, priority 30200 from 172.16.5.4/32 table 30200". -+ and -+ "priority 30400 from 172.16.5.3/32 table 30400, priority 30400 from 172.16.5.4/32 table 30400" -+ The 30200+ rules select the table to reach the subnet directly, while the 30400+ rules use the -+ default route. Also add a rule -+ "priority 30350 table main suppress_prefixlength 0". This has a priority between -+ the two previous rules and causes a lookup of routes in the main table while ignoring the default -+ route. The purpose of this is so that other specific routes in the main table are honored over -+ the default route in table 30400+. - - - With above example, this roughly corresponds for interface eth0 to -- nmcli device modify "eth0" ipv4.addresses "172.16.5.3/24,172.16.5.4/24" ipv4.routes "0.0.0.0/0 172.16.5.1 10 table=30401" ipv4.routing-rules "priority 30401 from 172.16.5.3/32 table 30401, priority 30401 from 172.16.5.4/32 table 30401". -+ nmcli device modify "eth0" ipv4.addresses "172.16.5.3/24,172.16.5.4/24" ipv4.routes "172.16.5.0/24 0.0.0.0 10 table=30200, 0.0.0.0/0 172.16.5.1 10 table=30400" ipv4.routing-rules "priority 30200 from 172.16.5.3/32 table 30200, priority 30200 from 172.16.5.4/32 table 30200, priority 20350 table main suppress_prefixlength 0, priority 30400 from 172.16.5.3/32 table 30400, priority 30400 from 172.16.5.4/32 table 30400". - Note that this replaces the previous addresses, routes and rules with the new information. - But also note that this only changes the run time configuration of the device. The - connection profile on disk is not affected. -@@ -360,14 +372,8 @@ ln -s /etc/systemd/system/timers.target.wants/nm-cloud-setup.timer /usr/lib/syst - - - At this point, we have a list of all interfaces (by MAC address) and their configured IPv4 addresses. -- For each device, we lookup the currently applied connection in NetworkManager. That implies, that the device is currently activated -- in NetworkManager. If no such device was in NetworkManager, or if the profile has user-data org.freedesktop.nm-cloud-setup.skip=yes, -- we skip the device. Now for each found IP address we add a static address "$ADDR/$SUBNET_PREFIX". Also we configure policy routing -- by adding a static route "$ADDR/$SUBNET_PREFIX $GATEWAY 10, table=$TABLE" where $GATEWAY is the first IP address in the subnet and table -- is 30400 plus the interface index. Also we add a policy routing rule "priority $TABLE from $ADDR/32 table $TABLE". -- The effect is not unlike calling -- nmcli device modify "$DEVICE" ipv4.addresses "$ADDR/$SUBNET [,...]" ipv4.routes "$ADDR/32 $GATEWAY 10 table=$TABLE" ipv4.routing-rules "priority $TABLE from $ADDR/32 table $TABLE" -- for all relevant devices and all found addresses. -+ Then the tool configures the system like doing for AWS environment. That is, using source based policy routing -+ with the tables/rules 30200/30400. - - - -@@ -389,9 +395,10 @@ ln -s /etc/systemd/system/timers.target.wants/nm-cloud-setup.timer /usr/lib/syst - of available interface. Interfaces are identified by their MAC address. - - -- Then for each interface fetch http://100.100.100.200/2016-01-01/meta-data/network/interfaces/macs/$MAC/vpc-cidr-block -- , http://100.100.100.200/2016-01-01/meta-data/network/interfaces/macs/$MAC/private-ipv4s and -- http://100.100.100.200/2016-01-01/meta-data/network/interfaces/macs/$MAC/netmask. -+ Then for each interface fetch http://100.100.100.200/2016-01-01/meta-data/network/interfaces/macs/$MAC/vpc-cidr-block, -+ http://100.100.100.200/2016-01-01/meta-data/network/interfaces/macs/$MAC/private-ipv4s, -+ http://100.100.100.200/2016-01-01/meta-data/network/interfaces/macs/$MAC/netmask and -+ http://100.100.100.200/2016-01-01/meta-data/network/interfaces/macs/$MAC/gateway. - Thereby we get a list of private IPv4 addresses, one CIDR subnet block and private IPv4 addresses prefix. - - -@@ -399,31 +406,10 @@ ln -s /etc/systemd/system/timers.target.wants/nm-cloud-setup.timer /usr/lib/syst - If no ethernet device for the respective MAC address is found, it is skipped. - Also, if the device is currently not activated in NetworkManager or if the currently - activated profile has a user-data org.freedesktop.nm-cloud-setup.skip=yes, -- it is skipped. -- Then, the tool will change the runtime configuration of the device. -- -- -- Add static IPv4 addresses for all the configured addresses from private-ipv4s with -- prefix length according to netmask. For example, -- we might have here 2 IP addresses like "10.0.0.150/24,10.0.0.152/24". -- -- -- Choose a route table 30400 + the index of the interface and -- add a default route 0.0.0.0/0. The gateway -- is the default gateway retrieved from metadata server. For -- example, we might get a route "0.0.0.0/0 10.0.0.253 10 table=30400". -- -- -- Finally, add a policy routing rule for each address. For example -- "priority 30400 from 10.0.0.150/32 table 30400, priority 30400 from 10.0.0.152/32 table 30400". -- -- -- With above example, this roughly corresponds for interface eth0 to -- nmcli device modify "eth0" ipv4.addresses "10.0.0.150/24,10.0.0.152/24" ipv4.routes "0.0.0.0/0 10.0.0.253 10 table=30400" ipv4.routing-rules "priority 30400 from 10.0.0.150/32 table 30400, priority 30400 from 10.0.0.152/32 table 30400". -- Note that this replaces the previous addresses, routes and rules with the new information. -- But also note that this only changes the run time configuration of the device. The -- connection profile on disk is not affected. -- -+ it is skipped. Also, there is only one interface and one IP address, the tool does nothing. -+ Then the tool configures the system like doing for AWS environment. That is, using source based policy routing -+ with the tables/rules 30200/30400. One difference to AWS is that the gateway is also fetched via metadata instead -+ of using the first IP address in the subnet. - - - -diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c -index 260d111205f5..916f41da91d3 100644 ---- a/src/nm-cloud-setup/main.c -+++ b/src/nm-cloud-setup/main.c -@@ -4,6 +4,8 @@ - - #include "libnm-client-aux-extern/nm-libnm-aux.h" - -+#include -+ - #include "nm-cloud-setup-utils.h" - #include "nmcs-provider-ec2.h" - #include "nmcs-provider-gcp.h" -@@ -335,6 +337,8 @@ _nmc_mangle_connection(NMDevice * device, - * We don't need to configure policy routing in this case. */ - NM_SET_OUT(out_skipped_single_addr, TRUE); - } else if (config_data->has_ipv4s && config_data->has_cidr) { -+ gs_unref_hashtable GHashTable *unique_subnets = -+ g_hash_table_new(nm_direct_hash, g_direct_equal); - NMIPAddress * addr_entry; - NMIPRoute * route_entry; - NMIPRoutingRule *rule_entry; -@@ -359,6 +363,38 @@ _nmc_mangle_connection(NMDevice * device, - ((guint8 *) &gateway)[3] += 1; - } - -+ for (i = 0; i < config_data->ipv4s_len; i++) { -+ in_addr_t a = config_data->ipv4s_arr[i]; -+ -+ a = nm_utils_ip4_address_clear_host_address(a, config_data->cidr_prefix); -+ -+ G_STATIC_ASSERT_EXPR(sizeof(gsize) >= sizeof(in_addr_t)); -+ if (g_hash_table_add(unique_subnets, GSIZE_TO_POINTER(a))) { -+ route_entry = -+ nm_ip_route_new_binary(AF_INET, &a, config_data->cidr_prefix, NULL, 10, NULL); -+ nm_ip_route_set_attribute(route_entry, -+ NM_IP_ROUTE_ATTRIBUTE_TABLE, -+ g_variant_new_uint32(30200 + config_data->iface_idx)); -+ g_ptr_array_add(routes_new, route_entry); -+ } -+ -+ rule_entry = nm_ip_routing_rule_new(AF_INET); -+ nm_ip_routing_rule_set_priority(rule_entry, 30200 + config_data->iface_idx); -+ nm_ip_routing_rule_set_from(rule_entry, -+ _nm_utils_inet4_ntop(config_data->ipv4s_arr[i], sbuf), -+ 32); -+ nm_ip_routing_rule_set_table(rule_entry, 30200 + config_data->iface_idx); -+ nm_assert(nm_ip_routing_rule_validate(rule_entry, NULL)); -+ g_ptr_array_add(rules_new, rule_entry); -+ } -+ -+ rule_entry = nm_ip_routing_rule_new(AF_INET); -+ nm_ip_routing_rule_set_priority(rule_entry, 30350); -+ nm_ip_routing_rule_set_table(rule_entry, RT_TABLE_MAIN); -+ nm_ip_routing_rule_set_suppress_prefixlength(rule_entry, 0); -+ nm_assert(nm_ip_routing_rule_validate(rule_entry, NULL)); -+ g_ptr_array_add(rules_new, rule_entry); -+ - route_entry = nm_ip_route_new_binary(AF_INET, &nm_ip_addr_zero, 0, &gateway, 10, NULL); - nm_ip_route_set_attribute(route_entry, - NM_IP_ROUTE_ATTRIBUTE_TABLE, --- -2.31.1 - diff --git a/SOURCES/1003-fix-ovsdb-removal-ports-rhbz1935026.patch b/SOURCES/1003-fix-ovsdb-removal-ports-rhbz1935026.patch new file mode 100644 index 0000000..30821d5 --- /dev/null +++ b/SOURCES/1003-fix-ovsdb-removal-ports-rhbz1935026.patch @@ -0,0 +1,52 @@ +From 482f9671c69800de2077d2dab9352a9b385115d3 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Tue, 22 Feb 2022 16:18:40 +0100 +Subject: [PATCH] ovs-port: fix removal of ovsdb entry if the interface goes + away + +Hope third time is the charm. + +The idea here is to remove the OVSDB entry if the device actually went away +violently (like, the it was actually removed from the platform), but keep it if +we're shutting down. + +Fixes-test: @ovs_nmstate +Fixes: 966413e78f14 ('ovs-port: avoid removing the OVSDB entry if we're shutting down') +Fixes: ecc73eb239e6 ('ovs-port: always remove the OVSDB entry on slave release') + +https://bugzilla.redhat.com/show_bug.cgi?id=2055665 +(cherry picked from commit 65fdfb25006acc3c67059792579dd7a770d04768) +(cherry picked from commit fee7328c86e5fe8171f8382492f147e7d263891b) +--- + src/core/devices/ovs/nm-device-ovs-port.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +diff --git a/src/core/devices/ovs/nm-device-ovs-port.c b/src/core/devices/ovs/nm-device-ovs-port.c +index 8406c3648cef..116f58c43ace 100644 +--- a/src/core/devices/ovs/nm-device-ovs-port.c ++++ b/src/core/devices/ovs/nm-device-ovs-port.c +@@ -188,8 +188,10 @@ del_iface_cb(GError *error, gpointer user_data) + static void + release_slave(NMDevice *device, NMDevice *slave, gboolean configure) + { +- NMDeviceOvsPort *self = NM_DEVICE_OVS_PORT(device); +- bool slave_removed = nm_device_sys_iface_state_get(slave) == NM_DEVICE_SYS_IFACE_STATE_REMOVED; ++ NMDeviceOvsPort *self = NM_DEVICE_OVS_PORT(device); ++ bool slave_not_managed = !NM_IN_SET(nm_device_sys_iface_state_get(slave), ++ NM_DEVICE_SYS_IFACE_STATE_MANAGED, ++ NM_DEVICE_SYS_IFACE_STATE_ASSUME); + + _LOGI(LOGD_DEVICE, "releasing ovs interface %s", nm_device_get_ip_iface(slave)); + +@@ -197,7 +199,7 @@ release_slave(NMDevice *device, NMDevice *slave, gboolean configure) + * removed and thus we're called with configure=FALSE), we still need + * to make sure its OVSDB entry is gone. + */ +- if (configure || slave_removed) { ++ if (configure || slave_not_managed) { + nm_ovsdb_del_interface(nm_ovsdb_get(), + nm_device_get_iface(slave), + del_iface_cb, +-- +2.35.1 + diff --git a/SOURCES/1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2065188.patch b/SOURCES/1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2059673.patch similarity index 98% rename from SOURCES/1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2065188.patch rename to SOURCES/1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2059673.patch index 5cc8294..cd6d791 100644 --- a/SOURCES/1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2065188.patch +++ b/SOURCES/1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2059673.patch @@ -1,4 +1,4 @@ -From 49e9c3560289f5d02ad1bbf95ae3b2d8d81baa37 Mon Sep 17 00:00:00 2001 +From 118561e284ff7f28421b19530d4471075b89645c Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 10 Mar 2022 12:07:49 +0100 Subject: [PATCH] n-dhcp4: discard NAKs from other servers in SELECTING diff --git a/SOURCES/9999-fix-pregen-doc.patch b/SOURCES/9999-fix-pregen-doc.patch index a4e81b3..c759e3f 100644 --- a/SOURCES/9999-fix-pregen-doc.patch +++ b/SOURCES/9999-fix-pregen-doc.patch @@ -1,4 +1,4 @@ -From 7423b47a3333b09fce9ddce33041e5dbdbb4c7e6 Mon Sep 17 00:00:00 2001 +From 9603d930557bcd8268c3e36897db9941ea3af0b7 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 27 Aug 2019 15:47:32 +0200 Subject: [PATCH] patch documentation with the proper default values @@ -9,21 +9,15 @@ of defaults. Patch the man pages with the proper values. --- - docs/api/html/NetworkManager.conf.html | 2 +- - docs/api/html/nm-settings-nmcli.html | 2 +- - man/NetworkManager.conf.5 | 2 +- - man/nm-settings-nmcli.5 | 2 +- - man/nm-settings-nmcli.xml | 2 +- - src/libnm-client-impl/nm-property-infos-nmcli.xml | 2 +- - src/libnmc-setting/settings-docs.h | 2 +- - src/nmcli/generate-docs-nm-settings-nmcli.xml | 2 +- - 8 files changed, 8 insertions(+), 8 deletions(-) + docs/api/html/NetworkManager.conf.html | 2 +- + man/NetworkManager.conf.5 | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/html/NetworkManager.conf.html b/docs/api/html/NetworkManager.conf.html -index e8efb5e7fe7d..f432f6736691 100644 +index 02029c2e336a..cf9269c7bef4 100644 --- a/docs/api/html/NetworkManager.conf.html +++ b/docs/api/html/NetworkManager.conf.html -@@ -658,7 +658,7 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth +@@ -663,7 +663,7 @@ unmanaged-devices=mac:00:22:68:1c:59:b1;mac:00:1E:65:30:D1:C4;interface-name:eth are "syslog" and "journal". When NetworkManager is started with "--debug" in addition all messages will be printed to stderr. @@ -32,24 +26,11 @@ index e8efb5e7fe7d..f432f6736691 100644

-diff --git a/docs/api/html/nm-settings-nmcli.html b/docs/api/html/nm-settings-nmcli.html -index e221ce1496fa..1ce647f7bf7d 100644 ---- a/docs/api/html/nm-settings-nmcli.html -+++ b/docs/api/html/nm-settings-nmcli.html -@@ -1955,7 +1955,7 @@ - -

- Alias: ip4

--

A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example "192.168.1.5/24, 10.1.0.5/24". The addresses are listed in increasing priority, meaning the last address will be the primary address.

-+

A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example "192.168.1.5/24, 10.1.0.5/24". The addresses are listed in decreasing priority, meaning the first address will be the primary address.

-

- Format: a comma separated list of addresses

- diff --git a/man/NetworkManager.conf.5 b/man/NetworkManager.conf.5 -index 33850bb0e398..cd0379806b29 100644 +index 4f62ed7c0cde..74daf4c8dc02 100644 --- a/man/NetworkManager.conf.5 +++ b/man/NetworkManager.conf.5 -@@ -664,7 +664,7 @@ INFO\&. +@@ -669,7 +669,7 @@ INFO\&. .PP \fIbackend\fR .RS 4 @@ -58,71 +39,6 @@ index 33850bb0e398..cd0379806b29 100644 .RE .PP \fIaudit\fR -diff --git a/man/nm-settings-nmcli.5 b/man/nm-settings-nmcli.5 -index 2d9c067a4679..d3a03d306a1d 100644 ---- a/man/nm-settings-nmcli.5 -+++ b/man/nm-settings-nmcli.5 -@@ -1655,7 +1655,7 @@ Properties: - .RS 4 - Alias: ip4 - .sp --A list of IPv4 addresses and their prefix length\&. Multiple addresses can be separated by comma\&. For example "192\&.168\&.1\&.5/24, 10\&.1\&.0\&.5/24"\&. The addresses are listed in increasing priority, meaning the last address will be the primary address\&. -+A list of IPv4 addresses and their prefix length\&. Multiple addresses can be separated by comma\&. For example "192\&.168\&.1\&.5/24, 10\&.1\&.0\&.5/24"\&. The addresses are listed in decreasing priority, meaning the first address will be the primary address\&. - .sp - Format: a comma separated list of addresses - .RE -diff --git a/man/nm-settings-nmcli.xml b/man/nm-settings-nmcli.xml -index 258e4135009b..199e49e91794 100644 ---- a/man/nm-settings-nmcli.xml -+++ b/man/nm-settings-nmcli.xml -@@ -274,7 +274,7 @@ - Format: stringipv4 settingIPv4 Settings. - Properties: - -- Alias: ip4A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example "192.168.1.5/24, 10.1.0.5/24". The addresses are listed in increasing priority, meaning the last address will be the primary address. -+ Alias: ip4A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example "192.168.1.5/24, 10.1.0.5/24". The addresses are listed in decreasing priority, meaning the first address will be the primary address. - Format: a comma separated list of addressesTimeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4. - Format: int32A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values "mac" and "perm-mac" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value "ipv6-duid" uses the DUID from "ipv6.dhcp-duid" property as an RFC4361-compliant client identifier. As IAID it uses "ipv4.dhcp-iaid" and falls back to "ipv6.dhcp-iaid" if unset. The special value "duid" generates a RFC4361-compliant client identifier based on "ipv4.dhcp-iaid" and uses a DUID generated by hashing /etc/machine-id. The special value "stable" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the "${DEVICE}" or "${MAC}" specifier to get a per-device key. If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin. - Format: stringIf the "dhcp-send-hostname" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and "dhcp-hostname" are mutually exclusive and cannot be set at the same time. -diff --git a/src/libnm-client-impl/nm-property-infos-nmcli.xml b/src/libnm-client-impl/nm-property-infos-nmcli.xml -index b771b74c5909..d6aa8a80c8e3 100644 ---- a/src/libnm-client-impl/nm-property-infos-nmcli.xml -+++ b/src/libnm-client-impl/nm-property-infos-nmcli.xml -@@ -34,7 +34,7 @@ - - - -- -+ - - - -diff --git a/src/libnmc-setting/settings-docs.h b/src/libnmc-setting/settings-docs.h -index 12625d445966..85c5aca1e4c8 100644 ---- a/src/libnmc-setting/settings-docs.h -+++ b/src/libnmc-setting/settings-docs.h -@@ -226,7 +226,7 @@ - #define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_REMOTE N_("The remote endpoint of the tunnel; the value must contain an IPv4 or IPv6 address.") - #define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_TOS N_("The type of service (IPv4) or traffic class (IPv6) field to be set on tunneled packets.") - #define DESCRIBE_DOC_NM_SETTING_IP_TUNNEL_TTL N_("The TTL to assign to tunneled packets. 0 is a special value meaning that packets inherit the TTL value.") --#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ADDRESSES N_("A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example \"192.168.1.5/24, 10.1.0.5/24\". The addresses are listed in increasing priority, meaning the last address will be the primary address.") -+#define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_ADDRESSES N_("A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example \"192.168.1.5/24, 10.1.0.5/24\". The addresses are listed in decreasing priority, meaning the first address will be the primary address.") - #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DAD_TIMEOUT N_("Timeout in milliseconds used to check for the presence of duplicate IP addresses on the network. If an address conflict is detected, the activation will fail. A zero value means that no duplicate address detection is performed, -1 means the default value (either configuration ipvx.dad-timeout override or zero). A value greater than zero is a timeout in milliseconds. The property is currently implemented only for IPv4.") - #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_CLIENT_ID N_("A string sent to the DHCP server to identify the local machine which the DHCP server may use to customize the DHCP lease and options. When the property is a hex string ('aa:bb:cc') it is interpreted as a binary client ID, in which case the first byte is assumed to be the 'type' field as per RFC 2132 section 9.14 and the remaining bytes may be an hardware address (e.g. '01:xx:xx:xx:xx:xx:xx' where 1 is the Ethernet ARP type and the rest is a MAC address). If the property is not a hex string it is considered as a non-hardware-address client ID and the 'type' field is set to 0. The special values \"mac\" and \"perm-mac\" are supported, which use the current or permanent MAC address of the device to generate a client identifier with type ethernet (01). Currently, these options only work for ethernet type of links. The special value \"ipv6-duid\" uses the DUID from \"ipv6.dhcp-duid\" property as an RFC4361-compliant client identifier. As IAID it uses \"ipv4.dhcp-iaid\" and falls back to \"ipv6.dhcp-iaid\" if unset. The special value \"duid\" generates a RFC4361-compliant client identifier based on \"ipv4.dhcp-iaid\" and uses a DUID generated by hashing /etc/machine-id. The special value \"stable\" is supported to generate a type 0 client identifier based on the stable-id (see connection.stable-id) and a per-host key. If you set the stable-id, you may want to include the \"${DEVICE}\" or \"${MAC}\" specifier to get a per-device key. If unset, a globally configured default is used. If still unset, the default depends on the DHCP plugin.") - #define DESCRIBE_DOC_NM_SETTING_IP4_CONFIG_DHCP_FQDN N_("If the \"dhcp-send-hostname\" property is TRUE, then the specified FQDN will be sent to the DHCP server when acquiring a lease. This property and \"dhcp-hostname\" are mutually exclusive and cannot be set at the same time.") -diff --git a/src/nmcli/generate-docs-nm-settings-nmcli.xml b/src/nmcli/generate-docs-nm-settings-nmcli.xml -index 88803094d6ce..ca5225ba2811 100644 ---- a/src/nmcli/generate-docs-nm-settings-nmcli.xml -+++ b/src/nmcli/generate-docs-nm-settings-nmcli.xml -@@ -650,7 +650,7 @@ - description="DNS servers priority. The relative priority for DNS servers specified by this setting. A lower numerical value is better (higher priority). Negative values have the special effect of excluding other configurations with a greater numerical priority value; so in presence of at least one negative priority, only DNS servers from connections with the lowest priority value will be used. To avoid all DNS leaks, set the priority of the profile that should be used to the most negative value of all active connections profiles. Zero selects a globally configured default value. If the latter is missing or zero too, it defaults to 50 for VPNs (including WireGuard) and 100 for other connections. Note that the priority is to order DNS settings for multiple active connections. It does not disambiguate multiple DNS servers within the same connection profile. When multiple devices have configurations with the same priority, VPNs will be considered first, then devices with the best (lowest metric) default route and then all other devices. When using dns=default, servers with higher priority will be on top of resolv.conf. To prioritize a given server over another one within the same connection, just specify them in the desired order. Note that commonly the resolver tries name servers in /etc/resolv.conf in the order listed, proceeding with the next server in the list on failure. See for example the "rotate" option of the dns-options setting. If there are any negative DNS priorities, then only name servers from the devices with that lowest priority will be considered. When using a DNS resolver that supports Conditional Forwarding or Split DNS (with dns=dnsmasq or dns=systemd-resolved settings), each connection is used to query domains in its search list. The search domains determine which name servers to ask, and the DNS priority is used to prioritize name servers based on the domain. Queries for domains not present in any search list are routed through connections having the '~.' special wildcard domain, which is added automatically to connections with the default route (or can be added manually). When multiple connections specify the same domain, the one with the best priority (lowest numerical value) wins. If a sub domain is configured on another interface it will be accepted regardless the priority, unless parent domain on the other interface has a negative priority, which causes the sub domain to be shadowed. With Split DNS one can avoid undesired DNS leaks by properly configuring DNS priorities and the search domains, so that only name servers of the desired interface are configured." /> - -+ description="A list of IPv4 addresses and their prefix length. Multiple addresses can be separated by comma. For example "192.168.1.5/24, 10.1.0.5/24". The addresses are listed in decreasing priority, meaning the first address will be the primary address." /> - -- 2.31.1 diff --git a/SPECS/NetworkManager.spec b/SPECS/NetworkManager.spec index c2c2abc..641ee43 100644 --- a/SPECS/NetworkManager.spec +++ b/SPECS/NetworkManager.spec @@ -5,14 +5,15 @@ %global glib2_version %(pkg-config --modversion glib-2.0 2>/dev/null || echo bad) %global epoch_version 1 -%global rpm_version 1.32.10 -%global real_version 1.32.10 -%global release_version 5 +%global rpm_version 1.36.0 +%global real_version 1.36.0 +%global release_version 4 %global snapshot %{nil} %global git_sha %{nil} -%global obsoletes_device_plugins 1:0.9.9.95-1 -%global obsoletes_ppp_plugin 1:1.5.3 +%global obsoletes_device_plugins 1:0.9.9.95-1 +%global obsoletes_ppp_plugin 1:1.5.3 +%global obsoletes_initscripts_updown 1:1.36.0-0.6 %global systemd_dir %{_prefix}/lib/systemd/system %global sysctl_dir %{_prefix}/lib/sysctl.d @@ -193,11 +194,10 @@ Patch1: 0001-cloud-setup-systemd-unit-rh1791758.patch Patch2: 0002-firewall-Default-to-iptables-backend-to-preserve-behavior.patch # Bugfixes that are only relevant until next rebase of the package. -Patch1000: 1000-platform-fix-capturing-addresses-from-platform-for-assuming-after-restart.patch -Patch1001: 1001-nmcli-docs-fix-address-order-in-ipv46-addresses-documentation-for-nm-settings-nmcli.patch -Patch1002: 1002-preserve-IPv6-multicast-route-rh2004212.patch -Patch1003: 1003-cloud-setup-better-handle-other-routes-rh1977984.patch -Patch1004: 1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2065188.patch +Patch1001: 1001-wwan-dns-fix-rh2059138.patch +Patch1002: 1002-checkpoint-preserve-external-bridge-ports-rh2035519.patch +Patch1003: 1003-fix-ovsdb-removal-ports-rhbz1935026.patch +Patch1004: 1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2059673.patch # The pregenerated docs contain default values and paths that depend # on the configure options when creating the source tarball. @@ -206,6 +206,9 @@ Patch1004: 1004-n-dhcp4-discard-NAKs-from-other-servers-rhbz2065188.patch Patch9999: 9999-fix-pregen-doc.patch Requires(post): systemd +%if 0%{?fedora} || 0%{?rhel} > 7 +Requires(post): systemd-udev +%endif Requires(post): /usr/sbin/update-alternatives Requires(preun): systemd Requires(preun): /usr/sbin/update-alternatives @@ -220,6 +223,10 @@ Requires: libndp >= %{libndp_version} Obsoletes: NetworkManager < %{obsoletes_device_plugins} Obsoletes: NetworkManager < %{obsoletes_ppp_plugin} Obsoletes: NetworkManager-wimax < 1.2 +%if 0%{?rhel} && 0%{?rhel} == 8 +Suggests: NetworkManager-initscripts-updown +%endif +Obsoletes: NetworkManager < %{obsoletes_initscripts_updown} %if 0%{?rhel} && 0%{?rhel} <= 7 # Kept for RHEL to ensure that wired 802.1x works out of the box @@ -567,6 +574,20 @@ This tool is still experimental. %endif +%package initscripts-updown +Summary: Legacy ifup/ifdown scripts for NetworkManager that replace initscripts (network-scripts) +Group: System Environment/Base +BuildArch: noarch +Requires: NetworkManager +Requires: /usr/bin/nmcli +Obsoletes: NetworkManager < %{obsoletes_initscripts_updown} + +%description initscripts-updown +Installs alternative ifup/ifdown scripts that talk to NetworkManager. +This is only for backward compatibility with initscripts (network-scripts). +Preferably use nmcli instead. + + %prep %autosetup -p1 -n NetworkManager-%{real_version} @@ -693,8 +714,7 @@ This tool is still experimental. -Dresolvconf=no \ -Dnetconfig=no \ -Dconfig_dns_rc_manager_default=%{dns_rc_manager_default} \ - -Dconfig_logging_backend_default=%{logging_backend_default} \ - -Djson_validation=true + -Dconfig_logging_backend_default=%{logging_backend_default} %meson_build @@ -880,7 +900,8 @@ mkdir -p %{buildroot}%{_prefix}/src/debug/NetworkManager-%{real_version} cp valgrind.suppressions %{buildroot}%{_prefix}/src/debug/NetworkManager-%{real_version} %endif -touch %{buildroot}%{_sbindir}/ifup %{buildroot}%{_sbindir}/ifdown +touch %{buildroot}%{_sbindir}/ifup +touch %{buildroot}%{_sbindir}/ifdown %check @@ -923,7 +944,8 @@ fi %systemd_post %{systemd_units} -%triggerin -- initscripts + +%post initscripts-updown if [ -f %{_sbindir}/ifup -a ! -L %{_sbindir}/ifup ]; then # initscripts package too old, won't let us set an alternative /usr/sbin/update-alternatives --remove ifup %{_libexecdir}/nm-ifup >/dev/null 2>&1 || : @@ -946,12 +968,16 @@ if [ $1 -eq 0 ]; then # Don't kill networking entirely just on package remove #/bin/systemctl stop NetworkManager.service >/dev/null 2>&1 || : - - /usr/sbin/update-alternatives --remove ifup %{_libexecdir}/nm-ifup >/dev/null 2>&1 || : fi %systemd_preun NetworkManager-wait-online.service NetworkManager-dispatcher.service +%preun initscripts-updown +if [ $1 -eq 0 ]; then + /usr/sbin/update-alternatives --remove ifup %{_libexecdir}/nm-ifup >/dev/null 2>&1 || : +fi + + %if %{with nm_cloud_setup} %preun cloud-setup %systemd_preun %{systemd_units_cloud_setup} @@ -983,6 +1009,7 @@ fi %files %{dbus_sys_dir}/org.freedesktop.NetworkManager.conf %{dbus_sys_dir}/nm-dispatcher.conf +%exclude %{dbus_sys_dir}/nm-priv-helper.conf %{dbus_sys_dir}/nm-ifcfg-rh.conf %{_sbindir}/%{name} %{_bindir}/nmcli @@ -999,15 +1026,11 @@ fi %config(noreplace) %{_sysconfdir}/%{name}/NetworkManager.conf %ghost %{_sysconfdir}/%{name}/VPN %{_bindir}/nm-online -%{_libexecdir}/nm-ifup -%ghost %attr(755, root, root) %{_sbindir}/ifup -%{_libexecdir}/nm-ifdown -%ghost %attr(755, root, root) %{_sbindir}/ifdown %{_libexecdir}/nm-dhcp-helper %{_libexecdir}/nm-dispatcher -%{_libexecdir}/nm-iface-helper %{_libexecdir}/nm-initrd-generator %{_libexecdir}/nm-daemon-helper +%exclude %{_libexecdir}/nm-priv-helper %dir %{_libdir}/%{name} %dir %{nmplugindir} %{nmplugindir}/libnm-settings-plugin*.so @@ -1031,6 +1054,7 @@ fi %dir %{_localstatedir}/lib/NetworkManager %dir %{_sysconfdir}/sysconfig/network-scripts %{_datadir}/dbus-1/system-services/org.freedesktop.nm_dispatcher.service +%{_datadir}/dbus-1/system-services/org.freedesktop.nm_priv_helper.service %{_datadir}/polkit-1/actions/*.policy %{_prefix}/lib/udev/rules.d/*.rules %if %{with firewalld_zone} @@ -1040,6 +1064,7 @@ fi %{systemd_dir}/NetworkManager.service %{systemd_dir}/NetworkManager-wait-online.service %{systemd_dir}/NetworkManager-dispatcher.service +%exclude %{systemd_dir}/nm-priv-helper.service %dir %{_datadir}/doc/NetworkManager/examples %{_datadir}/doc/NetworkManager/examples/server.conf %doc NEWS AUTHORS README CONTRIBUTING.md TODO @@ -1166,16 +1191,108 @@ fi %endif +%files initscripts-updown +%{_libexecdir}/nm-ifup +%ghost %attr(755, root, root) %{_sbindir}/ifup +%{_libexecdir}/nm-ifdown +%ghost %attr(755, root, root) %{_sbindir}/ifdown + + %changelog -* Mon Mar 21 2022 Fernando Fernandez Mancera - 1:1.36.10-5 -- n-dhcp4: discard NAKs from different servers in SELECTING (rh #2065188) +* Fri Mar 11 2022 Thomas Haller - 1:1.36.0-3 +- core: preserve external bridge ports during checkpoint rollback (rh #2035519) +- ovs-port: fix removal of ovsdb entry if the interface goes away (rh #1935026) -* Tue Sep 28 2021 Thomas Haller - 1:1.32.10-4 -- revert unapproved patches part of "cloud-setup" change (rh #1977984) +* Mon Feb 28 2022 Beniamino Galvani - 1:1.36.0-2 +- core: fix setting DNS from WWAN and PPP (rh #2059138) -* Fri Sep 24 2021 Beniamino Galvani - 1:1.32.10-3 -- preserve the IPv6 multicast route added by kernel (rh #2004212) -- cloud-setup: better handle other route configuration (rh #1977984) +* Thu Feb 24 2022 Lubomir Rintel - 1:1.36.0-1 +- Upgrade to 1.36.0 release +- core: avoid losing L3 configuration the second time it's applied (rh #2043514) +- ovs: avoid removing OVSDB entries on daemon shutdown (rh #2055665) +- nmcli: fix defaults for some properties on interactive add (rh #2053603) + +* Sat Feb 19 2022 Lubomir Rintel - 1:1.36.0-0.9 +- revert: generate docs during build instead of using pre-generated (rh #1995915) +- Upgrade to 1.35.92 (release candidate) +- ppp: increase disconnect timeout (rh #2049596) +- core: finish activation after all objects are committed (rh #2043133) +- ipv6: add support for multipath routes (rh #1837254) +- keyfile: do not write empty string list properties (rh #2022623) + +* Fri Feb 04 2022 Lubomir Rintel - 1:1.36.0-0.8 +- Upgrade to 1.35.91 release (release candidate) +- bond: fix duplicate IPv4 address detection (rh #2028751) +- core: add support for blackhole routes (rh #1937823) (rh #2013587) +- core: re-assess IP configuration if one IP family times out (rh #2051904) +- ovs: remove ovsdb entry on interface removal (rh #2047302) +- ovs: properly clean up devices on daemon shutdown (rh #2029937) +- core: avoid losing addresses on handover from initrd to ral root (rh #2047302) +- core: fix a possibe assertion failure in ACD (rh #2047788) + +* Fri Jan 28 2022 Thomas Haller - 1:1.36.0-0.7 +- Upgrade to 1.35.7 release (development) +- core: fix crash related to DHCPv6 leases (rh #2028849) +- wifi: fix stale ActiveAccessPoint in D-Bus (rh #1983747) +- libnm: fix dangling pointer in NMObject (rh #2039331) + +* Wed Jan 26 2022 Thomas Haller - 1:1.36.0-0.6 +- Upgrade to 1.35.6 release (development) +- Move ifup/ifdown scripts to new NetworkManager-initscripts-updown package (rh #2022418) +- wwan: fix assertion failure in modem/ppp code (rh #2028385) +- core: fix performance regression with 500vlans test (rh #2028849) +- core: drop defective BPF filter for netlink sockets that caused hangs (rh #2037411) +- initrd: add support for rd.znet_ifnames (rh #1980387) + +* Thu Jan 20 2022 Thomas Haller - 1:1.36.0-0.5 +- generate docs during build instead of using pre-generated (rh #1995915) + +* Wed Jan 12 2022 Wen Liang - 1:1.36.0-0.4 +- Upgrade to 1.35.4 release (development) +- ipv4ll: fix assert on external LL address removal (rh #2028404) +- openvswitch: add DPDK n_rxq configuration option (rh #2001563) +- device: ignore ndisc signal if device has no ifindex (rh #2013266) +- bluetooth: fix invalid assertion in NMBluezManager:dispose() (rh #2028427) +- supplicant: enable SAE-H2E (rh #2019396) + +* Thu Dec 16 2021 Wen Liang - 1:1.36.0-0.3 +- Upgrade to 1.35.3 release (development) +- device: fix update of the ip-iface property (rh #2027490) +- platform: add bpf filter to ignore routes from routing daemons (rh #1861527) + +* Wed Dec 1 2021 Wen Liang - 1:1.36.0-0.2 +- Upgrade to 1.35.2 release (development) +- initrd: handle ip=dhcp,dhcp6 specially to wait for both IPv4 and IPv6 (rh #1961666) +- bridge: fix ageing_time bridge option (rh #1871950) +- core: make sure Device and AC emit StateChanged a bit later (rh #2006677) +- ovsdb: deactivate removed device if does not have a master (rh #2022275) +- nmcli: fix setting wake-on-lan property on edit mode (rh #2016348) +- core: fix wrong DHCPv6 timeouts due to endianness problem (rh #2027267) + +* Thu Nov 18 2021 Beniamino Galvani - 1:1.36.0-0.1 +- Upgrade to 1.35.1 release (development) +- core: refactor IP configuration code (rh #1868254) +- core: fix deleting external route during service restart (rh #2010640) + +* Thu Oct 21 2021 Ana Cabral - 1:1.34.0-0.3 +- Upgrade to 1.33.4 release (development) +- Deprecate "master"/"slave" on bonding and bridge API (rh #1949023) +- core: Fix configuration reload for active devices (rh #1852445) +- Update systemd-udev dependency (rh #2012123) + +* Thu Sep 23 2021 Ana Cabral - 1:1.34.0-0.2 +- Upgrade to 1.33.3 release (development) +- platform: don't listen for tc netlink messages (rh #1753677) +- cloud-setup: better handle other route configuration (rh #2006370) +- Fix autoneg advertisement (rh #1897004) + +* Thu Sep 9 2021 Ana Cabral - 1:1.34.0-0.1 +- Upgrade to 1.33.2 release (development) (rh #1996617) +- Obtain permanent hardware address via netlink or lookup via ethtool (rh #1987286) +- Show more information about routes in nmcli (rh #1870059) +- Add test for creation and activation of new connection via interface (rh #1763054) +- ethtool: fix setting autonegotiation/speed on reactivation (rh #1897004) +- Fix MTU's decrease after the removal of 802-3-ethernet configuration (rh #1973536) * Thu Aug 19 2021 Wen Liang - 1:1.32.10-2 - platform: fix capturing IPv4 addresses from platform for assuming after restart (rh #1988751)