diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c index 026c6701b4..c3f3332095 100644 --- a/src/nm-cloud-setup/main.c +++ b/src/nm-cloud-setup/main.c @@ -450,6 +450,7 @@ _config_one(GCancellable *sigterm_cancellable, gboolean version_id_changed; guint try_count; gboolean any_changes = FALSE; + gboolean maybe_no_preserved_external_ip; g_main_context_iteration(NULL, FALSE); @@ -538,10 +539,17 @@ try_again: /* we are about to call Reapply(). Even if that fails, it counts as if we changed something. */ any_changes = TRUE; + /* "preserve-external-ip" flag was only introduced in 1.41.6 (but maybe backported!). + * If we run 1.41.6+, we are sure that it's gonna work. Otherwise, we take into account + * that the call might fail due to the invalid flag and we retry. */ + maybe_no_preserved_external_ip = + (nmc_client_has_version_info_v(nmc) < NM_ENCODE_VERSION(1, 41, 6)); + if (!nmcs_device_reapply(device, sigterm_cancellable, applied_connection, applied_version_id, + maybe_no_preserved_external_ip, &version_id_changed, &error)) { if (version_id_changed && try_count < 5) { diff --git a/src/nm-cloud-setup/nm-cloud-setup-utils.c b/src/nm-cloud-setup/nm-cloud-setup-utils.c index e8c9943d78..cb8e9f559c 100644 --- a/src/nm-cloud-setup/nm-cloud-setup-utils.c +++ b/src/nm-cloud-setup/nm-cloud-setup-utils.c @@ -822,6 +822,7 @@ nmcs_device_reapply(NMDevice *device, GCancellable *sigterm_cancellable, NMConnection *connection, guint64 version_id, + gboolean maybe_no_preserved_external_ip, gboolean *out_version_id_changed, GError **error) { @@ -829,11 +830,13 @@ nmcs_device_reapply(NMDevice *device, DeviceReapplyData data = { .main_loop = main_loop, }; + NMDeviceReapplyFlags reapply_flags = NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP; +again: nm_device_reapply_async(device, connection, version_id, - 0, + reapply_flags, sigterm_cancellable, _nmcs_device_reapply_cb, &data); @@ -841,6 +844,17 @@ nmcs_device_reapply(NMDevice *device, g_main_loop_run(main_loop); if (data.error) { + if (maybe_no_preserved_external_ip + && reapply_flags == NM_DEVICE_REAPPLY_FLAGS_PRESERVE_EXTERNAL_IP + && nm_g_error_matches(data.error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_FAILED)) { + /* Hm? Maybe we running against an older version of NetworkManager that + * doesn't support "preserve-external-ip" flags? Retry without the flag. + * + * Note that recent version would reject invalid flags with NM_DEVICE_ERROR_INVALID_ARGUMENT, + * but we want to detect old daemon versions here. */ + reapply_flags = NM_DEVICE_REAPPLY_FLAGS_NONE; + goto again; + } NM_SET_OUT( out_version_id_changed, g_error_matches(data.error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_VERSION_ID_MISMATCH)); diff --git a/src/nm-cloud-setup/nm-cloud-setup-utils.h b/src/nm-cloud-setup/nm-cloud-setup-utils.h index 4131abfe7c..fed0f4b6ed 100644 --- a/src/nm-cloud-setup/nm-cloud-setup-utils.h +++ b/src/nm-cloud-setup/nm-cloud-setup-utils.h @@ -136,6 +136,7 @@ gboolean nmcs_device_reapply(NMDevice *device, GCancellable *sigterm_cancellable, NMConnection *connection, guint64 version_id, + gboolean maybe_no_preserved_external_ip, gboolean *out_version_id_changed, GError **error);