about summary refs log tree commit diff
path: root/clients/cloud-setup
diff options
context:
space:
mode:
authorSebastien Bacher <seb128@ubuntu.com>2021-01-11 18:07:03 +0100
committerSebastien Bacher <seb128@ubuntu.com>2021-01-11 18:15:57 +0100
commit2567f558da3eb9911678227d4aeb15162e707d89 (patch)
tree13c80b0e091c8ba585b14b966cda998f95f1936d /clients/cloud-setup
parent02d99ffd62ede29cffcb45fcbe33d044b7406d3a (diff)
parentf54032b30e1ddd84f10a339e0caf493772e049a7 (diff)
Merge branch 'debian/master' into ubuntu/master
Diffstat (limited to 'clients/cloud-setup')
-rw-r--r--clients/cloud-setup/main.c956
-rw-r--r--clients/cloud-setup/meson.build1
-rw-r--r--clients/cloud-setup/nm-cloud-setup-utils.c1179
-rw-r--r--clients/cloud-setup/nm-cloud-setup-utils.h139
-rw-r--r--clients/cloud-setup/nm-cloud-setup.service.in1
-rw-r--r--clients/cloud-setup/nm-http-client.c1171
-rw-r--r--clients/cloud-setup/nm-http-client.h98
-rw-r--r--clients/cloud-setup/nmcs-provider-azure.c530
-rw-r--r--clients/cloud-setup/nmcs-provider-azure.h28
-rw-r--r--clients/cloud-setup/nmcs-provider-ec2.c887
-rw-r--r--clients/cloud-setup/nmcs-provider-ec2.h21
-rw-r--r--clients/cloud-setup/nmcs-provider-gcp.c802
-rw-r--r--clients/cloud-setup/nmcs-provider-gcp.h21
-rw-r--r--clients/cloud-setup/nmcs-provider.c250
-rw-r--r--clients/cloud-setup/nmcs-provider.h114
15 files changed, 3308 insertions, 2890 deletions
diff --git a/clients/cloud-setup/main.c b/clients/cloud-setup/main.c
index 78260b97..1baf0feb 100644
--- a/clients/cloud-setup/main.c
+++ b/clients/cloud-setup/main.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "nm-default.h"
 
@@ -7,625 +7,599 @@
 #include "nm-cloud-setup-utils.h"
 #include "nmcs-provider-ec2.h"
 #include "nmcs-provider-gcp.h"
+#include "nmcs-provider-azure.h"
 #include "nm-libnm-core-intern/nm-libnm-core-utils.h"
 
 /*****************************************************************************/
 
 typedef struct {
-	GMainLoop *main_loop;
-	GCancellable *cancellable;
-	NMCSProvider *provider_result;
-	guint detect_count;
+    GMainLoop *   main_loop;
+    GCancellable *cancellable;
+    NMCSProvider *provider_result;
+    guint         detect_count;
 } ProviderDetectData;
 
 static void
-_provider_detect_cb (GObject *source,
-                     GAsyncResult *result,
-                     gpointer user_data)
+_provider_detect_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	gs_unref_object NMCSProvider *provider = NMCS_PROVIDER (source);
-	gs_free_error GError *error = NULL;
-	ProviderDetectData *dd;
-	gboolean success;
+    gs_unref_object NMCSProvider *provider = NMCS_PROVIDER(source);
+    gs_free_error GError *error            = NULL;
+    ProviderDetectData *  dd;
+    gboolean              success;
 
-	success = nmcs_provider_detect_finish (provider, result, &error);
+    success = nmcs_provider_detect_finish(provider, result, &error);
 
-	nm_assert (success != (!!error));
+    nm_assert(success != (!!error));
 
-	if (nm_utils_error_is_cancelled (error))
-		return;
+    if (nm_utils_error_is_cancelled(error))
+        return;
 
-	dd = user_data;
+    dd = user_data;
 
-	nm_assert (dd->detect_count > 0);
-	dd->detect_count--;
+    nm_assert(dd->detect_count > 0);
+    dd->detect_count--;
 
-	if (error) {
-		_LOGI ("provider %s not detected: %s", nmcs_provider_get_name (provider), error->message);
-		if (dd->detect_count > 0) {
-			/* wait longer. */
-			return;
-		}
+    if (error) {
+        _LOGI("provider %s not detected: %s", nmcs_provider_get_name(provider), error->message);
+        if (dd->detect_count > 0) {
+            /* wait longer. */
+            return;
+        }
 
-		_LOGI ("no provider detected");
-		goto done;
-	}
+        _LOGI("no provider detected");
+        goto done;
+    }
 
-	_LOGI ("provider %s detected", nmcs_provider_get_name (provider));
-	dd->provider_result = g_steal_pointer (&provider);
+    _LOGI("provider %s detected", nmcs_provider_get_name(provider));
+    dd->provider_result = g_steal_pointer(&provider);
 
 done:
-	g_cancellable_cancel (dd->cancellable);
-	g_main_loop_quit (dd->main_loop);
+    g_cancellable_cancel(dd->cancellable);
+    g_main_loop_quit(dd->main_loop);
 }
 
 static void
-_provider_detect_sigterm_cb (GCancellable *source,
-                             gpointer user_data)
+_provider_detect_sigterm_cb(GCancellable *source, gpointer user_data)
 {
-	ProviderDetectData *dd = user_data;
+    ProviderDetectData *dd = user_data;
 
-	g_cancellable_cancel (dd->cancellable);
-	g_clear_object (&dd->provider_result);
-	dd->detect_count = 0;
-	g_main_loop_quit (dd->main_loop);
+    g_cancellable_cancel(dd->cancellable);
+    g_clear_object(&dd->provider_result);
+    dd->detect_count = 0;
+    g_main_loop_quit(dd->main_loop);
 }
 
 static NMCSProvider *
-_provider_detect (GCancellable *sigterm_cancellable)
+_provider_detect(GCancellable *sigterm_cancellable)
 {
-	nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new (NULL, FALSE);
-	gs_unref_object GCancellable *cancellable = g_cancellable_new ();
-	gs_unref_object NMHttpClient *http_client = NULL;
-	ProviderDetectData dd = {
-		.cancellable     = cancellable,
-		.main_loop       = main_loop,
-		.detect_count    = 0,
-		.provider_result = NULL,
-	};
-	const GType gtypes[] = {
-		NMCS_TYPE_PROVIDER_EC2,
-		NMCS_TYPE_PROVIDER_GCP,
-	};
-	int i;
-	gulong cancellable_signal_id;
-
-	cancellable_signal_id = g_cancellable_connect (sigterm_cancellable,
-	                                               G_CALLBACK (_provider_detect_sigterm_cb),
-	                                               &dd,
-	                                               NULL);
-	if (!cancellable_signal_id)
-		goto out;
-
-	http_client = nmcs_wait_for_objects_register (nm_http_client_new ());
-
-	for (i = 0; i < G_N_ELEMENTS (gtypes); i++) {
-		NMCSProvider *provider;
-
-		provider = g_object_new (gtypes[i],
-		                         NMCS_PROVIDER_HTTP_CLIENT, http_client,
-		                         NULL);
-		nmcs_wait_for_objects_register (provider);
-
-		_LOGD ("start detecting %s provider...", nmcs_provider_get_name (provider));
-		dd.detect_count++;
-		nmcs_provider_detect (provider,
-		                      cancellable,
-		                      _provider_detect_cb,
-		                      &dd);
-	}
-
-	if (dd.detect_count > 0)
-		g_main_loop_run (main_loop);
+    nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new(NULL, FALSE);
+    gs_unref_object GCancellable *cancellable    = g_cancellable_new();
+    gs_unref_object NMHttpClient *http_client    = NULL;
+    ProviderDetectData            dd             = {
+        .cancellable     = cancellable,
+        .main_loop       = main_loop,
+        .detect_count    = 0,
+        .provider_result = NULL,
+    };
+    const GType gtypes[] = {
+        NMCS_TYPE_PROVIDER_EC2,
+        NMCS_TYPE_PROVIDER_GCP,
+        NMCS_TYPE_PROVIDER_AZURE,
+    };
+    int    i;
+    gulong cancellable_signal_id;
+
+    cancellable_signal_id = g_cancellable_connect(sigterm_cancellable,
+                                                  G_CALLBACK(_provider_detect_sigterm_cb),
+                                                  &dd,
+                                                  NULL);
+    if (!cancellable_signal_id)
+        goto out;
+
+    http_client = nmcs_wait_for_objects_register(nm_http_client_new());
+
+    for (i = 0; i < G_N_ELEMENTS(gtypes); i++) {
+        NMCSProvider *provider;
+
+        provider = g_object_new(gtypes[i], NMCS_PROVIDER_HTTP_CLIENT, http_client, NULL);
+        nmcs_wait_for_objects_register(provider);
+
+        _LOGD("start detecting %s provider...", nmcs_provider_get_name(provider));
+        dd.detect_count++;
+        nmcs_provider_detect(provider, cancellable, _provider_detect_cb, &dd);
+    }
+
+    if (dd.detect_count > 0)
+        g_main_loop_run(main_loop);
 
 out:
-	nm_clear_g_signal_handler (sigterm_cancellable, &cancellable_signal_id);
-	return dd.provider_result;
+    nm_clear_g_signal_handler(sigterm_cancellable, &cancellable_signal_id);
+    return dd.provider_result;
 }
 
 /*****************************************************************************/
 
 static char **
-_nmc_get_hwaddrs (NMClient *nmc)
+_nmc_get_hwaddrs(NMClient *nmc)
 {
-	gs_unref_ptrarray GPtrArray *hwaddrs = NULL;
-	const GPtrArray *devices;
-	char **hwaddrs_v;
-	gs_free char *str = NULL;
-	guint i;
+    gs_unref_ptrarray GPtrArray *hwaddrs = NULL;
+    const GPtrArray *            devices;
+    char **                      hwaddrs_v;
+    gs_free char *               str = NULL;
+    guint                        i;
 
-	devices = nm_client_get_devices (nmc);
+    devices = nm_client_get_devices(nmc);
 
-	for (i = 0; i < devices->len; i++) {
-		NMDevice *device = devices->pdata[i];
-		const char *hwaddr;
-		char *s;
+    for (i = 0; i < devices->len; i++) {
+        NMDevice *  device = devices->pdata[i];
+        const char *hwaddr;
+        char *      s;
 
-		if (!NM_IS_DEVICE_ETHERNET (device))
-			continue;
+        if (!NM_IS_DEVICE_ETHERNET(device))
+            continue;
 
-		if (nm_device_get_state (device) < NM_DEVICE_STATE_UNAVAILABLE)
-			continue;
+        if (nm_device_get_state(device) < NM_DEVICE_STATE_UNAVAILABLE)
+            continue;
 
-		hwaddr = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device));
-		if (!hwaddr)
-			continue;
+        hwaddr = nm_device_ethernet_get_permanent_hw_address(NM_DEVICE_ETHERNET(device));
+        if (!hwaddr)
+            continue;
 
-		s = nmcs_utils_hwaddr_normalize (hwaddr, -1);
-		if (!s)
-			continue;
+        s = nmcs_utils_hwaddr_normalize(hwaddr, -1);
+        if (!s)
+            continue;
 
-		if (!hwaddrs)
-			hwaddrs = g_ptr_array_new_with_free_func (g_free);
-		g_ptr_array_add (hwaddrs, s);
-	}
+        if (!hwaddrs)
+            hwaddrs = g_ptr_array_new_with_free_func(g_free);
+        g_ptr_array_add(hwaddrs, s);
+    }
 
-	if (!hwaddrs) {
-		_LOGD ("found interfaces: none");
-		return NULL;
-	}
+    if (!hwaddrs) {
+        _LOGD("found interfaces: none");
+        return NULL;
+    }
 
-	g_ptr_array_add (hwaddrs, NULL);
-	hwaddrs_v = (char **) g_ptr_array_free (g_steal_pointer (&hwaddrs), FALSE);
+    g_ptr_array_add(hwaddrs, NULL);
+    hwaddrs_v = (char **) g_ptr_array_free(g_steal_pointer(&hwaddrs), FALSE);
 
-	_LOGD ("found interfaces: %s", (str = g_strjoinv (", ", hwaddrs_v)));
+    _LOGD("found interfaces: %s", (str = g_strjoinv(", ", hwaddrs_v)));
 
-	return hwaddrs_v;
+    return hwaddrs_v;
 }
 
 static NMDevice *
-_nmc_get_device_by_hwaddr (NMClient *nmc,
-                           const char *hwaddr)
+_nmc_get_device_by_hwaddr(NMClient *nmc, const char *hwaddr)
 {
-	const GPtrArray *devices;
-	guint i;
+    const GPtrArray *devices;
+    guint            i;
 
-	devices = nm_client_get_devices (nmc);
+    devices = nm_client_get_devices(nmc);
 
-	for (i = 0; i < devices->len; i++) {
-		NMDevice *device = devices->pdata[i];
-		const char *hwaddr_dev;
-		gs_free char *s = NULL;
+    for (i = 0; i < devices->len; i++) {
+        NMDevice *    device = devices->pdata[i];
+        const char *  hwaddr_dev;
+        gs_free char *s = NULL;
 
-		if (!NM_IS_DEVICE_ETHERNET (device))
-			continue;
+        if (!NM_IS_DEVICE_ETHERNET(device))
+            continue;
 
-		hwaddr_dev = nm_device_ethernet_get_permanent_hw_address (NM_DEVICE_ETHERNET (device));
-		if (!hwaddr_dev)
-			continue;
+        hwaddr_dev = nm_device_ethernet_get_permanent_hw_address(NM_DEVICE_ETHERNET(device));
+        if (!hwaddr_dev)
+            continue;
 
-		s = nmcs_utils_hwaddr_normalize (hwaddr_dev, -1);
-		if (s && nm_streq (s, hwaddr))
-			return device;
-	}
+        s = nmcs_utils_hwaddr_normalize(hwaddr_dev, -1);
+        if (s && nm_streq(s, hwaddr))
+            return device;
+    }
 
-	return NULL;
+    return NULL;
 }
 
 /*****************************************************************************/
 
 typedef struct {
-	GMainLoop *main_loop;
-	GHashTable *config_dict;
+    GMainLoop * main_loop;
+    GHashTable *config_dict;
 } GetConfigData;
 
 static void
-_get_config_cb (GObject *source,
-                GAsyncResult *result,
-                gpointer user_data)
+_get_config_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	GetConfigData *data = user_data;
-	gs_unref_hashtable GHashTable *config_dict = NULL;
-	gs_free_error GError *error = NULL;
+    GetConfigData *    data                    = user_data;
+    gs_unref_hashtable GHashTable *config_dict = NULL;
+    gs_free_error GError *error                = NULL;
 
-	config_dict = nmcs_provider_get_config_finish (NMCS_PROVIDER (source), result, &error);
+    config_dict = nmcs_provider_get_config_finish(NMCS_PROVIDER(source), result, &error);
 
-	if (!config_dict) {
-		if (!nm_utils_error_is_cancelled (error))
-			_LOGI ("failure to get meta data: %s", error->message);
-	} else
-		_LOGD ("meta data received");
+    if (!config_dict) {
+        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);
-	g_main_loop_quit (data->main_loop);
+    data->config_dict = g_steal_pointer(&config_dict);
+    g_main_loop_quit(data->main_loop);
 }
 
 static GHashTable *
-_get_config (GCancellable *sigterm_cancellable,
-             NMCSProvider *provider,
-             NMClient *nmc)
+_get_config(GCancellable *sigterm_cancellable, NMCSProvider *provider, NMClient *nmc)
 {
-	nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new (NULL, FALSE);
-	GetConfigData data = {
-		.main_loop = main_loop,
-	};
-	gs_strfreev char **hwaddrs = NULL;
+    nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new(NULL, FALSE);
+    GetConfigData                      data      = {
+        .main_loop = main_loop,
+    };
+    gs_strfreev char **hwaddrs = NULL;
 
-	hwaddrs = _nmc_get_hwaddrs (nmc);
+    hwaddrs = _nmc_get_hwaddrs(nmc);
 
-	nmcs_provider_get_config (provider,
-	                          TRUE,
-	                          (const char *const*) hwaddrs,
-	                          sigterm_cancellable,
-	                          _get_config_cb,
-	                          &data);
+    nmcs_provider_get_config(provider,
+                             TRUE,
+                             (const char *const *) hwaddrs,
+                             sigterm_cancellable,
+                             _get_config_cb,
+                             &data);
 
-	g_main_loop_run (main_loop);
+    g_main_loop_run(main_loop);
 
-	return data.config_dict;
+    return data.config_dict;
 }
 
 /*****************************************************************************/
 
 static gboolean
-_nmc_skip_connection (NMConnection *connection)
+_nmc_skip_connection(NMConnection *connection)
 {
-	NMSettingUser *s_user;
-	const char *v;
+    NMSettingUser *s_user;
+    const char *   v;
 
-	s_user = NM_SETTING_USER (nm_connection_get_setting (connection, NM_TYPE_SETTING_USER));
-	if (!s_user)
-		return FALSE;
+    s_user = NM_SETTING_USER(nm_connection_get_setting(connection, NM_TYPE_SETTING_USER));
+    if (!s_user)
+        return FALSE;
 
 #define USER_TAG_SKIP "org.freedesktop.nm-cloud-setup.skip"
 
-	nm_assert (nm_setting_user_check_key (USER_TAG_SKIP, NULL));
+    nm_assert(nm_setting_user_check_key(USER_TAG_SKIP, NULL));
 
-	v = nm_setting_user_get_data (s_user, USER_TAG_SKIP);
-	return _nm_utils_ascii_str_to_bool (v, FALSE);
+    v = nm_setting_user_get_data(s_user, USER_TAG_SKIP);
+    return _nm_utils_ascii_str_to_bool(v, FALSE);
 }
 
 static gboolean
-_nmc_mangle_connection (NMDevice *device,
-                        NMConnection *connection,
-                        const NMCSProviderGetConfigIfaceData *config_data,
-                        gboolean *out_changed)
+_nmc_mangle_connection(NMDevice *                            device,
+                       NMConnection *                        connection,
+                       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;
-	gs_unref_ptrarray GPtrArray *addrs_new = NULL;
-	gs_unref_ptrarray GPtrArray *rules_new = NULL;
-	gs_unref_ptrarray GPtrArray *routes_new = NULL;
-
-	if (!nm_streq0 (nm_connection_get_connection_type (connection), NM_SETTING_WIRED_SETTING_NAME))
-		return FALSE;
-
-	s_ip = nm_connection_get_setting_ip4_config (connection);
-	if (!s_ip)
-		return FALSE;
-
-	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 (   config_data->has_ipv4s
-	    && config_data->has_cidr) {
-		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);
-		}
-
-		gateway = nm_utils_ip4_address_clear_host_address (config_data->cidr_addr, config_data->cidr_prefix);
-		((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);
-		nm_ip_route_set_attribute (route_entry,
-		                           NM_IP_ROUTE_ATTRIBUTE_TABLE,
-		                           g_variant_new_uint32 (rt_table));
-		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,
-			                             _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);
-		}
-	}
-
-	for (i = 0; i < config_data->iproutes_len; ++i)
-		g_ptr_array_add (routes_new, config_data->iproutes_arr[i]);
-
-	if (addrs_new->len) {
-		addrs_changed = nmcs_setting_ip_replace_ipv4_addresses (s_ip,
-		                                                        (NMIPAddress **) addrs_new->pdata,
-		                                                        addrs_new->len);
-	}
-
-	if (routes_new->len) {
-		routes_changed = nmcs_setting_ip_replace_ipv4_routes (s_ip,
-		                                                      (NMIPRoute **) routes_new->pdata,
-		                                                      routes_new->len);
-	}
-
-	if (rules_new->len) {
-		rules_changed = nmcs_setting_ip_replace_ipv4_rules (s_ip,
-		                                                    (NMIPRoutingRule **) rules_new->pdata,
-		                                                    rules_new->len);
-	}
-
-	NM_SET_OUT (out_changed,    addrs_changed
-	                         || routes_changed
-	                         || rules_changed);
-	return TRUE;
+    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;
+    gs_unref_ptrarray GPtrArray *addrs_new  = NULL;
+    gs_unref_ptrarray GPtrArray *rules_new  = NULL;
+    gs_unref_ptrarray GPtrArray *routes_new = NULL;
+
+    if (!nm_streq0(nm_connection_get_connection_type(connection), NM_SETTING_WIRED_SETTING_NAME))
+        return FALSE;
+
+    s_ip = nm_connection_get_setting_ip4_config(connection);
+    if (!s_ip)
+        return FALSE;
+
+    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 (config_data->has_ipv4s && config_data->has_cidr) {
+        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);
+        }
+
+        gateway = nm_utils_ip4_address_clear_host_address(config_data->cidr_addr,
+                                                          config_data->cidr_prefix);
+        ((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);
+        nm_ip_route_set_attribute(route_entry,
+                                  NM_IP_ROUTE_ATTRIBUTE_TABLE,
+                                  g_variant_new_uint32(rt_table));
+        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,
+                                        _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);
+        }
+    }
+
+    for (i = 0; i < config_data->iproutes_len; ++i)
+        g_ptr_array_add(routes_new, config_data->iproutes_arr[i]);
+
+    addrs_changed = nmcs_setting_ip_replace_ipv4_addresses(s_ip,
+                                                           (NMIPAddress **) addrs_new->pdata,
+                                                           addrs_new->len);
+
+    routes_changed = nmcs_setting_ip_replace_ipv4_routes(s_ip,
+                                                         (NMIPRoute **) routes_new->pdata,
+                                                         routes_new->len);
+
+    rules_changed = nmcs_setting_ip_replace_ipv4_rules(s_ip,
+                                                       (NMIPRoutingRule **) rules_new->pdata,
+                                                       rules_new->len);
+
+    NM_SET_OUT(out_changed, addrs_changed || routes_changed || rules_changed);
+    return TRUE;
 }
 
 /*****************************************************************************/
 
 static guint
-_config_data_get_num_valid (GHashTable *config_dict)
+_config_data_get_num_valid(GHashTable *config_dict)
 {
-	const NMCSProviderGetConfigIfaceData *config_data;
-	GHashTableIter h_iter;
-	guint n = 0;
+    const NMCSProviderGetConfigIfaceData *config_data;
+    GHashTableIter                        h_iter;
+    guint                                 n = 0;
 
-	g_hash_table_iter_init (&h_iter, config_dict);
-	while (g_hash_table_iter_next (&h_iter, NULL, (gpointer *) &config_data)) {
-		if (nmcs_provider_get_config_iface_data_is_valid (config_data))
-			n++;
-	}
+    g_hash_table_iter_init(&h_iter, config_dict);
+    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;
+    return n;
 }
 
 static gboolean
-_config_one (GCancellable *sigterm_cancellable,
-             NMClient *nmc,
-             gboolean is_single_nic,
-             const char *hwaddr,
-             const NMCSProviderGetConfigIfaceData *config_data)
+_config_one(GCancellable *                        sigterm_cancellable,
+            NMClient *                            nmc,
+            gboolean                              is_single_nic,
+            const char *                          hwaddr,
+            const NMCSProviderGetConfigIfaceData *config_data)
 {
-	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;
-	gboolean version_id_changed;
-	guint try_count;
-	gboolean any_changes = FALSE;
-
-	g_main_context_iteration (NULL, FALSE);
-
-	if (g_cancellable_is_cancelled (sigterm_cancellable))
-		return FALSE;
-
-	device = nm_g_object_ref (_nmc_get_device_by_hwaddr (nmc, hwaddr));
-	if (!device) {
-		_LOGD ("config device %s: skip because device not found", hwaddr);
-		return FALSE;
-	}
-
-	if (!nmcs_provider_get_config_iface_data_is_valid (config_data)) {
-		_LOGD ("config device %s: skip because meta data not successfully fetched", hwaddr);
-		return FALSE;
-	}
-
-	_LOGD ("config device %s: configuring \"%s\" (%s)...",
-	       hwaddr,
-	       nm_device_get_iface (device) ?: "/unknown/",
-	       nm_object_get_path (NM_OBJECT (device)));
-
-	try_count = 0;
+    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;
+    gboolean              version_id_changed;
+    guint                 try_count;
+    gboolean              any_changes = FALSE;
+
+    g_main_context_iteration(NULL, FALSE);
+
+    if (g_cancellable_is_cancelled(sigterm_cancellable))
+        return FALSE;
+
+    device = nm_g_object_ref(_nmc_get_device_by_hwaddr(nmc, hwaddr));
+    if (!device) {
+        _LOGD("config device %s: skip because device not found", hwaddr);
+        return FALSE;
+    }
+
+    if (!nmcs_provider_get_config_iface_data_is_valid(config_data)) {
+        _LOGD("config device %s: skip because meta data not successfully fetched", hwaddr);
+        return FALSE;
+    }
+
+    _LOGD("config device %s: configuring \"%s\" (%s)...",
+          hwaddr,
+          nm_device_get_iface(device) ?: "/unknown/",
+          nm_object_get_path(NM_OBJECT(device)));
+
+    try_count = 0;
 
 try_again:
 
-	applied_connection = nmcs_device_get_applied_connection (device,
-	                                                         sigterm_cancellable,
-	                                                         &applied_version_id,
-	                                                         &error);
-	if (!applied_connection) {
-		if (!nm_utils_error_is_cancelled (error))
-			_LOGD ("config device %s: device has no applied connection (%s). Skip", hwaddr, error->message);
-		return any_changes;
-	}
-
-	if (_nmc_skip_connection (applied_connection)) {
-		_LOGD ("config device %s: skip applied connection due to user data %s", hwaddr, USER_TAG_SKIP);
-		return any_changes;
-	}
-
-	if (!_nmc_mangle_connection (device,
-	                             applied_connection,
-	                             config_data,
-	                             &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));
-		return any_changes;
-	}
-
-	_LOGD ("config device %s: reapply connection \"%s\" (%s)",
-	       hwaddr,
-	       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. */
-	any_changes = TRUE;
-
-	if (!nmcs_device_reapply (device,
-	                          sigterm_cancellable,
-	                          applied_connection,
-	                          applied_version_id,
-	                          &version_id_changed,
-	                          &error)) {
-		if (   version_id_changed
-		    && try_count < 5) {
-			_LOGD ("config device %s: applied connection changed in the meantime. Retry...",
-			       hwaddr);
-			g_clear_object (&applied_connection);
-			g_clear_error (&error);
-			try_count++;
-			goto try_again;
-		}
-
-		if (!nm_utils_error_is_cancelled (error)) {
-			_LOGD ("config device %s: failure to reapply connection \"%s\" (%s): %s",
-			       hwaddr,
-			       nm_connection_get_id (applied_connection),
-			       nm_connection_get_uuid (applied_connection),
-			       error->message);
-		}
-		return any_changes;
-	}
-
-	_LOGD ("config device %s: connection \"%s\" (%s) reapplied",
-	       hwaddr,
-	       nm_connection_get_id (applied_connection),
-	       nm_connection_get_uuid (applied_connection));
-
-	return any_changes;
+    applied_connection = nmcs_device_get_applied_connection(device,
+                                                            sigterm_cancellable,
+                                                            &applied_version_id,
+                                                            &error);
+    if (!applied_connection) {
+        if (!nm_utils_error_is_cancelled(error))
+            _LOGD("config device %s: device has no applied connection (%s). Skip",
+                  hwaddr,
+                  error->message);
+        return any_changes;
+    }
+
+    if (_nmc_skip_connection(applied_connection)) {
+        _LOGD("config device %s: skip applied connection due to user data %s",
+              hwaddr,
+              USER_TAG_SKIP);
+        return any_changes;
+    }
+
+    if (!_nmc_mangle_connection(device, applied_connection, config_data, &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));
+        return any_changes;
+    }
+
+    _LOGD("config device %s: reapply connection \"%s\" (%s)",
+          hwaddr,
+          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. */
+    any_changes = TRUE;
+
+    if (!nmcs_device_reapply(device,
+                             sigterm_cancellable,
+                             applied_connection,
+                             applied_version_id,
+                             &version_id_changed,
+                             &error)) {
+        if (version_id_changed && try_count < 5) {
+            _LOGD("config device %s: applied connection changed in the meantime. Retry...", hwaddr);
+            g_clear_object(&applied_connection);
+            g_clear_error(&error);
+            try_count++;
+            goto try_again;
+        }
+
+        if (!nm_utils_error_is_cancelled(error)) {
+            _LOGD("config device %s: failure to reapply connection \"%s\" (%s): %s",
+                  hwaddr,
+                  nm_connection_get_id(applied_connection),
+                  nm_connection_get_uuid(applied_connection),
+                  error->message);
+        }
+        return any_changes;
+    }
+
+    _LOGD("config device %s: connection \"%s\" (%s) reapplied",
+          hwaddr,
+          nm_connection_get_id(applied_connection),
+          nm_connection_get_uuid(applied_connection));
+
+    return any_changes;
 }
 
 static gboolean
-_config_all (GCancellable *sigterm_cancellable,
-             NMClient *nmc,
-             GHashTable *config_dict)
+_config_all(GCancellable *sigterm_cancellable, NMClient *nmc, GHashTable *config_dict)
 {
-	GHashTableIter h_iter;
-	const NMCSProviderGetConfigIfaceData *c_config_data;
-	const char *c_hwaddr;
-	gboolean is_single_nic;
-	gboolean any_changes = FALSE;
+    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 (config_dict) <= 1);
+    is_single_nic = (_config_data_get_num_valid(config_dict) <= 1);
 
-	g_hash_table_iter_init (&h_iter, config_dict);
-	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;
-	}
+    g_hash_table_iter_init(&h_iter, config_dict);
+    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;
+    }
 
-	return any_changes;
+    return any_changes;
 }
 
 /*****************************************************************************/
 
 static gboolean
-sigterm_handler (gpointer user_data)
+sigterm_handler(gpointer user_data)
 {
-	GCancellable *sigterm_cancellable = user_data;
-
-	if (!g_cancellable_is_cancelled (sigterm_cancellable)) {
-		_LOGD ("SIGTERM received");
-		g_cancellable_cancel (user_data);
-	} else
-		_LOGD ("SIGTERM received (again)");
-	return G_SOURCE_CONTINUE;
+    GCancellable *sigterm_cancellable = user_data;
+
+    if (!g_cancellable_is_cancelled(sigterm_cancellable)) {
+        _LOGD("SIGTERM received");
+        g_cancellable_cancel(user_data);
+    } else
+        _LOGD("SIGTERM received (again)");
+    return G_SOURCE_CONTINUE;
 }
 
 /*****************************************************************************/
 
 int
-main (int argc, const char *const*argv)
+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;
-
-	_nm_logging_enabled_init (g_getenv (NMCS_ENV_VARIABLE ("NM_CLOUD_SETUP_LOG")));
-
-	_LOGD ("nm-cloud-setup %s starting...", NM_DIST_VERSION);
-
-	if (argc != 1) {
-		g_printerr ("%s: no command line arguments supported\n", argv[0]);
-		return EXIT_FAILURE;
-	}
-
-	sigterm_cancellable = g_cancellable_new ();
-
-	sigterm_source = nm_g_source_attach (nm_g_unix_signal_source_new (SIGTERM,
-	                                                                  G_PRIORITY_DEFAULT,
-	                                                                  sigterm_handler,
-	                                                                  sigterm_cancellable,
-	                                                                  NULL),
-	                                     NULL);
-
-	provider = _provider_detect (sigterm_cancellable);
-	if (!provider)
-		goto done;
-
-	nmc_client_new_waitsync (sigterm_cancellable,
-	                         &nmc,
-	                         &error,
-	                         NM_CLIENT_INSTANCE_FLAGS, (guint) NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS,
-	                         NULL);
-
-	nmcs_wait_for_objects_register (nmc);
-	nmcs_wait_for_objects_register (nm_client_get_context_busy_watcher (nmc));
-
-	if (error) {
-		if (!nm_utils_error_is_cancelled (error))
-			_LOGI ("failure to talk to NetworkManager: %s", error->message);
-		goto done;
-	}
-
-	if (!nm_client_get_nm_running (nmc)) {
-		_LOGI ("NetworkManager is not running");
-		goto done;
-	}
-
-	config_dict = _get_config (sigterm_cancellable, provider, nmc);
-	if (!config_dict)
-		goto done;
-
-	if (_config_all (sigterm_cancellable, nmc, config_dict))
-		_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));
+    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;
+
+    _nm_logging_enabled_init(g_getenv(NMCS_ENV_VARIABLE("NM_CLOUD_SETUP_LOG")));
+
+    _LOGD("nm-cloud-setup %s starting...", NM_DIST_VERSION);
+
+    if (argc != 1) {
+        g_printerr("%s: no command line arguments supported\n", argv[0]);
+        return EXIT_FAILURE;
+    }
+
+    sigterm_cancellable = g_cancellable_new();
+
+    sigterm_source = nm_g_source_attach(nm_g_unix_signal_source_new(SIGTERM,
+                                                                    G_PRIORITY_DEFAULT,
+                                                                    sigterm_handler,
+                                                                    sigterm_cancellable,
+                                                                    NULL),
+                                        NULL);
+
+    provider = _provider_detect(sigterm_cancellable);
+    if (!provider)
+        goto done;
+
+    nmc_client_new_waitsync(sigterm_cancellable,
+                            &nmc,
+                            &error,
+                            NM_CLIENT_INSTANCE_FLAGS,
+                            (guint) NM_CLIENT_INSTANCE_FLAGS_NO_AUTO_FETCH_PERMISSIONS,
+                            NULL);
+
+    nmcs_wait_for_objects_register(nmc);
+    nmcs_wait_for_objects_register(nm_client_get_context_busy_watcher(nmc));
+
+    if (error) {
+        if (!nm_utils_error_is_cancelled(error))
+            _LOGI("failure to talk to NetworkManager: %s", error->message);
+        goto done;
+    }
+
+    if (!nm_client_get_nm_running(nmc)) {
+        _LOGI("NetworkManager is not running");
+        goto done;
+    }
+
+    config_dict = _get_config(sigterm_cancellable, provider, nmc);
+    if (!config_dict)
+        goto done;
+
+    if (_config_all(sigterm_cancellable, nmc, config_dict))
+        _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);
-	g_clear_object (&nmc);
-	g_clear_object (&provider);
+    nm_clear_pointer(&config_dict, g_hash_table_unref);
+    g_clear_object(&nmc);
+    g_clear_object(&provider);
 
