mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-01 21:10:12 +01:00
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:
commit
341bf7dedf
6 changed files with 159 additions and 66 deletions
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue