summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-05-05 08:36:28 +0200
committerThomas Haller <thaller@redhat.com>2022-05-05 08:36:28 +0200
commitebe8a9b292d9390f34dd3a8b389515b452a7626a (patch)
treeb3103230bffb2c0fc255965eb1d61960bb56c343
parent298784aa9247857f2d08d0dacce6e8537250af1f (diff)
parent7d71aff24770ad8ba6c6bc16a83d4d9e2544bd45 (diff)
downloadNetworkManager-ebe8a9b292d9390f34dd3a8b389515b452a7626a.tar.gz
cloud-setup: merge branch 'th/cloud-setup-aliyun-primary-ip'
https://bugzilla.redhat.com/show_bug.cgi?id=2079849
-rw-r--r--src/nm-cloud-setup/nmcs-provider-aliyun.c109
-rw-r--r--src/nm-cloud-setup/nmcs-provider-azure.c4
-rw-r--r--src/nm-cloud-setup/nmcs-provider-ec2.c33
-rw-r--r--src/nm-cloud-setup/nmcs-provider-gcp.c4
-rw-r--r--src/nm-cloud-setup/nmcs-provider.c32
-rw-r--r--src/nm-cloud-setup/nmcs-provider.h43
6 files changed, 159 insertions, 66 deletions
diff --git a/src/nm-cloud-setup/nmcs-provider-aliyun.c b/src/nm-cloud-setup/nmcs-provider-aliyun.c
index 31c9830d2d..1a5e5459e4 100644
--- a/src/nm-cloud-setup/nmcs-provider-aliyun.c
+++ b/src/nm-cloud-setup/nmcs-provider-aliyun.c
@@ -123,29 +123,26 @@ detect(NMCSProvider *provider, GTask *task)
typedef enum {
GET_CONFIG_FETCH_DONE_TYPE_SUBNET_VPC_CIDR_BLOCK,
GET_CONFIG_FETCH_DONE_TYPE_PRIVATE_IPV4S,
+ GET_CONFIG_FETCH_DONE_TYPE_PRIMARY_IP_ADDRESS,
GET_CONFIG_FETCH_DONE_TYPE_NETMASK,
GET_CONFIG_FETCH_DONE_TYPE_GATEWAY,
} GetConfigFetchDoneType;
static void
-_get_config_fetch_done_cb(NMHttpClient *http_client,
- GAsyncResult *result,
- gpointer user_data,
- GetConfigFetchDoneType fetch_type)
+_get_config_fetch_done_cb(NMHttpClient *http_client,
+ GAsyncResult *result,
+ NMCSProviderGetConfigIfaceData *config_iface_data,
+ GetConfigFetchDoneType fetch_type)
{
- NMCSProviderGetConfigTaskData *get_config_data;
- gs_unref_bytes GBytes *response = NULL;
- gs_free_error GError *error = NULL;
- NMCSProviderGetConfigIfaceData *config_iface_data;
- in_addr_t tmp_addr;
- int tmp_prefix;
- in_addr_t netmask_bin;
- in_addr_t gateway_bin;
- gs_free const char **s_addrs = NULL;
- gsize i;
- gsize len;
-
- nm_utils_user_data_unpack(user_data, &get_config_data, &config_iface_data);
+ gs_unref_bytes GBytes *response = NULL;
+ gs_free_error GError *error = NULL;
+ in_addr_t tmp_addr;
+ int tmp_prefix;
+ in_addr_t netmask_bin;
+ in_addr_t gateway_bin;
+ gs_free const char **s_addrs = NULL;
+ gsize i;
+ gsize len;
nm_http_client_poll_get_finish(http_client, result, NULL, &response, &error);
@@ -177,6 +174,16 @@ _get_config_fetch_done_cb(NMHttpClient *http_client,
}
break;
+ case GET_CONFIG_FETCH_DONE_TYPE_PRIMARY_IP_ADDRESS:
+
+ if (nm_utils_parse_inaddr_bin(AF_INET, g_bytes_get_data(response, NULL), NULL, &tmp_addr)) {
+ nm_assert(config_iface_data->priv.aliyun.primary_ip_address == 0);
+ nm_assert(!config_iface_data->priv.aliyun.has_primary_ip_address);
+ config_iface_data->priv.aliyun.primary_ip_address = tmp_addr;
+ config_iface_data->priv.aliyun.has_primary_ip_address = TRUE;
+ }
+ break;
+
case GET_CONFIG_FETCH_DONE_TYPE_SUBNET_VPC_CIDR_BLOCK:
if (nm_utils_parse_inaddr_prefix_bin(AF_INET,
@@ -212,9 +219,30 @@ _get_config_fetch_done_cb(NMHttpClient *http_client,
break;
}
+ if (!config_iface_data->priv.aliyun.ipv4s_arr_ordered
+ && config_iface_data->priv.aliyun.has_primary_ip_address
+ && config_iface_data->ipv4s_len > 0) {
+ for (i = 0; i < config_iface_data->ipv4s_len; i++) {
+ if (config_iface_data->ipv4s_arr[i]
+ != config_iface_data->priv.aliyun.primary_ip_address)
+ continue;
+ if (i > 0) {
+ /* OK, at position [i] we found the primary address.
+ * Move the elements from [0..(i-1)] to [1..i] and then set [0]. */
+ memmove(&config_iface_data->ipv4s_arr[1],
+ &config_iface_data->ipv4s_arr[0],
+ i * sizeof(in_addr_t));
+ config_iface_data->ipv4s_arr[0] = config_iface_data->priv.aliyun.primary_ip_address;
+ }
+ break;
+ }
+ config_iface_data->priv.aliyun.ipv4s_arr_ordered = TRUE;
+ }
+
out:
- get_config_data->n_pending--;
- _nmcs_provider_get_config_task_maybe_return(get_config_data, g_steal_pointer(&error));
+ config_iface_data->get_config_data->n_pending--;
+ _nmcs_provider_get_config_task_maybe_return(config_iface_data->get_config_data,
+ g_steal_pointer(&error));
}
static void
@@ -236,6 +264,17 @@ _get_config_fetch_done_cb_private_ipv4s(GObject *source, GAsyncResult *result, g
}
static void
+_get_config_fetch_done_cb_primary_ip_address(GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ _get_config_fetch_done_cb(NM_HTTP_CLIENT(source),
+ result,
+ user_data,
+ GET_CONFIG_FETCH_DONE_TYPE_PRIMARY_IP_ADDRESS);
+}
+
+static void
_get_config_fetch_done_cb_netmask(GObject *source, GAsyncResult *result, gpointer user_data)
{
_get_config_fetch_done_cb(NM_HTTP_CLIENT(source),
@@ -297,6 +336,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
gs_free char *uri2 = NULL;
gs_free char *uri3 = NULL;
gs_free char *uri4 = NULL;
+ gs_free char *uri5 = NULL;
config_iface_data = g_hash_table_lookup(get_config_data->result_dict, v_hwaddr);
@@ -309,9 +349,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
}
config_iface_data =
- nmcs_provider_get_config_iface_data_create(get_config_data->result_dict,
- FALSE,
- v_hwaddr);
+ nmcs_provider_get_config_iface_data_create(get_config_data, FALSE, v_hwaddr);
}
nm_assert(config_iface_data->iface_idx == -1);
@@ -338,7 +376,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
NULL,
NULL,
_get_config_fetch_done_cb_vpc_cidr_block,
- nm_utils_user_data_pack(get_config_data, config_iface_data));
+ config_iface_data);
get_config_data->n_pending++;
nm_http_client_poll_get(
@@ -355,13 +393,30 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
NULL,
NULL,
_get_config_fetch_done_cb_private_ipv4s,
- nm_utils_user_data_pack(get_config_data, config_iface_data));
+ config_iface_data);
get_config_data->n_pending++;
nm_http_client_poll_get(
http_client,
(uri3 = _aliyun_uri_interfaces(v_mac_data->path,
NM_STR_HAS_SUFFIX(v_mac_data->path, "/") ? "" : "/",
+ "primary-ip-address")),
+ HTTP_TIMEOUT_MS,
+ 512 * 1024,
+ 10000,
+ 1000,
+ NULL,
+ get_config_data->intern_cancellable,
+ NULL,
+ NULL,
+ _get_config_fetch_done_cb_primary_ip_address,
+ config_iface_data);
+
+ get_config_data->n_pending++;
+ nm_http_client_poll_get(
+ http_client,
+ (uri4 = _aliyun_uri_interfaces(v_mac_data->path,
+ NM_STR_HAS_SUFFIX(v_mac_data->path, "/") ? "" : "/",
"netmask")),
HTTP_TIMEOUT_MS,
512 * 1024,
@@ -372,12 +427,12 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
NULL,
NULL,
_get_config_fetch_done_cb_netmask,
- nm_utils_user_data_pack(get_config_data, config_iface_data));
+ config_iface_data);
get_config_data->n_pending++;
nm_http_client_poll_get(
http_client,
- (uri4 = _aliyun_uri_interfaces(v_mac_data->path,
+ (uri5 = _aliyun_uri_interfaces(v_mac_data->path,
NM_STR_HAS_SUFFIX(v_mac_data->path, "/") ? "" : "/",
"gateway")),
HTTP_TIMEOUT_MS,
@@ -389,7 +444,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
NULL,
NULL,
_get_config_fetch_done_cb_gateway,
- nm_utils_user_data_pack(get_config_data, config_iface_data));
+ config_iface_data);
}
_nmcs_provider_get_config_task_maybe_return(get_config_data, NULL);
diff --git a/src/nm-cloud-setup/nmcs-provider-azure.c b/src/nm-cloud-setup/nmcs-provider-azure.c
index 06f23ea73e..9b27af288a 100644
--- a/src/nm-cloud-setup/nmcs-provider-azure.c
+++ b/src/nm-cloud-setup/nmcs-provider-azure.c
@@ -387,9 +387,7 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data)
goto out_done;
}
iface_data->iface_get_config =
- nmcs_provider_get_config_iface_data_create(get_config_data->result_dict,
- FALSE,
- v_hwaddr);
+ nmcs_provider_get_config_iface_data_create(get_config_data, FALSE, v_hwaddr);
} else {
if (iface_data->iface_get_config->iface_idx >= 0) {
_LOGI("interface[%" G_GSSIZE_FORMAT "]: duplicate MAC address %s returned",
diff --git a/src/nm-cloud-setup/nmcs-provider-ec2.c b/src/nm-cloud-setup/nmcs-provider-ec2.c
index ee4e2a95fa..d6fa03118d 100644
--- a/src/nm-cloud-setup/nmcs-provider-ec2.c
+++ b/src/nm-cloud-setup/nmcs-provider-ec2.c
@@ -116,19 +116,15 @@ detect(NMCSProvider *provider, GTask *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,
+ NMCSProviderGetConfigIfaceData *config_iface_data,
+ gboolean is_local_ipv4)
{
- NMCSProviderGetConfigTaskData *get_config_data;
- gs_unref_bytes GBytes *response = NULL;
- gs_free_error GError *error = NULL;
- NMCSProviderGetConfigIfaceData *config_iface_data;
- in_addr_t tmp_addr;
- int tmp_prefix;
-
- nm_utils_user_data_unpack(user_data, &get_config_data, &config_iface_data);
+ gs_unref_bytes GBytes *response = NULL;
+ gs_free_error GError *error = NULL;
+ in_addr_t tmp_addr;
+ int tmp_prefix;
nm_http_client_poll_get_finish(http_client, result, NULL, &response, &error);
@@ -173,8 +169,9 @@ _get_config_fetch_done_cb(NMHttpClient *http_client,
}
out:
- get_config_data->n_pending--;
- _nmcs_provider_get_config_task_maybe_return(get_config_data, g_steal_pointer(&error));
+ config_iface_data->get_config_data->n_pending--;
+ _nmcs_provider_get_config_task_maybe_return(config_iface_data->get_config_data,
+ g_steal_pointer(&error));
}
static void
@@ -244,9 +241,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
continue;
}
config_iface_data =
- nmcs_provider_get_config_iface_data_create(get_config_data->result_dict,
- FALSE,
- v_hwaddr);
+ nmcs_provider_get_config_iface_data_create(get_config_data, FALSE, v_hwaddr);
}
nm_assert(config_iface_data->iface_idx == -1);
@@ -273,7 +268,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
NULL,
NULL,
_get_config_fetch_done_cb_subnet_ipv4_cidr_block,
- nm_utils_user_data_pack(get_config_data, config_iface_data));
+ config_iface_data);
get_config_data->n_pending++;
nm_http_client_poll_get(
@@ -290,7 +285,7 @@ _get_config_metadata_ready_cb(GObject *source, GAsyncResult *result, gpointer us
NULL,
NULL,
_get_config_fetch_done_cb_local_ipv4s,
- nm_utils_user_data_pack(get_config_data, config_iface_data));
+ config_iface_data);
}
_nmcs_provider_get_config_task_maybe_return(get_config_data, NULL);
diff --git a/src/nm-cloud-setup/nmcs-provider-gcp.c b/src/nm-cloud-setup/nmcs-provider-gcp.c
index 0df2bdd607..a325f31a17 100644
--- a/src/nm-cloud-setup/nmcs-provider-gcp.c
+++ b/src/nm-cloud-setup/nmcs-provider-gcp.c
@@ -282,9 +282,7 @@ _get_config_iface_cb(GObject *source, GAsyncResult *result, gpointer user_data)
goto out_done;
}
iface_data->iface_get_config =
- nmcs_provider_get_config_iface_data_create(get_config_data->result_dict,
- FALSE,
- v_hwaddr);
+ nmcs_provider_get_config_iface_data_create(get_config_data, FALSE, v_hwaddr);
is_requested = FALSE;
} else {
if (iface_data->iface_get_config->iface_idx >= 0) {
diff --git a/src/nm-cloud-setup/nmcs-provider.c b/src/nm-cloud-setup/nmcs-provider.c
index f14a3d0272..fd9a61b813 100644
--- a/src/nm-cloud-setup/nmcs-provider.c
+++ b/src/nm-cloud-setup/nmcs-provider.c
@@ -174,24 +174,38 @@ nmcs_provider_detect_finish(NMCSProvider *self, GAsyncResult *result, GError **e
/*****************************************************************************/
NMCSProviderGetConfigIfaceData *
-nmcs_provider_get_config_iface_data_create(GHashTable *iface_datas,
- gboolean was_requested,
- const char *hwaddr)
+nmcs_provider_get_config_iface_data_create(NMCSProviderGetConfigTaskData *get_config_data,
+ gboolean was_requested,
+ const char *hwaddr)
{
NMCSProviderGetConfigIfaceData *iface_data;
nm_assert(hwaddr);
+ nm_assert(get_config_data);
+ nm_assert(NMCS_IS_PROVIDER(get_config_data->self));
iface_data = g_slice_new(NMCSProviderGetConfigIfaceData);
*iface_data = (NMCSProviderGetConfigIfaceData){
- .hwaddr = g_strdup(hwaddr),
- .iface_idx = -1,
- .was_requested = was_requested,
+ .get_config_data = get_config_data,
+ .hwaddr = g_strdup(hwaddr),
+ .iface_idx = -1,
+ .was_requested = was_requested,
};
+ /* "priv" is a union, and according to C, it might not be properly initialized
+ * that all union members are set to false/0/NULL/0.0. We need to know which
+ * union field we are going to use, and that depends on the type of "self".
+ * Also, knowing the type would allow us to initialize to something other than
+ * false/0/NULL/0.0. */
+ if (G_OBJECT_TYPE(get_config_data->self) == nmcs_provider_aliyun_get_type()) {
+ iface_data->priv.aliyun = (typeof(iface_data->priv.aliyun)){
+ .has_primary_ip_address = FALSE,
+ };
+ }
+
/* the has does not own the key (iface_datta->hwaddr), the lifetime of the
* key is associated with the iface_data instance. */
- g_hash_table_replace(iface_datas, (char *) iface_data->hwaddr, iface_data);
+ g_hash_table_replace(get_config_data->result_dict, (char *) iface_data->hwaddr, iface_data);
return iface_data;
}
@@ -280,6 +294,8 @@ nmcs_provider_get_config(NMCSProvider *self,
get_config_data = g_slice_new(NMCSProviderGetConfigTaskData);
*get_config_data = (NMCSProviderGetConfigTaskData){
+ /* "self" is kept alive by "task". */
+ .self = self,
.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, NULL, _iface_data_free),
@@ -288,7 +304,7 @@ nmcs_provider_get_config(NMCSProvider *self,
nmcs_wait_for_objects_register(get_config_data->task);
for (; hwaddrs && hwaddrs[0]; hwaddrs++)
- nmcs_provider_get_config_iface_data_create(get_config_data->result_dict, TRUE, hwaddrs[0]);
+ nmcs_provider_get_config_iface_data_create(get_config_data, TRUE, hwaddrs[0]);
if (cancellable) {
gulong cancelled_id;
diff --git a/src/nm-cloud-setup/nmcs-provider.h b/src/nm-cloud-setup/nmcs-provider.h
index bce41dcb82..502f1d0323 100644
--- a/src/nm-cloud-setup/nmcs-provider.h
+++ b/src/nm-cloud-setup/nmcs-provider.h
@@ -9,11 +9,16 @@
/*****************************************************************************/
+struct _NMCSProvider;
+struct _NMCSProviderGetConfigTaskData;
+
typedef struct {
/* And it's exactly the same pointer that is also the key for the iface_datas
* dictionary. */
const char *hwaddr;
+ struct _NMCSProviderGetConfigTaskData *get_config_data;
+
in_addr_t *ipv4s_arr;
gsize ipv4s_len;
@@ -36,6 +41,18 @@ typedef struct {
* nmcs_provider_get_config(). */
bool was_requested : 1;
+ /* Usually we would want that the parent class NMCSProvider is not aware about
+ * the implementations. However, it's convenient to track implementation specific data
+ * here, thus we violate such separation. In practice, all subclasses are known
+ * at compile time, and it will be simpler this way. */
+ union {
+ struct {
+ in_addr_t primary_ip_address;
+ bool has_primary_ip_address : 1;
+ bool ipv4s_arr_ordered : 1;
+ } aliyun;
+ } priv;
+
} NMCSProviderGetConfigIfaceData;
static inline gboolean
@@ -45,10 +62,6 @@ nmcs_provider_get_config_iface_data_is_valid(const NMCSProviderGetConfigIfaceDat
&& ((config_data->has_ipv4s && config_data->has_cidr) || config_data->iproutes_len);
}
-NMCSProviderGetConfigIfaceData *nmcs_provider_get_config_iface_data_create(GHashTable *iface_datas,
- gboolean was_requested,
- const char *hwaddr);
-
/*****************************************************************************/
typedef struct {
@@ -83,9 +96,11 @@ NM_AUTO_DEFINE_FCN0(NMCSProviderGetConfigResult *,
/*****************************************************************************/
-typedef struct {
+typedef struct _NMCSProviderGetConfigTaskData {
GTask *task;
+ struct _NMCSProvider *self;
+
GHashTable *result_dict;
/* this cancellable should be used for the provider implementation
@@ -105,6 +120,15 @@ typedef struct {
bool any : 1;
} NMCSProviderGetConfigTaskData;
+/*****************************************************************************/
+
+NMCSProviderGetConfigIfaceData *
+nmcs_provider_get_config_iface_data_create(NMCSProviderGetConfigTaskData *get_config_data,
+ gboolean was_requested,
+ const char *hwaddr);
+
+/*****************************************************************************/
+
#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) \
@@ -118,7 +142,7 @@ typedef struct {
struct _NMCSProviderPrivate;
-typedef struct {
+typedef struct _NMCSProvider {
GObject parent;
struct _NMCSProviderPrivate *_priv;
} NMCSProvider;
@@ -167,4 +191,11 @@ void nmcs_provider_get_config(NMCSProvider *provider,
NMCSProviderGetConfigResult *
nmcs_provider_get_config_finish(NMCSProvider *provider, GAsyncResult *result, GError **error);
+/*****************************************************************************/
+
+/* Forward declare the implemented gtype getters so we can use it at a few places without requiring
+ * to include the full header. The other parts of those headers should not be used aside where they
+ * are necessary. */
+GType nmcs_provider_aliyun_get_type(void);
+
#endif /* __NMCS_PROVIDER_H__ */