-	if (!nmcs_wait_for_objects_iterate_until_done (NULL, 2000)) {
-		_LOGE ("shutdown: timeout waiting to application to quit. This is a bug");
-		nm_assert_not_reached ();
-	}
+    if (!nmcs_wait_for_objects_iterate_until_done(NULL, 2000)) {
+        _LOGE("shutdown: timeout waiting to application to quit. This is a bug");
+        nm_assert_not_reached();
+    }
 
-	nm_clear_g_source_inst (&sigterm_source);
-	g_clear_object (&sigterm_cancellable);
+    nm_clear_g_source_inst(&sigterm_source);
+    g_clear_object(&sigterm_cancellable);
 
-	return 0;
+    return 0;
 }
diff --git a/clients/cloud-setup/meson.build b/clients/cloud-setup/meson.build
index 805d4681..c29d73df 100644
--- a/clients/cloud-setup/meson.build
+++ b/clients/cloud-setup/meson.build
@@ -29,6 +29,7 @@ sources = files(
   'nm-http-client.c',
   'nmcs-provider-ec2.c',
   'nmcs-provider-gcp.c',
+  'nmcs-provider-azure.c',
   'nmcs-provider.c',
 )
 
diff --git a/clients/cloud-setup/nm-cloud-setup-utils.c b/clients/cloud-setup/nm-cloud-setup-utils.c
index ff059e7a..0820ed59 100644
--- a/clients/cloud-setup/nm-cloud-setup-utils.c
+++ b/clients/cloud-setup/nm-cloud-setup-utils.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "nm-default.h"
 
@@ -6,91 +6,96 @@
 
 #include "nm-glib-aux/nm-time-utils.h"
 #include "nm-glib-aux/nm-logging-base.h"
+#include "nm-glib-aux/nm-str-buf.h"
 
 /*****************************************************************************/
 
 volatile NMLogLevel _nm_logging_configured_level = LOGL_TRACE;
 
 void
-_nm_logging_enabled_init (const char *level_str)
+_nm_logging_enabled_init(const char *level_str)
 {
-	NMLogLevel level;
+    NMLogLevel level;
 
-	if (!_nm_log_parse_level (level_str, &level))
-		level = LOGL_WARN;
-	else if (level == _LOGL_KEEP)
-		level = LOGL_WARN;
+    if (!_nm_log_parse_level(level_str, &level))
+        level = LOGL_WARN;
+    else if (level == _LOGL_KEEP)
+        level = LOGL_WARN;
 
-	_nm_logging_configured_level = level;
+    _nm_logging_configured_level = level;
 }
 
 void
-_nm_log_impl_cs (NMLogLevel level,
-                 const char *fmt,
-                 ...)
+_nm_log_impl_cs(NMLogLevel level, const char *fmt, ...)
 {
-	gs_free char *msg = NULL;
-	va_list ap;
-	const char *level_str;
-	gint64 ts;
-
-	va_start (ap, fmt);
-	msg = g_strdup_vprintf (fmt, ap);
-	va_end (ap);
-
-	switch (level) {
-	case LOGL_TRACE: level_str = "<trace>"; break;
-	case LOGL_DEBUG: level_str = "<debug>"; break;
-	case LOGL_INFO:  level_str = "<info> "; break;
-	case LOGL_WARN:  level_str = "<warn> "; break;
-	default:
-		nm_assert (level == LOGL_ERR);
-		level_str = "<error>";
-		break;
-	}
-
-	ts = nm_utils_clock_gettime_nsec (CLOCK_BOOTTIME);
-
-	g_print ("[%"G_GINT64_FORMAT".%05"G_GINT64_FORMAT"] %s %s\n",
-	         ts / NM_UTILS_NSEC_PER_SEC,
-	         (ts / (NM_UTILS_NSEC_PER_SEC / 10000)) % 10000,
-	         level_str,
-	         msg);
+    gs_free char *msg = NULL;
+    va_list       ap;
+    const char *  level_str;
+    gint64        ts;
+
+    va_start(ap, fmt);
+    msg = g_strdup_vprintf(fmt, ap);
+    va_end(ap);
+
+    switch (level) {
+    case LOGL_TRACE:
+        level_str = "<trace>";
+        break;
+    case LOGL_DEBUG:
+        level_str = "<debug>";
+        break;
+    case LOGL_INFO:
+        level_str = "<info> ";
+        break;
+    case LOGL_WARN:
+        level_str = "<warn> ";
+        break;
+    default:
+        nm_assert(level == LOGL_ERR);
+        level_str = "<error>";
+        break;
+    }
+
+    ts = nm_utils_clock_gettime_nsec(CLOCK_BOOTTIME);
+
+    g_print("[%" G_GINT64_FORMAT ".%05" G_GINT64_FORMAT "] %s %s\n",
+            ts / NM_UTILS_NSEC_PER_SEC,
+            (ts / (NM_UTILS_NSEC_PER_SEC / 10000)) % 10000,
+            level_str,
+            msg);
 }
 
 void
-_nm_utils_monotonic_timestamp_initialized (const struct timespec *tp,
-                                           gint64 offset_sec,
-                                           gboolean is_boottime)
-{
-}
+_nm_utils_monotonic_timestamp_initialized(const struct timespec *tp,
+                                          gint64                 offset_sec,
+                                          gboolean               is_boottime)
+{}
 
 /*****************************************************************************/
 
-G_LOCK_DEFINE_STATIC  (_wait_for_objects_lock);
+G_LOCK_DEFINE_STATIC(_wait_for_objects_lock);
 static GSList *_wait_for_objects_list;
 static GSList *_wait_for_objects_iterate_loops;
 
 static void
-_wait_for_objects_maybe_quit_mainloops_with_lock (void)
+_wait_for_objects_maybe_quit_mainloops_with_lock(void)
 {
-	GSList *iter;
+    GSList *iter;
 
-	if (!_wait_for_objects_list) {
-		for (iter = _wait_for_objects_iterate_loops; iter; iter = iter->next)
-			g_main_loop_quit (iter->data);
-	}
+    if (!_wait_for_objects_list) {
+        for (iter = _wait_for_objects_iterate_loops; iter; iter = iter->next)
+            g_main_loop_quit(iter->data);
+    }
 }
 
 static void
-_wait_for_objects_weak_cb (gpointer data,
-                           GObject *where_the_object_was)
+_wait_for_objects_weak_cb(gpointer data, GObject *where_the_object_was)
 {
-	G_LOCK (_wait_for_objects_lock);
-	nm_assert (g_slist_find (_wait_for_objects_list, where_the_object_was));
-	_wait_for_objects_list = g_slist_remove (_wait_for_objects_list, where_the_object_was);
-	_wait_for_objects_maybe_quit_mainloops_with_lock ();
-	G_UNLOCK (_wait_for_objects_lock);
+    G_LOCK(_wait_for_objects_lock);
+    nm_assert(g_slist_find(_wait_for_objects_list, where_the_object_was));
+    _wait_for_objects_list = g_slist_remove(_wait_for_objects_list, where_the_object_was);
+    _wait_for_objects_maybe_quit_mainloops_with_lock();
+    G_UNLOCK(_wait_for_objects_lock);
 }
 
 /**
@@ -102,55 +107,53 @@ _wait_for_objects_weak_cb (gpointer data,
  * @target gets destroyed, which means that it gets completely unreferenced.
  */
 gpointer
-nmcs_wait_for_objects_register (gpointer target)
+nmcs_wait_for_objects_register(gpointer target)
 {
-	g_return_val_if_fail (G_IS_OBJECT (target), NULL);
+    g_return_val_if_fail(G_IS_OBJECT(target), NULL);
 
-	G_LOCK (_wait_for_objects_lock);
-	_wait_for_objects_list = g_slist_prepend (_wait_for_objects_list, target);
-	G_UNLOCK (_wait_for_objects_lock);
+    G_LOCK(_wait_for_objects_lock);
+    _wait_for_objects_list = g_slist_prepend(_wait_for_objects_list, target);
+    G_UNLOCK(_wait_for_objects_lock);
 
-	g_object_weak_ref (target,
-	                   _wait_for_objects_weak_cb,
-	                   NULL);
-	return target;
+    g_object_weak_ref(target, _wait_for_objects_weak_cb, NULL);
+    return target;
 }
 
 typedef struct {
-	GMainLoop *loop;
-	gboolean got_timeout;
+    GMainLoop *loop;
+    gboolean   got_timeout;
 } WaitForObjectsData;
 
 static gboolean
-_wait_for_objects_iterate_until_done_timeout_cb (gpointer user_data)
+_wait_for_objects_iterate_until_done_timeout_cb(gpointer user_data)
 {
-	WaitForObjectsData *data = user_data;
+    WaitForObjectsData *data = user_data;
 
-	data->got_timeout = TRUE;
-	g_main_loop_quit (data->loop);
-	return G_SOURCE_CONTINUE;
+    data->got_timeout = TRUE;
+    g_main_loop_quit(data->loop);
+    return G_SOURCE_CONTINUE;
 }
 
 static gboolean
-_wait_for_objects_iterate_until_done_idle_cb (gpointer user_data)
+_wait_for_objects_iterate_until_done_idle_cb(gpointer user_data)
 {
-	/* This avoids a race where:
-	 *
-	 *   - we check whether there are objects to wait for.
-	 *   - the last object to wait for gets removed (issuing g_main_loop_quit()).
-	 *   - we run the mainloop (and missed our signal).
-	 *
-	 * It's really a missing feature of GMainLoop where the "is-running" flag is always set to
-	 * TRUE by g_main_loop_run(). That means, you cannot catch a g_main_loop_quit() in a race
-	 * free way while not iterating the loop.
-	 *
-	 * Avoid this, by checking once again after we start running the mainloop.
-	 */
-
-	G_LOCK (_wait_for_objects_lock);
-	_wait_for_objects_maybe_quit_mainloops_with_lock ();
-	G_UNLOCK (_wait_for_objects_lock);
-	return G_SOURCE_REMOVE;
+    /* This avoids a race where:
+     *
+     *   - we check whether there are objects to wait for.
+     *   - the last object to wait for gets removed (issuing g_main_loop_quit()).
+     *   - we run the mainloop (and missed our signal).
+     *
+     * It's really a missing feature of GMainLoop where the "is-running" flag is always set to
+     * TRUE by g_main_loop_run(). That means, you cannot catch a g_main_loop_quit() in a race
+     * free way while not iterating the loop.
+     *
+     * Avoid this, by checking once again after we start running the mainloop.
+     */
+
+    G_LOCK(_wait_for_objects_lock);
+    _wait_for_objects_maybe_quit_mainloops_with_lock();
+    G_UNLOCK(_wait_for_objects_lock);
+    return G_SOURCE_REMOVE;
 }
 
 /**
@@ -168,211 +171,204 @@ _wait_for_objects_iterate_until_done_idle_cb (gpointer user_data)
  * Returns: %FALSE on timeout or %TRUE if all objects destroyed before timeout.
  */
 gboolean
-nmcs_wait_for_objects_iterate_until_done (GMainContext *context,
-                                          int timeout_msec)
+nmcs_wait_for_objects_iterate_until_done(GMainContext *context, int timeout_msec)
 {
-	nm_auto_unref_gmainloop GMainLoop *loop = g_main_loop_new (context, FALSE);
-	nm_auto_destroy_and_unref_gsource GSource *timeout_source = NULL;
-	WaitForObjectsData data;
-	gboolean has_more_objects;
-
-	G_LOCK (_wait_for_objects_lock);
-	if (!_wait_for_objects_list) {
-		G_UNLOCK (_wait_for_objects_lock);
-		return TRUE;
-	}
-	_wait_for_objects_iterate_loops = g_slist_prepend (_wait_for_objects_iterate_loops, loop);
-	G_UNLOCK (_wait_for_objects_lock);
-
-	data = (WaitForObjectsData) {
-		.loop        = loop,
-		.got_timeout = FALSE,
-	};
-
-	if (timeout_msec >= 0) {
-		timeout_source = nm_g_source_attach (nm_g_timeout_source_new (timeout_msec,
-		                                                              G_PRIORITY_DEFAULT,
-		                                                              _wait_for_objects_iterate_until_done_timeout_cb,
-		                                                              &data,
-		                                                              NULL),
-		                                     context);
-	}
-
-	has_more_objects = TRUE;
-	while (   has_more_objects
-	       && !data.got_timeout) {
-		nm_auto_destroy_and_unref_gsource GSource *idle_source = NULL;
-
-		idle_source = nm_g_source_attach (nm_g_idle_source_new (G_PRIORITY_DEFAULT,
-		                                                        _wait_for_objects_iterate_until_done_idle_cb,
-		                                                        &data,
-		                                                        NULL),
-		                                  context);
-
-		g_main_loop_run (loop);
-
-		G_LOCK (_wait_for_objects_lock);
-		has_more_objects = (!!_wait_for_objects_list);
-		if (   data.got_timeout
-			|| !has_more_objects)
-			_wait_for_objects_iterate_loops = g_slist_remove (_wait_for_objects_iterate_loops, loop);
-		G_UNLOCK (_wait_for_objects_lock);
-	}
-
-	return !data.got_timeout;
+    nm_auto_unref_gmainloop GMainLoop *loop                   = g_main_loop_new(context, FALSE);
+    nm_auto_destroy_and_unref_gsource GSource *timeout_source = NULL;
+    WaitForObjectsData                         data;
+    gboolean                                   has_more_objects;
+
+    G_LOCK(_wait_for_objects_lock);
+    if (!_wait_for_objects_list) {
+        G_UNLOCK(_wait_for_objects_lock);
+        return TRUE;
+    }
+    _wait_for_objects_iterate_loops = g_slist_prepend(_wait_for_objects_iterate_loops, loop);
+    G_UNLOCK(_wait_for_objects_lock);
+
+    data = (WaitForObjectsData){
+        .loop        = loop,
+        .got_timeout = FALSE,
+    };
+
+    if (timeout_msec >= 0) {
+        timeout_source = nm_g_source_attach(
+            nm_g_timeout_source_new(timeout_msec,
+                                    G_PRIORITY_DEFAULT,
+                                    _wait_for_objects_iterate_until_done_timeout_cb,
+                                    &data,
+                                    NULL),
+            context);
+    }
+
+    has_more_objects = TRUE;
+    while (has_more_objects && !data.got_timeout) {
+        nm_auto_destroy_and_unref_gsource GSource *idle_source = NULL;
+
+        idle_source =
+            nm_g_source_attach(nm_g_idle_source_new(G_PRIORITY_DEFAULT,
+                                                    _wait_for_objects_iterate_until_done_idle_cb,
+                                                    &data,
+                                                    NULL),
+                               context);
+
+        g_main_loop_run(loop);
+
+        G_LOCK(_wait_for_objects_lock);
+        has_more_objects = (!!_wait_for_objects_list);
+        if (data.got_timeout || !has_more_objects)
+            _wait_for_objects_iterate_loops = g_slist_remove(_wait_for_objects_iterate_loops, loop);
+        G_UNLOCK(_wait_for_objects_lock);
+    }
+
+    return !data.got_timeout;
 }
 
 /*****************************************************************************/
 
 typedef struct {
-	GTask *task;
-	GSource *source_timeout;
-	GSource *source_next_poll;
-	GMainContext *context;
-	GCancellable *internal_cancellable;
-	NMCSUtilsPollProbeStartFcn probe_start_fcn;
-	NMCSUtilsPollProbeFinishFcn probe_finish_fcn;
-	gpointer probe_user_data;
-	gulong cancellable_id;
-	gint64 last_poll_start_ms;
-	int sleep_timeout_ms;
-	int ratelimit_timeout_ms;
-	bool completed:1;
+    GTask *                     task;
+    GSource *                   source_timeout;
+    GSource *                   source_next_poll;
+    GMainContext *              context;
+    GCancellable *              internal_cancellable;
+    NMCSUtilsPollProbeStartFcn  probe_start_fcn;
+    NMCSUtilsPollProbeFinishFcn probe_finish_fcn;
+    gpointer                    probe_user_data;
+    gulong                      cancellable_id;
+    gint64                      last_poll_start_ms;
+    int                         sleep_timeout_ms;
+    int                         ratelimit_timeout_ms;
+    bool                        completed : 1;
 } PollTaskData;
 
 static void
-_poll_task_data_free (gpointer data)
+_poll_task_data_free(gpointer data)
 {
-	PollTaskData *poll_task_data = data;
+    PollTaskData *poll_task_data = data;
 
-	nm_assert (G_IS_TASK (poll_task_data->task));
-	nm_assert (!poll_task_data->source_next_poll);
-	nm_assert (!poll_task_data->source_timeout);
-	nm_assert (poll_task_data->cancellable_id == 0);
+    nm_assert(G_IS_TASK(poll_task_data->task));
+    nm_assert(!poll_task_data->source_next_poll);
+    nm_assert(!poll_task_data->source_timeout);
+    nm_assert(poll_task_data->cancellable_id == 0);
 
-	g_main_context_unref (poll_task_data->context);
+    g_main_context_unref(poll_task_data->context);
 
-	nm_g_slice_free (poll_task_data);
+    nm_g_slice_free(poll_task_data);
 }
 
 static void
-_poll_return (PollTaskData *poll_task_data,
-              gboolean success,
-              GError *error_take)
+_poll_return(PollTaskData *poll_task_data, GError *error_take)
 {
-	nm_clear_g_source_inst (&poll_task_data->source_next_poll);
-	nm_clear_g_source_inst (&poll_task_data->source_timeout);
-	nm_clear_g_cancellable_disconnect (g_task_get_cancellable (poll_task_data->task),
-	                                   &poll_task_data->cancellable_id);
+    nm_clear_g_source_inst(&poll_task_data->source_next_poll);
+    nm_clear_g_source_inst(&poll_task_data->source_timeout);
+    nm_clear_g_cancellable_disconnect(g_task_get_cancellable(poll_task_data->task),
+                                      &poll_task_data->cancellable_id);
 
-	nm_clear_g_cancellable (&poll_task_data->internal_cancellable);
+    nm_clear_g_cancellable(&poll_task_data->internal_cancellable);
 
-	if (error_take)
-		g_task_return_error (poll_task_data->task, g_steal_pointer (&error_take));
-	else
-		g_task_return_boolean (poll_task_data->task, success);
+    if (error_take)
+        g_task_return_error(poll_task_data->task, g_steal_pointer(&error_take));
+    else
+        g_task_return_boolean(poll_task_data->task, TRUE);
 
-	g_object_unref (poll_task_data->task);
+    g_object_unref(poll_task_data->task);
 }
 
-static gboolean _poll_start_cb (gpointer user_data);
+static gboolean _poll_start_cb(gpointer user_data);
 
 static void
-_poll_done_cb (GObject *source,
-               GAsyncResult *result,
-               gpointer user_data)
+_poll_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	PollTaskData *poll_task_data = user_data;
-	_nm_unused gs_unref_object GTask *task = poll_task_data->task; /* balance ref from _poll_start_cb() */
-	gs_free_error GError *error = NULL;
-	gint64 now_ms;
-	gint64 wait_ms;
-	gboolean is_finished;
-
-	is_finished = poll_task_data->probe_finish_fcn (source,
-	                                                result,
-	                                                poll_task_data->probe_user_data,
-	                                                &error);
-
-	if (nm_utils_error_is_cancelled (error)) {
-		/* we already handle this differently. Nothing to do. */
-		return;
-	}
-
-	if (   error
-	    || is_finished) {
-		_poll_return (poll_task_data, TRUE, g_steal_pointer (&error));
-		return;
-	}
-
-	now_ms = nm_utils_get_monotonic_timestamp_msec ();
-	if (poll_task_data->ratelimit_timeout_ms > 0)
-		wait_ms = (poll_task_data->last_poll_start_ms + poll_task_data->ratelimit_timeout_ms) - now_ms;
-	else
-		wait_ms = 0;
-	if (poll_task_data->sleep_timeout_ms > 0)
-		wait_ms = MAX (wait_ms, poll_task_data->sleep_timeout_ms);
-
-	poll_task_data->source_next_poll = nm_g_source_attach (nm_g_timeout_source_new (MAX (1, wait_ms),
-	                                                                                G_PRIORITY_DEFAULT,
-	                                                                                _poll_start_cb,
-	                                                                                poll_task_data,
-	                                                                                NULL),
-	                                                       poll_task_data->context);
+    PollTaskData *             poll_task_data = user_data;
+    _nm_unused gs_unref_object GTask *task =
+        poll_task_data->task; /* balance ref from _poll_start_cb() */
+    gs_free_error GError *error = NULL;
+    gint64                now_ms;
+    gint64                wait_ms;
+    gboolean              is_finished;
+
+    is_finished =
+        poll_task_data->probe_finish_fcn(source, result, poll_task_data->probe_user_data, &error);
+
+    if (nm_utils_error_is_cancelled(error)) {
+        /* we already handle this differently. Nothing to do. */
+        return;
+    }
+
+    if (error || is_finished) {
+        _poll_return(poll_task_data, g_steal_pointer(&error));
+        return;
+    }
+
+    now_ms = nm_utils_get_monotonic_timestamp_msec();
+    if (poll_task_data->ratelimit_timeout_ms > 0)
+        wait_ms =
+            (poll_task_data->last_poll_start_ms + poll_task_data->ratelimit_timeout_ms) - now_ms;
+    else
+        wait_ms = 0;
+    if (poll_task_data->sleep_timeout_ms > 0)
+        wait_ms = MAX(wait_ms, poll_task_data->sleep_timeout_ms);
+
+    poll_task_data->source_next_poll =
+        nm_g_source_attach(nm_g_timeout_source_new(MAX(1, wait_ms),
+                                                   G_PRIORITY_DEFAULT,
+                                                   _poll_start_cb,
+                                                   poll_task_data,
+                                                   NULL),
+                           poll_task_data->context);
 }
 
 static gboolean
-_poll_start_cb (gpointer user_data)
+_poll_start_cb(gpointer user_data)
 {
-	PollTaskData *poll_task_data = user_data;
+    PollTaskData *poll_task_data = user_data;
 
-	nm_clear_g_source_inst (&poll_task_data->source_next_poll);
+    nm_clear_g_source_inst(&poll_task_data->source_next_poll);
 
-	poll_task_data->last_poll_start_ms = nm_utils_get_monotonic_timestamp_msec ();
+    poll_task_data->last_poll_start_ms = nm_utils_get_monotonic_timestamp_msec();
 
-	g_object_ref (poll_task_data->task); /* balanced by _poll_done_cb() */
+    g_object_ref(poll_task_data->task); /* balanced by _poll_done_cb() */
 
-	poll_task_data->probe_start_fcn (poll_task_data->internal_cancellable,
-	                                 poll_task_data->probe_user_data,
-	                                 _poll_done_cb,
-	                                 poll_task_data);
+    poll_task_data->probe_start_fcn(poll_task_data->internal_cancellable,
+                                    poll_task_data->probe_user_data,
+                                    _poll_done_cb,
+                                    poll_task_data);
 
-	return G_SOURCE_CONTINUE;
+    return G_SOURCE_CONTINUE;
 }
 
 static gboolean
-_poll_timeout_cb (gpointer user_data)
+_poll_timeout_cb(gpointer user_data)
 {
-	PollTaskData *poll_task_data = user_data;
+    PollTaskData *poll_task_data = user_data;
 
-	_poll_return (poll_task_data, FALSE, nm_utils_error_new (NM_UTILS_ERROR_UNKNOWN,
-	                                                         "timeout expired"));
-	return G_SOURCE_CONTINUE;
+    _poll_return(poll_task_data, nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, "timeout expired"));
+    return G_SOURCE_CONTINUE;
 }
 
 static void
-_poll_cancelled_cb (GObject *object, gpointer user_data)
+_poll_cancelled_cb(GObject *object, gpointer user_data)
 {
-	PollTaskData *poll_task_data = user_data;
-	GError *error = NULL;
-
-	_LOGD (">> poll cancelled");
-	nm_clear_g_signal_handler (g_task_get_cancellable (poll_task_data->task),
-	                           &poll_task_data->cancellable_id);
-	nm_utils_error_set_cancelled (&error, FALSE, NULL);
-	_poll_return (poll_task_data, FALSE, error);
+    PollTaskData *poll_task_data = user_data;
+    GError *      error          = NULL;
+
+    nm_clear_g_signal_handler(g_task_get_cancellable(poll_task_data->task),
+                              &poll_task_data->cancellable_id);
+    nm_utils_error_set_cancelled(&error, FALSE, NULL);
+    _poll_return(poll_task_data, error);
 }
 
 /**
  * nmcs_utils_poll:
  * @poll_timeout_ms: if >= 0, then this is the overall timeout for how long we poll.
- *   When this timeout expires, the request completes with failure (but no error set).
+ *   When this timeout expires, the request completes with failure (and error set).
  * @ratelimit_timeout_ms: if > 0, we ratelimit the starts from one prope_start_fcn
  *   call to the next.
  * @sleep_timeout_ms: if > 0, then we wait after a probe finished this timeout
  *   before the next. Together with @ratelimit_timeout_ms this determines how
  *   frequently we probe.
- * @probe_start_fcn: used to start a (asynchrnous) probe. A probe must be completed
+ * @probe_start_fcn: used to start a (asynchronous) probe. A probe must be completed
  *   by calling the provided callback. While a probe is in progress, we will not
  *   start another. This function is already invoked the first time synchronously,
  *   during nmcs_utils_poll().
@@ -388,63 +384,62 @@ _poll_cancelled_cb (GObject *object, gpointer user_data)
  * actions.
  */
 void
-nmcs_utils_poll (int poll_timeout_ms,
-                 int ratelimit_timeout_ms,
-                 int sleep_timeout_ms,
-                 NMCSUtilsPollProbeStartFcn probe_start_fcn,
-                 NMCSUtilsPollProbeFinishFcn probe_finish_fcn,
-                 gpointer probe_user_data,
-                 GCancellable *cancellable,
-                 GAsyncReadyCallback callback,
-                 gpointer user_data)
+nmcs_utils_poll(int                         poll_timeout_ms,
+                int                         ratelimit_timeout_ms,
+                int                         sleep_timeout_ms,
+                NMCSUtilsPollProbeStartFcn  probe_start_fcn,
+                NMCSUtilsPollProbeFinishFcn probe_finish_fcn,
+                gpointer                    probe_user_data,
+                GCancellable *              cancellable,
+                GAsyncReadyCallback         callback,
+                gpointer                    user_data)
 {
-	PollTaskData *poll_task_data;
-
-	poll_task_data = g_slice_new (PollTaskData);
-	*poll_task_data = (PollTaskData) {
-		.task                 = nm_g_task_new (NULL, cancellable, nmcs_utils_poll, callback, user_data),
-		.probe_start_fcn      = probe_start_fcn,
-		.probe_finish_fcn     = probe_finish_fcn,
-		.probe_user_data      = probe_user_data,
-		.completed            = FALSE,
-		.context              = g_main_context_ref_thread_default (),
-		.sleep_timeout_ms     = sleep_timeout_ms,
-		.ratelimit_timeout_ms = ratelimit_timeout_ms,
-		.internal_cancellable = g_cancellable_new (),
-	};
-
-	nmcs_wait_for_objects_register (poll_task_data->task);
-
-	g_task_set_task_data (poll_task_data->task, poll_task_data, _poll_task_data_free);
-
-	if (poll_timeout_ms >= 0) {
-		poll_task_data->source_timeout = nm_g_source_attach (nm_g_timeout_source_new (poll_timeout_ms,
-		                                                                              G_PRIORITY_DEFAULT,
-		                                                                              _poll_timeout_cb,
-		                                                                              poll_task_data,
-		                                                                              NULL),
-		                                                     poll_task_data->context);
-	}
-
-	poll_task_data->source_next_poll = nm_g_source_attach (nm_g_idle_source_new (G_PRIORITY_DEFAULT,
-	                                                                             _poll_start_cb,
-	                                                                             poll_task_data,
-	                                                                             NULL),
-	                                                       poll_task_data->context);
-
-	if (cancellable) {
-		gulong signal_id;
-
-		signal_id = g_cancellable_connect (cancellable,
-		                                   G_CALLBACK (_poll_cancelled_cb),
-		                                   poll_task_data,
-		                                   NULL);
-		if (signal_id == 0) {
-			/* the request is already cancelled. Return. */
-			return;
-		}
-		poll_task_data->cancellable_id = signal_id;
-	}
+    PollTaskData *poll_task_data;
+
+    poll_task_data  = g_slice_new(PollTaskData);
+    *poll_task_data = (PollTaskData){
+        .task             = nm_g_task_new(NULL, cancellable, nmcs_utils_poll, callback, user_data),
+        .probe_start_fcn  = probe_start_fcn,
+        .probe_finish_fcn = probe_finish_fcn,
+        .probe_user_data  = probe_user_data,
+        .completed        = FALSE,
+        .context          = g_main_context_ref_thread_default(),
+        .sleep_timeout_ms = sleep_timeout_ms,
+        .ratelimit_timeout_ms = ratelimit_timeout_ms,
+        .internal_cancellable = g_cancellable_new(),
+    };
+
+    nmcs_wait_for_objects_register(poll_task_data->task);
+
+    g_task_set_task_data(poll_task_data->task, poll_task_data, _poll_task_data_free);
+
+    if (poll_timeout_ms >= 0) {
+        poll_task_data->source_timeout =
+            nm_g_source_attach(nm_g_timeout_source_new(poll_timeout_ms,
+                                                       G_PRIORITY_DEFAULT,
+                                                       _poll_timeout_cb,
+                                                       poll_task_data,
+                                                       NULL),
+                               poll_task_data->context);
+    }
+
+    poll_task_data->source_next_poll = nm_g_source_attach(
+        nm_g_idle_source_new(G_PRIORITY_DEFAULT, _poll_start_cb, poll_task_data, NULL),
+        poll_task_data->context);
+
+    if (cancellable) {
+        gulong signal_id;
+
+        signal_id = g_cancellable_connect(cancellable,
+                                          G_CALLBACK(_poll_cancelled_cb),
+                                          poll_task_data,
+                                          NULL);
+        if (signal_id == 0) {
+            /* the request is already cancelled. Return. */
+            return;
+        }
+        poll_task_data->cancellable_id = signal_id;
+    }
 }
 
 /**
@@ -459,378 +454,376 @@ nmcs_utils_poll (int poll_timeout_ms,
  *   %FALSE will be returned.
  *   If the probe returned a failure, this returns %FALSE and the error
  *   provided by @probe_finish_fcn.
- *   If the request times out, this returns %FALSE without error set.
+ *   If the request times out, this returns %FALSE with error set.
+ *   Error is always set if (and only if) the function returns %FALSE.
  */
 gboolean
-nmcs_utils_poll_finish (GAsyncResult *result,
-                        gpointer *probe_user_data,
-                        GError **error)
+nmcs_utils_poll_finish(GAsyncResult *result, gpointer *probe_user_data, GError **error)
 {
-	GTask *task;
-	PollTaskData *poll_task_data;
+    GTask *       task;
+    PollTaskData *poll_task_data;
 
-	g_return_val_if_fail (nm_g_task_is_valid (result, NULL, nmcs_utils_poll), FALSE);
-	g_return_val_if_fail (!error || !*error, FALSE);
+    g_return_val_if_fail(nm_g_task_is_valid(result, NULL, nmcs_utils_poll), FALSE);
+    g_return_val_if_fail(!error || !*error, FALSE);
 
-	task = G_TASK (result);
+    task = G_TASK(result);
 
-	if (probe_user_data) {
-		poll_task_data = g_task_get_task_data (task);
-		NM_SET_OUT (probe_user_data, poll_task_data->probe_user_data);
-	}
+    if (probe_user_data) {
+        poll_task_data = g_task_get_task_data(task);
+        NM_SET_OUT(probe_user_data, poll_task_data->probe_user_data);
+    }
 
-	return g_task_propagate_boolean (task, error);
+    return g_task_propagate_boolean(task, error);
 }
 
 /*****************************************************************************/
 
 char *
