Reapply "cloud-setup: parse OCI metadata related to VLAN config"
Baremetal instances in Oracle Cloud require special VLAN config. Parse the metadata related to it. This reverts commit5eefd2d59c
. (cherry picked from commit5c3efeef15
)
This commit is contained in:
@@ -92,6 +92,9 @@ _get_config_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||||||
gs_unref_bytes GBytes *response = NULL;
|
gs_unref_bytes GBytes *response = NULL;
|
||||||
gs_free_error GError *error = NULL;
|
gs_free_error GError *error = NULL;
|
||||||
nm_auto_decref_json json_t *vnics = NULL;
|
nm_auto_decref_json json_t *vnics = NULL;
|
||||||
|
gboolean is_baremetal;
|
||||||
|
gs_unref_ptrarray GPtrArray *phys_nic_macs = NULL;
|
||||||
|
GHashTableIter h_iter;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
nm_http_client_poll_req_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error);
|
nm_http_client_poll_req_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error);
|
||||||
@@ -112,12 +115,24 @@ _get_config_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (json_array_size(vnics) > 0) {
|
||||||
|
is_baremetal = NULL != json_object_get(json_array_get(vnics, 0), "nicIndex");
|
||||||
|
_LOGI("get-config: detected %s instance", is_baremetal ? "baremetal" : "VM");
|
||||||
|
} else {
|
||||||
|
is_baremetal = FALSE;
|
||||||
|
_LOGI("get-config: empty VNICs metadata, cannot detect instance type");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_baremetal)
|
||||||
|
phys_nic_macs = g_ptr_array_sized_new(16);
|
||||||
|
|
||||||
for (i = 0; i < json_array_size(vnics); i++) {
|
for (i = 0; i < json_array_size(vnics); i++) {
|
||||||
json_t *vnic, *field;
|
json_t *vnic, *field;
|
||||||
const char *vnic_id = "", *val;
|
const char *vnic_id = "", *val;
|
||||||
gs_free char *mac = NULL;
|
gs_free char *mac = NULL;
|
||||||
in_addr_t addr;
|
in_addr_t addr;
|
||||||
int prefix;
|
int prefix;
|
||||||
|
json_int_t nic_index = -1, vlan_tag = -1;
|
||||||
|
|
||||||
vnic = json_array_get(vnics, i);
|
vnic = json_array_get(vnics, i);
|
||||||
if (!json_is_object(vnic)) {
|
if (!json_is_object(vnic)) {
|
||||||
@@ -130,12 +145,28 @@ _get_config_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||||||
|
|
||||||
field = json_object_get(vnic, "macAddr");
|
field = json_object_get(vnic, "macAddr");
|
||||||
val = field && json_is_string(field) ? json_string_value(field) : NULL;
|
val = field && json_is_string(field) ? json_string_value(field) : NULL;
|
||||||
if (!val) {
|
mac = val ? nmcs_utils_hwaddr_normalize(val, json_string_length(field)) : NULL;
|
||||||
|
if (!mac) {
|
||||||
_VNIC_WARN("missing or invalid 'macAddr', ignoring VNIC");
|
_VNIC_WARN("missing or invalid 'macAddr', ignoring VNIC");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mac = nmcs_utils_hwaddr_normalize(val, json_string_length(field));
|
if (is_baremetal) {
|
||||||
|
field = json_object_get(vnic, "nicIndex");
|
||||||
|
nic_index = field && json_is_integer(field) ? json_integer_value(field) : -1;
|
||||||
|
if (nic_index < 0 || nic_index >= 1024) { /* 1024 = random limit to prevent abuse*/
|
||||||
|
_VNIC_WARN("missing or invalid 'nicIndex', ignoring VNIC");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
field = json_object_get(vnic, "vlanTag");
|
||||||
|
vlan_tag = field && json_is_integer(field) ? json_integer_value(field) : -1;
|
||||||
|
if (vlan_tag < 0) {
|
||||||
|
_VNIC_WARN("missing or invalid 'vlanTag', ignoring VNIC");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
config_iface_data = nmcs_provider_get_config_iface_data_create(get_config_data, FALSE, mac);
|
config_iface_data = nmcs_provider_get_config_iface_data_create(get_config_data, FALSE, mac);
|
||||||
config_iface_data->iface_idx = i;
|
config_iface_data->iface_idx = i;
|
||||||
|
|
||||||
@@ -168,6 +199,48 @@ _get_config_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||||||
} else {
|
} else {
|
||||||
_VNIC_WARN("missing or invalid 'subnetCidrBlock'");
|
_VNIC_WARN("missing or invalid 'subnetCidrBlock'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_baremetal) {
|
||||||
|
gboolean is_phys_nic = vlan_tag == 0;
|
||||||
|
|
||||||
|
/* In baremetal instances, configure VNICs' VLAN (physical NICs don't need it) */
|
||||||
|
if (is_phys_nic) {
|
||||||
|
config_iface_data->priv.oci.vlan_tag = 0;
|
||||||
|
config_iface_data->priv.oci.parent_hwaddr = NULL;
|
||||||
|
if (nic_index >= phys_nic_macs->len)
|
||||||
|
g_ptr_array_set_size(phys_nic_macs,
|
||||||
|
NM_MAX((guint) (nic_index + 1), phys_nic_macs->len * 2));
|
||||||
|
phys_nic_macs->pdata[nic_index] = (gpointer) config_iface_data->hwaddr;
|
||||||
|
} else {
|
||||||
|
/* We might not have all the physical NICs' MACs yet, save nicIndex for later */
|
||||||
|
config_iface_data->priv.oci.parent_hwaddr = GINT_TO_POINTER((int) nic_index);
|
||||||
|
config_iface_data->priv.oci.vlan_tag = vlan_tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_baremetal) {
|
||||||
|
g_hash_table_iter_init(&h_iter, get_config_data->result_dict);
|
||||||
|
|
||||||
|
/* Now that all the metadata is processed we should have all the physical NICs' MACs */
|
||||||
|
while (g_hash_table_iter_next(&h_iter, NULL, (gpointer *) &config_iface_data)) {
|
||||||
|
bool is_phys_nic = config_iface_data->priv.oci.vlan_tag == 0;
|
||||||
|
int nic_index = GPOINTER_TO_INT(config_iface_data->priv.oci.parent_hwaddr);
|
||||||
|
|
||||||
|
if (is_phys_nic)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (nic_index >= phys_nic_macs->len || phys_nic_macs->pdata[nic_index] == NULL) {
|
||||||
|
_LOGW("get-config: physical NIC for nicIndex=%d not found, ignoring VNIC "
|
||||||
|
"(VNIC macAddr=%s)",
|
||||||
|
nic_index,
|
||||||
|
config_iface_data->hwaddr);
|
||||||
|
g_hash_table_iter_remove(&h_iter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
config_iface_data->priv.oci.parent_hwaddr = g_strdup(phys_nic_macs->pdata[nic_index]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@@ -188,6 +188,7 @@ nmcs_provider_get_config_iface_data_create(NMCSProviderGetConfigTaskData *get_co
|
|||||||
|
|
||||||
iface_data = g_slice_new(NMCSProviderGetConfigIfaceData);
|
iface_data = g_slice_new(NMCSProviderGetConfigIfaceData);
|
||||||
*iface_data = (NMCSProviderGetConfigIfaceData) {
|
*iface_data = (NMCSProviderGetConfigIfaceData) {
|
||||||
|
.provider = g_object_ref(get_config_data->self),
|
||||||
.get_config_data = get_config_data,
|
.get_config_data = get_config_data,
|
||||||
.hwaddr = g_strdup(hwaddr),
|
.hwaddr = g_strdup(hwaddr),
|
||||||
.iface_idx = -1,
|
.iface_idx = -1,
|
||||||
@@ -203,6 +204,11 @@ nmcs_provider_get_config_iface_data_create(NMCSProviderGetConfigTaskData *get_co
|
|||||||
iface_data->priv.aliyun = (typeof(iface_data->priv.aliyun)) {
|
iface_data->priv.aliyun = (typeof(iface_data->priv.aliyun)) {
|
||||||
.has_primary_ip_address = FALSE,
|
.has_primary_ip_address = FALSE,
|
||||||
};
|
};
|
||||||
|
} else if (G_OBJECT_TYPE(get_config_data->self) == nmcs_provider_oci_get_type()) {
|
||||||
|
iface_data->priv.oci = (typeof(iface_data->priv.oci)) {
|
||||||
|
.vlan_tag = 0,
|
||||||
|
.parent_hwaddr = NULL,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the has does not own the key (iface_datta->hwaddr), the lifetime of the
|
/* the has does not own the key (iface_datta->hwaddr), the lifetime of the
|
||||||
@@ -220,6 +226,9 @@ _iface_data_free(gpointer data)
|
|||||||
g_free(iface_data->ipv4s_arr);
|
g_free(iface_data->ipv4s_arr);
|
||||||
nm_g_ptr_array_unref(iface_data->iproutes);
|
nm_g_ptr_array_unref(iface_data->iproutes);
|
||||||
g_free((char *) iface_data->hwaddr);
|
g_free((char *) iface_data->hwaddr);
|
||||||
|
if (G_OBJECT_TYPE(iface_data->provider) == nmcs_provider_oci_get_type())
|
||||||
|
g_free((char *) iface_data->priv.oci.parent_hwaddr);
|
||||||
|
g_clear_object(&iface_data->provider);
|
||||||
|
|
||||||
nm_g_slice_free(iface_data);
|
nm_g_slice_free(iface_data);
|
||||||
}
|
}
|
||||||
|
@@ -17,6 +17,8 @@ typedef struct {
|
|||||||
* dictionary. */
|
* dictionary. */
|
||||||
const char *hwaddr;
|
const char *hwaddr;
|
||||||
|
|
||||||
|
struct _NMCSProvider *provider;
|
||||||
|
|
||||||
struct _NMCSProviderGetConfigTaskData *get_config_data;
|
struct _NMCSProviderGetConfigTaskData *get_config_data;
|
||||||
|
|
||||||
in_addr_t *ipv4s_arr;
|
in_addr_t *ipv4s_arr;
|
||||||
@@ -51,6 +53,10 @@ typedef struct {
|
|||||||
bool has_primary_ip_address : 1;
|
bool has_primary_ip_address : 1;
|
||||||
bool ipv4s_arr_ordered : 1;
|
bool ipv4s_arr_ordered : 1;
|
||||||
} aliyun;
|
} aliyun;
|
||||||
|
struct {
|
||||||
|
guint32 vlan_tag; /* 0 if no VLAN is needed */
|
||||||
|
const char *parent_hwaddr;
|
||||||
|
} oci;
|
||||||
} priv;
|
} priv;
|
||||||
|
|
||||||
} NMCSProviderGetConfigIfaceData;
|
} NMCSProviderGetConfigIfaceData;
|
||||||
|
Reference in New Issue
Block a user