cloud-setup: merge branch 'th/cloud-setup-aliyun-primary-ip'

https://bugzilla.redhat.com/show_bug.cgi?id=2079849

(cherry picked from commit ebe8a9b292)
This commit is contained in:
Thomas Haller 2022-05-05 08:36:28 +02:00
commit 341bf7dedf
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
6 changed files with 159 additions and 66 deletions

View file

@ -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
@ -235,6 +263,17 @@ _get_config_fetch_done_cb_private_ipv4s(GObject *source, GAsyncResult *result, g
GET_CONFIG_FETCH_DONE_TYPE_PRIVATE_IPV4S);
}
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)
{
@ -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,12 +393,29 @@ _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,
@ -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);

View file

@ -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",

View file

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

View file

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

View file

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

View file

@ -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__ */