-nmcs_utils_hwaddr_normalize (const char *hwaddr, gssize len)
+nmcs_utils_hwaddr_normalize(const char *hwaddr, gssize len)
 {
-	gs_free char *hwaddr_clone = NULL;
-	guint8 buf[ETH_ALEN];
-
-	nm_assert (len >= -1);
-
-	if (len < 0) {
-		if (!hwaddr)
-			return NULL;
-	} else {
-		if (len == 0)
-			return NULL;
-		nm_assert (hwaddr);
-		hwaddr = nm_strndup_a (300, hwaddr, len, &hwaddr_clone);
-	}
-
-	if (!nm_utils_hwaddr_aton (hwaddr, buf, sizeof (buf)))
-		return NULL;
-
-	return nm_utils_hwaddr_ntoa (buf, sizeof (buf));
+    gs_free char *hwaddr_clone = NULL;
+    guint8        buf[ETH_ALEN];
+
+    nm_assert(len >= -1);
+
+    if (len < 0) {
+        if (!hwaddr)
+            return NULL;
+    } else {
+        if (len == 0)
+            return NULL;
+        nm_assert(hwaddr);
+        hwaddr = nm_strndup_a(300, hwaddr, len, &hwaddr_clone);
+    }
+    /* we cannot use _nm_utils_hwaddr_aton() because that requires a delimiter.
+     * Azure exposes MAC addresses without delimiter, so accept that too. */
+    if (!nm_utils_hexstr2bin_full(hwaddr,
+                                  FALSE,
+                                  FALSE,
+                                  FALSE,
+                                  ":-",
+                                  sizeof(buf),
+                                  buf,
+                                  sizeof(buf),
+                                  NULL))
+        return NULL;
+
+    return nm_utils_hwaddr_ntoa(buf, sizeof(buf));
 }
 
 /*****************************************************************************/
 
 const char *
-nmcs_utils_parse_memmem (GBytes *mem, const char *needle)
+nmcs_utils_parse_memmem(GBytes *mem, const char *needle)
 {
-	const char *mem_data;
-	gsize mem_size;
+    const char *mem_data;
+    gsize       mem_size;
 
-	g_return_val_if_fail (mem, NULL);
-	g_return_val_if_fail (needle, NULL);
+    g_return_val_if_fail(mem, NULL);
+    g_return_val_if_fail(needle, NULL);
 
-	mem_data = g_bytes_get_data (mem, &mem_size);
-	return memmem (mem_data, mem_size, needle, strlen (needle));
+    mem_data = g_bytes_get_data(mem, &mem_size);
+    return memmem(mem_data, mem_size, needle, strlen(needle));
 }
 
 const char *
-nmcs_utils_parse_get_full_line (GBytes *mem, const char *needle)
+nmcs_utils_parse_get_full_line(GBytes *mem, const char *needle)
 {
-	const char *mem_data;
-	gsize mem_size;
-	gsize c;
-	gsize l;
+    const char *mem_data;
+    gsize       mem_size;
+    gsize       c;
+    gsize       l;
 
-	const char *line;
+    const char *line;
 
-	line = nmcs_utils_parse_memmem (mem, needle);
-	if (!line)
-		return NULL;
+    line = nmcs_utils_parse_memmem(mem, needle);
+    if (!line)
+        return NULL;
 
-	mem_data = g_bytes_get_data (mem, &mem_size);
+    mem_data = g_bytes_get_data(mem, &mem_size);
 
-	if (   line != mem_data
-	    && line[-1] != '\n') {
-		/* the line must be preceeded either by the begin of the data or
-		 * by a newline. */
-		return NULL;
-	}
+    if (line != mem_data && line[-1] != '\n') {
+        /* the line must be preceeded either by the begin of the data or
+         * by a newline. */
+        return NULL;
+    }
 
-	c = mem_size - (line - mem_data);
-	l = strlen (needle);
+    c = mem_size - (line - mem_data);
+    l = strlen(needle);
 
-	if (   c != l
-	    && line[l] != '\n') {
-		/* the end of the needle must be either a newline or the end of the buffer. */
-		return NULL;
-	}
+    if (c != l && line[l] != '\n') {
+        /* the end of the needle must be either a newline or the end of the buffer. */
+        return NULL;
+    }
 
-	return line;
+    return line;
 }
 
 /*****************************************************************************/
 
 char *
-nmcs_utils_uri_build_concat_v (const char *base,
-                               const char **components,
-                               gsize n_components)
+nmcs_utils_uri_build_concat_v(const char *base, const char **components, gsize n_components)
 {
-	GString *uri;
-
-	nm_assert (base);
-	nm_assert (base[0]);
-	nm_assert (!NM_STR_HAS_SUFFIX (base, "/"));
-
-	uri = g_string_sized_new (100);
-
-	g_string_append (uri, base);
-
-	if (   n_components > 0
-	    && components[0]
-	    && components[0][0] == '/') {
-		/* the first component starts with a slash. We allow that, and don't add a duplicate
-		 * slash. Otherwise, we add a separator after base.
-		 *
-		 * We only do that for the first component. */
-	} else
-		g_string_append_c (uri, '/');
-
-	while (n_components > 0) {
-		if (!components[0]) {
-			/* we allow NULL, to indicate nothing to append*/
-		} else
-			g_string_append (uri, components[0]);
-		components++;
-		n_components--;
-	}
-
-	return g_string_free (uri, FALSE);
+    NMStrBuf strbuf = NM_STR_BUF_INIT(NM_UTILS_GET_NEXT_REALLOC_SIZE_104, FALSE);
+
+    nm_assert(base);
+    nm_assert(base[0]);
+    nm_assert(!NM_STR_HAS_SUFFIX(base, "/"));
+
+    nm_str_buf_append(&strbuf, base);
+
+    if (n_components > 0 && components[0] && components[0][0] == '/') {
+        /* the first component starts with a slash. We allow that, and don't add a duplicate
+         * slash. Otherwise, we add a separator after base.
+         *
+         * We only do that for the first component. */
+    } else
+        nm_str_buf_append_c(&strbuf, '/');
+
+    while (n_components > 0) {
+        if (!components[0]) {
+            /* we allow NULL, to indicate nothing to append */
+        } else
+            nm_str_buf_append(&strbuf, components[0]);
+        components++;
+        n_components--;
+    }
+
+    return nm_str_buf_finalize(&strbuf, NULL);
 }
 
 /*****************************************************************************/
 
 gboolean
-nmcs_setting_ip_replace_ipv4_addresses (NMSettingIPConfig *s_ip,
-                                        NMIPAddress **entries_arr,
-                                        guint entries_len)
+nmcs_setting_ip_replace_ipv4_addresses(NMSettingIPConfig *s_ip,
+                                       NMIPAddress **     entries_arr,
+                                       guint              entries_len)
 {
-	gboolean any_changes = FALSE;
-	guint i_next;
-	guint num;
-	guint i;
-
-	num = nm_setting_ip_config_get_num_addresses (s_ip);
-
-	i_next = 0;
-
-	for (i = 0; i < entries_len; i++) {
-		NMIPAddress *entry = entries_arr[i];
-
-		if (!any_changes) {
-			if (i_next < num) {
-				if (nm_ip_address_cmp_full (entry,
-				                            nm_setting_ip_config_get_address (s_ip, i_next),
-				                            NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS) == 0) {
-					i_next++;
-					continue;
-				}
-			}
-			while (i_next < num)
-				nm_setting_ip_config_remove_address (s_ip, --num);
-			any_changes = TRUE;
-		}
-
-		if (!nm_setting_ip_config_add_address (s_ip, entry))
-			continue;
-
-		i_next++;
-	}
-	if (any_changes) {
-		while (i_next < num) {
-			nm_setting_ip_config_remove_address (s_ip, --num);
-			any_changes = TRUE;
-		}
-	}
-
-	return any_changes;
+    gboolean any_changes = FALSE;
+    guint    i_next;
+    guint    num;
+    guint    i;
+
+    num = nm_setting_ip_config_get_num_addresses(s_ip);
+
+    i_next = 0;
+
+    for (i = 0; i < entries_len; i++) {
+        NMIPAddress *entry = entries_arr[i];
+
+        if (!any_changes) {
+            if (i_next < num) {
+                if (nm_ip_address_cmp_full(entry,
+                                           nm_setting_ip_config_get_address(s_ip, i_next),
+                                           NM_IP_ADDRESS_CMP_FLAGS_WITH_ATTRS)
+                    == 0) {
+                    i_next++;
+                    continue;
+                }
+            }
+            while (i_next < num)
+                nm_setting_ip_config_remove_address(s_ip, --num);
+            any_changes = TRUE;
+        }
+
+        if (!nm_setting_ip_config_add_address(s_ip, entry))
+            continue;
+
+        i_next++;
+    }
+    if (any_changes) {
+        while (i_next < num) {
+            nm_setting_ip_config_remove_address(s_ip, --num);
+            any_changes = TRUE;
+        }
+    }
+
+    return any_changes;
 }
 
 gboolean
-nmcs_setting_ip_replace_ipv4_routes (NMSettingIPConfig *s_ip,
-                                     NMIPRoute **entries_arr,
-                                     guint entries_len)
+nmcs_setting_ip_replace_ipv4_routes(NMSettingIPConfig *s_ip,
+                                    NMIPRoute **       entries_arr,
+                                    guint              entries_len)
 {
-	gboolean any_changes = FALSE;
-	guint i_next;
-	guint num;
-	guint i;
-
-	num = nm_setting_ip_config_get_num_routes (s_ip);
-
-	i_next = 0;
-
-	for (i = 0; i < entries_len; i++) {
-		NMIPRoute *entry = entries_arr[i];
-
-		if (!any_changes) {
-			if (i_next < num) {
-				if (nm_ip_route_equal_full (entry,
-				                            nm_setting_ip_config_get_route (s_ip, i_next),
-				                            NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS)) {
-					i_next++;
-					continue;
-				}
-			}
-			while (i_next < num)
-				nm_setting_ip_config_remove_route (s_ip, --num);
-			any_changes = TRUE;
-		}
-
-		if (!nm_setting_ip_config_add_route (s_ip, entry))
-			continue;
-
-		i_next++;
-	}
-	if (!any_changes) {
-		while (i_next < num) {
-			nm_setting_ip_config_remove_route (s_ip, --num);
-			any_changes = TRUE;
-		}
-	}
-
-	return any_changes;
+    gboolean any_changes = FALSE;
+    guint    i_next;
+    guint    num;
+    guint    i;
+
+    num = nm_setting_ip_config_get_num_routes(s_ip);
+
+    i_next = 0;
+
+    for (i = 0; i < entries_len; i++) {
+        NMIPRoute *entry = entries_arr[i];
+
+        if (!any_changes) {
+            if (i_next < num) {
+                if (nm_ip_route_equal_full(entry,
+                                           nm_setting_ip_config_get_route(s_ip, i_next),
+                                           NM_IP_ROUTE_EQUAL_CMP_FLAGS_WITH_ATTRS)) {
+                    i_next++;
+                    continue;
+                }
+            }
+            while (i_next < num)
+                nm_setting_ip_config_remove_route(s_ip, --num);
+            any_changes = TRUE;
+        }
+
+        if (!nm_setting_ip_config_add_route(s_ip, entry))
+            continue;
+
+        i_next++;
+    }
+    if (!any_changes) {
+        while (i_next < num) {
+            nm_setting_ip_config_remove_route(s_ip, --num);
+            any_changes = TRUE;
+        }
+    }
+
+    return any_changes;
 }
 
 gboolean
-nmcs_setting_ip_replace_ipv4_rules (NMSettingIPConfig *s_ip,
-                                    NMIPRoutingRule **entries_arr,
-                                    guint entries_len)
+nmcs_setting_ip_replace_ipv4_rules(NMSettingIPConfig *s_ip,
+                                   NMIPRoutingRule ** entries_arr,
+                                   guint              entries_len)
 {
-	gboolean any_changes = FALSE;
-	guint i_next;
-	guint num;
-	guint i;
-
-	num = nm_setting_ip_config_get_num_routing_rules (s_ip);
-
-	i_next = 0;
-
-	for (i = 0; i < entries_len; i++) {
-		NMIPRoutingRule *entry = entries_arr[i];
-
-		if (!any_changes) {
-			if (i_next < num) {
-				if (nm_ip_routing_rule_cmp (entry,
-				                            nm_setting_ip_config_get_routing_rule (s_ip, i_next)) == 0) {
-					i_next++;
-					continue;
-				}
-			}
-			while (i_next < num)
-				nm_setting_ip_config_remove_routing_rule (s_ip, --num);
-			any_changes = TRUE;
-		}
-
-		nm_setting_ip_config_add_routing_rule (s_ip, entry);
-		i_next++;
-	}
-	if (!any_changes) {
-		while (i_next < num) {
-			nm_setting_ip_config_remove_routing_rule (s_ip, --num);
-			any_changes = TRUE;
-		}
-	}
-
-	return any_changes;
+    gboolean any_changes = FALSE;
+    guint    i_next;
+    guint    num;
+    guint    i;
+
+    num = nm_setting_ip_config_get_num_routing_rules(s_ip);
+
+    i_next = 0;
+
+    for (i = 0; i < entries_len; i++) {
+        NMIPRoutingRule *entry = entries_arr[i];
+
+        if (!any_changes) {
+            if (i_next < num) {
+                if (nm_ip_routing_rule_cmp(entry,
+                                           nm_setting_ip_config_get_routing_rule(s_ip, i_next))
+                    == 0) {
+                    i_next++;
+                    continue;
+                }
+            }
+            while (i_next < num)
+                nm_setting_ip_config_remove_routing_rule(s_ip, --num);
+            any_changes = TRUE;
+        }
+
+        nm_setting_ip_config_add_routing_rule(s_ip, entry);
+        i_next++;
+    }
+    if (!any_changes) {
+        while (i_next < num) {
+            nm_setting_ip_config_remove_routing_rule(s_ip, --num);
+            any_changes = TRUE;
+        }
+    }
+
+    return any_changes;
 }
 
 /*****************************************************************************/
 
 typedef struct {
-	GMainLoop *main_loop;
-	NMConnection *connection;
-	GError *error;
-	guint64 version_id;
+    GMainLoop *   main_loop;
+    NMConnection *connection;
+    GError *      error;
+    guint64       version_id;
 } DeviceGetAppliedConnectionData;
 
 static void
-_nmcs_device_get_applied_connection_cb (GObject *source,
-                                        GAsyncResult *result,
-                                        gpointer user_data)
+_nmcs_device_get_applied_connection_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	DeviceGetAppliedConnectionData *data = user_data;
+    DeviceGetAppliedConnectionData *data = user_data;
 
-	data->connection = nm_device_get_applied_connection_finish (NM_DEVICE (source),
-	                                                            result,
-	                                                            &data->version_id,
-	                                                            &data->error);
-	g_main_loop_quit (data->main_loop);
+    data->connection = nm_device_get_applied_connection_finish(NM_DEVICE(source),
+                                                               result,
+                                                               &data->version_id,
+                                                               &data->error);
+    g_main_loop_quit(data->main_loop);
 }
 
 NMConnection *
-nmcs_device_get_applied_connection (NMDevice *device,
-                                    GCancellable *cancellable,
-                                    guint64 *version_id,
-                                    GError **error)
+nmcs_device_get_applied_connection(NMDevice *    device,
+                                   GCancellable *cancellable,
+                                   guint64 *     version_id,
+                                   GError **     error)
 {
-	nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new (NULL, FALSE);
-	DeviceGetAppliedConnectionData data = {
-		.main_loop = main_loop,
-	};
-
-	nm_device_get_applied_connection_async (device,
-	                                        0,
-	                                        cancellable,
-	                                        _nmcs_device_get_applied_connection_cb,
-	                                        &data);
-
-	g_main_loop_run (main_loop);
-
-	if (data.error)
-		g_propagate_error (error, data.error);
-	NM_SET_OUT (version_id, data.version_id);
-	return data.connection;
+    nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new(NULL, FALSE);
+    DeviceGetAppliedConnectionData     data      = {
+        .main_loop = main_loop,
+    };
+
+    nm_device_get_applied_connection_async(device,
+                                           0,
+                                           cancellable,
+                                           _nmcs_device_get_applied_connection_cb,
+                                           &data);
+
+    g_main_loop_run(main_loop);
+
+    if (data.error)
+        g_propagate_error(error, data.error);
+    NM_SET_OUT(version_id, data.version_id);
+    return data.connection;
 }
 
 /*****************************************************************************/
 
 typedef struct {
-	GMainLoop *main_loop;
-	GError *error;
+    GMainLoop *main_loop;
+    GError *   error;
 } DeviceReapplyData;
 
 static void
-_nmcs_device_reapply_cb (GObject *source,
-                         GAsyncResult *result,
-                         gpointer user_data)
+_nmcs_device_reapply_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	DeviceReapplyData *data = user_data;
+    DeviceReapplyData *data = user_data;
 
-	nm_device_reapply_finish (NM_DEVICE (source),
-	                          result,
-	                          &data->error);
-	g_main_loop_quit (data->main_loop);
+    nm_device_reapply_finish(NM_DEVICE(source), result, &data->error);
+    g_main_loop_quit(data->main_loop);
 }
 
 gboolean
-nmcs_device_reapply (NMDevice *device,
-                     GCancellable *sigterm_cancellable,
-                     NMConnection *connection,
-                     guint64 version_id,
-                     gboolean *out_version_id_changed,
-                     GError **error)
+nmcs_device_reapply(NMDevice *    device,
+                    GCancellable *sigterm_cancellable,
+                    NMConnection *connection,
+                    guint64       version_id,
+                    gboolean *    out_version_id_changed,
+                    GError **     error)
 {
-	nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new (NULL, FALSE);
-	DeviceReapplyData data = {
-		.main_loop = main_loop,
-	};
-
-	nm_device_reapply_async (device,
-	                         connection,
-	                         version_id,
-	                         0,
-	                         sigterm_cancellable,
-	                         _nmcs_device_reapply_cb,
-	                         &data);
-
-	g_main_loop_run (main_loop);
-
-	if (data.error) {
-		NM_SET_OUT (out_version_id_changed, g_error_matches (data.error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_VERSION_ID_MISMATCH));
-		g_propagate_error (error, data.error);
-		return FALSE;
-	}
-
-	NM_SET_OUT (out_version_id_changed, FALSE);
-	return TRUE;
+    nm_auto_unref_gmainloop GMainLoop *main_loop = g_main_loop_new(NULL, FALSE);
+    DeviceReapplyData                  data      = {
+        .main_loop = main_loop,
+    };
+
+    nm_device_reapply_async(device,
+                            connection,
+                            version_id,
+                            0,
+                            sigterm_cancellable,
+                            _nmcs_device_reapply_cb,
+                            &data);
+
+    g_main_loop_run(main_loop);
+
+    if (data.error) {
+        NM_SET_OUT(
+            out_version_id_changed,
+            g_error_matches(data.error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_VERSION_ID_MISMATCH));
+        g_propagate_error(error, data.error);
+        return FALSE;
+    }
+
+    NM_SET_OUT(out_version_id_changed, FALSE);
+    return TRUE;
 }
diff --git a/clients/cloud-setup/nm-cloud-setup-utils.h b/clients/cloud-setup/nm-cloud-setup-utils.h
index 7c3e267a..6980e752 100644
--- a/clients/cloud-setup/nm-cloud-setup-utils.h
+++ b/clients/cloud-setup/nm-cloud-setup-utils.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #ifndef __NM_CLOUD_SETUP_UTILS_H__
 #define __NM_CLOUD_SETUP_UTILS_H__
@@ -9,119 +9,114 @@
 
 /* mark names for  variables that can be used as configuration. Search
  * for NMCS_ENV_VARIABLE() to find all honored environment variables. */
-#define NMCS_ENV_VARIABLE(var) ""var""
+#define NMCS_ENV_VARIABLE(var) "" var ""
 
 /*****************************************************************************/
 
 extern volatile NMLogLevel _nm_logging_configured_level;
 
 static inline gboolean
-nm_logging_enabled (NMLogLevel level)
+nm_logging_enabled(NMLogLevel level)
 {
-	return level >= _nm_logging_configured_level;
+    return level >= _nm_logging_configured_level;
 }
 
-void _nm_logging_enabled_init (const char *level_str);
+void _nm_logging_enabled_init(const char *level_str);
 
-void _nm_log_impl_cs (NMLogLevel level,
-                      const char *fmt,
-                      ...) _nm_printf (2, 3);
+void _nm_log_impl_cs(NMLogLevel level, const char *fmt, ...) _nm_printf(2, 3);
 
-#define _nm_log(level, ...) \
-	_nm_log_impl_cs ((level), __VA_ARGS__);
+#define _nm_log(level, ...) _nm_log_impl_cs((level), __VA_ARGS__);
 
-#define _NMLOG(level, ...) \
-	G_STMT_START { \
-		const NMLogLevel _level = (level); \
-		\
-		if (nm_logging_enabled (_level)) { \
-			_nm_log (_level, __VA_ARGS__); \
-		} \
-	} G_STMT_END
+#define _NMLOG(level, ...)                 \
+    G_STMT_START                           \
+    {                                      \
+        const NMLogLevel _level = (level); \
+                                           \
+        if (nm_logging_enabled(_level)) {  \
+            _nm_log(_level, __VA_ARGS__);  \
+        }                                  \
+    }                                      \
+    G_STMT_END
 
 /*****************************************************************************/
 
 #ifndef NM_DIST_VERSION
-#define NM_DIST_VERSION VERSION
+    #define NM_DIST_VERSION VERSION
 #endif
 
 /*****************************************************************************/
 
-gpointer nmcs_wait_for_objects_register (gpointer target);
+gpointer nmcs_wait_for_objects_register(gpointer target);
 
-gboolean nmcs_wait_for_objects_iterate_until_done (GMainContext *context,
-                                                   int timeout_msec);
+gboolean nmcs_wait_for_objects_iterate_until_done(GMainContext *context, int timeout_msec);
 
 /*****************************************************************************/
 
-typedef void (*NMCSUtilsPollProbeStartFcn) (GCancellable *cancellable,
-                                            gpointer probe_user_data,
-                                            GAsyncReadyCallback callback,
-                                            gpointer user_data);
-
-typedef gboolean (*NMCSUtilsPollProbeFinishFcn) (GObject *source,
-                                                 GAsyncResult *result,
-                                                 gpointer probe_user_data,
-                                                 GError **error);
-
-void nmcs_utils_poll (int poll_timeout_ms,
-                      int ratelimit_timeout_ms,
-                      int sleep_timeout_ms,
-                      NMCSUtilsPollProbeStartFcn probe_start_fcn,
-                      NMCSUtilsPollProbeFinishFcn probe_finish_fcn,
-                      gpointer probe_user_data,
-                      GCancellable *cancellable,
-                      GAsyncReadyCallback callback,
-                      gpointer user_data);
-
-gboolean nmcs_utils_poll_finish (GAsyncResult *result,
-                                 gpointer *probe_user_data,
-                                 GError **error);
+typedef void (*NMCSUtilsPollProbeStartFcn)(GCancellable *      cancellable,
+                                           gpointer            probe_user_data,
+                                           GAsyncReadyCallback callback,
+                                           gpointer            user_data);
+
+typedef gboolean (*NMCSUtilsPollProbeFinishFcn)(GObject *     source,
+                                                GAsyncResult *result,
+                                                gpointer      probe_user_data,
+                                                GError **     error);
+
+void nmcs_utils_poll(int                         poll_timeout_ms,
+                     int                         ratelimit_timeout_ms,
+                     int                         sleep_timeout_ms,
+                     NMCSUtilsPollProbeStartFcn  probe_start_fcn,
+                     NMCSUtilsPollProbeFinishFcn probe_finish_fcn,
+                     gpointer                    probe_user_data,
+                     GCancellable *              cancellable,
+                     GAsyncReadyCallback         callback,
+                     gpointer                    user_data);
+
+gboolean nmcs_utils_poll_finish(GAsyncResult *result, gpointer *probe_user_data, GError **error);
 
 /*****************************************************************************/
 
-char *nmcs_utils_hwaddr_normalize (const char *hwaddr, gssize len);
+char *nmcs_utils_hwaddr_normalize(const char *hwaddr, gssize len);
 
 /*****************************************************************************/
 
-const char *nmcs_utils_parse_memmem (GBytes *mem, const char *needle);
+const char *nmcs_utils_parse_memmem(GBytes *mem, const char *needle);
 
-const char *nmcs_utils_parse_get_full_line (GBytes *mem, const char *needle);
+const char *nmcs_utils_parse_get_full_line(GBytes *mem, const char *needle);
 
 /*****************************************************************************/
 
-char *nmcs_utils_uri_build_concat_v (const char *base,
-                                     const char **components,
-                                     gsize n_components);
+char *nmcs_utils_uri_build_concat_v(const char *base, const char **components, gsize n_components);
 
-#define nmcs_utils_uri_build_concat(base, ...) nmcs_utils_uri_build_concat_v (base, ((const char *[]) { __VA_ARGS__ }), NM_NARG (__VA_ARGS__))
+#define nmcs_utils_uri_build_concat(base, ...) \
+    nmcs_utils_uri_build_concat_v(base, ((const char *[]){__VA_ARGS__}), NM_NARG(__VA_ARGS__))
 
 /*****************************************************************************/
 
-gboolean nmcs_setting_ip_replace_ipv4_addresses (NMSettingIPConfig *s_ip,
-                                                 NMIPAddress **entries_arr,
-                                                 guint entries_len);
+gboolean nmcs_setting_ip_replace_ipv4_addresses(NMSettingIPConfig *s_ip,
+                                                NMIPAddress **     entries_arr,
+                                                guint              entries_len);
 
-gboolean nmcs_setting_ip_replace_ipv4_routes (NMSettingIPConfig *s_ip,
-                                              NMIPRoute **entries_arr,
-                                              guint entries_len);
+gboolean nmcs_setting_ip_replace_ipv4_routes(NMSettingIPConfig *s_ip,
+                                             NMIPRoute **       entries_arr,
+                                             guint              entries_len);
 
-gboolean nmcs_setting_ip_replace_ipv4_rules (NMSettingIPConfig *s_ip,
-                                             NMIPRoutingRule **entries_arr,
-                                             guint entries_len);
+gboolean nmcs_setting_ip_replace_ipv4_rules(NMSettingIPConfig *s_ip,
+                                            NMIPRoutingRule ** entries_arr,
+                                            guint              entries_len);
 
 /*****************************************************************************/
 
-NMConnection *nmcs_device_get_applied_connection (NMDevice *device,
-                                                  GCancellable *cancellable,
-                                                  guint64 *version_id,
-                                                  GError **error);
-
-gboolean nmcs_device_reapply (NMDevice *device,
-                              GCancellable *sigterm_cancellable,
-                              NMConnection *connection,
-                              guint64 version_id,
-                              gboolean *out_version_id_changed,
-                              GError **error);
+NMConnection *nmcs_device_get_applied_connection(NMDevice *    device,
+                                                 GCancellable *cancellable,
+                                                 guint64 *     version_id,
+                                                 GError **     error);
+
+gboolean nmcs_device_reapply(NMDevice *    device,
+                             GCancellable *sigterm_cancellable,
+                             NMConnection *connection,
+                             guint64       version_id,
+                             gboolean *    out_version_id_changed,
+                             GError **     error);
 
 #endif /* __NM_CLOUD_SETUP_UTILS_H__ */
diff --git a/clients/cloud-setup/nm-cloud-setup.service.in b/clients/cloud-setup/nm-cloud-setup.service.in
index 9866acd8..57f9e931 100644
--- a/clients/cloud-setup/nm-cloud-setup.service.in
+++ b/clients/cloud-setup/nm-cloud-setup.service.in
@@ -13,6 +13,7 @@ ExecStart=@libexecdir@/nm-cloud-setup
 # the provider.
 #Environment=NM_CLOUD_SETUP_EC2=yes
 #Environment=NM_CLOUD_SETUP_GCP=yes
+#Environment=NM_CLOUD_SETUP_AZURE=yes
 
 CapabilityBoundingSet=
 LockPersonality=yes
diff --git a/clients/cloud-setup/nm-http-client.c b/clients/cloud-setup/nm-http-client.c
index b4260ffe..221e8c71 100644
--- a/clients/cloud-setup/nm-http-client.c
+++ b/clients/cloud-setup/nm-http-client.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "nm-default.h"
 
@@ -7,780 +7,795 @@
 #include <curl/curl.h>
 
 #include "nm-cloud-setup-utils.h"
+#include "nm-glib-aux/nm-str-buf.h"
 
 #define NM_CURL_DEBUG 0
 
 /*****************************************************************************/
 
 typedef struct {
-	GMainContext *context;
-	CURLM *mhandle;
-	GSource *mhandle_source_timeout;
-	GHashTable *source_sockets_hashtable;
+    GMainContext *context;
+    CURLM *       mhandle;
+    GSource *     mhandle_source_timeout;
+    GHashTable *  source_sockets_hashtable;
 } NMHttpClientPrivate;
 
 struct _NMHttpClient {
-	GObject parent;
-	NMHttpClientPrivate _priv;
+    GObject             parent;
+    NMHttpClientPrivate _priv;
 };
 
 struct _NMHttpClientClass {
-	GObjectClass parent;
+    GObjectClass parent;
 };
 
-G_DEFINE_TYPE (NMHttpClient, nm_http_client, G_TYPE_OBJECT);
+G_DEFINE_TYPE(NMHttpClient, nm_http_client, G_TYPE_OBJECT);
 
 #define NM_HTTP_CLIENT_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMHttpClient, NM_IS_HTTP_CLIENT)
 
 /*****************************************************************************/
 
-#define _NMLOG2(level, edata, ...) \
-	G_STMT_START { \
-		EHandleData *_edata = (edata); \
-		\
-		_NMLOG (level, \
-		        "http-request["NM_HASH_OBFUSCATE_PTR_FMT", \"%s\"]: " \
-		        _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
-		        NM_HASH_OBFUSCATE_PTR (_edata), \
-		        (_edata)->url \
-		        _NM_UTILS_MACRO_REST (__VA_ARGS__)); \
-	} G_STMT_END
+#define _NMLOG2(level, edata, ...)                               \
+    G_STMT_START                                                 \
+    {                                                            \
+        EHandleData *_edata = (edata);                           \
+                                                                 \
+        _NMLOG(level,                                            \
+               "http-request[" NM_HASH_OBFUSCATE_PTR_FMT         \
+               ", \"%s\"]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
+               NM_HASH_OBFUSCATE_PTR(_edata),                    \
+               (_edata)->url _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
+    }                                                            \
+    G_STMT_END
 
 /*****************************************************************************/
 
-G_LOCK_DEFINE_STATIC (_my_curl_initalized_lock);
+G_LOCK_DEFINE_STATIC(_my_curl_initalized_lock);
 static bool _my_curl_initialized = FALSE;
 
-__attribute__((destructor))
-static void
-_my_curl_global_cleanup (void)
+__attribute__((destructor)) static void
+_my_curl_global_cleanup(void)
 {
-	G_LOCK (_my_curl_initalized_lock);
-	if (_my_curl_initialized) {
-		_my_curl_initialized = FALSE;
-		curl_global_cleanup ();
-	}
-	G_UNLOCK (_my_curl_initalized_lock);
+    G_LOCK(_my_curl_initalized_lock);
+    if (_my_curl_initialized) {
+        _my_curl_initialized = FALSE;
+        curl_global_cleanup();
+    }
+    G_UNLOCK(_my_curl_initalized_lock);
 }
 
 static void
-nm_http_client_curl_global_init (void)
+nm_http_client_curl_global_init(void)
 {
-	G_LOCK (_my_curl_initalized_lock);
-	if (!_my_curl_initialized) {
-		_my_curl_initialized = TRUE;
-		if (curl_global_init (CURL_GLOBAL_ALL) != CURLE_OK) {
-			/* Even if this fails, we are partly initialized. WTF. */
-			_LOGE ("curl: curl_global_init() failed!");
-		}
-	}
-	G_UNLOCK (_my_curl_initalized_lock);
+    G_LOCK(_my_curl_initalized_lock);
+    if (!_my_curl_initialized) {
+        _my_curl_initialized = TRUE;
+        if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
+            /* Even if this fails, we are partly initialized. WTF. */
+            _LOGE("curl: curl_global_init() failed!");
+        }
+    }
+    G_UNLOCK(_my_curl_initalized_lock);
 }
 
 /*****************************************************************************/
 
 GMainContext *
