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.
This commit is contained in:
Thomas Haller 2021-01-05 14:20:48 +01:00
parent 511b4ab411
commit f0faf2e1a1
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
4 changed files with 92 additions and 37 deletions

View file

@ -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);

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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;