diff options
author | Thomas Haller <thaller@redhat.com> | 2021-01-05 14:20:48 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2021-01-08 16:32:48 +0100 |
commit | f0faf2e1a1eeaa15f7e84c1ccc8d4d8b28d2fe9f (patch) | |
tree | 8183c6bb07761d92c9a8295c36e998d52866f1ca | |
parent | 511b4ab4112bf21bf0b42ccea85db228ffe720b5 (diff) | |
download | NetworkManager-f0faf2e1a1eeaa15f7e84c1ccc8d4d8b28d2fe9f.tar.gz |
cloud-setup: handle unknown interaces in get_config() for GCP/Azure
The API of mcs_provider_get_config() allows to explicitly request
for certain interfaces (MAC addresses), but it also allows to fetch
any.
That means, the result dictionary will be pre-populated with the
MAC addresses that were requested, but if we encounter an unknown
interface, then that is not a reason to fail.
-rw-r--r-- | clients/cloud-setup/nmcs-provider-azure.c | 46 | ||||
-rw-r--r-- | clients/cloud-setup/nmcs-provider-ec2.c | 2 | ||||
-rw-r--r-- | clients/cloud-setup/nmcs-provider-gcp.c | 66 | ||||
-rw-r--r-- | clients/cloud-setup/nmcs-provider.h | 15 |
4 files changed, 92 insertions, 37 deletions
diff --git a/clients/cloud-setup/nmcs-provider-azure.c b/clients/cloud-setup/nmcs-provider-azure.c index 65ff058c77..b2490b87f9 100644 --- a/clients/cloud-setup/nmcs-provider-azure.c +++ b/clients/cloud-setup/nmcs-provider-azure.c @@ -98,13 +98,12 @@ typedef struct { NMCSProviderGetConfigIfaceData *iface_get_config; gssize iface_idx; guint n_ips_prefix_pending; - char * hwaddr; + const char * hwaddr; } AzureIfaceData; static void _azure_iface_data_destroy(AzureIfaceData *iface_data) { - g_free(iface_data->hwaddr); nm_g_slice_free(iface_data); } @@ -135,8 +134,7 @@ _get_config_fetch_done_cb(NMHttpClient * http_client, fip_str = g_bytes_get_data(response, NULL); iface_data->iface_get_config = g_hash_table_lookup(get_config_data->result_dict, iface_data->hwaddr); - iface_get_config = iface_data->iface_get_config; - iface_get_config->iface_idx = iface_data->iface_idx; + iface_get_config = iface_data->iface_get_config; if (is_ipv4) { if (!nm_utils_parse_inaddr_bin(AF_INET, fip_str, NULL, &tmp_addr)) { @@ -301,6 +299,7 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data) NMCSProviderGetConfigTaskData *get_config_data; gs_unref_bytes GBytes *response = NULL; AzureIfaceData * iface_data = user_data; + gs_free char * v_hwaddr = NULL; gs_free_error GError *error = NULL; gs_free const char * uri = NULL; char buf[100]; @@ -315,27 +314,44 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data) if (error) goto out_done; - iface_data->hwaddr = nmcs_utils_hwaddr_normalize_gbytes(response); - - if (!iface_data->hwaddr) + v_hwaddr = nmcs_utils_hwaddr_normalize_gbytes(response); + if (!v_hwaddr) { + _LOGI("interface[%" G_GSSIZE_FORMAT "]: invalid MAC address returned", + iface_data->iface_idx); + error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, + "invalid MAC address for index %" G_GSSIZE_FORMAT, + iface_data->iface_idx); goto out_done; + } - iface_data->iface_get_config = - g_hash_table_lookup(get_config_data->result_dict, iface_data->hwaddr); - - if (!iface_data->iface_get_config) { + if (!g_hash_table_lookup_extended(get_config_data->result_dict, + v_hwaddr, + (gpointer *) &iface_data->hwaddr, + (gpointer *) &iface_data->iface_get_config)) { if (!get_config_data->any) { - _LOGD("interface[%" G_GSSIZE_FORMAT "]: ignore hwaddr %s", - iface_data->iface_idx, - iface_data->hwaddr); + _LOGD("get-config: skip fetching meta data for %s (%" G_GSSIZE_FORMAT ")", + v_hwaddr, + iface_data->iface_idx); goto out_done; } iface_data->iface_get_config = nmcs_provider_get_config_iface_data_new(FALSE); g_hash_table_insert(get_config_data->result_dict, - g_strdup(iface_data->hwaddr), + (char *) (iface_data->hwaddr = g_steal_pointer(&v_hwaddr)), iface_data->iface_get_config); + } else { + if (iface_data->iface_get_config->iface_idx >= 0) { + _LOGI("interface[%" G_GSSIZE_FORMAT "]: duplicate MAC address %s returned", + iface_data->iface_idx, + iface_data->hwaddr); + error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, + "duplicate MAC address for index %" G_GSSIZE_FORMAT, + iface_data->iface_idx); + goto out_done; + } } + iface_data->iface_get_config->iface_idx = iface_data->iface_idx; + _LOGD("interface[%" G_GSSIZE_FORMAT "]: found a matching device with hwaddr %s", iface_data->iface_idx, iface_data->hwaddr); diff --git a/clients/cloud-setup/nmcs-provider-ec2.c b/clients/cloud-setup/nmcs-provider-ec2.c index 276479f254..49b909bf77 100644 --- a/clients/cloud-setup/nmcs-provider-ec2.c +++ b/clients/cloud-setup/nmcs-provider-ec2.c @@ -269,6 +269,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us } 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)", @@ -364,6 +365,7 @@ _get_config_metadata_ready_check(long response_code, mac_data->iface_idx = iface_idx_counter++; memcpy(mac_data->path, cur_line, cur_line_len + 1u); + /* here we will ignore duplicate responses. */ g_hash_table_insert(response_parsed, hwaddr, mac_data); } diff --git a/clients/cloud-setup/nmcs-provider-gcp.c b/clients/cloud-setup/nmcs-provider-gcp.c index d30749484f..aa01356113 100644 --- a/clients/cloud-setup/nmcs-provider-gcp.c +++ b/clients/cloud-setup/nmcs-provider-gcp.c @@ -134,9 +134,8 @@ _get_config_fip_cb(GObject *source, GAsyncResult *result, gpointer user_data) 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; + iface_get_config = iface_data->iface_get_config; + routes_arr = iface_get_config->iproutes_arr; route_new = nm_ip_route_new(AF_INET, fip_str, 32, NULL, 100, &error); if (error) @@ -243,13 +242,15 @@ out_error: static void _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_unref_bytes GBytes *response = NULL; + GCPIfaceData * iface_data = user_data; + gs_free_error GError * error = NULL; + gs_free char * v_hwaddr = NULL; + const char * hwaddr = NULL; + gs_free const char * uri = NULL; char sbuf[100]; NMCSProviderGetConfigTaskData *get_config_data; + gboolean is_requested; nm_http_client_poll_get_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error); @@ -259,20 +260,51 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data) get_config_data = iface_data->get_config_data; if (error) - goto out_error; + goto out_done; - hwaddr = nmcs_utils_hwaddr_normalize_gbytes(response); - iface_data->iface_get_config = g_hash_table_lookup(get_config_data->result_dict, hwaddr); - if (!iface_data->iface_get_config) { - _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: did not find a matching device", + v_hwaddr = nmcs_utils_hwaddr_normalize_gbytes(response); + if (!v_hwaddr) { + _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: invalid MAC address returned", iface_data->iface_idx); error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, - "no matching hwaddr found for GCP interface"); - goto out_error; + "invalid MAC address for index %" G_GSSIZE_FORMAT, + iface_data->iface_idx); + goto out_done; } - _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: found a matching device with hwaddr %s", + if (!g_hash_table_lookup_extended(get_config_data->result_dict, + v_hwaddr, + (gpointer *) &hwaddr, + (gpointer *) &iface_data->iface_get_config)) { + if (!get_config_data->any) { + _LOGD("get-config: skip fetching meta data for %s (%" G_GSSIZE_FORMAT ")", + v_hwaddr, + iface_data->iface_idx); + goto out_done; + } + iface_data->iface_get_config = nmcs_provider_get_config_iface_data_new(FALSE); + g_hash_table_insert(get_config_data->result_dict, + (char *) (hwaddr = g_steal_pointer(&v_hwaddr)), + iface_data->iface_get_config); + is_requested = FALSE; + } else { + if (iface_data->iface_get_config->iface_idx >= 0) { + _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: duplicate MAC address %s returned", + iface_data->iface_idx, + hwaddr); + error = nm_utils_error_new(NM_UTILS_ERROR_UNKNOWN, + "duplicate MAC address for index %" G_GSSIZE_FORMAT, + iface_data->iface_idx); + goto out_done; + } + is_requested = TRUE; + } + + iface_data->iface_get_config->iface_idx = iface_data->iface_idx; + + _LOGI("GCP interface[%" G_GSSIZE_FORMAT "]: found a %sdevice with hwaddr %s", iface_data->iface_idx, + is_requested ? "requested " : "", hwaddr); nm_sprintf_buf(sbuf, "%" G_GSSIZE_FORMAT "/forwarded-ips/", iface_data->iface_idx); @@ -291,7 +323,7 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data) iface_data); return; -out_error: +out_done: --get_config_data->n_pending; _nmcs_provider_get_config_task_maybe_return(get_config_data, g_steal_pointer(&error)); } diff --git a/clients/cloud-setup/nmcs-provider.h b/clients/cloud-setup/nmcs-provider.h index 3edd874337..3b0c2529ed 100644 --- a/clients/cloud-setup/nmcs-provider.h +++ b/clients/cloud-setup/nmcs-provider.h @@ -12,11 +12,16 @@ 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; + + /* If the interface was seen, get_config() should set this to a + * unique, increasing, positive index. If the interface is requested, + * it is initialized to -1. */ + 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; |