-nm_http_client_get_main_context (NMHttpClient *self)
+nm_http_client_get_main_context(NMHttpClient *self)
 {
-	g_return_val_if_fail (NM_IS_HTTP_CLIENT (self), NULL);
+    g_return_val_if_fail(NM_IS_HTTP_CLIENT(self), NULL);
 
-	return NM_HTTP_CLIENT_GET_PRIVATE (self)->context;
+    return NM_HTTP_CLIENT_GET_PRIVATE(self)->context;
 }
 
 /*****************************************************************************/
 
 static GSource *
-_source_attach (NMHttpClient *self,
-                GSource *source)
+_source_attach(NMHttpClient *self, GSource *source)
 {
-	return nm_g_source_attach (source, NM_HTTP_CLIENT_GET_PRIVATE (self)->context);
+    return nm_g_source_attach(source, NM_HTTP_CLIENT_GET_PRIVATE(self)->context);
 }
 
 /*****************************************************************************/
 
 typedef struct {
-	long response_code;
-	GBytes *response_data;
+    long    response_code;
+    GBytes *response_data;
 } GetResult;
 
 static void
-_get_result_free (gpointer data)
+_get_result_free(gpointer data)
 {
-	GetResult *get_result = data;
+    GetResult *get_result = data;
 
-	g_bytes_unref (get_result->response_data);
-	nm_g_slice_free (get_result);
+    g_bytes_unref(get_result->response_data);
+    nm_g_slice_free(get_result);
 }
 
 typedef struct {
-	GTask *task;
-	GSource *timeout_source;
-	CURLcode ehandle_result;
-	CURL *ehandle;
-	char *url;
-	GString *recv_data;
-	struct curl_slist *headers;
-	gssize max_data;
-	gulong cancellable_id;
+    GTask *            task;
+    GSource *          timeout_source;
+    CURLcode           ehandle_result;
+    CURL *             ehandle;
+    char *             url;
+    NMStrBuf           recv_data;
+    struct curl_slist *headers;
+    gssize             max_data;
+    gulong             cancellable_id;
 } EHandleData;
 
 static void
-_ehandle_free_ehandle (EHandleData *edata)
+_ehandle_free_ehandle(EHandleData *edata)
 {
-	if (edata->ehandle) {
-		NMHttpClient *self = g_task_get_source_object (edata->task);
-		NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
+    if (edata->ehandle) {
+        NMHttpClient *       self = g_task_get_source_object(edata->task);
+        NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE(self);
 
-		curl_multi_remove_handle (priv->mhandle, edata->ehandle);
-		curl_easy_cleanup (g_steal_pointer (&edata->ehandle));
-	}
+        curl_multi_remove_handle(priv->mhandle, edata->ehandle);
+        curl_easy_cleanup(g_steal_pointer(&edata->ehandle));
+    }
 }
 
 static void
-_ehandle_free (EHandleData *edata)
+_ehandle_free(EHandleData *edata)
 {
-	nm_assert (!edata->ehandle);
-	nm_assert (!edata->timeout_source);
+    nm_assert(!edata->ehandle);
+    nm_assert(!edata->timeout_source);
 
-	g_object_unref (edata->task);
+    g_object_unref(edata->task);
 
-	if (edata->recv_data)
-		g_string_free (edata->recv_data, TRUE);
-	if (edata->headers)
-		curl_slist_free_all (edata->headers);
-	g_free (edata->url);
-	nm_g_slice_free (edata);
+    nm_str_buf_destroy(&edata->recv_data);
+    if (edata->headers)
+        curl_slist_free_all(edata->headers);
+    g_free(edata->url);
+    nm_g_slice_free(edata);
 }
 
 static void
-_ehandle_complete (EHandleData *edata,
-                   GError *error_take)
+_ehandle_complete(EHandleData *edata, GError *error_take)
 {
-	GetResult *get_result;
-	gs_free char *str_tmp_1 = NULL;
-	long response_code = -1;
-
-	nm_clear_pointer (&edata->timeout_source, nm_g_source_destroy_and_unref);
-
-	nm_clear_g_cancellable_disconnect (g_task_get_cancellable (edata->task),
-	                                   &edata->cancellable_id);
-
-	if (error_take) {
-		if (nm_utils_error_is_cancelled (error_take))
-			_LOG2T (edata, "cancelled");
-		else
-			_LOG2D (edata, "failed with %s", error_take->message);
-	} else if (edata->ehandle_result != CURLE_OK) {
-		_LOG2D (edata, "failed with curl error \"%s\"", curl_easy_strerror (edata->ehandle_result));
-		nm_utils_error_set (&error_take,
-		                    NM_UTILS_ERROR_UNKNOWN,
-		                    "failed with curl error \"%s\"",
-		                    curl_easy_strerror (edata->ehandle_result));
-	}
-
-	if (error_take) {
-		_ehandle_free_ehandle (edata);
-		g_task_return_error (edata->task, error_take);
-		_ehandle_free (edata);
-		return;
-	}
-
-	if (curl_easy_getinfo (edata->ehandle,
-	                       CURLINFO_RESPONSE_CODE,
-	                       &response_code) != CURLE_OK)
-		_LOG2E (edata, "failed to get response code from curl easy handle");
-
-	_LOG2D (edata, "success getting %"G_GSIZE_FORMAT" bytes (response code %ld)",
-	        edata->recv_data->len,
-	        response_code);
-
-	_LOG2T (edata, "received %"G_GSIZE_FORMAT" bytes: [[%s]]",
-	       edata->recv_data->len,
-	       nm_utils_buf_utf8safe_escape (edata->recv_data->str, edata->recv_data->len, NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL, &str_tmp_1));
-
-	_ehandle_free_ehandle (edata);
-
-	get_result = g_slice_new (GetResult);
-	*get_result = (GetResult) {
-		.response_code = response_code,
-		/* This ensures that response_data is always NUL terminated. This is an important guarantee
-		 * that NMHttpClient makes. */
-		.response_data = g_string_free_to_bytes (g_steal_pointer (&edata->recv_data)),
-	};
-
-	g_task_return_pointer (edata->task, get_result, _get_result_free);
-
-	_ehandle_free (edata);
+    GetResult *   get_result;
+    gs_free char *str_tmp_1     = NULL;
+    long          response_code = -1;
+
+    nm_clear_pointer(&edata->timeout_source, nm_g_source_destroy_and_unref);
+
+    nm_clear_g_cancellable_disconnect(g_task_get_cancellable(edata->task), &edata->cancellable_id);
+
+    if (error_take) {
+        if (nm_utils_error_is_cancelled(error_take))
+            _LOG2T(edata, "cancelled");
+        else
+            _LOG2D(edata, "failed with %s", error_take->message);
+    } else if (edata->ehandle_result != CURLE_OK) {
+        _LOG2D(edata, "failed with curl error \"%s\"", curl_easy_strerror(edata->ehandle_result));
+        nm_utils_error_set(&error_take,
+                           NM_UTILS_ERROR_UNKNOWN,
+                           "failed with curl error \"%s\"",
+                           curl_easy_strerror(edata->ehandle_result));
+    }
+
+    if (error_take) {
+        _ehandle_free_ehandle(edata);
+        g_task_return_error(edata->task, error_take);
+        _ehandle_free(edata);
+        return;
+    }
+
+    if (curl_easy_getinfo(edata->ehandle, CURLINFO_RESPONSE_CODE, &response_code) != CURLE_OK)
+        _LOG2E(edata, "failed to get response code from curl easy handle");
+
+    _LOG2D(edata,
+           "success getting %" G_GSIZE_FORMAT " bytes (response code %ld)",
+           edata->recv_data.len,
+           response_code);
+
+    _LOG2T(edata,
+           "received %" G_GSIZE_FORMAT " bytes: [[%s]]",
+           edata->recv_data.len,
+           nm_utils_buf_utf8safe_escape(nm_str_buf_get_str(&edata->recv_data),
+                                        edata->recv_data.len,
+                                        NM_UTILS_STR_UTF8_SAFE_FLAG_ESCAPE_CTRL,
+                                        &str_tmp_1));
+
+    _ehandle_free_ehandle(edata);
+
+    get_result  = g_slice_new(GetResult);
+    *get_result = (GetResult){
+        .response_code = response_code,
+        /* This ensures that response_data is always NUL terminated. This is an important guarantee
+         * that NMHttpClient makes. */
+        .response_data = nm_str_buf_finalize_to_gbytes(&edata->recv_data),
+    };
+
+    g_task_return_pointer(edata->task, get_result, _get_result_free);
+
+    _ehandle_free(edata);
 }
 
 /*****************************************************************************/
 
 static size_t
-_get_writefunction_cb (char *ptr, size_t size, size_t nmemb, void *user_data)
+_get_writefunction_cb(char *ptr, size_t size, size_t nmemb, void *user_data)
 {
-	EHandleData *edata = user_data;
-	gsize nconsume;
-
-	/* size should always be 1, but still. Multiply them to be sure. */
-	nmemb *= size;
-
-	if (edata->max_data >= 0) {
-		nm_assert (edata->recv_data->len <= edata->max_data);
-		nconsume = (((gsize) edata->max_data) - edata->recv_data->len);
-		if (nconsume > nmemb)
-			nconsume = nmemb;
-	} else
-		nconsume = nmemb;
-
-	g_string_append_len (edata->recv_data, ptr, nconsume);
-	return nconsume;
+    EHandleData *edata = user_data;
+    gsize        nconsume;
+
+    /* size should always be 1, but still. Multiply them to be sure. */
+    nmemb *= size;
+
+    if (edata->max_data >= 0) {
+        nm_assert(edata->recv_data.len <= edata->max_data);
+        nconsume = (((gsize) edata->max_data) - edata->recv_data.len);
+        if (nconsume > nmemb)
+            nconsume = nmemb;
+    } else
+        nconsume = nmemb;
+
+    nm_str_buf_append_len(&edata->recv_data, ptr, nconsume);
+    return nconsume;
 }
 
 static gboolean
-_get_timeout_cb (gpointer user_data)
+_get_timeout_cb(gpointer user_data)
 {
-	_ehandle_complete (user_data,
-	                   g_error_new_literal (NM_UTILS_ERROR,
-	                                        NM_UTILS_ERROR_UNKNOWN,
-	                                        "HTTP request timed out"));
-	return G_SOURCE_REMOVE;
+    _ehandle_complete(
+        user_data,
+        g_error_new_literal(NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "HTTP request timed out"));
+    return G_SOURCE_REMOVE;
 }
 
 static void
-_get_cancelled_cb (GObject *object, gpointer user_data)
+_get_cancelled_cb(GObject *object, gpointer user_data)
 {
-	EHandleData *edata = user_data;
-	GError *error = NULL;
+    EHandleData *edata = user_data;
+    GError *     error = NULL;
 
-	nm_clear_g_signal_handler (g_task_get_cancellable (edata->task),
-	                           &edata->cancellable_id);
-	nm_utils_error_set_cancelled (&error, FALSE, NULL);
-	_ehandle_complete (edata, error);
+    nm_clear_g_signal_handler(g_task_get_cancellable(edata->task), &edata->cancellable_id);
+    nm_utils_error_set_cancelled(&error, FALSE, NULL);
+    _ehandle_complete(edata, error);
 }
 
 void
-nm_http_client_get (NMHttpClient *self,
-                    const char *url,
-                    int timeout_msec,
-                    gssize max_data,
-                    const char *const *http_headers,
-                    GCancellable *cancellable,
-                    GAsyncReadyCallback callback,
-                    gpointer user_data)
+nm_http_client_get(NMHttpClient *      self,
+                   const char *        url,
+                   int                 timeout_msec,
+                   gssize              max_data,
+                   const char *const * http_headers,
+                   GCancellable *      cancellable,
+                   GAsyncReadyCallback callback,
+                   gpointer            user_data)
 {
-	NMHttpClientPrivate *priv;
-	EHandleData *edata;
-	guint i;
-
-	g_return_if_fail (NM_IS_HTTP_CLIENT (self));
-	g_return_if_fail (url);
-	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
-	g_return_if_fail (timeout_msec >= 0);
-	g_return_if_fail (max_data >= -1);
-
-	priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
-
-	edata = g_slice_new (EHandleData);
-	*edata = (EHandleData) {
-		.task           = nm_g_task_new (self, cancellable, nm_http_client_get, callback, user_data),
-		.recv_data      = g_string_sized_new (NM_MIN (max_data, 245)),
-		.max_data       = max_data,
-		.url            = g_strdup (url),
-		.headers        = NULL,
-	};
-
-	nmcs_wait_for_objects_register (edata->task);
-
-	_LOG2D (edata, "start get ...");
-
-	edata->ehandle = curl_easy_init ();
-	if (!edata->ehandle) {
-		_ehandle_complete (edata,
-		                   g_error_new_literal (NM_UTILS_ERROR,
-		                                        NM_UTILS_ERROR_UNKNOWN,
-		                                        "HTTP request failed to create curl handle"));
-		return;
-	}
-
-	curl_easy_setopt (edata->ehandle, CURLOPT_URL, url);
-
-	curl_easy_setopt (edata->ehandle, CURLOPT_WRITEFUNCTION, _get_writefunction_cb);
-	curl_easy_setopt (edata->ehandle, CURLOPT_WRITEDATA, edata);
-	curl_easy_setopt (edata->ehandle, CURLOPT_PRIVATE, edata);
-
-	if (http_headers) {
-		for (i = 0; http_headers[i]; ++i) {
-			struct curl_slist *tmp;
-
-			tmp = curl_slist_append (edata->headers,
-			                         http_headers[i]);
-			if (!tmp) {
-				curl_slist_free_all (tmp);
-				_LOGE ("curl: curl_slist_append() failed adding %s", http_headers[i]);
-				continue;
-			}
-			edata->headers = tmp;
-		}
-
-		curl_easy_setopt (edata->ehandle, CURLOPT_HTTPHEADER, edata->headers);
-	}
-
-	if (timeout_msec > 0) {
-		edata->timeout_source = _source_attach (self,
-		                                        nm_g_timeout_source_new (timeout_msec,
-		                                                                 G_PRIORITY_DEFAULT,
-		                                                                 _get_timeout_cb,
-		                                                                 edata,
-		                                                                 NULL));
-	}
-
-	curl_multi_add_handle (priv->mhandle, edata->ehandle);
-
-	if (cancellable) {
-		gulong signal_id;
-
-		signal_id = g_cancellable_connect (cancellable,
-		                                   G_CALLBACK (_get_cancelled_cb),
-		                                   edata,
-		                                   NULL);
-		if (signal_id == 0) {
-			/* the request is already cancelled. Return. */
-			return;
-		}
-		edata->cancellable_id = signal_id;
-	}
+    NMHttpClientPrivate *priv;
+    EHandleData *        edata;
+    guint                i;
+
+    g_return_if_fail(NM_IS_HTTP_CLIENT(self));
+    g_return_if_fail(url);
+    g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
+    g_return_if_fail(timeout_msec >= 0);
+    g_return_if_fail(max_data >= -1);
+
+    priv = NM_HTTP_CLIENT_GET_PRIVATE(self);
+
+    edata  = g_slice_new(EHandleData);
+    *edata = (EHandleData){
+        .task      = nm_g_task_new(self, cancellable, nm_http_client_get, callback, user_data),
+        .recv_data = NM_STR_BUF_INIT(0, FALSE),
+        .max_data  = max_data,
+        .url       = g_strdup(url),
+        .headers   = NULL,
+    };
+
+    nmcs_wait_for_objects_register(edata->task);
+
+    _LOG2D(edata, "start get ...");
+
+    edata->ehandle = curl_easy_init();
+    if (!edata->ehandle) {
+        _ehandle_complete(edata,
+                          g_error_new_literal(NM_UTILS_ERROR,
+                                              NM_UTILS_ERROR_UNKNOWN,
+                                              "HTTP request failed to create curl handle"));
+        return;
+    }
+
+    curl_easy_setopt(edata->ehandle, CURLOPT_URL, url);
+
+    curl_easy_setopt(edata->ehandle, CURLOPT_WRITEFUNCTION, _get_writefunction_cb);
+    curl_easy_setopt(edata->ehandle, CURLOPT_WRITEDATA, edata);
+    curl_easy_setopt(edata->ehandle, CURLOPT_PRIVATE, edata);
+
+    if (http_headers) {
+        for (i = 0; http_headers[i]; ++i) {
+            struct curl_slist *tmp;
+
+            tmp = curl_slist_append(edata->headers, http_headers[i]);
+            if (!tmp) {
+                curl_slist_free_all(tmp);
+                _LOGE("curl: curl_slist_append() failed adding %s", http_headers[i]);
+                continue;
+            }
+            edata->headers = tmp;
+        }
+
+        curl_easy_setopt(edata->ehandle, CURLOPT_HTTPHEADER, edata->headers);
+    }
+
+    if (timeout_msec > 0) {
+        edata->timeout_source = _source_attach(self,
+                                               nm_g_timeout_source_new(timeout_msec,
+                                                                       G_PRIORITY_DEFAULT,
+                                                                       _get_timeout_cb,
+                                                                       edata,
+                                                                       NULL));
+    }
+
+    curl_multi_add_handle(priv->mhandle, edata->ehandle);
+
+    if (cancellable) {
+        gulong signal_id;
+
+        signal_id = g_cancellable_connect(cancellable, G_CALLBACK(_get_cancelled_cb), edata, NULL);
+        if (signal_id == 0) {
+            /* the request is already cancelled. Return. */
+            return;
+        }
+        edata->cancellable_id = signal_id;
+    }
 }
 
+/**
+ * nm_http_client_get_finish:
+ * @self: the #NMHttpClient instance
+ * @result: the #GAsyncResult which to complete.
+ * @out_response_code: (allow-none) (out): the HTTP response code or -1 on other error.
+ * @out_response_data: (allow-none) (transfer full): the HTTP response data, if any.
+ *   The GBytes buffer is guaranteed to have a trailing NUL character *after* the
+ *   returned buffer size. That means, you can always trust that the buffer is NUL terminated
+ *   and that there is one additional hidden byte after the data.
+ *   Also, the returned buffer is allocated just for you. While GBytes is immutable, you are
+ *   allowed to modify the buffer as it's not used by anybody else.
+ * @error: the error
+ *
+ * Returns: %TRUE on success or %FALSE with an error code.
+ */
 gboolean
-nm_http_client_get_finish (NMHttpClient *self,
-                           GAsyncResult *result,
-                           long *out_response_code,
-                           GBytes **out_response_data,
-                           GError **error)
+nm_http_client_get_finish(NMHttpClient *self,
+                          GAsyncResult *result,
+                          long *        out_response_code,
+                          GBytes **     out_response_data,
+                          GError **     error)
 {
-	GetResult *get_result;
+    GetResult *get_result;
+
+    g_return_val_if_fail(NM_IS_HTTP_CLIENT(self), FALSE);
+    g_return_val_if_fail(nm_g_task_is_valid(result, self, nm_http_client_get), FALSE);
 
-	g_return_val_if_fail (NM_IS_HTTP_CLIENT (self), FALSE);
-	g_return_val_if_fail (nm_g_task_is_valid (result, self, nm_http_client_get), FALSE);
+    get_result = g_task_propagate_pointer(G_TASK(result), error);
 
-	get_result = g_task_propagate_pointer (G_TASK (result), error);
-	if (!get_result) {
-		NM_SET_OUT (out_response_code, -1);
-		NM_SET_OUT (out_response_data, NULL);
-		return FALSE;
-	}
+    nm_assert(!error || (!!get_result) == (!*error));
 
-	NM_SET_OUT (out_response_code, get_result->response_code);
+    if (!get_result) {
+        NM_SET_OUT(out_response_code, -1);
+        NM_SET_OUT(out_response_data, NULL);
+        return FALSE;
+    }
 
-	/* response_data is binary, but is also guaranteed to be NUL terminated! */
-	NM_SET_OUT (out_response_data, g_steal_pointer (&get_result->response_data));
+    NM_SET_OUT(out_response_code, get_result->response_code);
 
-	_get_result_free (get_result);
+    /* response_data is binary, but is also guaranteed to be NUL terminated! */
+    NM_SET_OUT(out_response_data, g_steal_pointer(&get_result->response_data));
 
-	return TRUE;
+    _get_result_free(get_result);
+    return TRUE;
 }
 
 /*****************************************************************************/
 
 typedef struct {
-	GTask *task;
-	char *uri;
-	const char *const *http_headers;
-	NMHttpClientPollGetCheckFcn check_fcn;
-	gpointer check_user_data;
-	GBytes *response_data;
-	gsize request_max_data;
-	long response_code;
-	int request_timeout_ms;
+    GTask *                     task;
+    char *                      uri;
+    const char *const *         http_headers;
+    NMHttpClientPollGetCheckFcn check_fcn;
+    gpointer                    check_user_data;
+    GBytes *                    response_data;
+    gsize                       request_max_data;
+    long                        response_code;
+    int                         request_timeout_ms;
 } PollGetData;
 
 static void
-_poll_get_data_free (gpointer data)
+_poll_get_data_free(gpointer data)
 {
-	PollGetData *poll_get_data = data;
+    PollGetData *poll_get_data = data;
 
-	g_free (poll_get_data->uri);
+    g_free(poll_get_data->uri);
 
-	nm_clear_pointer (&poll_get_data->response_data, g_bytes_unref);
-	g_strfreev ((char **) poll_get_data->http_headers);
+    nm_clear_pointer(&poll_get_data->response_data, g_bytes_unref);
+    g_strfreev((char **) poll_get_data->http_headers);
 
-	nm_g_slice_free (poll_get_data);
+    nm_g_slice_free(poll_get_data);
 }
 
 static void
-_poll_get_probe_start_fcn (GCancellable *cancellable,
-                           gpointer probe_user_data,
-                           GAsyncReadyCallback callback,
-                           gpointer user_data)
+_poll_get_probe_start_fcn(GCancellable *      cancellable,
+                          gpointer            probe_user_data,
+                          GAsyncReadyCallback callback,
+                          gpointer            user_data)
 {
-	PollGetData *poll_get_data = probe_user_data;
-
-	/* balanced by _poll_get_probe_finish_fcn() */
-	g_object_ref (poll_get_data->task);
-
-	nm_http_client_get (g_task_get_source_object (poll_get_data->task),
-	                    poll_get_data->uri,
-	                    poll_get_data->request_timeout_ms,
-	                    poll_get_data->request_max_data,
-	                    poll_get_data->http_headers,
-	                    cancellable,
-	                    callback,
-	                    user_data);
+    PollGetData *poll_get_data = probe_user_data;
+
+    /* balanced by _poll_get_probe_finish_fcn() */
+    g_object_ref(poll_get_data->task);
+
+    nm_http_client_get(g_task_get_source_object(poll_get_data->task),
+                       poll_get_data->uri,
+                       poll_get_data->request_timeout_ms,
+                       poll_get_data->request_max_data,
+                       poll_get_data->http_headers,
+                       cancellable,
+                       callback,
+                       user_data);
 }
 
 static gboolean
-_poll_get_probe_finish_fcn (GObject *source,
-                            GAsyncResult *result,
-                            gpointer probe_user_data,
-                            GError **error)
+_poll_get_probe_finish_fcn(GObject *     source,
+                           GAsyncResult *result,
+                           gpointer      probe_user_data,
+                           GError **     error)
 {
-	PollGetData *poll_get_data = probe_user_data;
-	_nm_unused gs_unref_object GTask *task = poll_get_data->task; /* balance ref from _poll_get_probe_start_fcn() */
-	gboolean success;
-	gs_free_error GError *local_error = NULL;
-	gs_unref_bytes GBytes *response_data = NULL;
-	long response_code = -1;
-
-	success = nm_http_client_get_finish (g_task_get_source_object (poll_get_data->task),
-	                                     result,
-	                                     &response_code,
-	                                     &response_data,
-	                                     &local_error);
-
-	if (!success) {
-		if (nm_utils_error_is_cancelled (local_error)) {
-			g_propagate_error (error, g_steal_pointer (&local_error));
-			return TRUE;
-		}
-		return FALSE;
-	}
-
-	if (poll_get_data->check_fcn) {
-		success = poll_get_data->check_fcn (response_code,
-		                                    response_data,
-		                                    poll_get_data->check_user_data,
-		                                    &local_error);
-	} else
-		success = (response_code == 200);
-
-	if (local_error) {
-		g_propagate_error (error, g_steal_pointer (&local_error));
-		return TRUE;
-	}
-
-	if (!success)
-		return FALSE;
-
-	poll_get_data->response_code = response_code;
-	poll_get_data->response_data = g_steal_pointer (&response_data);
-	return TRUE;
+    PollGetData *              poll_get_data = probe_user_data;
+    _nm_unused gs_unref_object GTask *task =
+        poll_get_data->task; /* balance ref from _poll_get_probe_start_fcn() */
+    gboolean      success;
+    gs_free_error GError *local_error    = NULL;
+    gs_unref_bytes GBytes *response_data = NULL;
+    long                   response_code = -1;
+
+    success = nm_http_client_get_finish(g_task_get_source_object(poll_get_data->task),
+                                        result,
+                                        &response_code,
+                                        &response_data,
+                                        &local_error);
+
+    nm_assert((!!success) == (!local_error));
+
+    if (local_error) {
+        if (nm_utils_error_is_cancelled(local_error)) {
+            g_propagate_error(error, g_steal_pointer(&local_error));
+            return TRUE;
+        }
+        /* any other error. Continue polling. */
+        return FALSE;
+    }
+
+    if (poll_get_data->check_fcn) {
+        success = poll_get_data->check_fcn(response_code,
+                                           response_data,
+                                           poll_get_data->check_user_data,
+                                           &local_error);
+    } else
+        success = (response_code == 200);
+
+    if (local_error) {
+        g_propagate_error(error, g_steal_pointer(&local_error));
+        return TRUE;
+    }
+
+    if (!success) {
+        /* Not yet ready. Continue polling. */
+        return FALSE;
+    }
+
+    poll_get_data->response_code = response_code;
+    poll_get_data->response_data = g_steal_pointer(&response_data);
+    return TRUE;
 }
 
 static void
-_poll_get_done_cb (GObject *source,
-                   GAsyncResult *result,
-                   gpointer user_data)
+_poll_get_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	PollGetData *poll_get_data = user_data;
-	gs_free_error GError *error = NULL;
-	gboolean success;
+    PollGetData * poll_get_data = user_data;
+    gs_free_error GError *error = NULL;
+    gboolean              success;
+
+    success = nmcs_utils_poll_finish(result, NULL, &error);
 
-	success = nmcs_utils_poll_finish (result, NULL, &error);
+    nm_assert((!!success) == (!error));
 
-	if (error)
-		g_task_return_error (poll_get_data->task, g_steal_pointer (&error));
-	else
-		g_task_return_boolean (poll_get_data->task, success);
+    if (error)
+        g_task_return_error(poll_get_data->task, g_steal_pointer(&error));
+    else
+        g_task_return_boolean(poll_get_data->task, TRUE);
 
-	g_object_unref (poll_get_data->task);
+    g_object_unref(poll_get_data->task);
 }
 
 void
-nm_http_client_poll_get (NMHttpClient *self,
-                         const char *uri,
-                         int request_timeout_ms,
-                         gssize request_max_data,
-                         int poll_timeout_ms,
-                         int ratelimit_timeout_ms,
-                         const char *const *http_headers,
-                         GCancellable *cancellable,
-                         NMHttpClientPollGetCheckFcn check_fcn,
-                         gpointer check_user_data,
-                         GAsyncReadyCallback callback,
-                         gpointer user_data)
+nm_http_client_poll_get(NMHttpClient *              self,
+                        const char *                uri,
+                        int                         request_timeout_ms,
+                        gssize                      request_max_data,
+                        int                         poll_timeout_ms,
+                        int                         ratelimit_timeout_ms,
+                        const char *const *         http_headers,
+                        GCancellable *              cancellable,
+                        NMHttpClientPollGetCheckFcn check_fcn,
+                        gpointer                    check_user_data,
+                        GAsyncReadyCallback         callback,
+                        gpointer                    user_data)
 {
-	nm_auto_pop_gmaincontext GMainContext *context = NULL;
-	PollGetData *poll_get_data;
-
-	g_return_if_fail (NM_IS_HTTP_CLIENT (self));
-	g_return_if_fail (uri && uri[0]);
-	g_return_if_fail (request_timeout_ms >= -1);
-	g_return_if_fail (request_max_data >= -1);
-	g_return_if_fail (poll_timeout_ms >= -1);
-	g_return_if_fail (ratelimit_timeout_ms >= -1);
-	g_return_if_fail (!cancellable || G_CANCELLABLE (cancellable));
-
-	poll_get_data = g_slice_new (PollGetData);
-	*poll_get_data = (PollGetData) {
-		.task               = nm_g_task_new (self, cancellable, nm_http_client_poll_get, callback, user_data),
-		.uri                = g_strdup (uri),
-		.request_timeout_ms = request_timeout_ms,
-		.request_max_data   = request_max_data,
-		.check_fcn          = check_fcn,
-		.check_user_data    = check_user_data,
-		.response_code      = -1,
-		.http_headers       =  NM_CAST_STRV_CC (g_strdupv ((char **) http_headers)),
-	};
-
-	nmcs_wait_for_objects_register (poll_get_data->task);
-
-	g_task_set_task_data (poll_get_data->task,
-	                      poll_get_data,
-	                      _poll_get_data_free);
-
-	context = nm_g_main_context_push_thread_default_if_necessary (nm_http_client_get_main_context (self));
-
-	nmcs_utils_poll (poll_timeout_ms,
-	                 ratelimit_timeout_ms,
-	                 0,
-	                 _poll_get_probe_start_fcn,
-	                 _poll_get_probe_finish_fcn,
-	                 poll_get_data,
-	                 cancellable,
-	                 _poll_get_done_cb,
-	                 poll_get_data);
+    nm_auto_pop_gmaincontext GMainContext *context = NULL;
+    PollGetData *                          poll_get_data;
+
+    g_return_if_fail(NM_IS_HTTP_CLIENT(self));
+    g_return_if_fail(uri && uri[0]);
+    g_return_if_fail(request_timeout_ms >= -1);
+    g_return_if_fail(request_max_data >= -1);
+    g_return_if_fail(poll_timeout_ms >= -1);
+    g_return_if_fail(ratelimit_timeout_ms >= -1);
+    g_return_if_fail(!cancellable || G_CANCELLABLE(cancellable));
+
+    poll_get_data  = g_slice_new(PollGetData);
+    *poll_get_data = (PollGetData){
+        .task = nm_g_task_new(self, cancellable, nm_http_client_poll_get, callback, user_data),
+        .uri  = g_strdup(uri),
+        .request_timeout_ms = request_timeout_ms,
+        .request_max_data   = request_max_data,
+        .check_fcn          = check_fcn,
+        .check_user_data    = check_user_data,
+        .response_code      = -1,
+        .http_headers       = NM_CAST_STRV_CC(g_strdupv((char **) http_headers)),
+    };
+
+    nmcs_wait_for_objects_register(poll_get_data->task);
+
+    g_task_set_task_data(poll_get_data->task, poll_get_data, _poll_get_data_free);
+
+    context =
+        nm_g_main_context_push_thread_default_if_necessary(nm_http_client_get_main_context(self));
+
+    nmcs_utils_poll(poll_timeout_ms,
+                    ratelimit_timeout_ms,
+                    0,
+                    _poll_get_probe_start_fcn,
+                    _poll_get_probe_finish_fcn,
+                    poll_get_data,
+                    cancellable,
+                    _poll_get_done_cb,
+                    poll_get_data);
 }
 
 gboolean
-nm_http_client_poll_get_finish (NMHttpClient *self,
-                                GAsyncResult *result,
-                                long *out_response_code,
-                                GBytes **out_response_data,
-                                GError **error)
+nm_http_client_poll_get_finish(NMHttpClient *self,
+                               GAsyncResult *result,
+                               long *        out_response_code,
+                               GBytes **     out_response_data,
+                               GError **     error)
 {
-	PollGetData *poll_get_data;
-	GTask *task;
-	gboolean success;
-	gs_free_error GError *local_error = NULL;
+    PollGetData * poll_get_data;
+    GTask *       task;
+    gboolean      success;
+    gs_free_error GError *local_error = NULL;
+
+    g_return_val_if_fail(NM_HTTP_CLIENT(self), FALSE);
+    g_return_val_if_fail(nm_g_task_is_valid(result, self, nm_http_client_poll_get), FALSE);
 
-	g_return_val_if_fail (NM_HTTP_CLIENT (self), FALSE);
-	g_return_val_if_fail (nm_g_task_is_valid (result, self, nm_http_client_poll_get), FALSE);
+    task = G_TASK(result);
 
-	task = G_TASK (result);
+    success = g_task_propagate_boolean(task, &local_error);
 
-	success = g_task_propagate_boolean (task, &local_error);
-	if (   local_error
-	    || !success) {
-		if (local_error)
-			g_propagate_error (error, g_steal_pointer (&local_error));
-		NM_SET_OUT (out_response_code, -1);
-		NM_SET_OUT (out_response_data, NULL);
-		return FALSE;
-	}
+    nm_assert((!!success) == (!local_error));
 
-	poll_get_data = g_task_get_task_data (task);
+    if (local_error) {
+        g_propagate_error(error, g_steal_pointer(&local_error));
+        NM_SET_OUT(out_response_code, -1);
+        NM_SET_OUT(out_response_data, NULL);
+        return FALSE;
+    }
 
-	NM_SET_OUT (out_response_code, poll_get_data->response_code);
-	NM_SET_OUT (out_response_data, g_steal_pointer (&poll_get_data->response_data));
+    poll_get_data = g_task_get_task_data(task);
 
-	return TRUE;
+    NM_SET_OUT(out_response_code, poll_get_data->response_code);
+    NM_SET_OUT(out_response_data, g_steal_pointer(&poll_get_data->response_data));
+    return TRUE;
 }
 
 /*****************************************************************************/
 
 static void
