From 2b96e9314cb7d886b11e8787d28f540ef50ddd3c Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 15 Jun 2021 18:58:52 +0200 Subject: [PATCH] cloud-setup: preserve IPv4 addresses/routes/rules from profile nm-cloud-setup automatically detects routes, addresses and rules and configures them on the device using the emphermal Reapply() API. That is, it does not modify the existing profile (on disk), but changes the runtime configuration only. As such, it used to wipe otherwise statically configured IP addresses, routes and rules. That seems unnecessary. Let's keep the configuration from the (persistent) configuration. There is of course the problem that nm-cloud-setup doesn't really understand the existing IP configuration, and it can only hope that it can be meaningfully combined with what nm-cloud-setup wants to configure. This should cover most simple cases, for more complex setups, the user probably should disable nm-cloud-setup and configure the network explicitly to their liking. https://bugzilla.redhat.com/show_bug.cgi?id=1971527 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/893 (cherry picked from commit 4201ee5119e58ffef87115e5d12f928f728dba30) (cherry picked from commit 9541b0bea4082b25bdc11c7cfa0087d549e5ceeb) --- clients/cloud-setup/main.c | 49 +++++++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/clients/cloud-setup/main.c b/clients/cloud-setup/main.c index 32d29ef4fa..9dadf3c618 100644 --- a/clients/cloud-setup/main.c +++ b/clients/cloud-setup/main.c @@ -270,15 +270,18 @@ _nmc_mangle_connection(NMDevice * device, const NMCSProviderGetConfigIfaceData *config_data, gboolean * out_changed) { - NMSettingIPConfig *s_ip; - 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; + NMSettingIPConfig * s_ip; + NMActiveConnection *ac; + 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; gs_unref_ptrarray GPtrArray *addrs_new = NULL; gs_unref_ptrarray GPtrArray *rules_new = NULL; gs_unref_ptrarray GPtrArray *routes_new = NULL; @@ -290,12 +293,40 @@ _nmc_mangle_connection(NMDevice * device, if (!s_ip) return FALSE; + if ((ac = nm_device_get_active_connection(device)) + && (remote_connection = NM_CONNECTION(nm_active_connection_get_connection(ac)))) + remote_s_ip = nm_connection_get_setting_ip4_config(remote_connection); + addrs_new = g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_address_unref); rules_new = g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_routing_rule_unref); routes_new = g_ptr_array_new_full(config_data->iproutes_len + !!config_data->ipv4s_len, (GDestroyNotify) nm_ip_route_unref); + if (remote_s_ip) { + guint len; + guint j; + + len = nm_setting_ip_config_get_num_addresses(remote_s_ip); + for (j = 0; j < len; j++) { + g_ptr_array_add(addrs_new, + nm_ip_address_dup(nm_setting_ip_config_get_address(remote_s_ip, j))); + } + + len = nm_setting_ip_config_get_num_routes(remote_s_ip); + for (j = 0; j < len; j++) { + g_ptr_array_add(routes_new, + nm_ip_route_dup(nm_setting_ip_config_get_route(remote_s_ip, j))); + } + + len = nm_setting_ip_config_get_num_routing_rules(remote_s_ip); + for (j = 0; j < len; j++) { + g_ptr_array_add( + rules_new, + nm_ip_routing_rule_ref(nm_setting_ip_config_get_routing_rule(remote_s_ip, j))); + } + } + if (config_data->has_ipv4s && config_data->has_cidr) { for (i = 0; i < config_data->ipv4s_len; i++) { NMIPAddress *entry;