summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2021-01-05 14:20:48 +0100
committerThomas Haller <thaller@redhat.com>2021-01-08 16:32:48 +0100
commitf0faf2e1a1eeaa15f7e84c1ccc8d4d8b28d2fe9f (patch)
tree8183c6bb07761d92c9a8295c36e998d52866f1ca
parent511b4ab4112bf21bf0b42ccea85db228ffe720b5 (diff)
downloadNetworkManager-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.c46
-rw-r--r--clients/cloud-setup/nmcs-provider-ec2.c2
-rw-r--r--clients/cloud-setup/nmcs-provider-gcp.c66
-rw-r--r--clients/cloud-setup/nmcs-provider.h15
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;