-_mhandle_action (NMHttpClient *self,
-                 int sockfd,
-                 int ev_bitmask)
+_mhandle_action(NMHttpClient *self, int sockfd, int ev_bitmask)
 {
-	NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
-	EHandleData *edata;
-	CURLMsg *msg;
-	CURLcode eret;
-	int m_left;
-	CURLMcode ret;
-	int running_handles;
-
-	ret = curl_multi_socket_action (priv->mhandle, sockfd, ev_bitmask, &running_handles);
-	if (ret != CURLM_OK) {
-		_LOGE ("curl: curl_multi_socket_action() failed: (%d) %s", ret, curl_multi_strerror (ret));
-		/* really unexpected. Not clear how to handle this. */
-	}
-
-	while ((msg = curl_multi_info_read (priv->mhandle, &m_left))) {
-
-		if (msg->msg != CURLMSG_DONE)
-			continue;
-
-		eret = curl_easy_getinfo (msg->easy_handle, CURLINFO_PRIVATE, (char **) &edata);
-
-		nm_assert (eret == CURLE_OK);
-		nm_assert (edata);
-
-		edata->ehandle_result = msg->data.result;
-		_ehandle_complete (edata, NULL);
-	}
+    NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE(self);
+    EHandleData *        edata;
+    CURLMsg *            msg;
+    CURLcode             eret;
+    int                  m_left;
+    CURLMcode            ret;
+    int                  running_handles;
+
+    ret = curl_multi_socket_action(priv->mhandle, sockfd, ev_bitmask, &running_handles);
+    if (ret != CURLM_OK) {
+        _LOGE("curl: curl_multi_socket_action() failed: (%d) %s", ret, curl_multi_strerror(ret));
+        /* really unexpected. Not clear how to handle this. */
+    }
+
+    while ((msg = curl_multi_info_read(priv->mhandle, &m_left))) {
+        if (msg->msg != CURLMSG_DONE)
+            continue;
+
+        eret = curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, (char **) &edata);
+
+        nm_assert(eret == CURLE_OK);
+        nm_assert(edata);
+
+        edata->ehandle_result = msg->data.result;
+        _ehandle_complete(edata, NULL);
+    }
 }
 
 static gboolean
-_mhandle_socket_cb (int fd,
-                    GIOCondition condition,
-                    gpointer user_data)
+_mhandle_socket_cb(int fd, GIOCondition condition, gpointer user_data)
 {
-	int ev_bitmask = 0;
+    int ev_bitmask = 0;
 
-	if (condition & G_IO_IN)
-		ev_bitmask |= CURL_CSELECT_IN;
-	if (condition & G_IO_OUT)
-		ev_bitmask |= CURL_CSELECT_OUT;
-	if (condition & G_IO_ERR)
-		ev_bitmask |= CURL_CSELECT_ERR;
+    if (condition & G_IO_IN)
+        ev_bitmask |= CURL_CSELECT_IN;
+    if (condition & G_IO_OUT)
+        ev_bitmask |= CURL_CSELECT_OUT;
+    if (condition & G_IO_ERR)
+        ev_bitmask |= CURL_CSELECT_ERR;
 
-	_mhandle_action (user_data, fd, ev_bitmask);
-	return G_SOURCE_CONTINUE;
+    _mhandle_action(user_data, fd, ev_bitmask);
+    return G_SOURCE_CONTINUE;
 }
 
 static int
-_mhandle_socketfunction_cb (CURL *e_handle, curl_socket_t fd, int what, void *user_data, void *socketp)
+_mhandle_socketfunction_cb(CURL *        e_handle,
+                           curl_socket_t fd,
+                           int           what,
+                           void *        user_data,
+                           void *        socketp)
 {
-	GSource *source_socket;
-	NMHttpClient *self = user_data;
-	NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
-
-	(void) _NM_ENSURE_TYPE (int, fd);
-
-	g_hash_table_remove (priv->source_sockets_hashtable, GINT_TO_POINTER (fd));
-
-	if (what != CURL_POLL_REMOVE) {
-		GIOCondition condition = 0;
-
-		if (what == CURL_POLL_IN)
-			condition = G_IO_IN;
-		else if (what == CURL_POLL_OUT)
-			condition = G_IO_OUT;
-		else if (what == CURL_POLL_INOUT)
-			condition = G_IO_IN | G_IO_OUT;
-		else
-			condition = 0;
-
-		if (condition) {
-			source_socket = nm_g_unix_fd_source_new (fd,
-			                                         condition,
-			                                         G_PRIORITY_DEFAULT,
-			                                         _mhandle_socket_cb,
-			                                         self,
-			                                                       NULL);
-			g_source_attach (source_socket, priv->context);
-
-			g_hash_table_insert (priv->source_sockets_hashtable,
-			                     GINT_TO_POINTER (fd),
-			                     source_socket);
-		}
-	}
-
-	return CURLM_OK;
+    GSource *            source_socket;
+    NMHttpClient *       self = user_data;
+    NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE(self);
+
+    (void) _NM_ENSURE_TYPE(int, fd);
+
+    g_hash_table_remove(priv->source_sockets_hashtable, GINT_TO_POINTER(fd));
+
+    if (what != CURL_POLL_REMOVE) {
+        GIOCondition condition = 0;
+
+        if (what == CURL_POLL_IN)
+            condition = G_IO_IN;
+        else if (what == CURL_POLL_OUT)
+            condition = G_IO_OUT;
+        else if (what == CURL_POLL_INOUT)
+            condition = G_IO_IN | G_IO_OUT;
+        else
+            condition = 0;
+
+        if (condition) {
+            source_socket = nm_g_unix_fd_source_new(fd,
+                                                    condition,
+                                                    G_PRIORITY_DEFAULT,
+                                                    _mhandle_socket_cb,
+                                                    self,
+                                                    NULL);
+            g_source_attach(source_socket, priv->context);
+
+            g_hash_table_insert(priv->source_sockets_hashtable, GINT_TO_POINTER(fd), source_socket);
+        }
+    }
+
+    return CURLM_OK;
 }
 
 static gboolean
-_mhandle_timeout_cb (gpointer user_data)
+_mhandle_timeout_cb(gpointer user_data)
 {
-	_mhandle_action (user_data, CURL_SOCKET_TIMEOUT, 0);
-	return G_SOURCE_REMOVE;
+    _mhandle_action(user_data, CURL_SOCKET_TIMEOUT, 0);
+    return G_SOURCE_REMOVE;
 }
 
 static int
-_mhandle_timerfunction_cb (CURLM *multi, long timeout_msec, void *user_data)
+_mhandle_timerfunction_cb(CURLM *multi, long timeout_msec, void *user_data)
 {
-	NMHttpClient *self = user_data;
-	NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
-
-	nm_clear_pointer (&priv->mhandle_source_timeout, nm_g_source_destroy_and_unref);
-	if (timeout_msec >= 0) {
-		priv->mhandle_source_timeout = _source_attach (self,
-		                                               nm_g_timeout_source_new (NM_MIN (timeout_msec, G_MAXINT),
-		                                                                        G_PRIORITY_DEFAULT,
-		                                                                        _mhandle_timeout_cb,
-		                                                                        self,
-		                                                                        NULL));
-	}
-	return 0;
+    NMHttpClient *       self = user_data;
+    NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE(self);
+
+    nm_clear_pointer(&priv->mhandle_source_timeout, nm_g_source_destroy_and_unref);
+    if (timeout_msec >= 0) {
+        priv->mhandle_source_timeout =
+            _source_attach(self,
+                           nm_g_timeout_source_new(NM_MIN(timeout_msec, G_MAXINT),
+                                                   G_PRIORITY_DEFAULT,
+                                                   _mhandle_timeout_cb,
+                                                   self,
+                                                   NULL));
+    }
+    return 0;
 }
 
 /*****************************************************************************/
 
 static void
-nm_http_client_init (NMHttpClient *self)
+nm_http_client_init(NMHttpClient *self)
 {
-	NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
+    NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE(self);
 
-	priv->source_sockets_hashtable = g_hash_table_new_full (nm_direct_hash,
-	                                                        NULL,
-	                                                        NULL,
-	                                                        (GDestroyNotify) nm_g_source_destroy_and_unref);
+    priv->source_sockets_hashtable =
+        g_hash_table_new_full(nm_direct_hash,
+                              NULL,
+                              NULL,
+                              (GDestroyNotify) nm_g_source_destroy_and_unref);
 }
 
 static void
-constructed (GObject *object)
+constructed(GObject *object)
 {
-	NMHttpClient *self = NM_HTTP_CLIENT (object);
-	NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
-
-	priv->context = g_main_context_ref_thread_default ();
-
-	priv->mhandle = curl_multi_init ();
-	if (!priv->mhandle)
-		_LOGE ("curl: failed to create multi-handle");
-	else {
-		curl_multi_setopt (priv->mhandle, CURLMOPT_SOCKETFUNCTION, _mhandle_socketfunction_cb);
-		curl_multi_setopt (priv->mhandle, CURLMOPT_SOCKETDATA, self);
-		curl_multi_setopt (priv->mhandle, CURLMOPT_TIMERFUNCTION, _mhandle_timerfunction_cb);
-		curl_multi_setopt (priv->mhandle, CURLMOPT_TIMERDATA, self);
-	}
-
-	G_OBJECT_CLASS (nm_http_client_parent_class)->constructed (object);
+    NMHttpClient *       self = NM_HTTP_CLIENT(object);
+    NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE(self);
+
+    priv->context = g_main_context_ref_thread_default();
+
+    priv->mhandle = curl_multi_init();
+    if (!priv->mhandle)
+        _LOGE("curl: failed to create multi-handle");
+    else {
+        curl_multi_setopt(priv->mhandle, CURLMOPT_SOCKETFUNCTION, _mhandle_socketfunction_cb);
+        curl_multi_setopt(priv->mhandle, CURLMOPT_SOCKETDATA, self);
+        curl_multi_setopt(priv->mhandle, CURLMOPT_TIMERFUNCTION, _mhandle_timerfunction_cb);
+        curl_multi_setopt(priv->mhandle, CURLMOPT_TIMERDATA, self);
+    }
+
+    G_OBJECT_CLASS(nm_http_client_parent_class)->constructed(object);
 }
 
 NMHttpClient *
-nm_http_client_new (void)
+nm_http_client_new(void)
 {
-	return g_object_new (NM_TYPE_HTTP_CLIENT, NULL);
+    return g_object_new(NM_TYPE_HTTP_CLIENT, NULL);
 }
 
 static void
-dispose (GObject *object)
+dispose(GObject *object)
 {
-	NMHttpClient *self = NM_HTTP_CLIENT (object);
-	NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
+    NMHttpClient *       self = NM_HTTP_CLIENT(object);
+    NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE(self);
 
-	nm_clear_pointer (&priv->mhandle, curl_multi_cleanup);
-	nm_clear_pointer (&priv->source_sockets_hashtable, g_hash_table_unref);
+    nm_clear_pointer(&priv->mhandle, curl_multi_cleanup);
+    nm_clear_pointer(&priv->source_sockets_hashtable, g_hash_table_unref);
 
-	nm_clear_g_source_inst (&priv->mhandle_source_timeout);
+    nm_clear_g_source_inst(&priv->mhandle_source_timeout);
 
-	G_OBJECT_CLASS (nm_http_client_parent_class)->dispose (object);
+    G_OBJECT_CLASS(nm_http_client_parent_class)->dispose(object);
 }
 
 static void
-finalize (GObject *object)
+finalize(GObject *object)
 {
-	NMHttpClient *self = NM_HTTP_CLIENT (object);
-	NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE (self);
+    NMHttpClient *       self = NM_HTTP_CLIENT(object);
+    NMHttpClientPrivate *priv = NM_HTTP_CLIENT_GET_PRIVATE(self);
 
-	G_OBJECT_CLASS (nm_http_client_parent_class)->finalize (object);
+    G_OBJECT_CLASS(nm_http_client_parent_class)->finalize(object);
 
-	g_main_context_unref (priv->context);
+    g_main_context_unref(priv->context);
 
-	curl_global_cleanup ();
+    curl_global_cleanup();
 }
 
 static void
-nm_http_client_class_init (NMHttpClientClass *klass)
+nm_http_client_class_init(NMHttpClientClass *klass)
 {
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
-	object_class->constructed = constructed;
-	object_class->dispose     = dispose;
-	object_class->finalize    = finalize;
+    object_class->constructed = constructed;
+    object_class->dispose     = dispose;
+    object_class->finalize    = finalize;
 
-	nm_http_client_curl_global_init ();
+    nm_http_client_curl_global_init();
 }
diff --git a/clients/cloud-setup/nm-http-client.h b/clients/cloud-setup/nm-http-client.h
index ef7c984a..fc465e35 100644
--- a/clients/cloud-setup/nm-http-client.h
+++ b/clients/cloud-setup/nm-http-client.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #ifndef __NM_HTTP_CLIENT_C__
 #define __NM_HTTP_CLIENT_C__
@@ -8,61 +8,63 @@
 typedef struct _NMHttpClient      NMHttpClient;
 typedef struct _NMHttpClientClass NMHttpClientClass;
 
-#define NM_TYPE_HTTP_CLIENT            (nm_http_client_get_type ())
-#define NM_HTTP_CLIENT(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_HTTP_CLIENT, NMHttpClient))
-#define NM_HTTP_CLIENT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_HTTP_CLIENT, NMHttpClientClass))
-#define NM_IS_HTTP_CLIENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_HTTP_CLIENT))
-#define NM_IS_HTTP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_HTTP_CLIENT))
-#define NM_HTTP_CLIENT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_HTTP_CLIENT, NMHttpClientClass))
+#define NM_TYPE_HTTP_CLIENT (nm_http_client_get_type())
+#define NM_HTTP_CLIENT(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_HTTP_CLIENT, NMHttpClient))
+#define NM_HTTP_CLIENT_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_HTTP_CLIENT, NMHttpClientClass))
+#define NM_IS_HTTP_CLIENT(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_HTTP_CLIENT))
+#define NM_IS_HTTP_CLIENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_HTTP_CLIENT))
+#define NM_HTTP_CLIENT_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_HTTP_CLIENT, NMHttpClientClass))
 
-GType nm_http_client_get_type (void);
+GType nm_http_client_get_type(void);
 
-NMHttpClient *nm_http_client_new (void);
+NMHttpClient *nm_http_client_new(void);
 
 /*****************************************************************************/
 
-GMainContext *nm_http_client_get_main_context (NMHttpClient *self);
+GMainContext *nm_http_client_get_main_context(NMHttpClient *self);
 
 /*****************************************************************************/
 
-void nm_http_client_get (NMHttpClient *self,
-                         const char *uri,
-                         int timeout_msec,
-                         gssize max_data,
-                         const char *const *http_headers,
-                         GCancellable *cancellable,
-                         GAsyncReadyCallback callback,
-                         gpointer user_data);
-
-gboolean nm_http_client_get_finish (NMHttpClient *self,
-                                    GAsyncResult *result,
-                                    long *out_response_code,
-                                    GBytes **out_response_data,
-                                    GError **error);
-
-typedef gboolean (*NMHttpClientPollGetCheckFcn) (long response_code,
-                                                 GBytes *response_data,
-                                                 gpointer check_user_data,
-                                                 GError **error);
-
-void nm_http_client_poll_get (NMHttpClient *self,
-                              const char *uri,
-                              int request_timeout_ms,
-                              gssize request_max_data,
-                              int poll_timeout_ms,
-                              int ratelimit_timeout_ms,
-                              const char *const *http_headers,
-                              GCancellable *cancellable,
-                              NMHttpClientPollGetCheckFcn check_fcn,
-                              gpointer check_user_data,
-                              GAsyncReadyCallback callback,
-                              gpointer user_data);
-
-gboolean nm_http_client_poll_get_finish (NMHttpClient *self,
-                                         GAsyncResult *result,
-                                         long *out_response_code,
-                                         GBytes **out_response_data,
-                                         GError **error);
+void nm_http_client_get(NMHttpClient *      self,
+                        const char *        uri,
+                        int                 timeout_msec,
+                        gssize              max_data,
+                        const char *const * http_headers,
+                        GCancellable *      cancellable,
+                        GAsyncReadyCallback callback,
+                        gpointer            user_data);
+
+gboolean nm_http_client_get_finish(NMHttpClient *self,
+                                   GAsyncResult *result,
+                                   long *        out_response_code,
+                                   GBytes **     out_response_data,
+                                   GError **     error);
+
+typedef gboolean (*NMHttpClientPollGetCheckFcn)(long     response_code,
+                                                GBytes * response_data,
+                                                gpointer check_user_data,
+                                                GError **error);
+
+void nm_http_client_poll_get(NMHttpClient *              self,
+                             const char *                uri,
+                             int                         request_timeout_ms,
+                             gssize                      request_max_data,
+                             int                         poll_timeout_ms,
+                             int                         ratelimit_timeout_ms,
+                             const char *const *         http_headers,
+                             GCancellable *              cancellable,
+                             NMHttpClientPollGetCheckFcn check_fcn,
+                             gpointer                    check_user_data,
+                             GAsyncReadyCallback         callback,
+                             gpointer                    user_data);
+
+gboolean nm_http_client_poll_get_finish(NMHttpClient *self,
+                                        GAsyncResult *result,
+                                        long *        out_response_code,
+                                        GBytes **     out_response_data,
+                                        GError **     error);
 
 /*****************************************************************************/
 
diff --git a/clients/cloud-setup/nmcs-provider-azure.c b/clients/cloud-setup/nmcs-provider-azure.c
new file mode 100644
index 00000000..1a80327c
--- /dev/null
+++ b/clients/cloud-setup/nmcs-provider-azure.c
@@ -0,0 +1,530 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include "nm-default.h"
+
+#include "nmcs-provider-azure.h"
+
+#include "nm-cloud-setup-utils.h"
+
+/*****************************************************************************/
+
+#define HTTP_TIMEOUT_MS 3000
+
+#define NM_AZURE_METADATA_HEADER   "Metadata:true"
+#define NM_AZURE_HOST              "169.254.169.254"
+#define NM_AZURE_BASE              "http://" NM_AZURE_HOST
+#define NM_AZURE_API_VERSION       "?format=text&api-version=2017-04-02"
+#define NM_AZURE_METADATA_URL_BASE /* $NM_AZURE_BASE/$NM_AZURE_API_VERSION */ \
+    "/metadata/instance/network/interface/"
+
+#define _azure_uri_concat(...) \
+    nmcs_utils_uri_build_concat(NM_AZURE_BASE, __VA_ARGS__, NM_AZURE_API_VERSION)
+#define _azure_uri_interfaces(...) _azure_uri_concat(NM_AZURE_METADATA_URL_BASE, ##__VA_ARGS__)
+
+/*****************************************************************************/
+
+struct _NMCSProviderAzure {
+    NMCSProvider parent;
+};
+
+struct _NMCSProviderAzureClass {
+    NMCSProviderClass parent;
+};
+
+G_DEFINE_TYPE(NMCSProviderAzure, nmcs_provider_azure, NMCS_TYPE_PROVIDER);
+
+/*****************************************************************************/
+
+static void
+_detect_get_meta_data_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+    gs_unref_object GTask *task     = user_data;
+    gs_free_error GError *get_error = NULL;
+    gs_free_error GError *error     = NULL;
+    gboolean              success;
+
+    success =
+        nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, NULL, &get_error);
+
+    if (nm_utils_error_is_cancelled(get_error)) {
+        g_task_return_error(task, g_steal_pointer(&get_error));
+        return;
+    }
+
+    if (get_error) {
+        nm_utils_error_set(&error,
+                           NM_UTILS_ERROR_UNKNOWN,
+                           "failure to get Azure metadata: %s",
+                           get_error->message);
+        g_task_return_error(task, g_steal_pointer(&error));
+        return;
+    }
+
+    if (!success) {
+        nm_utils_error_set(&error, NM_UTILS_ERROR_UNKNOWN, "failure to detect azure metadata");
+        g_task_return_error(task, g_steal_pointer(&error));
+        return;
+    }
+
+    g_task_return_boolean(task, TRUE);
+}
+
+static void
+detect(NMCSProvider *provider, GTask *task)
+{
+    NMHttpClient *http_client;
+    gs_free char *uri = NULL;
+
+    http_client = nmcs_provider_get_http_client(provider);
+
+    nm_http_client_poll_get(http_client,
+                            (uri = _azure_uri_concat("/metadata/instance")),
+                            HTTP_TIMEOUT_MS,
+                            256 * 1024,
+                            7000,
+                            1000,
+                            NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+                            g_task_get_cancellable(task),
+                            NULL,
+                            NULL,
+                            _detect_get_meta_data_done_cb,
+                            task);
+}
+
+/*****************************************************************************/
+
+typedef struct {
+    NMCSProviderGetConfigTaskData *config_data;
+    guint                          n_ifaces_pending;
+    GError *                       error;
+} AzureData;
+
+typedef struct {
+    NMCSProviderGetConfigIfaceData *iface_get_config;
+    AzureData *                     azure_data;
+    gssize                          iface_idx;
+    guint                           n_ips_prefix_pending;
+    char *                          hwaddr;
+} AzureIfaceData;
+
+static void
+_azure_iface_data_free(AzureIfaceData *iface_data)
+{
+    g_free(iface_data->hwaddr);
+    nm_g_slice_free(iface_data);
+}
+
+static void
+_get_config_maybe_task_return(AzureData *azure_data, GError *error_take)
+{
+    NMCSProviderGetConfigTaskData *config_data = azure_data->config_data;
+
+    if (error_take) {
+        if (!azure_data->error)
+            azure_data->error = error_take;
+        else if (!nm_utils_error_is_cancelled(azure_data->error)
+                 && nm_utils_error_is_cancelled(error_take)) {
+            nm_clear_error(&azure_data->error);
+            azure_data->error = error_take;
+        } else
+            g_error_free(error_take);
+    }
+
+    if (azure_data->n_ifaces_pending > 0)
+        return;
+
+    if (azure_data->error) {
+        if (nm_utils_error_is_cancelled(azure_data->error))
+            _LOGD("get-config: cancelled");
+        else
+            _LOGD("get-config: failed: %s", azure_data->error->message);
+        g_task_return_error(config_data->task, g_steal_pointer(&azure_data->error));
+    } else {
+        _LOGD("get-config: success");
+        g_task_return_pointer(config_data->task,
+                              g_hash_table_ref(config_data->result_dict),
+                              (GDestroyNotify) g_hash_table_unref);
+    }
+
+    nm_g_slice_free(azure_data);
+    g_object_unref(config_data->task);
+}
+
+static void
+_get_config_fetch_done_cb(NMHttpClient *http_client,
+                          GAsyncResult *result,
+                          gpointer      user_data,
+                          gboolean      is_ipv4)
+{
+    NMCSProviderGetConfigIfaceData *iface_get_config;
+    gs_unref_bytes GBytes *response   = NULL;
+    AzureIfaceData *       iface_data = user_data;
+    gs_free_error GError *error       = NULL;
+    const char *          fip_str     = NULL;
+    AzureData *           azure_data;
+
+    azure_data = iface_data->azure_data;
+
+    nm_http_client_poll_get_finish(http_client, result, NULL, &response, &error);
+
+    if (error)
+        goto done;
+
+    if (!error) {
+        in_addr_t tmp_addr;
+        int       tmp_prefix;
+
+        fip_str = g_bytes_get_data(response, NULL);
+        iface_data->iface_get_config =
+            g_hash_table_lookup(azure_data->config_data->result_dict, iface_data->hwaddr);
+        iface_get_config            = iface_data->iface_get_config;
+        iface_get_config->iface_idx = iface_data->iface_idx;
+
+        if (is_ipv4) {
+            if (!nm_utils_parse_inaddr_bin(AF_INET, fip_str, NULL, &tmp_addr)) {
+                error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN,
+                                           "ip is not a valid private ip address");
+                goto done;
+            }
+            _LOGD("interface[%" G_GSSIZE_FORMAT "]: adding private ip %s",
+                  iface_data->iface_idx,
+                  fip_str);
+            iface_get_config->ipv4s_arr[iface_get_config->ipv4s_len] = tmp_addr;
+            iface_get_config->has_ipv4s                              = TRUE;
+            iface_get_config->ipv4s_len++;
+        } else {
+            tmp_prefix = (_nm_utils_ascii_str_to_int64(fip_str, 10, 0, 32, -1));
+
+            if (tmp_prefix == -1) {
+                _LOGD("interface[%" G_GSSIZE_FORMAT "]: invalid prefix %d",
+                      iface_data->iface_idx,
+                      tmp_prefix);
+                goto done;
+            }
+            _LOGD("interface[%" G_GSSIZE_FORMAT "]: adding prefix %d",
+                  iface_data->iface_idx,
+                  tmp_prefix);
+            iface_get_config->cidr_prefix = tmp_prefix;
+            iface_get_config->has_cidr    = TRUE;
+        }
+    }
+
+done:
+    --iface_data->n_ips_prefix_pending;
+    if (iface_data->n_ips_prefix_pending == 0) {
+        _azure_iface_data_free(iface_data);
+        --azure_data->n_ifaces_pending;
+        _get_config_maybe_task_return(azure_data, g_steal_pointer(&error));
+    }
+}
+
+static void
+_get_config_fetch_done_cb_private_ipv4s(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+    _get_config_fetch_done_cb(NM_HTTP_CLIENT(source), result, user_data, TRUE);
+}
+
+static void
+_get_config_fetch_done_cb_subnet_cidr_prefix(GObject *     source,
+                                             GAsyncResult *result,
+                                             gpointer      user_data)
+{
+    _get_config_fetch_done_cb(NM_HTTP_CLIENT(source), result, user_data, FALSE);
+}
+
+static void
+_get_config_ips_prefix_list_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+    gs_unref_bytes GBytes *response    = NULL;
+    AzureIfaceData *       iface_data  = user_data;
+    gs_free_error GError *error        = NULL;
+    const char *          response_str = NULL;
+    gsize                 response_len;
+    AzureData *           azure_data;
+    const char *          line;
+    gsize                 line_len;
+
+    azure_data = iface_data->azure_data;
+
+    nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error);
+    if (error)
+        goto done;
+
+    response_str = g_bytes_get_data(response, &response_len);
+    /* NMHttpClient guarantees that there is a trailing NUL after the data. */
+    nm_assert(response_str[response_len] == 0);
+
+    nm_assert(!iface_data->iface_get_config->has_ipv4s);
+    nm_assert(!iface_data->iface_get_config->ipv4s_arr);
+    nm_assert(!iface_data->iface_get_config->has_cidr);
+
+    while (nm_utils_parse_next_line(&response_str, &response_len, &line, &line_len)) {
+        gint64 ips_prefix_idx;
+
+        if (line_len == 0)
+            continue;
+        /* Truncate the string. It's safe to do, because we own @response_data an it has an
+         * extra NULL character after the buffer. */
+        ((char *) line)[line_len] = '\0';
+
+        if (line[line_len - 1] == '/')
+            ((char *) line)[--line_len] = '\0';
+
+        ips_prefix_idx = _nm_utils_ascii_str_to_int64(line, 10, 0, G_MAXINT64, -1);
+
+        if (ips_prefix_idx < 0)
+            continue;
+
+        {
+            gs_free const char *uri = NULL;
+            char                buf[100];
+
+            iface_data->n_ips_prefix_pending++;
+
+            nm_http_client_poll_get(
+                NM_HTTP_CLIENT(source),
+                (uri = _azure_uri_interfaces(nm_sprintf_buf(
+                     buf,
+                     "%" G_GSSIZE_FORMAT "/ipv4/ipAddress/%" G_GINT64_FORMAT "/privateIpAddress",
+                     iface_data->iface_idx,
+                     ips_prefix_idx))),
+                HTTP_TIMEOUT_MS,
+                512 * 1024,
+                10000,
+                1000,
+                NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+                g_task_get_cancellable(azure_data->config_data->task),
+                NULL,
+                NULL,
+                _get_config_fetch_done_cb_private_ipv4s,
+                iface_data);
+        }
+    }
+
+    iface_data->iface_get_config->ipv4s_len = 0;
+    iface_data->iface_get_config->ipv4s_arr = g_new(in_addr_t, iface_data->n_ips_prefix_pending);
+
+    {
+        gs_free const char *uri = NULL;
+        char                buf[30];
+
+        iface_data->n_ips_prefix_pending++;
+        nm_http_client_poll_get(
+            NM_HTTP_CLIENT(source),
+            (uri = _azure_uri_interfaces(
+                 nm_sprintf_buf(buf, "%" G_GSSIZE_FORMAT, iface_data->iface_idx),
+                 "/ipv4/subnet/0/prefix/")),
+            HTTP_TIMEOUT_MS,
+            512 * 1024,
+            10000,
+            1000,
+            NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+            g_task_get_cancellable(azure_data->config_data->task),
+            NULL,
+            NULL,
+            _get_config_fetch_done_cb_subnet_cidr_prefix,
+            iface_data);
+    }
+    return;
+
+done:
+    _azure_iface_data_free(iface_data);
+    --azure_data->n_ifaces_pending;
+    _get_config_maybe_task_return(azure_data, g_steal_pointer(&error));
+}
+
+static void
+_get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+    gs_unref_bytes GBytes *response   = NULL;
+    AzureIfaceData *       iface_data = user_data;
+    gs_free_error GError *error       = NULL;
+    gs_free const char *  uri         = NULL;
+    char                  buf[100];
+    AzureData *           azure_data;
+
+    azure_data = iface_data->azure_data;
+
+    nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error);
+
+    if (error)
+        goto done;
+
+    iface_data->hwaddr = nmcs_utils_hwaddr_normalize(g_bytes_get_data(response, NULL), -1);
+
+    if (!iface_data->hwaddr) {
+        goto done;
+    }
+
+    iface_data->iface_get_config =
+        g_hash_table_lookup(azure_data->config_data->result_dict, iface_data->hwaddr);
+
+    if (!iface_data->iface_get_config) {
+        if (!iface_data->azure_data->config_data->any) {
+            _LOGD("interface[%" G_GSSIZE_FORMAT "]: ignore hwaddr %s",
+                  iface_data->iface_idx,
+                  iface_data->hwaddr);
+            goto done;
+        }
+        iface_data->iface_get_config = nmcs_provider_get_config_iface_data_new(FALSE);
+        g_hash_table_insert(azure_data->config_data->result_dict,
+                            g_strdup(iface_data->hwaddr),
+                            iface_data->iface_get_config);
+    }
+
+    _LOGD("interface[%" G_GSSIZE_FORMAT "]: found a matching device with hwaddr %s",
+          iface_data->iface_idx,
+          iface_data->hwaddr);
+
+    nm_sprintf_buf(buf, "%" G_GSSIZE_FORMAT "/ipv4/ipAddress/", iface_data->iface_idx);
+
+    nm_http_client_poll_get(NM_HTTP_CLIENT(source),
+                            (uri = _azure_uri_interfaces(buf)),
+                            HTTP_TIMEOUT_MS,
+                            512 * 1024,
+                            10000,
+                            1000,
+                            NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+                            g_task_get_cancellable(azure_data->config_data->task),
+                            NULL,
+                            NULL,
+                            _get_config_ips_prefix_list_cb,
+                            iface_data);
+    return;
+
+done:
+    nm_g_slice_free(iface_data);
+    --azure_data->n_ifaces_pending;
+    _get_config_maybe_task_return(azure_data, g_steal_pointer(&error));
+}
+
+static void
+_get_net_ifaces_list_cb(GObject *source, GAsyncResult *result, gpointer user_data)
+{
+    gs_unref_ptrarray GPtrArray *ifaces_arr = NULL;
+    gs_unref_bytes GBytes *response         = NULL;
+    gs_free_error GError *error             = NULL;
+    AzureData *           azure_data        = user_data;
+    const char *          response_str;
+    gsize                 response_len;
+    const char *          line;
+    gsize                 line_len;
+    guint                 i;
+
+    nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error);
+
+    if (error) {
+        _get_config_maybe_task_return(azure_data, g_steal_pointer(&error));
+        return;
+    }
+
+    response_str = g_bytes_get_data(response, &response_len);
+    /* NMHttpClient guarantees that there is a trailing NUL after the data. */
+    nm_assert(response_str[response_len] == 0);
+
+    ifaces_arr = g_ptr_array_new();
+
+    while (nm_utils_parse_next_line(&response_str, &response_len, &line, &line_len)) {
+        AzureIfaceData *iface_data;
+        gssize          iface_idx;
+
+        if (line_len == 0)
+            continue;
+
+        /* Truncate the string. It's safe to do, because we own @response_data an it has an
+         * extra NULL character after the buffer. */
+        ((char *) line)[line_len] = '\0';
+
+        if (line[line_len - 1] == '/' && line_len != 0)
+            ((char *) line)[--line_len] = '\0';
+
+        iface_idx = _nm_utils_ascii_str_to_int64(line, 10, 0, G_MAXSSIZE, -1);
+        if (iface_idx < 0)
+            continue;
+
+        iface_data  = g_slice_new(AzureIfaceData);
+        *iface_data = (AzureIfaceData){
+            .iface_get_config     = NULL,
+            .azure_data           = azure_data,
+            .iface_idx            = iface_idx,
+            .n_ips_prefix_pending = 0,
+            .hwaddr               = NULL,
+        };
+        g_ptr_array_add(ifaces_arr, iface_data);
+    }
+
+    _LOGD("found azure interfaces: %u", ifaces_arr->len);
+
+    if (ifaces_arr->len == 0) {
+        error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, "no Azure interfaces found");
+        _get_config_maybe_task_return(azure_data, g_steal_pointer(&error));
+        return;
+    }
+
+    for (i = 0; i < ifaces_arr->len; ++i) {
+        AzureIfaceData *    data = ifaces_arr->pdata[i];
+        gs_free const char *uri  = NULL;
+        char                buf[100];
+
+        _LOGD("azure interface[%" G_GSSIZE_FORMAT "]: retrieving configuration", data->iface_idx);
+
+        nm_sprintf_buf(buf, "%" G_GSSIZE_FORMAT "/macAddress", data->iface_idx);
+
+        azure_data->n_ifaces_pending++;
+        nm_http_client_poll_get(NM_HTTP_CLIENT(source),
+                                (uri = _azure_uri_interfaces(buf)),
+                                HTTP_TIMEOUT_MS,
+                                512 * 1024,
+                                10000,
+                                1000,
+                                NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+                                g_task_get_cancellable(azure_data->config_data->task),
+                                NULL,
+                                NULL,
+                                _get_config_iface_cb,
+                                data);
+    }
+}
+
+static void
+get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_data)
+{
+    gs_free const char *uri = NULL;
+    AzureData *         azure_data;
+
+    azure_data  = g_slice_new(AzureData);
+    *azure_data = (AzureData){
+        .config_data      = get_config_data,
+        .n_ifaces_pending = 0,
+    };
+
+    nm_http_client_poll_get(nmcs_provider_get_http_client(provider),
+                            (uri = _azure_uri_interfaces()),
+                            HTTP_TIMEOUT_MS,
+                            256 * 1024,
+                            15000,
+                            1000,
+                            NM_MAKE_STRV(NM_AZURE_METADATA_HEADER),
+                            g_task_get_cancellable(get_config_data->task),
+                            NULL,
+                            NULL,
+                            _get_net_ifaces_list_cb,
+                            azure_data);
+}
+
+/*****************************************************************************/
+
+static void
+nmcs_provider_azure_init(NMCSProviderAzure *self)
+{}
+
+static void
+nmcs_provider_azure_class_init(NMCSProviderAzureClass *klass)
+{
+    NMCSProviderClass *provider_class = NMCS_PROVIDER_CLASS(klass);
+
+    provider_class->_name                 = "azure";
+    provider_class->_env_provider_enabled = NMCS_ENV_VARIABLE("NM_CLOUD_SETUP_AZURE");
+    provider_class->detect                = detect;
+    provider_class->get_config            = get_config;
+}
diff --git a/clients/cloud-setup/nmcs-provider-azure.h b/clients/cloud-setup/nmcs-provider-azure.h
new file mode 100644
index 00000000..849e94c1
--- /dev/null
+++ b/clients/cloud-setup/nmcs-provider-azure.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#ifndef __NMCS_PROVIDER_AZURE_H__
+#define __NMCS_PROVIDER_AZURE_H__
+
+#include "nmcs-provider.h"
+
+/*****************************************************************************/
+
+typedef struct _NMCSProviderAzure      NMCSProviderAzure;
+typedef struct _NMCSProviderAzureClass NMCSProviderAzureClass;
+
+#define NMCS_TYPE_PROVIDER_AZURE (nmcs_provider_azure_get_type())
+#define NMCS_PROVIDER_AZURE(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST((obj), NMCS_TYPE_PROVIDER_AZURE, NMCSProviderAzure))
+#define NMCS_PROVIDER_AZURE_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST((klass), NMCS_TYPE_PROVIDER_AZURE, NMCSProviderAzureClass))
+#define NMCS_IS_PROVIDER_AZURE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMCS_TYPE_PROVIDER_AZURE))
+#define NMCS_IS_PROVIDER_AZURE_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE((klass), NMCS_TYPE_PROVIDER_AZURE))
+#define NMCS_PROVIDER_AZURE_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS((obj), NMCS_TYPE_PROVIDER_AZURE, NMCSProviderAzureClass))
+
+GType nmcs_provider_azure_get_type(void);
+
+/*****************************************************************************/
+
+#endif /* __NMCS_PROVIDER_AZURE_H__ */
diff --git a/clients/cloud-setup/nmcs-provider-ec2.c b/clients/cloud-setup/nmcs-provider-ec2.c
index 3b5f6d36..fb82914f 100644
--- a/clients/cloud-setup/nmcs-provider-ec2.c
+++ b/clients/cloud-setup/nmcs-provider-ec2.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "nm-default.h"
 
