diff options
author | Thomas Haller <thaller@redhat.com> | 2022-05-05 08:36:28 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-05-05 08:36:28 +0200 |
commit | ebe8a9b292d9390f34dd3a8b389515b452a7626a (patch) | |
tree | b3103230bffb2c0fc255965eb1d61960bb56c343 | |
parent | 298784aa9247857f2d08d0dacce6e8537250af1f (diff) | |
parent | 7d71aff24770ad8ba6c6bc16a83d4d9e2544bd45 (diff) | |
download | NetworkManager-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.c | 109 | ||||
-rw-r--r-- | src/nm-cloud-setup/nmcs-provider-azure.c | 4 | ||||
-rw-r--r-- | src/nm-cloud-setup/nmcs-provider-ec2.c | 33 | ||||
-rw-r--r-- | src/nm-cloud-setup/nmcs-provider-gcp.c | 4 | ||||
-rw-r--r-- | src/nm-cloud-setup/nmcs-provider.c | 32 | ||||
-rw-r--r-- | src/nm-cloud-setup/nmcs-provider.h | 43 |
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__ */ |