@@ -10,550 +10,509 @@
 
 #define HTTP_TIMEOUT_MS 3000
 
-#define NM_EC2_HOST               "169.254.169.254"
-#define NM_EC2_BASE               "http://" NM_EC2_HOST
-#define NM_EC2_API_VERSION        "2018-09-24"
-#define NM_EC2_METADATA_URL_BASE  /* $NM_EC2_BASE/$NM_EC2_API_VERSION */ "/meta-data/network/interfaces/macs/"
+#define NM_EC2_HOST              "169.254.169.254"
+#define NM_EC2_BASE              "http://" NM_EC2_HOST
+#define NM_EC2_API_VERSION       "2018-09-24"
+#define NM_EC2_METADATA_URL_BASE /* $NM_EC2_BASE/$NM_EC2_API_VERSION */ \
+    "/meta-data/network/interfaces/macs/"
 
 static const char *
-_ec2_base (void)
+_ec2_base(void)
 {
-	static const char *base_cached = NULL;
-	const char *base;
+    static const char *base_cached = NULL;
+    const char *       base;
 
 again:
-	base = g_atomic_pointer_get (&base_cached);
-	if (G_UNLIKELY (!base)) {
-
-		/* The base URI can be set via environment variable.
-		 * This is mainly for testing, it's not usually supposed to be configured.
-		 * Consider this private API! */
-		base = g_getenv (NMCS_ENV_VARIABLE ("NM_CLOUD_SETUP_EC2_HOST"));
-
-		if (   base
-		    && base[0]
-		    && !strchr (base, '/')) {
-			if (   NM_STR_HAS_PREFIX (base, "http://")
-			    || NM_STR_HAS_PREFIX (base, "https://"))
-				base = g_intern_string (base);
-			else {
-				gs_free char *s = NULL;
-
-				s = g_strconcat ("http://", base, NULL);
-				base = g_intern_string (s);
-			}
-		}
-		if (!base)
-			base = NM_EC2_BASE;
-
-		nm_assert (!NM_STR_HAS_SUFFIX (base, "/"));
-
-		if (!g_atomic_pointer_compare_and_exchange (&base_cached, NULL, base))
-			goto again;
-	}
-
-	return base;
+    base = g_atomic_pointer_get(&base_cached);
+    if (G_UNLIKELY(!base)) {
+        /* The base URI can be set via environment variable.
+         * This is mainly for testing, it's not usually supposed to be configured.
+         * Consider this private API! */
+        base = g_getenv(NMCS_ENV_VARIABLE("NM_CLOUD_SETUP_EC2_HOST"));
+
+        if (base && base[0] && !strchr(base, '/')) {
+            if (NM_STR_HAS_PREFIX(base, "http://") || NM_STR_HAS_PREFIX(base, "https://"))
+                base = g_intern_string(base);
+            else {
+                gs_free char *s = NULL;
+
+                s    = g_strconcat("http://", base, NULL);
+                base = g_intern_string(s);
+            }
+        }
+        if (!base)
+            base = NM_EC2_BASE;
+
+        nm_assert(!NM_STR_HAS_SUFFIX(base, "/"));
+
+        if (!g_atomic_pointer_compare_and_exchange(&base_cached, NULL, base))
+            goto again;
+    }
+
+    return base;
 }
 
-#define _ec2_uri_concat(...)     nmcs_utils_uri_build_concat (_ec2_base (), __VA_ARGS__)
-#define _ec2_uri_interfaces(...) _ec2_uri_concat (NM_EC2_API_VERSION, NM_EC2_METADATA_URL_BASE, ##__VA_ARGS__)
+#define _ec2_uri_concat(...) nmcs_utils_uri_build_concat(_ec2_base(), __VA_ARGS__)
+#define _ec2_uri_interfaces(...) \
+    _ec2_uri_concat(NM_EC2_API_VERSION, NM_EC2_METADATA_URL_BASE, ##__VA_ARGS__)
 
 /*****************************************************************************/
 
 struct _NMCSProviderEC2 {
-	NMCSProvider parent;
+    NMCSProvider parent;
 };
 
 struct _NMCSProviderEC2Class {
-	NMCSProviderClass parent;
+    NMCSProviderClass parent;
 };
 
-G_DEFINE_TYPE (NMCSProviderEC2, nmcs_provider_ec2, NMCS_TYPE_PROVIDER);
+G_DEFINE_TYPE(NMCSProviderEC2, nmcs_provider_ec2, NMCS_TYPE_PROVIDER);
 
 /*****************************************************************************/
 
 static gboolean
-_detect_get_meta_data_check_cb (long response_code,
-                                GBytes *response_data,
-                                gpointer check_user_data,
-                                GError **error)
+_detect_get_meta_data_check_cb(long     response_code,
+                               GBytes * response_data,
+                               gpointer check_user_data,
+                               GError **error)
 {
-	return    response_code == 200
-	       && nmcs_utils_parse_get_full_line (response_data, "ami-id");
+    return response_code == 200 && nmcs_utils_parse_get_full_line(response_data, "ami-id");
 }
 
 static void
-_detect_get_meta_data_done_cb (GObject *source,
-                               GAsyncResult *result,
-                               gpointer user_data)
+_detect_get_meta_data_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	gs_unref_object GTask *task = user_data;
-	gs_free_error GError *get_error = NULL;
-	gs_free_error GError *error = NULL;
-	gboolean success;
-
-	success = nm_http_client_poll_get_finish (NM_HTTP_CLIENT (source),
-	                                          result,
-	                                          NULL,
-	                                          NULL,
-	                                          &get_error);
-
-	if (nm_utils_error_is_cancelled (get_error)) {
-		g_task_return_error (task, g_steal_pointer (&get_error));
-		return;
-	}
-
-	if (get_error) {
-		nm_utils_error_set (&error,
-		                    NM_UTILS_ERROR_UNKNOWN,
-		                    "failure to get EC2 metadata: %s",
-		                    get_error->message);
-		g_task_return_error (task, g_steal_pointer (&error));
-		return;
-	}
-
-	if (!success) {
-		nm_utils_error_set (&error,
-		                    NM_UTILS_ERROR_UNKNOWN,
-		                    "failure to detect EC2 metadata");
-		g_task_return_error (task, g_steal_pointer (&error));
-		return;
-	}
-
-	g_task_return_boolean (task, TRUE);
+    gs_unref_object GTask *task     = user_data;
+    gs_free_error GError *get_error = NULL;
+    gs_free_error GError *error     = NULL;
+
+    nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, NULL, &get_error);
+
+    if (nm_utils_error_is_cancelled(get_error)) {
+        g_task_return_error(task, g_steal_pointer(&get_error));
+        return;
+    }
+
+    if (get_error) {
+        nm_utils_error_set(&error,
+                           NM_UTILS_ERROR_UNKNOWN,
+                           "failure to get EC2 metadata: %s",
+                           get_error->message);
+        g_task_return_error(task, g_steal_pointer(&error));
+        return;
+    }
+
+    g_task_return_boolean(task, TRUE);
 }
 
 static void
-detect (NMCSProvider *provider,
-        GTask *task)
+detect(NMCSProvider *provider, GTask *task)
 {
-	NMHttpClient *http_client;
-	gs_free char *uri = NULL;
-
-	http_client = nmcs_provider_get_http_client (provider);
-
-	nm_http_client_poll_get (http_client,
-	                         (uri = _ec2_uri_concat ("latest/meta-data/")),
-	                         HTTP_TIMEOUT_MS,
-	                         256*1024,
-	                         7000,
-	                         1000,
-	                         NULL,
-	                         g_task_get_cancellable (task),
-	                         _detect_get_meta_data_check_cb,
-	                         NULL,
-	                         _detect_get_meta_data_done_cb,
-	                         task);
+    NMHttpClient *http_client;
+    gs_free char *uri = NULL;
+
+    http_client = nmcs_provider_get_http_client(provider);
+
+    nm_http_client_poll_get(http_client,
+                            (uri = _ec2_uri_concat("latest/meta-data/")),
+                            HTTP_TIMEOUT_MS,
+                            256 * 1024,
+                            7000,
+                            1000,
+                            NULL,
+                            g_task_get_cancellable(task),
+                            _detect_get_meta_data_check_cb,
+                            NULL,
+                            _detect_get_meta_data_done_cb,
+                            task);
 }
 
 /*****************************************************************************/
 
 typedef struct {
-	NMCSProviderGetConfigTaskData *get_config_data;
-	GCancellable *cancellable;
-	gulong cancelled_id;
-	guint n_pending;
+    NMCSProviderGetConfigTaskData *get_config_data;
+    GError *                       error;
+    GCancellable *                 cancellable;
+    gulong                         cancelled_id;
+    guint                          n_pending;
 } GetConfigIfaceData;
 
 static void
-_get_config_task_return (GetConfigIfaceData *iface_data,
-                         GError *error_take)
+_get_config_task_maybe_return(GetConfigIfaceData *iface_data, GError *error_take)
 {
-	NMCSProviderGetConfigTaskData *get_config_data = iface_data->get_config_data;
-
-	nm_clear_g_cancellable_disconnect (g_task_get_cancellable (get_config_data->task),
-	                                   &iface_data->cancelled_id);
-
-	nm_clear_g_cancellable (&iface_data->cancellable);
-
-	nm_g_slice_free (iface_data);
-
-	if (error_take) {
-		if (nm_utils_error_is_cancelled (error_take))
-			_LOGD ("get-config: cancelled");
-		else
-			_LOGD ("get-config: failed: %s", error_take->message);
-		g_task_return_error (get_config_data->task, error_take);
-	} 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);
-	}
-
-	g_object_unref (get_config_data->task);
+    NMCSProviderGetConfigTaskData *get_config_data = iface_data->get_config_data;
+
+    if (error_take) {
+        if (!iface_data->error)
+            iface_data->error = error_take;
+        else if (!nm_utils_error_is_cancelled(iface_data->error)
+                 && nm_utils_error_is_cancelled(error_take)) {
+            nm_clear_error(&iface_data->error);
+            iface_data->error = error_take;
+        } else
+            g_error_free(error_take);
+    }
+
+    if (iface_data->n_pending > 0)
+        return;
+
+    nm_clear_g_cancellable_disconnect(g_task_get_cancellable(get_config_data->task),
+                                      &iface_data->cancelled_id);
+
+    nm_clear_g_cancellable(&iface_data->cancellable);
+
+    if (iface_data->error) {
+        if (nm_utils_error_is_cancelled(iface_data->error))
+            _LOGD("get-config: cancelled");
+        else
+            _LOGD("get-config: failed: %s", iface_data->error->message);
+        g_task_return_error(get_config_data->task, g_steal_pointer(&iface_data->error));
+    } 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);
+    }
+
+    nm_g_slice_free(iface_data);
+    g_object_unref(get_config_data->task);
 }
 
 static void
-_get_config_fetch_done_cb (NMHttpClient *http_client,
-                           GAsyncResult *result,
-                           gpointer user_data,
-                           gboolean is_local_ipv4)
+_get_config_fetch_done_cb(NMHttpClient *http_client,
+                          GAsyncResult *result,
+                          gpointer      user_data,
+                          gboolean      is_local_ipv4)
 {
-	GetConfigIfaceData *iface_data;
-	NMCSProviderGetConfigTaskData *get_config_data;
-	const char *hwaddr = NULL;
-	gs_unref_bytes GBytes *response_data = NULL;
-	gs_free_error GError *error = NULL;
-	gboolean success;
-	NMCSProviderGetConfigIfaceData *config_iface_data;
-
-	nm_utils_user_data_unpack (user_data, &iface_data, &hwaddr);
-
-	success = nm_http_client_poll_get_finish (http_client,
-	                                          result,
-	                                          NULL,
-	                                          &response_data,
-	                                          &error);
-	if (nm_utils_error_is_cancelled (error))
-		return;
-
-	get_config_data = iface_data->get_config_data;
-
-	config_iface_data = g_hash_table_lookup (get_config_data->result_dict, hwaddr);
-
-	if (success) {
-		in_addr_t tmp_addr;
-		int tmp_prefix;
-
-		if (is_local_ipv4) {
-			gs_free const char **s_addrs = NULL;
-			gsize i, len;
-
-			s_addrs = nm_utils_strsplit_set_full (g_bytes_get_data (response_data, NULL), "\n", NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP);
-			len = NM_PTRARRAY_LEN (s_addrs);
-
-			nm_assert (!config_iface_data->has_ipv4s);
-			nm_assert (!config_iface_data->ipv4s_arr);
-			config_iface_data->has_ipv4s = TRUE;
-			config_iface_data->ipv4s_len = 0;
-			if (len > 0) {
-				config_iface_data->ipv4s_arr = g_new (in_addr_t, len);
-
-				for (i = 0; i < len; i++) {
-					if (nm_utils_parse_inaddr_bin (AF_INET,
-					                               s_addrs[i],
-					                               NULL,
-					                               &tmp_addr))
-						config_iface_data->ipv4s_arr[config_iface_data->ipv4s_len++] = tmp_addr;
-				}
-			}
-		} else {
-			if (nm_utils_parse_inaddr_prefix_bin (AF_INET,
-			                                      g_bytes_get_data (response_data, NULL),
-			                                      NULL,
-			                                      &tmp_addr,
-			                                      &tmp_prefix)) {
-				nm_assert (!config_iface_data->has_cidr);
-				config_iface_data->has_cidr = TRUE;
-				config_iface_data->cidr_prefix = tmp_prefix;
-				config_iface_data->cidr_addr = tmp_addr;
-			}
-		}
-	}
-
-	if (--iface_data->n_pending > 0)
-		return;
-
-	_get_config_task_return (iface_data, NULL);
+    GetConfigIfaceData *iface_data;
+    const char *        hwaddr           = NULL;
+    gs_unref_bytes GBytes *response_data = NULL;
+    gs_free_error GError *error          = NULL;
+
+    nm_utils_user_data_unpack(user_data, &iface_data, &hwaddr);
+
+    nm_http_client_poll_get_finish(http_client, result, NULL, &response_data, &error);
+
+    if (!error) {
+        NMCSProviderGetConfigIfaceData *config_iface_data;
+        in_addr_t                       tmp_addr;
+        int                             tmp_prefix;
+
+        config_iface_data = g_hash_table_lookup(iface_data->get_config_data->result_dict, hwaddr);
+
+        if (is_local_ipv4) {
+            gs_free const char **s_addrs = NULL;
+            gsize                i, len;
+
+            s_addrs = nm_utils_strsplit_set_full(g_bytes_get_data(response_data, NULL),
+                                                 "\n",
+                                                 NM_UTILS_STRSPLIT_SET_FLAGS_STRSTRIP);
+            len     = NM_PTRARRAY_LEN(s_addrs);
+
+            nm_assert(!config_iface_data->has_ipv4s);
+            nm_assert(!config_iface_data->ipv4s_arr);
+            config_iface_data->has_ipv4s = TRUE;
+            config_iface_data->ipv4s_len = 0;
+            if (len > 0) {
+                config_iface_data->ipv4s_arr = g_new(in_addr_t, len);
+
+                for (i = 0; i < len; i++) {
+                    if (nm_utils_parse_inaddr_bin(AF_INET, s_addrs[i], NULL, &tmp_addr))
+                        config_iface_data->ipv4s_arr[config_iface_data->ipv4s_len++] = tmp_addr;
+                }
+            }
+        } else {
+            if (nm_utils_parse_inaddr_prefix_bin(AF_INET,
+                                                 g_bytes_get_data(response_data, NULL),
+                                                 NULL,
+                                                 &tmp_addr,
+                                                 &tmp_prefix)) {
+                nm_assert(!config_iface_data->has_cidr);
+                config_iface_data->has_cidr    = TRUE;
+                config_iface_data->cidr_prefix = tmp_prefix;
+                config_iface_data->cidr_addr   = tmp_addr;
+            }
+        }
+    }
+
+    iface_data->n_pending--;
+    _get_config_task_maybe_return(iface_data, g_steal_pointer(&error));
 }
 
 static void
-_get_config_fetch_done_cb_subnet_ipv4_cidr_block (GObject *source,
-                                                  GAsyncResult *result,
-                                                  gpointer user_data)
+_get_config_fetch_done_cb_subnet_ipv4_cidr_block(GObject *     source,
+                                                 GAsyncResult *result,
+                                                 gpointer      user_data)
 {
-	_get_config_fetch_done_cb (NM_HTTP_CLIENT (source), result, user_data, FALSE);
+    _get_config_fetch_done_cb(NM_HTTP_CLIENT(source), result, user_data, FALSE);
 }
 
 static void
-_get_config_fetch_done_cb_local_ipv4s (GObject *source,
-                                       GAsyncResult *result,
-                                       gpointer user_data)
+_get_config_fetch_done_cb_local_ipv4s(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	_get_config_fetch_done_cb (NM_HTTP_CLIENT (source), result, user_data, TRUE);
+    _get_config_fetch_done_cb(NM_HTTP_CLIENT(source), result, user_data, TRUE);
 }
 
 static void
-_get_config_fetch_cancelled_cb (GObject *object, gpointer user_data)
+_get_config_fetch_cancelled_cb(GObject *object, gpointer user_data)
 {
-	GetConfigIfaceData *iface_data = user_data;
+    GetConfigIfaceData *iface_data = user_data;
 
-	if (iface_data->cancelled_id == 0)
-		return;
+    if (iface_data->cancelled_id == 0)
+        return;
 
-	nm_clear_g_signal_handler (g_task_get_cancellable (iface_data->get_config_data->task),
-	                           &iface_data->cancelled_id);
-	_get_config_task_return (iface_data,
-	                         nm_utils_error_new_cancelled (FALSE, NULL));
+    nm_clear_g_signal_handler(g_task_get_cancellable(iface_data->get_config_data->task),
+                              &iface_data->cancelled_id);
+    _get_config_task_maybe_return(iface_data, nm_utils_error_new_cancelled(FALSE, NULL));
 }
 
 typedef struct {
-	NMCSProviderGetConfigTaskData *get_config_data;
-	GHashTable *response_parsed;
+    NMCSProviderGetConfigTaskData *get_config_data;
+    GHashTable *                   response_parsed;
 } GetConfigMetadataData;
 
 typedef struct {
-	gssize iface_idx;
-	char path[0];
+    gssize iface_idx;
+    char   path[0];
 } GetConfigMetadataMac;
 
 static void
-_get_config_metadata_ready_cb (GObject *source,
-                               GAsyncResult *result,
-                               gpointer user_data)
+_get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	GetConfigMetadataData *metadata_data = user_data;
-	GetConfigIfaceData *iface_data;
-	NMCSProviderGetConfigTaskData *get_config_data = metadata_data->get_config_data;
-	gs_unref_hashtable GHashTable *response_parsed = g_steal_pointer (&metadata_data->response_parsed);
-	gs_free_error GError *error = NULL;
-	GCancellable *cancellable;
-	GetConfigMetadataMac *v_mac_data;
-	const char *v_hwaddr;
-	GHashTableIter h_iter;
-	NMHttpClient *http_client;
-
-	nm_g_slice_free (metadata_data);
-
-	nm_http_client_poll_get_finish (NM_HTTP_CLIENT (source),
-	                                result,
-	                                NULL,
-	                                NULL,
-	                                &error);
-
-	iface_data = g_slice_new (GetConfigIfaceData);
-	*iface_data = (GetConfigIfaceData) {
-		.get_config_data = get_config_data,
-		.n_pending       = 0,
-	};
-
-	if (nm_utils_error_is_cancelled (error)) {
-		_get_config_task_return (iface_data, g_steal_pointer (&error));
-		return;
-	}
-
-	/* We ignore errors. Only if we got no response at all, it's a problem.
-	 * Otherwise, we proceed with whatever we could fetch. */
-	if (!response_parsed) {
-		_get_config_task_return (iface_data,
-		                         nm_utils_error_new (NM_UTILS_ERROR_UNKNOWN,
-		                                             "meta data for interfaces not found"));
-		return;
-	}
-
-	cancellable = g_task_get_cancellable (get_config_data->task);
-	if (cancellable) {
-		gulong cancelled_id;
-
-		cancelled_id = g_cancellable_connect (cancellable,
-		                                      G_CALLBACK (_get_config_fetch_cancelled_cb),
-		                                      iface_data,
-		                                      NULL);
-		if (cancelled_id == 0) {
-			_get_config_task_return (iface_data,
-			                         nm_utils_error_new_cancelled (FALSE, NULL));
-			return;
-		}
-
-		iface_data->cancelled_id = cancelled_id;
-	}
-
-	iface_data->cancellable = g_cancellable_new ();
-
-	http_client = nmcs_provider_get_http_client (g_task_get_source_object (get_config_data->task));
-
-	g_hash_table_iter_init (&h_iter, response_parsed);
-	while (g_hash_table_iter_next (&h_iter, (gpointer *) &v_hwaddr, (gpointer *) &v_mac_data)) {
-		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)) {
-			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);
-		}
-
-		nm_assert (config_iface_data->iface_idx == -1);
-		config_iface_data->iface_idx = v_mac_data->iface_idx;
-
-		_LOGD ("get-config: start fetching meta data for #%"G_GSSIZE_FORMAT", %s (%s)", config_iface_data->iface_idx, hwaddr, v_mac_data->path);
-
-		iface_data->n_pending++;
-		nm_http_client_poll_get (http_client,
-		                         (uri1 = _ec2_uri_interfaces (v_mac_data->path,
-		                                                        NM_STR_HAS_SUFFIX (v_mac_data->path, "/")
-		                                                      ? ""
-		                                                      : "/",
-		                                                      "subnet-ipv4-cidr-block")),
-		                         HTTP_TIMEOUT_MS,
-		                         512*1024,
-		                         10000,
-		                         1000,
-		                         NULL,
-		                         iface_data->cancellable,
-		                         NULL,
-		                         NULL,
-		                         _get_config_fetch_done_cb_subnet_ipv4_cidr_block,
-		                         nm_utils_user_data_pack (iface_data, hwaddr));
-
-		iface_data->n_pending++;
-		nm_http_client_poll_get (http_client,
-		                         (uri2 = _ec2_uri_interfaces (v_mac_data->path,
-		                                                        NM_STR_HAS_SUFFIX (v_mac_data->path, "/")
-		                                                      ? ""
-		                                                      : "/",
-		                                                      "local-ipv4s")),
-		                         HTTP_TIMEOUT_MS,
-		                         512*1024,
-		                         10000,
-		                         1000,
-		                         NULL,
-		                         iface_data->cancellable,
-		                         NULL,
-		                         NULL,
-		                         _get_config_fetch_done_cb_local_ipv4s,
-		                         nm_utils_user_data_pack (iface_data, hwaddr));
-	}
-
-	if (iface_data->n_pending == 0)
-		_get_config_task_return (iface_data, NULL);
+    GetConfigMetadataData *        metadata_data = user_data;
+    GetConfigIfaceData *           iface_data;
+    NMCSProviderGetConfigTaskData *get_config_data = metadata_data->get_config_data;
+    gs_unref_hashtable GHashTable *response_parsed =
+        g_steal_pointer(&metadata_data->response_parsed);
+    gs_free_error GError *error = NULL;
+    GCancellable *        cancellable;
+    GetConfigMetadataMac *v_mac_data;
+    const char *          v_hwaddr;
+    GHashTableIter        h_iter;
+    NMHttpClient *        http_client;
+
+    nm_g_slice_free(metadata_data);
+
+    nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, NULL, &error);
+
+    iface_data  = g_slice_new(GetConfigIfaceData);
+    *iface_data = (GetConfigIfaceData){
+        .get_config_data = get_config_data,
+        .n_pending       = 0,
+    };
+
+    if (nm_utils_error_is_cancelled(error)) {
+        _get_config_task_maybe_return(iface_data, g_steal_pointer(&error));
+        return;
+    }
+
+    /* We ignore errors. Only if we got no response at all, it's a problem.
+     * Otherwise, we proceed with whatever we could fetch. */
+    if (!response_parsed) {
+        _get_config_task_maybe_return(
+            iface_data,
+            nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, "meta data for interfaces not found"));
+        return;
+    }
+
+    cancellable = g_task_get_cancellable(get_config_data->task);
+    if (cancellable) {
+        gulong cancelled_id;
+
+        cancelled_id = g_cancellable_connect(cancellable,
+                                             G_CALLBACK(_get_config_fetch_cancelled_cb),
+                                             iface_data,
+                                             NULL);
+        if (cancelled_id == 0) {
+            _get_config_task_maybe_return(iface_data, nm_utils_error_new_cancelled(FALSE, NULL));
+            return;
+        }
+
+        iface_data->cancelled_id = cancelled_id;
+    }
+
+    iface_data->cancellable = g_cancellable_new();
+
+    http_client = nmcs_provider_get_http_client(g_task_get_source_object(get_config_data->task));
+
+    g_hash_table_iter_init(&h_iter, response_parsed);
+    while (g_hash_table_iter_next(&h_iter, (gpointer *) &v_hwaddr, (gpointer *) &v_mac_data)) {
+        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)) {
+            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);
+        }
+
+        nm_assert(config_iface_data->iface_idx == -1);
+        config_iface_data->iface_idx = v_mac_data->iface_idx;
+
+        _LOGD("get-config: start fetching meta data for #%" G_GSSIZE_FORMAT ", %s (%s)",
+              config_iface_data->iface_idx,
+              hwaddr,
+              v_mac_data->path);
+
+        iface_data->n_pending++;
+        nm_http_client_poll_get(
+            http_client,
+            (uri1 = _ec2_uri_interfaces(v_mac_data->path,
+                                        NM_STR_HAS_SUFFIX(v_mac_data->path, "/") ? "" : "/",
+                                        "subnet-ipv4-cidr-block")),
+            HTTP_TIMEOUT_MS,
+            512 * 1024,
+            10000,
+            1000,
+            NULL,
+            iface_data->cancellable,
+            NULL,
+            NULL,
+            _get_config_fetch_done_cb_subnet_ipv4_cidr_block,
+            nm_utils_user_data_pack(iface_data, hwaddr));
+
+        iface_data->n_pending++;
+        nm_http_client_poll_get(
+            http_client,
+            (uri2 = _ec2_uri_interfaces(v_mac_data->path,
+                                        NM_STR_HAS_SUFFIX(v_mac_data->path, "/") ? "" : "/",
+                                        "local-ipv4s")),
+            HTTP_TIMEOUT_MS,
+            512 * 1024,
+            10000,
+            1000,
+            NULL,
+            iface_data->cancellable,
+            NULL,
+            NULL,
+            _get_config_fetch_done_cb_local_ipv4s,
+            nm_utils_user_data_pack(iface_data, hwaddr));
+    }
+
+    _get_config_task_maybe_return(iface_data, NULL);
 }
 
 static gboolean
-_get_config_metadata_ready_check (long response_code,
-                                  GBytes *response_data,
-                                  gpointer check_user_data,
-                                  GError **error)
+_get_config_metadata_ready_check(long     response_code,
+                                 GBytes * response_data,
+                                 gpointer check_user_data,
+                                 GError **error)
 {
-	GetConfigMetadataData *metadata_data = check_user_data;
-	gs_unref_hashtable GHashTable *response_parsed = NULL;
-	const guint8 *r_data;
-	gsize r_len;
-	GHashTableIter h_iter;
-	gboolean has_all;
-	const char *c_hwaddr;
-	gssize iface_idx_counter = 0;
-
-	if (   response_code != 200
-	    || !response_data) {
-		/* we wait longer. */
-		return FALSE;
-	}
-
-	r_data = g_bytes_get_data (response_data, &r_len);
-
-	while (r_len > 0) {
-		const guint8 *p_eol;
-		const char *p_start;
-		gsize p_start_l;
-		gsize p_start_l_2;
-		char *hwaddr;
-		GetConfigMetadataMac *mac_data;
-
-		p_start = (const char *) r_data;
-
-		p_eol = memchr (r_data, '\n', r_len);
-		if (p_eol) {
-			p_start_l = (p_eol - r_data);
-			r_len -= p_start_l + 1;
-			r_data = &p_eol[1];
-		} else {
-			p_start_l = r_len;
-			r_data = &r_data[r_len];
-			r_len = 0;
-		}
-
-		if (p_start_l == 0)
-			continue;
-
-		p_start_l_2 = p_start_l;
-		if (p_start[p_start_l_2 - 1] == '/') {
-			/* trim the trailing "/". */
-			p_start_l_2--;
-		}
-
-		hwaddr = nmcs_utils_hwaddr_normalize (p_start, p_start_l_2);
-		if (!hwaddr)
-			continue;
-
-		if (!response_parsed)
-			response_parsed = g_hash_table_new_full (nm_str_hash, g_str_equal, g_free, g_free);
-
-		mac_data = g_malloc (sizeof (GetConfigMetadataMac) + 1 + p_start_l);
-		mac_data->iface_idx = iface_idx_counter++;
-		memcpy (mac_data->path, p_start, p_start_l);
-		mac_data->path[p_start_l] = '\0';
-
-		g_hash_table_insert (response_parsed, hwaddr, mac_data);
-	}
-
-	has_all = TRUE;
-	g_hash_table_iter_init (&h_iter, metadata_data->get_config_data->result_dict);
-	while (g_hash_table_iter_next (&h_iter, (gpointer *) &c_hwaddr, NULL)) {
-		if (   !response_parsed
-		    || !g_hash_table_contains (response_parsed, c_hwaddr)) {
-			has_all = FALSE;
-			break;
-		}
-	}
-
-	nm_clear_pointer (&metadata_data->response_parsed, g_hash_table_unref);
-	metadata_data->response_parsed = g_steal_pointer (&response_parsed);
-	return has_all;
+    GetConfigMetadataData *metadata_data           = check_user_data;
+    gs_unref_hashtable GHashTable *response_parsed = NULL;
+    const guint8 *                 r_data;
+    const char *                   cur_line;
+    gsize                          r_len;
+    gsize                          cur_line_len;
+    GHashTableIter                 h_iter;
+    gboolean                       has_all;
+    const char *                   c_hwaddr;
+    gssize                         iface_idx_counter = 0;
+
+    if (response_code != 200 || !response_data) {
+        /* we wait longer. */
+        return FALSE;
+    }
+
+    r_data = g_bytes_get_data(response_data, &r_len);
+    /* NMHttpClient guarantees that there is a trailing NUL after the data. */
+    nm_assert(r_data[r_len] == 0);
+
+    while (nm_utils_parse_next_line((const char **) &r_data, &r_len, &cur_line, &cur_line_len)) {
+        GetConfigMetadataMac *mac_data;
+        char *                hwaddr;
+
+        if (cur_line_len == 0)
+            continue;
+
+        /* Truncate the string. It's safe to do, because we own @response_data an it has an
+         * extra NUL character after the buffer. */
+        ((char *) cur_line)[cur_line_len] = '\0';
+
+        hwaddr = nmcs_utils_hwaddr_normalize(
+            cur_line,
+            cur_line[cur_line_len - 1u] == '/' ? (gssize)(cur_line_len - 1u) : -1);
+        if (!hwaddr)
+            continue;
+
+        if (!response_parsed)
+            response_parsed = g_hash_table_new_full(nm_str_hash, g_str_equal, g_free, g_free);
+
+        mac_data            = g_malloc(sizeof(GetConfigMetadataMac) + 1u + cur_line_len);
+        mac_data->iface_idx = iface_idx_counter++;
+        memcpy(mac_data->path, cur_line, cur_line_len + 1u);
+
+        g_hash_table_insert(response_parsed, hwaddr, mac_data);
+    }
+
+    has_all = TRUE;
+    g_hash_table_iter_init(&h_iter, metadata_data->get_config_data->result_dict);
+    while (g_hash_table_iter_next(&h_iter, (gpointer *) &c_hwaddr, NULL)) {
+        if (!response_parsed || !g_hash_table_contains(response_parsed, c_hwaddr)) {
+            has_all = FALSE;
+            break;
+        }
+    }
+
+    nm_clear_pointer(&metadata_data->response_parsed, g_hash_table_unref);
+    metadata_data->response_parsed = g_steal_pointer(&response_parsed);
+    return has_all;
 }
 
 static void
-get_config (NMCSProvider *provider,
-            NMCSProviderGetConfigTaskData *get_config_data)
+get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_data)
 {
-	gs_free char *uri = NULL;
-	GetConfigMetadataData *metadata_data;
-
-	metadata_data = g_slice_new (GetConfigMetadataData);
-	*metadata_data = (GetConfigMetadataData) {
-		.get_config_data = get_config_data,
-	};
-
-	/* First we fetch the "macs/". If the caller requested some particular
-	 * MAC addresses, then we poll until we see them. They might not yet be
-	 * around from the start...
-	 */
-	nm_http_client_poll_get (nmcs_provider_get_http_client (provider),
-	                         (uri = _ec2_uri_interfaces ()),
-	                         HTTP_TIMEOUT_MS,
-	                         256 * 1024,
-	                         15000,
-	                         1000,
-	                         NULL,
-	                         g_task_get_cancellable (get_config_data->task),
-	                         _get_config_metadata_ready_check,
-	                         metadata_data,
-	                         _get_config_metadata_ready_cb,
-	                         metadata_data);
+    gs_free char *         uri = NULL;
+    GetConfigMetadataData *metadata_data;
+
+    metadata_data  = g_slice_new(GetConfigMetadataData);
+    *metadata_data = (GetConfigMetadataData){
+        .get_config_data = get_config_data,
+    };
+
+    /* First we fetch the "macs/". If the caller requested some particular
+     * MAC addresses, then we poll until we see them. They might not yet be
+     * around from the start...
+     */
+    nm_http_client_poll_get(nmcs_provider_get_http_client(provider),
+                            (uri = _ec2_uri_interfaces()),
+                            HTTP_TIMEOUT_MS,
+                            256 * 1024,
+                            15000,
+                            1000,
+                            NULL,
+                            g_task_get_cancellable(get_config_data->task),
+                            _get_config_metadata_ready_check,
+                            metadata_data,
+                            _get_config_metadata_ready_cb,
+                            metadata_data);
 }
 
 /*****************************************************************************/
 
 static void
-nmcs_provider_ec2_init (NMCSProviderEC2 *self)
-{
-}
+nmcs_provider_ec2_init(NMCSProviderEC2 *self)
+{}
 
 static void
-nmcs_provider_ec2_class_init (NMCSProviderEC2Class *klass)
+nmcs_provider_ec2_class_init(NMCSProviderEC2Class *klass)
 {
-	NMCSProviderClass *provider_class = NMCS_PROVIDER_CLASS (klass);
+    NMCSProviderClass *provider_class = NMCS_PROVIDER_CLASS(klass);
 
-	provider_class->_name                 = "ec2";
-	provider_class->_env_provider_enabled = NMCS_ENV_VARIABLE ("NM_CLOUD_SETUP_EC2");
-	provider_class->detect                = detect;
-	provider_class->get_config            = get_config;
+    provider_class->_name                 = "ec2";
+    provider_class->_env_provider_enabled = NMCS_ENV_VARIABLE("NM_CLOUD_SETUP_EC2");
+    provider_class->detect                = detect;
+    provider_class->get_config            = get_config;
 }
diff --git a/clients/cloud-setup/nmcs-provider-ec2.h b/clients/cloud-setup/nmcs-provider-ec2.h
index 763c3af8..b5f178f5 100644
--- a/clients/cloud-setup/nmcs-provider-ec2.h
+++ b/clients/cloud-setup/nmcs-provider-ec2.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #ifndef __NMCS_PROVIDER_EC2_H__
 #define __NMCS_PROVIDER_EC2_H__
@@ -10,14 +10,17 @@
 typedef struct _NMCSProviderEC2      NMCSProviderEC2;
 typedef struct _NMCSProviderEC2Class NMCSProviderEC2Class;
 
-#define NMCS_TYPE_PROVIDER_EC2            (nmcs_provider_ec2_get_type ())
-#define NMCS_PROVIDER_EC2(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMCS_TYPE_PROVIDER_EC2, NMCSProviderEC2))
-#define NMCS_PROVIDER_EC2_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NMCS_TYPE_PROVIDER_EC2, NMCSProviderEC2Class))
-#define NMCS_IS_PROVIDER_EC2(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMCS_TYPE_PROVIDER_EC2))
-#define NMCS_IS_PROVIDER_EC2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMCS_TYPE_PROVIDER_EC2))
-#define NMCS_PROVIDER_EC2_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NMCS_TYPE_PROVIDER_EC2, NMCSProviderEC2Class))
-
-GType nmcs_provider_ec2_get_type (void);
+#define NMCS_TYPE_PROVIDER_EC2 (nmcs_provider_ec2_get_type())
+#define NMCS_PROVIDER_EC2(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST((obj), NMCS_TYPE_PROVIDER_EC2, NMCSProviderEC2))
+#define NMCS_PROVIDER_EC2_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST((klass), NMCS_TYPE_PROVIDER_EC2, NMCSProviderEC2Class))
+#define NMCS_IS_PROVIDER_EC2(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMCS_TYPE_PROVIDER_EC2))
+#define NMCS_IS_PROVIDER_EC2_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NMCS_TYPE_PROVIDER_EC2))
+#define NMCS_PROVIDER_EC2_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS((obj), NMCS_TYPE_PROVIDER_EC2, NMCSProviderEC2Class))
+
+GType nmcs_provider_ec2_get_type(void);
 
 /*****************************************************************************/
 
diff --git a/clients/cloud-setup/nmcs-provider-gcp.c b/clients/cloud-setup/nmcs-provider-gcp.c
index ba4016dd..b4398fb8 100644
--- a/clients/cloud-setup/nmcs-provider-gcp.c
+++ b/clients/cloud-setup/nmcs-provider-gcp.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "nm-default.h"
 
@@ -9,7 +9,7 @@
 /*****************************************************************************/
 
 #define HTTP_TIMEOUT_MS      3000
-#define HTTP_REQ_MAX_DATA    512*1024
+#define HTTP_REQ_MAX_DATA    512 * 1024
 #define HTTP_POLL_TIMEOUT_MS 10000
 #define HTTP_RATE_LIMIT_MS   1000
 
@@ -19,502 +19,436 @@
 #define NM_GCP_METADATA_URL_BASE NM_GCP_BASE "/computeMetadata" NM_GCP_API_VERSION "/instance"
 #define NM_GCP_METADATA_URL_NET  "/network-interfaces/"
 
-#define NM_GCP_METADATA_HEADER   "Metadata-Flavor: Google"
+#define NM_GCP_METADATA_HEADER "Metadata-Flavor: Google"
 
-#define _gcp_uri_concat(...)     nmcs_utils_uri_build_concat (NM_GCP_METADATA_URL_BASE, __VA_ARGS__)
-#define _gcp_uri_interfaces(...) _gcp_uri_concat (NM_GCP_METADATA_URL_NET, ##__VA_ARGS__)
+#define _gcp_uri_concat(...)     nmcs_utils_uri_build_concat(NM_GCP_METADATA_URL_BASE, __VA_ARGS__)
+#define _gcp_uri_interfaces(...) _gcp_uri_concat(NM_GCP_METADATA_URL_NET, ##__VA_ARGS__)
 
 /*****************************************************************************/
 
 struct _NMCSProviderGCP {
-	NMCSProvider parent;
+    NMCSProvider parent;
 };
 
 struct _NMCSProviderGCPClass {
-	NMCSProviderClass parent;
+    NMCSProviderClass parent;
 };
 
-G_DEFINE_TYPE (NMCSProviderGCP, nmcs_provider_gcp, NMCS_TYPE_PROVIDER);
+G_DEFINE_TYPE(NMCSProviderGCP, nmcs_provider_gcp, NMCS_TYPE_PROVIDER);
 
 /*****************************************************************************/
 
 static void
-_detect_get_meta_data_done_cb (GObject *source,
-                               GAsyncResult *result,
-                               gpointer user_data)
+_detect_get_meta_data_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	gs_unref_object GTask *task = user_data;
-	gs_free_error GError *get_error = NULL;
-	gs_free_error GError *error = NULL;
-	gboolean success;
-
-	success = nm_http_client_poll_get_finish (NM_HTTP_CLIENT (source),
-	                                          result,
-	                                          NULL,
-	                                          NULL,
-	                                          &get_error);
-
-	if (nm_utils_error_is_cancelled (get_error)) {
-		g_task_return_error (task, g_steal_pointer (&get_error));
-		return;
-	}
-
-	if (get_error) {
-		nm_utils_error_set (&error,
-		                    NM_UTILS_ERROR_UNKNOWN,
-		                    "failure to get GCP metadata: %s",
-		                    get_error->message);
-		g_task_return_error (task, g_steal_pointer (&error));
-		return;
-	}
-
-	if (!success) {
-		nm_utils_error_set (&error,
-		                    NM_UTILS_ERROR_UNKNOWN,
-		                    "failure to detect GCP metadata");
-		g_task_return_error (task, g_steal_pointer (&error));
-		return;
-	}
-
-	g_task_return_boolean (task, TRUE);
+    gs_unref_object GTask *task     = user_data;
+    gs_free_error GError *get_error = NULL;
+    gs_free_error GError *error     = NULL;
+
+    nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, NULL, &get_error);
+
+    if (nm_utils_error_is_cancelled(get_error)) {
+        g_task_return_error(task, g_steal_pointer(&get_error));
+        return;
+    }
+
+    if (get_error) {
+        nm_utils_error_set(&error,
+                           NM_UTILS_ERROR_UNKNOWN,
+                           "failure to get GCP metadata: %s",
+                           get_error->message);
+        g_task_return_error(task, g_steal_pointer(&error));
+        return;
+    }
+
+    g_task_return_boolean(task, TRUE);
 }
 
 static void
-detect (NMCSProvider *provider,
-        GTask *task)
+detect(NMCSProvider *provider, GTask *task)
 {
-	NMHttpClient *http_client;
-	gs_free char *uri = NULL;
-
-	http_client = nmcs_provider_get_http_client (provider);
-
-	nm_http_client_poll_get (http_client,
-	                         (uri = _gcp_uri_concat ("id")),
-	                         HTTP_TIMEOUT_MS,
-	                         256*1024,
-	                         7000,
-	                         1000,
-	                         NM_MAKE_STRV (NM_GCP_METADATA_HEADER),
-	                         g_task_get_cancellable (task),
-	                         NULL,
-	                         NULL,
-	                         _detect_get_meta_data_done_cb,
-	                         task);
+    NMHttpClient *http_client;
+    gs_free char *uri = NULL;
+
+    http_client = nmcs_provider_get_http_client(provider);
+
+    nm_http_client_poll_get(http_client,
+                            (uri = _gcp_uri_concat("id")),
+                            HTTP_TIMEOUT_MS,
+                            256 * 1024,
+                            7000,
+                            1000,
+                            NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+                            g_task_get_cancellable(task),
+                            NULL,
+                            NULL,
+                            _detect_get_meta_data_done_cb,
+                            task);
 }
 
 /*****************************************************************************/
 
 typedef struct {
-	NMCSProviderGetConfigTaskData *config_data;
-	guint n_ifaces_pending;
-	GError *error;
-	bool success:1;
+    NMCSProviderGetConfigTaskData *config_data;
+    guint                          n_ifaces_pending;
+    GError *                       error;
 } GCPData;
 
 typedef struct {
-	NMCSProviderGetConfigIfaceData *iface_get_config;
-	GCPData *gcp_data;
-	gssize iface_idx;
-	guint n_fips_pending;
+    NMCSProviderGetConfigIfaceData *iface_get_config;
+    GCPData *                       gcp_data;
+    gssize                          iface_idx;
+    guint                           n_fips_pending;
 } GCPIfaceData;
 
 static void
-_get_config_maybe_task_return (GCPData *gcp_data,
-                               GError *error_take)
+_get_config_maybe_task_return(GCPData *gcp_data, GError *error_take)
 {
-	NMCSProviderGetConfigTaskData *config_data =  gcp_data->config_data;
-	gs_free_error GError *gcp_error = NULL;
-
-	if (error_take) {
-		nm_clear_error (&gcp_data->error);
-		gcp_data->error = error_take;
-	}
-
-	if (gcp_data->n_ifaces_pending)
-		return;
-
-	gcp_error = gcp_data->error;
-
-	if (!gcp_data->success) {
-		nm_assert (gcp_error);
-
-		if (nm_utils_error_is_cancelled (gcp_error))
-			_LOGD ("get-config: cancelled");
-		else
-			_LOGD ("get-config: failed: %s", gcp_error->message);
-		g_task_return_error (config_data->task, g_steal_pointer (&gcp_error));
-	} else {
-		_LOGD ("get-config: success");
-		g_task_return_pointer (config_data->task,
-		                       g_hash_table_ref (config_data->result_dict),
-		                       (GDestroyNotify) g_hash_table_unref);
-	}
-
-	nm_g_slice_free (gcp_data);
-	g_object_unref (config_data->task);
+    NMCSProviderGetConfigTaskData *config_data = gcp_data->config_data;
+
+    if (error_take) {
+        if (!gcp_data->error)
+            gcp_data->error = error_take;
+        else if (!nm_utils_error_is_cancelled(gcp_data->error)
+                 && nm_utils_error_is_cancelled(error_take)) {
+            nm_clear_error(&gcp_data->error);
+            gcp_data->error = error_take;
+        } else
+            g_error_free(error_take);
+    }
+
+    if (gcp_data->n_ifaces_pending > 0)
+        return;
+
+    if (gcp_data->error) {
+        if (nm_utils_error_is_cancelled(gcp_data->error))
+            _LOGD("get-config: cancelled");
+        else
+            _LOGD("get-config: failed: %s", gcp_data->error->message);
+        g_task_return_error(config_data->task, g_steal_pointer(&gcp_data->error));
+    } else {
+        _LOGD("get-config: success");
+        g_task_return_pointer(config_data->task,
+                              g_hash_table_ref(config_data->result_dict),
+                              (GDestroyNotify) g_hash_table_unref);
+    }
+
+    nm_g_slice_free(gcp_data);
+    g_object_unref(config_data->task);
 }
 
 static void
-_get_config_fip_cb (GObject *source,
-                    GAsyncResult *result,
-                    gpointer user_data)
+_get_config_fip_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	NMCSProviderGetConfigIfaceData *iface_get_config;
-	gs_unref_bytes GBytes *response = NULL;
-	GCPIfaceData *iface_data = user_data;
-	gs_free_error GError *error = NULL;
-	const char *fip_str = NULL;
-	NMIPRoute **routes_arr;
-	NMIPRoute *route_new;
-	GCPData *gcp_data;
-
-	gcp_data = iface_data->gcp_data;
-
-	nm_http_client_poll_get_finish (NM_HTTP_CLIENT (source),
-	                                result,
-	                                NULL,
-	                                &response,
-	                                &error);
-
-	if (error)
-		goto iface_done;
-
-	fip_str = g_bytes_get_data (response, NULL);
-	if (!nm_utils_ipaddr_valid (AF_INET, fip_str)) {
-		error = nm_utils_error_new (NM_UTILS_ERROR_UNKNOWN,
-		                            "forwarded-ip is not a valid ip address");
-		goto iface_done;
-	}
-
-	_LOGI ("GCP interface[%"G_GSSIZE_FORMAT"]: adding forwarded-ip %s",
-	       iface_data->iface_idx,
-	       fip_str);
-
-	iface_get_config = iface_data->iface_get_config;
-	iface_get_config->iface_idx = iface_data->iface_idx;
-	routes_arr = iface_get_config->iproutes_arr;
-
-	route_new = nm_ip_route_new (AF_INET,
-	                             fip_str,
-	                             32,
-	                             NULL,
-	                             100,
-	                             &error);
-	if (error)
-		goto iface_done;
-
-	nm_ip_route_set_attribute (route_new,
-	                           NM_IP_ROUTE_ATTRIBUTE_TYPE,
-	                           g_variant_new_string ("local"));
-	routes_arr[iface_get_config->iproutes_len] = route_new;
-	++iface_get_config->iproutes_len;
-	gcp_data->success = TRUE;
+    NMCSProviderGetConfigIfaceData *iface_get_config;
+    gs_unref_bytes GBytes *response   = NULL;
+    GCPIfaceData *         iface_data = user_data;
+    gs_free_error GError *error       = NULL;
+    const char *          fip_str     = NULL;
+    NMIPRoute **          routes_arr;
+    NMIPRoute *           route_new;
+    GCPData *             gcp_data;
+
+    gcp_data = iface_data->gcp_data;
+
+    nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error);
+
+    if (error)
+        goto iface_done;
+
+    fip_str = g_bytes_get_data(response, NULL);
+    if (!nm_utils_ipaddr_valid(AF_INET, fip_str)) {
+        error =
+            nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, "forwarded-ip is not a valid ip address");
+        goto iface_done;
+    }
+
+    _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: adding forwarded-ip %s",
+          iface_data->iface_idx,
+          fip_str);
+
+    iface_get_config            = iface_data->iface_get_config;
+    iface_get_config->iface_idx = iface_data->iface_idx;
+    routes_arr                  = iface_get_config->iproutes_arr;
+
+    route_new = nm_ip_route_new(AF_INET, fip_str, 32, NULL, 100, &error);
+    if (error)
+        goto iface_done;
+
+    nm_ip_route_set_attribute(route_new, NM_IP_ROUTE_ATTRIBUTE_TYPE, g_variant_new_string("local"));
+    routes_arr[iface_get_config->iproutes_len] = route_new;
+    ++iface_get_config->iproutes_len;
 
 iface_done:
-	--iface_data->n_fips_pending;
-	if (iface_data->n_fips_pending == 0) {
-		nm_g_slice_free (iface_data);
-		--gcp_data->n_ifaces_pending;
-		_get_config_maybe_task_return (gcp_data, g_steal_pointer (&error));
-	}
+    --iface_data->n_fips_pending;
+    if (iface_data->n_fips_pending == 0) {
+        nm_g_slice_free(iface_data);
+        --gcp_data->n_ifaces_pending;
+    }
+
+    _get_config_maybe_task_return(gcp_data, g_steal_pointer(&error));
 }
 
 static void
-_get_config_ips_list_cb (GObject *source,
-                         GAsyncResult *result,
-                         gpointer user_data)
+_get_config_ips_list_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	gs_unref_ptrarray GPtrArray *uri_arr = NULL;
-	gs_unref_bytes GBytes *response = NULL;
-	GCPIfaceData *iface_data = user_data;
-	gs_free_error GError *error = NULL;
-	const char *response_str = NULL;
-	gsize response_len;
-	GCPData *gcp_data;
-	const char *line;
-	gsize line_len;
-	guint i;
-
-	gcp_data = iface_data->gcp_data;
-
-	nm_http_client_poll_get_finish (NM_HTTP_CLIENT (source),
-	                                result,
-	                                NULL,
-	                                &response,
-	                                &error);
-
-	if (error)
-		goto fips_error;
-
-
-	uri_arr = g_ptr_array_new_with_free_func (g_free);
-	response_str = g_bytes_get_data (response, &response_len);
-
-	while (nm_utils_parse_next_line (&response_str,
-	                                 &response_len,
-	                                 &line,
-	                                 &line_len)) {
-		nm_auto_free_gstring GString *gstr = NULL;
-		gint64 fip_index;
-
-		gstr = g_string_new_len (line, line_len);
-		fip_index = _nm_utils_ascii_str_to_int64 (gstr->str, 10, 0, G_MAXINT64, -1);
-
-		if (fip_index < 0) {
-			continue;
-		}
-
-		g_string_printf (gstr,
-		                 "%"G_GSSIZE_FORMAT"/forwarded-ips/%"G_GINT64_FORMAT,
-		                 iface_data->iface_idx,
-		                 fip_index);
-		g_ptr_array_add (uri_arr, g_string_free (g_steal_pointer (&gstr), FALSE));
-	}
-
-	iface_data->n_fips_pending = uri_arr->len;
-
-	_LOGI ("GCP interface[%"G_GSSIZE_FORMAT"]: found %u forwarded ips",
-	       iface_data->iface_idx,
-	       iface_data->n_fips_pending);
-
-	if (iface_data->n_fips_pending == 0) {
-		error = nm_utils_error_new (NM_UTILS_ERROR_UNKNOWN,
-		                            "found no forwarded ip");
-		goto fips_error;
-	}
-
-	iface_data->iface_get_config->iproutes_arr =
-	    g_new (NMIPRoute *, iface_data->n_fips_pending);
-
-	for (i = 0; i < uri_arr->len; ++i) {
-		const char *str = uri_arr->pdata[i];
-		gs_free const char *uri = NULL;
-
-		nm_http_client_poll_get (NM_HTTP_CLIENT (source),
-		                         (uri = _gcp_uri_interfaces (str)),
-		                         HTTP_TIMEOUT_MS,
-		                         HTTP_REQ_MAX_DATA,
-		                         HTTP_POLL_TIMEOUT_MS,
-		                         HTTP_RATE_LIMIT_MS,
-		                         NM_MAKE_STRV (NM_GCP_METADATA_HEADER),
-		                         g_task_get_cancellable (gcp_data->config_data->task),
-		                         NULL,
-		                         NULL,
-		                         _get_config_fip_cb,
-		                         iface_data);
-	}
-	return;
+    gs_unref_ptrarray GPtrArray *uri_arr = NULL;
+    gs_unref_bytes GBytes *response      = NULL;
+    GCPIfaceData *         iface_data    = user_data;
+    gs_free_error GError *error          = NULL;
+    const char *          response_str   = NULL;
+    gsize                 response_len;
+    GCPData *             gcp_data;
+    const char *          line;
+    gsize                 line_len;
+    guint                 i;
+
+    gcp_data = iface_data->gcp_data;
+
+    nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error);
+
+    if (error)
+        goto fips_error;
+
+    response_str = g_bytes_get_data(response, &response_len);
+    /* NMHttpClient guarantees that there is a trailing NUL after the data. */
+    nm_assert(response_str[response_len] == 0);
+
+    uri_arr = g_ptr_array_new_with_free_func(g_free);
+    while (nm_utils_parse_next_line(&response_str, &response_len, &line, &line_len)) {
+        gint64 fip_index;
+
+        /* Truncate the string. It's safe to do, because we own @response_data an it has an
+         * extra NUL character after the buffer. */
+        ((char *) line)[line_len] = '\0';
+
+        fip_index = _nm_utils_ascii_str_to_int64(line, 10, 0, G_MAXINT64, -1);
+        if (fip_index < 0)
+            continue;
+
+        g_ptr_array_add(uri_arr,
+                        g_strdup_printf("%" G_GSSIZE_FORMAT "/forwarded-ips/%" G_GINT64_FORMAT,
+                                        iface_data->iface_idx,
+                                        fip_index));
+    }
+
+    iface_data->n_fips_pending = uri_arr->len;
+
+    _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: found %u forwarded ips",
+          iface_data->iface_idx,
+          iface_data->n_fips_pending);
+
+    if (iface_data->n_fips_pending == 0) {
+        error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, "found no forwarded ip");
+        goto fips_error;
+    }
+
+    iface_data->iface_get_config->iproutes_arr = g_new(NMIPRoute *, iface_data->n_fips_pending);
+
+    for (i = 0; i < uri_arr->len; ++i) {
+        const char *        str = uri_arr->pdata[i];
+        gs_free const char *uri = NULL;
+
+        nm_http_client_poll_get(NM_HTTP_CLIENT(source),
+                                (uri = _gcp_uri_interfaces(str)),
+                                HTTP_TIMEOUT_MS,
+                                HTTP_REQ_MAX_DATA,
+                                HTTP_POLL_TIMEOUT_MS,
+                                HTTP_RATE_LIMIT_MS,
+                                NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+                                g_task_get_cancellable(gcp_data->config_data->task),
+                                NULL,
+                                NULL,
+                                _get_config_fip_cb,
+                                iface_data);
+    }
+    return;
 
 fips_error:
-	nm_g_slice_free (iface_data);
-	--gcp_data->n_ifaces_pending;
-	_get_config_maybe_task_return (gcp_data, g_steal_pointer (&error));
+    nm_g_slice_free(iface_data);
+    --gcp_data->n_ifaces_pending;
+    _get_config_maybe_task_return(gcp_data, g_steal_pointer(&error));
 }
 
 static void
-_get_config_iface_cb (GObject *source,
-                      GAsyncResult *result,
-                      gpointer user_data)
+_get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	gs_unref_bytes GBytes *response = NULL;
-	GCPIfaceData *iface_data = user_data;
-	gs_free_error GError *error = NULL;
-	gs_free const char *hwaddr = NULL;
-	gs_free const char *uri = NULL;
-	gs_free char *str = NULL;
-	GCPData *gcp_data;
-
-	gcp_data = iface_data->gcp_data;
-
-	nm_http_client_poll_get_finish (NM_HTTP_CLIENT (source),
-	                                result,
-	                                NULL,
-	                                &response,
-	                                &error);
-
-	if (error)
-		goto iface_error;
-
-	hwaddr = nmcs_utils_hwaddr_normalize (g_bytes_get_data (response, NULL), -1);
-	iface_data->iface_get_config = g_hash_table_lookup (gcp_data->config_data->result_dict,
-	                                                    hwaddr);
-	if (!iface_data->iface_get_config) {
-		_LOGI ("GCP interface[%"G_GSSIZE_FORMAT"]: did not find a matching device",
-		       iface_data->iface_idx);
-		error = nm_utils_error_new (NM_UTILS_ERROR_UNKNOWN,
-		                            "no matching hwaddr found for GCP interface");
-		goto iface_error;
-	}
-
-	_LOGI ("GCP interface[%"G_GSSIZE_FORMAT"]: found a matching device with hwaddr %s",
-	       iface_data->iface_idx,
-	       hwaddr);
-
-	str = g_strdup_printf ("%"G_GSSIZE_FORMAT"/forwarded-ips/",
-	                       iface_data->iface_idx);
-
-	nm_http_client_poll_get (NM_HTTP_CLIENT (source),
-	                         (uri = _gcp_uri_interfaces (str)),
-	                         HTTP_TIMEOUT_MS,
-	                         HTTP_REQ_MAX_DATA,
-	                         HTTP_POLL_TIMEOUT_MS,
-	                         HTTP_RATE_LIMIT_MS,
-	                         NM_MAKE_STRV (NM_GCP_METADATA_HEADER),
-	                         g_task_get_cancellable (gcp_data->config_data->task),
-	                         NULL,
-	                         NULL,
-	                         _get_config_ips_list_cb,
-	                        iface_data);
-	return;
+    gs_unref_bytes GBytes *response   = NULL;
+    GCPIfaceData *         iface_data = user_data;
+    gs_free_error GError *error       = NULL;
+    gs_free const char *  hwaddr      = NULL;
+    gs_free const char *  uri         = NULL;
+    char                  sbuf[100];
+    GCPData *             gcp_data;
+
+    gcp_data = iface_data->gcp_data;
+
+    nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error);
+
+    if (error)
+        goto iface_error;
+
+    hwaddr = nmcs_utils_hwaddr_normalize(g_bytes_get_data(response, NULL), -1);
+    iface_data->iface_get_config = g_hash_table_lookup(gcp_data->config_data->result_dict, hwaddr);
+    if (!iface_data->iface_get_config) {
+        _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: did not find a matching device",
+              iface_data->iface_idx);
+        error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN,
+                                   "no matching hwaddr found for GCP interface");
+        goto iface_error;
+    }
+
+    _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: found a matching device with hwaddr %s",
+          iface_data->iface_idx,
+          hwaddr);
+
+    nm_sprintf_buf(sbuf, "%" G_GSSIZE_FORMAT "/forwarded-ips/", iface_data->iface_idx);
+
+    nm_http_client_poll_get(NM_HTTP_CLIENT(source),
+                            (uri = _gcp_uri_interfaces(sbuf)),
+                            HTTP_TIMEOUT_MS,
+                            HTTP_REQ_MAX_DATA,
+                            HTTP_POLL_TIMEOUT_MS,
+                            HTTP_RATE_LIMIT_MS,
+                            NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+                            g_task_get_cancellable(gcp_data->config_data->task),
+                            NULL,
+                            NULL,
+                            _get_config_ips_list_cb,
+                            iface_data);
+    return;
 
 iface_error:
-	nm_g_slice_free (iface_data);
-	--gcp_data->n_ifaces_pending;
-	_get_config_maybe_task_return (gcp_data, g_steal_pointer (&error));
+    nm_g_slice_free(iface_data);
+    --gcp_data->n_ifaces_pending;
+    _get_config_maybe_task_return(gcp_data, g_steal_pointer(&error));
 }
 
 static void
-_get_net_ifaces_list_cb (GObject *source,
-                         GAsyncResult *result,
-                         gpointer user_data)
+_get_net_ifaces_list_cb(GObject *source, GAsyncResult *result, gpointer user_data)
 {
-	gs_unref_ptrarray GPtrArray *ifaces_arr = NULL;
-	nm_auto_free_gstring GString *gstr = NULL;
-	gs_unref_bytes GBytes *response = NULL;
-	gs_free_error GError *error = NULL;
-	GCPData *gcp_data = user_data;
-	const char *response_str;
-	const char *token_start;
-	const char *token_end;
-	gsize response_len;
-	const char *line;
-	gsize line_len;
-	guint i;
-
-	nm_http_client_poll_get_finish (NM_HTTP_CLIENT (source),
-	                                result,
-	                                NULL,
-	                                &response,
-	                                &error);
-
-	if (error) {
-		_get_config_maybe_task_return (gcp_data, g_steal_pointer (&error));
-		return;
-	}
-
-	response_str = g_bytes_get_data (response, &response_len);
-	ifaces_arr = g_ptr_array_new ();
-	gstr = g_string_new (NULL);
-
-	while (nm_utils_parse_next_line (&response_str,
-	                                 &response_len,
-	                                 &line,
-	                                 &line_len)) {
-		GCPIfaceData *iface_data;
-		gssize iface_idx;
-
-		token_start = line;
-		token_end = memchr (token_start, '/', line_len);
-
-		if (!token_end)
-			continue;
-
-		g_string_truncate (gstr, 0);
-		g_string_append_len (gstr, token_start, token_end - token_start);
-		iface_idx = _nm_utils_ascii_str_to_int64 (gstr->str, 10, 0, G_MAXSSIZE, -1);
-
-		if (iface_idx < 0)
-			continue;
-
-		iface_data = g_slice_new (GCPIfaceData);
-		*iface_data = (GCPIfaceData) {
-			.iface_get_config = NULL,
-			.gcp_data = gcp_data,
-			.iface_idx = iface_idx,
-			.n_fips_pending = 0,
-		};
-		g_ptr_array_add (ifaces_arr, iface_data);
-	}
-
-	gcp_data->n_ifaces_pending = ifaces_arr->len;
-	_LOGI ("found GCP interfaces: %u", ifaces_arr->len);
-
-	for (i = 0; i < ifaces_arr->len; ++i) {
-		GCPIfaceData *data = ifaces_arr->pdata[i];
-		gs_free const char *uri = NULL;
-
-		_LOGD ("GCP interface[%"G_GSSIZE_FORMAT"]: retrieving configuration",
-		       data->iface_idx);
-
-		g_string_printf (gstr, "%"G_GSSIZE_FORMAT"/mac", data->iface_idx);
-
-		nm_http_client_poll_get (NM_HTTP_CLIENT (source),
-		                         (uri = _gcp_uri_interfaces (gstr->str)),
-		                         HTTP_TIMEOUT_MS,
-		                         HTTP_REQ_MAX_DATA,
-		                         HTTP_POLL_TIMEOUT_MS,
-		                         HTTP_RATE_LIMIT_MS,
-		                         NM_MAKE_STRV (NM_GCP_METADATA_HEADER),
-		                         g_task_get_cancellable (gcp_data->config_data->task),
-		                         NULL,
-		                         NULL,
-		                         _get_config_iface_cb,
-		                         data);
-
-	}
-
-	if (ifaces_arr->len == 0) {
-		error = nm_utils_error_new (NM_UTILS_ERROR_UNKNOWN,
-		                            "no GCP interfaces found");
-		_get_config_maybe_task_return (gcp_data, g_steal_pointer (&error));
-	}
+    gs_unref_ptrarray GPtrArray *ifaces_arr = NULL;
+    gs_unref_bytes GBytes *response         = NULL;
+    gs_free_error GError *error             = NULL;
+    GCPData *             gcp_data          = user_data;
+    const char *          response_str;
+    gsize                 response_len;
+    const char *          line;
+    gsize                 line_len;
+    guint                 i;
+
+    nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error);
+
+    if (error) {
+        _get_config_maybe_task_return(gcp_data, g_steal_pointer(&error));
+        return;
+    }
+
+    response_str = g_bytes_get_data(response, &response_len);
+    /* NMHttpClient guarantees that there is a trailing NUL after the data. */
+    nm_assert(response_str[response_len] == 0);
+
+    ifaces_arr = g_ptr_array_new();
+
+    while (nm_utils_parse_next_line(&response_str, &response_len, &line, &line_len)) {
+        GCPIfaceData *iface_data;
+        gssize        iface_idx;
+
+        if (line_len == 0)
+            continue;
+
+        /* Truncate the string. It's safe to do, because we own @response_data an it has an
+         * extra NUL character after the buffer. */
+        ((char *) line)[line_len] = '\0';
+        if (line[line_len - 1] == '/')
+            ((char *) line)[--line_len] = '\0';
+
+        iface_idx = _nm_utils_ascii_str_to_int64(line, 10, 0, G_MAXSSIZE, -1);
+        if (iface_idx < 0)
+            continue;
+
+        iface_data  = g_slice_new(GCPIfaceData);
+        *iface_data = (GCPIfaceData){
+            .iface_get_config = NULL,
+            .gcp_data         = gcp_data,
+            .iface_idx        = iface_idx,
+            .n_fips_pending   = 0,
+        };
+        g_ptr_array_add(ifaces_arr, iface_data);
+    }
+
+    gcp_data->n_ifaces_pending = ifaces_arr->len;
+    _LOGI("found GCP interfaces: %u", ifaces_arr->len);
+
+    for (i = 0; i < ifaces_arr->len; ++i) {
+        GCPIfaceData *      data = ifaces_arr->pdata[i];
+        gs_free const char *uri  = NULL;
+        char                sbuf[100];
+
+        _LOGD("GCP interface[%" G_GSSIZE_FORMAT "]: retrieving configuration", data->iface_idx);
+
+        nm_sprintf_buf(sbuf, "%" G_GSSIZE_FORMAT "/mac", data->iface_idx);
+
+        nm_http_client_poll_get(NM_HTTP_CLIENT(source),
+                                (uri = _gcp_uri_interfaces(sbuf)),
+                                HTTP_TIMEOUT_MS,
+                                HTTP_REQ_MAX_DATA,
+                                HTTP_POLL_TIMEOUT_MS,
+                                HTTP_RATE_LIMIT_MS,
+                                NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+                                g_task_get_cancellable(gcp_data->config_data->task),
+                                NULL,
+                                NULL,
+                                _get_config_iface_cb,
+                                data);
+    }
+
+    if (ifaces_arr->len == 0) {
+        error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, "no GCP interfaces found");
+        _get_config_maybe_task_return(gcp_data, g_steal_pointer(&error));
+    }
 }
 
-
 static void
-get_config (NMCSProvider *provider,
-            NMCSProviderGetConfigTaskData *get_config_data)
+get_config(NMCSProvider *provider, NMCSProviderGetConfigTaskData *get_config_data)
 {
-	gs_free const char *uri = NULL;
-	GCPData *gcp_data;
-
-	gcp_data = g_slice_new (GCPData);
-	*gcp_data = (GCPData) {
-		.config_data = get_config_data,
-		.n_ifaces_pending = 0,
-		.error = NULL,
-		.success = FALSE,
-
-	};
-
-	nm_http_client_poll_get (nmcs_provider_get_http_client (provider),
-	                         (uri = _gcp_uri_interfaces ()),
-	                         HTTP_TIMEOUT_MS,
-	                         HTTP_REQ_MAX_DATA,
-	                         HTTP_POLL_TIMEOUT_MS,
-	                         HTTP_RATE_LIMIT_MS,
-	                         NM_MAKE_STRV (NM_GCP_METADATA_HEADER),
-	                         g_task_get_cancellable (gcp_data->config_data->task),
-	                         NULL,
-	                         NULL,
-	                         _get_net_ifaces_list_cb,
-	                         gcp_data);
+    gs_free const char *uri = NULL;
+    GCPData *           gcp_data;
+
+    gcp_data  = g_slice_new(GCPData);
+    *gcp_data = (GCPData){
+        .config_data      = get_config_data,
+        .n_ifaces_pending = 0,
+        .error            = NULL,
+    };
+
+    nm_http_client_poll_get(nmcs_provider_get_http_client(provider),
+                            (uri = _gcp_uri_interfaces()),
+                            HTTP_TIMEOUT_MS,
+                            HTTP_REQ_MAX_DATA,
+                            HTTP_POLL_TIMEOUT_MS,
+                            HTTP_RATE_LIMIT_MS,
+                            NM_MAKE_STRV(NM_GCP_METADATA_HEADER),
+                            g_task_get_cancellable(gcp_data->config_data->task),
+                            NULL,
+                            NULL,
+                            _get_net_ifaces_list_cb,
+                            gcp_data);
 }
 
 /*****************************************************************************/
 
 static void
-nmcs_provider_gcp_init (NMCSProviderGCP *self)
-{
-}
+nmcs_provider_gcp_init(NMCSProviderGCP *self)
+{}
 
 static void
-nmcs_provider_gcp_class_init (NMCSProviderGCPClass *klass)
+nmcs_provider_gcp_class_init(NMCSProviderGCPClass *klass)
 {
-	NMCSProviderClass *provider_class = NMCS_PROVIDER_CLASS (klass);
+    NMCSProviderClass *provider_class = NMCS_PROVIDER_CLASS(klass);
 
-	provider_class->_name                 = "GCP";
-	provider_class->_env_provider_enabled = NMCS_ENV_VARIABLE ("NM_CLOUD_SETUP_GCP");
-	provider_class->detect                = detect;
-	provider_class->get_config            = get_config;
+    provider_class->_name                 = "GCP";
+    provider_class->_env_provider_enabled = NMCS_ENV_VARIABLE("NM_CLOUD_SETUP_GCP");
+    provider_class->detect                = detect;
+    provider_class->get_config            = get_config;
 }
diff --git a/clients/cloud-setup/nmcs-provider-gcp.h b/clients/cloud-setup/nmcs-provider-gcp.h
index b0d3ec7d..4ead2191 100644
--- a/clients/cloud-setup/nmcs-provider-gcp.h
+++ b/clients/cloud-setup/nmcs-provider-gcp.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #ifndef __NMCS_PROVIDER_GCP_H__
 #define __NMCS_PROVIDER_GCP_H__
@@ -10,14 +10,17 @@
 typedef struct _NMCSProviderGCP      NMCSProviderGCP;
 typedef struct _NMCSProviderGCPClass NMCSProviderGCPClass;
 
-#define NMCS_TYPE_PROVIDER_GCP            (nmcs_provider_gcp_get_type ())
-#define NMCS_PROVIDER_GCP(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMCS_TYPE_PROVIDER_GCP, NMCSProviderGCP))
-#define NMCS_PROVIDER_GCP_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NMCS_TYPE_PROVIDER_GCP, NMCSProviderGCPClass))
-#define NMCS_IS_PROVIDER_GCP(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMCS_TYPE_PROVIDER_GCP))
-#define NMCS_IS_PROVIDER_GCP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMCS_TYPE_PROVIDER_GCP))
-#define NMCS_PROVIDER_GCP_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NMCS_TYPE_PROVIDER_GCP, NMCSProviderGCPClass))
-
-GType nmcs_provider_gcp_get_type (void);
+#define NMCS_TYPE_PROVIDER_GCP (nmcs_provider_gcp_get_type())
+#define NMCS_PROVIDER_GCP(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST((obj), NMCS_TYPE_PROVIDER_GCP, NMCSProviderGCP))
+#define NMCS_PROVIDER_GCP_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST((klass), NMCS_TYPE_PROVIDER_GCP, NMCSProviderGCPClass))
+#define NMCS_IS_PROVIDER_GCP(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMCS_TYPE_PROVIDER_GCP))
+#define NMCS_IS_PROVIDER_GCP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NMCS_TYPE_PROVIDER_GCP))
+#define NMCS_PROVIDER_GCP_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS((obj), NMCS_TYPE_PROVIDER_GCP, NMCSProviderGCPClass))
+
+GType nmcs_provider_gcp_get_type(void);
 
 /*****************************************************************************/
 
diff --git a/clients/cloud-setup/nmcs-provider.c b/clients/cloud-setup/nmcs-provider.c
index bc21d876..e9e79a35 100644
--- a/clients/cloud-setup/nmcs-provider.c
+++ b/clients/cloud-setup/nmcs-provider.c
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include "nm-default.h"
 
@@ -8,239 +8,225 @@
 
 /*****************************************************************************/
 
-NM_GOBJECT_PROPERTIES_DEFINE_BASE (
-	PROP_HTTP_CLIENT,
-);
+NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_HTTP_CLIENT, );
 
 typedef struct _NMCSProviderPrivate {
-	NMHttpClient *http_client;
+    NMHttpClient *http_client;
 } NMCSProviderPrivate;
 
-G_DEFINE_TYPE (NMCSProvider, nmcs_provider, G_TYPE_OBJECT);
+G_DEFINE_TYPE(NMCSProvider, nmcs_provider, G_TYPE_OBJECT);
 
 #define NMCS_PROVIDER_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMCSProvider, NMCS_IS_PROVIDER)
 
 /*****************************************************************************/
 
 const char *
-nmcs_provider_get_name (NMCSProvider *self)
+nmcs_provider_get_name(NMCSProvider *self)
 {
-	NMCSProviderClass *klass;
+    NMCSProviderClass *klass;
 
-	g_return_val_if_fail (NMCS_IS_PROVIDER (self), NULL);
+    g_return_val_if_fail(NMCS_IS_PROVIDER(self), NULL);
 
-	klass = NMCS_PROVIDER_GET_CLASS (self);
-	nm_assert (klass->_name);
-	return klass->_name;
+    klass = NMCS_PROVIDER_GET_CLASS(self);
+    nm_assert(klass->_name);
+    return klass->_name;
 }
 
 /*****************************************************************************/
 
 NMHttpClient *
-nmcs_provider_get_http_client (NMCSProvider *self)
+nmcs_provider_get_http_client(NMCSProvider *self)
 {
-	g_return_val_if_fail (NMCS_IS_PROVIDER (self), NULL);
+    g_return_val_if_fail(NMCS_IS_PROVIDER(self), NULL);
 
-	return NMCS_PROVIDER_GET_PRIVATE (self)->http_client;
+    return NMCS_PROVIDER_GET_PRIVATE(self)->http_client;
 }
 
 GMainContext *
-nmcs_provider_get_main_context (NMCSProvider *self)
+nmcs_provider_get_main_context(NMCSProvider *self)
 {
-	g_return_val_if_fail (NMCS_IS_PROVIDER (self), NULL);
+    g_return_val_if_fail(NMCS_IS_PROVIDER(self), NULL);
 
-	return nm_http_client_get_main_context (NMCS_PROVIDER_GET_PRIVATE (self)->http_client);
+    return nm_http_client_get_main_context(NMCS_PROVIDER_GET_PRIVATE(self)->http_client);
 }
 
 /*****************************************************************************/
 
 void
-nmcs_provider_detect (NMCSProvider *self,
-                      GCancellable *cancellable,
-                      GAsyncReadyCallback callback,
-                      gpointer user_data)
+nmcs_provider_detect(NMCSProvider *      self,
+                     GCancellable *      cancellable,
+                     GAsyncReadyCallback callback,
+                     gpointer            user_data)
 {
-	gs_unref_object GTask *task = NULL;
-	const char *env;
+    gs_unref_object GTask *task = NULL;
+    const char *           env;
 
-	g_return_if_fail (NMCS_IS_PROVIDER (self));
-	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+    g_return_if_fail(NMCS_IS_PROVIDER(self));
+    g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
 
-	task = nm_g_task_new (self, cancellable, nmcs_provider_detect, callback, user_data);
+    task = nm_g_task_new(self, cancellable, nmcs_provider_detect, callback, user_data);
 
-	nmcs_wait_for_objects_register (task);
+    nmcs_wait_for_objects_register(task);
 
-	env = g_getenv (NMCS_PROVIDER_GET_CLASS (self)->_env_provider_enabled);
-	if (!_nm_utils_ascii_str_to_bool (env, FALSE)) {
-		g_task_return_error (task,
-		                     nm_utils_error_new (NM_UTILS_ERROR_UNKNOWN,
-		                                         "provider is disabled"));
-		return;
-	}
+    env = g_getenv(NMCS_PROVIDER_GET_CLASS(self)->_env_provider_enabled);
+    if (!_nm_utils_ascii_str_to_bool(env, FALSE)) {
+        g_task_return_error(task,
+                            nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, "provider is disabled"));
+        return;
+    }
 
-	NMCS_PROVIDER_GET_CLASS (self)->detect (self,
-	                                        g_steal_pointer (&task));
+    NMCS_PROVIDER_GET_CLASS(self)->detect(self, g_steal_pointer(&task));
 }
 
 gboolean
-nmcs_provider_detect_finish (NMCSProvider *self,
-                             GAsyncResult *result,
-                             GError **error)
+nmcs_provider_detect_finish(NMCSProvider *self, GAsyncResult *result, GError **error)
 {
-	g_return_val_if_fail (NMCS_IS_PROVIDER (self), FALSE);
-	g_return_val_if_fail (nm_g_task_is_valid (result, self, nmcs_provider_detect), FALSE);
+    g_return_val_if_fail(NMCS_IS_PROVIDER(self), FALSE);
+    g_return_val_if_fail(nm_g_task_is_valid(result, self, nmcs_provider_detect), FALSE);
 
-	return g_task_propagate_boolean (G_TASK (result), error);
+    return g_task_propagate_boolean(G_TASK(result), error);
 }
 
 /*****************************************************************************/
 
 NMCSProviderGetConfigIfaceData *
-nmcs_provider_get_config_iface_data_new (gboolean was_requested)
+nmcs_provider_get_config_iface_data_new(gboolean was_requested)
 {
-	NMCSProviderGetConfigIfaceData *iface_data;
-
-	iface_data = g_slice_new (NMCSProviderGetConfigIfaceData);
-	*iface_data = (NMCSProviderGetConfigIfaceData) {
-		.iface_idx     = -1,
-		.was_requested = was_requested,
-	};
-	return iface_data;
+    NMCSProviderGetConfigIfaceData *iface_data;
+
+    iface_data  = g_slice_new(NMCSProviderGetConfigIfaceData);
+    *iface_data = (NMCSProviderGetConfigIfaceData){
+        .iface_idx     = -1,
+        .was_requested = was_requested,
+    };
+    return iface_data;
 }
 
 static void
-_iface_data_free (gpointer data)
+_iface_data_free(gpointer data)
 {
-	NMCSProviderGetConfigIfaceData *iface_data = data;
+    NMCSProviderGetConfigIfaceData *iface_data = data;
 
-	g_free (iface_data->ipv4s_arr);
-	g_free (iface_data->iproutes_arr);
+    g_free(iface_data->ipv4s_arr);
+    g_free(iface_data->iproutes_arr);
 
-	nm_g_slice_free (iface_data);
+    nm_g_slice_free(iface_data);
 }
 
 static void
-_get_config_data_free (gpointer data)
+_get_config_data_free(gpointer data)
 {
-	NMCSProviderGetConfigTaskData *get_config_data = data;
+    NMCSProviderGetConfigTaskData *get_config_data = data;
 
-	if (get_config_data->extra_destroy)
-		get_config_data->extra_destroy (get_config_data->extra_data);
+    if (get_config_data->extra_destroy)
+        get_config_data->extra_destroy(get_config_data->extra_data);
 
-	nm_clear_pointer (&get_config_data->result_dict, g_hash_table_unref);
+    nm_clear_pointer(&get_config_data->result_dict, g_hash_table_unref);
 
-	nm_g_slice_free (get_config_data);
+    nm_g_slice_free(get_config_data);
 }
 
 void
-nmcs_provider_get_config (NMCSProvider *self,
-                          gboolean any,
-                          const char *const*hwaddrs,
-                          GCancellable *cancellable,
-                          GAsyncReadyCallback callback,
-                          gpointer user_data)
+nmcs_provider_get_config(NMCSProvider *      self,
+                         gboolean            any,
+                         const char *const * hwaddrs,
+                         GCancellable *      cancellable,
+                         GAsyncReadyCallback callback,
+                         gpointer            user_data)
 {
-	NMCSProviderGetConfigTaskData *get_config_data;
+    NMCSProviderGetConfigTaskData *get_config_data;
 
-	g_return_if_fail (NMCS_IS_PROVIDER (self));
-	g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+    g_return_if_fail(NMCS_IS_PROVIDER(self));
+    g_return_if_fail(!cancellable || G_IS_CANCELLABLE(cancellable));
 
-	get_config_data = g_slice_new (NMCSProviderGetConfigTaskData);
-	*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),
-	};
+    get_config_data  = g_slice_new(NMCSProviderGetConfigTaskData);
+    *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),
+    };
 
-	g_task_set_task_data (get_config_data->task, get_config_data, _get_config_data_free);
+    g_task_set_task_data(get_config_data->task, get_config_data, _get_config_data_free);
 
-	nmcs_wait_for_objects_register (get_config_data->task);
+    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++) {
+        g_hash_table_insert(get_config_data->result_dict,
+                            g_strdup(hwaddrs[0]),
+                            nmcs_provider_get_config_iface_data_new(TRUE));
+    }
 
-	_LOGD ("get-config: starting");
+    _LOGD("get-config: starting");
 
-	NMCS_PROVIDER_GET_CLASS (self)->get_config (self, get_config_data);
+    NMCS_PROVIDER_GET_CLASS(self)->get_config(self, get_config_data);
 }
 
 GHashTable *
-nmcs_provider_get_config_finish (NMCSProvider *self,
-                                 GAsyncResult *result,
-                                 GError **error)
+nmcs_provider_get_config_finish(NMCSProvider *self, GAsyncResult *result, GError **error)
 {
-	g_return_val_if_fail (NMCS_IS_PROVIDER (self), FALSE);
-	g_return_val_if_fail (nm_g_task_is_valid (result, self, nmcs_provider_get_config), FALSE);
+    g_return_val_if_fail(NMCS_IS_PROVIDER(self), FALSE);
+    g_return_val_if_fail(nm_g_task_is_valid(result, self, nmcs_provider_get_config), FALSE);
 
-	return g_task_propagate_pointer (G_TASK (result), error);
+    return g_task_propagate_pointer(G_TASK(result), error);
 }
 
 /*****************************************************************************/
 
 static void
-set_property (GObject *object,
-              guint prop_id,
-              const GValue *value,
-              GParamSpec *pspec)
+set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
-	NMCSProviderPrivate *priv = NMCS_PROVIDER_GET_PRIVATE (object);
-
-	switch (prop_id) {
-	case PROP_HTTP_CLIENT:
-		priv->http_client = g_value_dup_object (value);
-		g_return_if_fail (NM_IS_HTTP_CLIENT (priv->http_client));
-		break;
-	default:
-		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-		break;
-	}
+    NMCSProviderPrivate *priv = NMCS_PROVIDER_GET_PRIVATE(object);
+
+    switch (prop_id) {
+    case PROP_HTTP_CLIENT:
+        priv->http_client = g_value_dup_object(value);
+        g_return_if_fail(NM_IS_HTTP_CLIENT(priv->http_client));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+        break;
+    }
 }
 
 /*****************************************************************************/
 
 static void
-nmcs_provider_init (NMCSProvider *self)
+nmcs_provider_init(NMCSProvider *self)
 {
-	NMCSProviderPrivate *priv;
+    NMCSProviderPrivate *priv;
 
-	priv = G_TYPE_INSTANCE_GET_PRIVATE (self, NMCS_TYPE_PROVIDER, NMCSProviderPrivate);
+    priv = G_TYPE_INSTANCE_GET_PRIVATE(self, NMCS_TYPE_PROVIDER, NMCSProviderPrivate);
 
-	self->_priv = priv;
+    self->_priv = priv;
 }
 
 static void
-dispose (GObject *object)
+dispose(GObject *object)
 {
-	NMCSProvider *self = NMCS_PROVIDER (object);
-	NMCSProviderPrivate *priv = NMCS_PROVIDER_GET_PRIVATE (self);
+    NMCSProvider *       self = NMCS_PROVIDER(object);
+    NMCSProviderPrivate *priv = NMCS_PROVIDER_GET_PRIVATE(self);
 
-	g_clear_object (&priv->http_client);
+    g_clear_object(&priv->http_client);
 
-	G_OBJECT_CLASS (nmcs_provider_parent_class)->dispose (object);
+    G_OBJECT_CLASS(nmcs_provider_parent_class)->dispose(object);
 }
 
 static void
-nmcs_provider_class_init (NMCSProviderClass *klass)
+nmcs_provider_class_init(NMCSProviderClass *klass)
 {
-	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+    GObjectClass *object_class = G_OBJECT_CLASS(klass);
 
-	g_type_class_add_private (object_class, sizeof (NMCSProviderPrivate));
+    g_type_class_add_private(object_class, sizeof(NMCSProviderPrivate));
 
-	object_class->set_property = set_property;
-	object_class->dispose      = dispose;
+    object_class->set_property = set_property;
+    object_class->dispose      = dispose;
 
-	obj_properties[PROP_HTTP_CLIENT] =
-	    g_param_spec_object (NMCS_PROVIDER_HTTP_CLIENT, "", "",
-	                         NM_TYPE_HTTP_CLIENT,
-	                         G_PARAM_WRITABLE |
-	                         G_PARAM_CONSTRUCT_ONLY |
-	                         G_PARAM_STATIC_STRINGS);
+    obj_properties[PROP_HTTP_CLIENT] =
+        g_param_spec_object(NMCS_PROVIDER_HTTP_CLIENT,
+                            "",
+                            "",
+                            NM_TYPE_HTTP_CLIENT,
+                            G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
 
-	g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
+    g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
 }
diff --git a/clients/cloud-setup/nmcs-provider.h b/clients/cloud-setup/nmcs-provider.h
index e5950f93..876b0a37 100644
--- a/clients/cloud-setup/nmcs-provider.h
+++ b/clients/cloud-setup/nmcs-provider.h
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: LGPL-2.1+
+/* SPDX-License-Identifier: LGPL-2.1+ */
 
 #ifndef __NMCS_PROVIDER_H__
 #define __NMCS_PROVIDER_H__
@@ -10,103 +10,97 @@
 /*****************************************************************************/
 
 typedef struct {
-	in_addr_t *ipv4s_arr;
-	gsize ipv4s_len;
-	gssize iface_idx;
-	in_addr_t cidr_addr;
-	guint8 cidr_prefix;
-	bool has_ipv4s:1;
-	bool has_cidr:1;
+    in_addr_t *ipv4s_arr;
+    gsize      ipv4s_len;
+    gssize     iface_idx;
+    in_addr_t  cidr_addr;
+    guint8     cidr_prefix;
+    bool       has_ipv4s : 1;
+    bool       has_cidr : 1;
 
-	NMIPRoute **iproutes_arr;
-	gsize iproutes_len;
+    NMIPRoute **iproutes_arr;
+    gsize       iproutes_len;
 
-	/* TRUE, if the configuration was requested via hwaddrs argument to
-	 * nmcs_provider_get_config(). */
-	bool was_requested:1;
+    /* TRUE, if the configuration was requested via hwaddrs argument to
+     * nmcs_provider_get_config(). */
+    bool was_requested : 1;
 
 } NMCSProviderGetConfigIfaceData;
 
 static inline gboolean
-nmcs_provider_get_config_iface_data_is_valid (const NMCSProviderGetConfigIfaceData *config_data)
+nmcs_provider_get_config_iface_data_is_valid(const NMCSProviderGetConfigIfaceData *config_data)
 {
-	return    config_data
-	       && config_data->iface_idx >= 0
-	       && (   (   config_data->has_ipv4s
-	               && config_data->has_cidr)
-	           || config_data->iproutes_len);
+    return config_data && config_data->iface_idx >= 0
+           && ((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_new(gboolean was_requested);
 
 typedef struct {
-	GTask *task;
-	GHashTable *result_dict;
-	gpointer extra_data;
-	GDestroyNotify extra_destroy;
-	bool any:1;
+    GTask *        task;
+    GHashTable *   result_dict;
+    gpointer       extra_data;
+    GDestroyNotify extra_destroy;
+    bool           any : 1;
 } NMCSProviderGetConfigTaskData;
 
-#define NMCS_TYPE_PROVIDER            (nmcs_provider_get_type ())
-#define NMCS_PROVIDER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), NMCS_TYPE_PROVIDER, NMCSProvider))
-#define NMCS_PROVIDER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), NMCS_TYPE_PROVIDER, NMCSProviderClass))
-#define NMCS_IS_PROVIDER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NMCS_TYPE_PROVIDER))
-#define NMCS_IS_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NMCS_TYPE_PROVIDER))
-#define NMCS_PROVIDER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), NMCS_TYPE_PROVIDER, NMCSProviderClass))
+#define NMCS_TYPE_PROVIDER (nmcs_provider_get_type())
+#define NMCS_PROVIDER(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NMCS_TYPE_PROVIDER, NMCSProvider))
+#define NMCS_PROVIDER_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST((klass), NMCS_TYPE_PROVIDER, NMCSProviderClass))
+#define NMCS_IS_PROVIDER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), NMCS_TYPE_PROVIDER))
+#define NMCS_IS_PROVIDER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NMCS_TYPE_PROVIDER))
+#define NMCS_PROVIDER_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS((obj), NMCS_TYPE_PROVIDER, NMCSProviderClass))
 
 #define NMCS_PROVIDER_HTTP_CLIENT "http-client"
 
 struct _NMCSProviderPrivate;
 
 typedef struct {
-	GObject parent;
-	struct _NMCSProviderPrivate *_priv;
+    GObject                      parent;
+    struct _NMCSProviderPrivate *_priv;
 } NMCSProvider;
 
 typedef struct {
-	GObjectClass parent;
-	const char *_name;
-	const char *_env_provider_enabled;
+    GObjectClass parent;
+    const char * _name;
+    const char * _env_provider_enabled;
 
-	void (*detect) (NMCSProvider *self,
-	                GTask *task);
+    void (*detect)(NMCSProvider *self, GTask *task);
 
-	void (*get_config) (NMCSProvider *self,
-	                    NMCSProviderGetConfigTaskData *get_config_data);
+    void (*get_config)(NMCSProvider *self, NMCSProviderGetConfigTaskData *get_config_data);
 
 } NMCSProviderClass;
 
-GType nmcs_provider_get_type (void);
+GType nmcs_provider_get_type(void);
 
 /*****************************************************************************/
 
-const char *nmcs_provider_get_name (NMCSProvider *provider);
+const char *nmcs_provider_get_name(NMCSProvider *provider);
 
-NMHttpClient *nmcs_provider_get_http_client (NMCSProvider *provider);
-GMainContext *nmcs_provider_get_main_context (NMCSProvider *provider);
+NMHttpClient *nmcs_provider_get_http_client(NMCSProvider *provider);
+GMainContext *nmcs_provider_get_main_context(NMCSProvider *provider);
 
 /*****************************************************************************/
 
-void nmcs_provider_detect (NMCSProvider *provider,
-                           GCancellable *cancellable,
-                           GAsyncReadyCallback callback,
-                           gpointer user_data);
+void nmcs_provider_detect(NMCSProvider *      provider,
+                          GCancellable *      cancellable,
+                          GAsyncReadyCallback callback,
+                          gpointer            user_data);
 
-gboolean nmcs_provider_detect_finish (NMCSProvider *provider,
-                                      GAsyncResult *result,
-                                      GError **error);
+gboolean nmcs_provider_detect_finish(NMCSProvider *provider, GAsyncResult *result, GError **error);
 
 /*****************************************************************************/
 
-void nmcs_provider_get_config (NMCSProvider *provider,
-                               gboolean any,
-                               const char *const*hwaddrs,
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data);
+void nmcs_provider_get_config(NMCSProvider *      provider,
+                              gboolean            any,
+                              const char *const * hwaddrs,
+                              GCancellable *      cancellable,
+                              GAsyncReadyCallback callback,
+                              gpointer            user_data);
 
-GHashTable *nmcs_provider_get_config_finish (NMCSProvider *provider,
-                                             GAsyncResult *result,
-                                             GError **error);
+GHashTable *
+nmcs_provider_get_config_finish(NMCSProvider *provider, GAsyncResult *result, GError **error);
 
 #endif /* __NMCS_PROVIDER_H__ */