diff --git a/src/nm-cloud-setup/main.c b/src/nm-cloud-setup/main.c index 199f4e599d..d913ea1ffe 100644 --- a/src/nm-cloud-setup/main.c +++ b/src/nm-cloud-setup/main.c @@ -427,23 +427,13 @@ _nmc_mangle_connection(NMDevice *device, NM_SET_OUT(out_skipped_single_addr, FALSE); NM_SET_OUT(out_changed, FALSE); - if (strcmp(nm_connection_get_connection_type(connection), NM_SETTING_MACVLAN_SETTING_NAME) - == 0) { - /* The MACVLAN just sits in between, no L3 configuration on it */ - return; - } else if (strcmp(nm_connection_get_connection_type(connection), NM_SETTING_VLAN_SETTING_NAME) - != 0) { - /* Preserve existing L3 configuration if not a VLAN */ - if (device) { - if ((ac = nm_device_get_active_connection(device)) - && (remote_connection = NM_CONNECTION(nm_active_connection_get_connection(ac)))) - remote_s_ip = nm_connection_get_setting_ip4_config(remote_connection); - } - } - s_ip = nm_connection_get_setting_ip4_config(connection); nm_assert(NM_IS_SETTING_IP4_CONFIG(s_ip)); + if ((ac = nm_device_get_active_connection(device)) + && (remote_connection = NM_CONNECTION(nm_active_connection_get_connection(ac)))) + remote_s_ip = nm_connection_get_setting_ip4_config(remote_connection); + addrs_new = g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_address_unref); rules_new = g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_routing_rule_unref); @@ -576,31 +566,54 @@ _nmc_mangle_connection(NMDevice *device, /*****************************************************************************/ static gboolean -_config_existing(SigTermData *sigterm_data, - const NMCSProviderGetConfigIfaceData *config_data, - NMClient *nmc, - const NMCSProviderGetConfigResult *result, - const char *connection_type, - NMDevice *device) +_config_one(SigTermData *sigterm_data, + NMClient *nmc, + const NMCSProviderGetConfigResult *result, + guint idx) { - const char *hwaddr = config_data->hwaddr; - gs_unref_object NMConnection *applied_connection = NULL; - guint64 applied_version_id; - gs_free_error GError *error = NULL; - gboolean changed; - gboolean skipped_single_addr; - gboolean version_id_changed; - guint try_count; - gboolean any_changes; - gboolean maybe_no_preserved_external_ip; + const NMCSProviderGetConfigIfaceData *config_data = result->iface_datas_arr[idx]; + const char *hwaddr = config_data->hwaddr; + gs_unref_object NMDevice *device = NULL; + gs_unref_object NMConnection *applied_connection = NULL; + guint64 applied_version_id; + gs_free_error GError *error = NULL; + gboolean changed; + gboolean skipped_single_addr; + gboolean version_id_changed; + guint try_count; + gboolean any_changes = FALSE; + gboolean maybe_no_preserved_external_ip; + + g_main_context_iteration(NULL, FALSE); + + if (g_cancellable_is_cancelled(sigterm_data->cancellable)) + return FALSE; + + device = nm_g_object_ref(_nmc_get_device_by_hwaddr(nmc, NM_DEVICE_TYPE_ETHERNET, hwaddr)); + if (!device) { + _LOGD("config device %s: skip because device not found", hwaddr); + return FALSE; + } + + if (!nmcs_provider_get_config_iface_data_is_valid(config_data)) { + _LOGD("config device %s: skip because meta data not successfully fetched", hwaddr); + return FALSE; + } + + if (config_data->iface_idx >= 100) { + /* since we use the iface_idx to select a table number, the range is limited from + * 0 to 99. Note that the providers are required to provide increasing numbers, + * so this means we bail out after the first 100 devices. */ + _LOGD("config device %s: skip because number of supported interfaces reached", hwaddr); + return FALSE; + } _LOGD("config device %s: configuring \"%s\" (%s)...", hwaddr, nm_device_get_iface(device) ?: "/unknown/", nm_object_get_path(NM_OBJECT(device))); - try_count = 0; - any_changes = FALSE; + try_count = 0; try_again: g_clear_object(&applied_connection); @@ -625,7 +638,7 @@ try_again: return any_changes; } - if (_nmc_skip_connection_by_type(applied_connection, connection_type)) { + if (_nmc_skip_connection_by_type(applied_connection, NM_SETTING_WIRED_SETTING_NAME)) { _LOGD("config device %s: device has no suitable applied connection. Skip", hwaddr); return any_changes; } @@ -692,7 +705,7 @@ try_again: nm_connection_get_uuid(applied_connection), error->message); } - return TRUE; + return any_changes; } _LOGD("config device %s: connection \"%s\" (%s) reapplied", @@ -700,233 +713,17 @@ try_again: nm_connection_get_id(applied_connection), nm_connection_get_uuid(applied_connection)); - return TRUE; -} - -static gboolean -_config_ethernet(SigTermData *sigterm_data, - const NMCSProviderGetConfigIfaceData *config_data, - NMClient *nmc, - const NMCSProviderGetConfigResult *result) -{ - gs_unref_object NMDevice *device = NULL; - - device = nm_g_object_ref( - _nmc_get_device_by_hwaddr(nmc, NM_TYPE_DEVICE_ETHERNET, config_data->hwaddr)); - if (!device) { - _LOGD("config device %s: skip because device not found", config_data->hwaddr); - return FALSE; - } - - return _config_existing(sigterm_data, - config_data, - nmc, - result, - NM_SETTING_WIRED_SETTING_NAME, - device); -} - -static gboolean -_oci_new_vlan_dev(SigTermData *sigterm_data, - const NMCSProviderGetConfigIfaceData *config_data, - NMClient *nmc, - const NMCSProviderGetConfigResult *result, - const char *connection_type, - const char *parent_hwaddr) -{ - const char *hwaddr = config_data->hwaddr; - gs_unref_object NMConnection *connection = NULL; - gs_unref_object NMActiveConnection *active_connection = NULL; - gs_free_error GError *error = NULL; - gs_free char *macvlan_name = NULL; - gs_free char *connection_id = NULL; - char *ifname = NULL; - const char *ip4_config_method; - NMSetting *s_user; - - connection = nm_simple_connection_new(); - - macvlan_name = g_strdup_printf("macvlan%ld", config_data->iface_idx); - connection_id = g_strdup_printf("%s%ld", connection_type, config_data->iface_idx); - - if (strcmp(connection_type, NM_SETTING_MACVLAN_SETTING_NAME) == 0) { - nm_connection_add_setting(connection, - g_object_new(NM_TYPE_SETTING_MACVLAN, - NM_SETTING_MACVLAN_MODE, - NM_SETTING_MACVLAN_MODE_VEPA, - NULL)); - nm_connection_add_setting(connection, - g_object_new(NM_TYPE_SETTING_IP6_CONFIG, - NM_SETTING_IP_CONFIG_METHOD, - NM_SETTING_IP6_CONFIG_METHOD_DISABLED, - NULL)); - ip4_config_method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; - ifname = macvlan_name; - } else if (strcmp(connection_type, NM_SETTING_VLAN_SETTING_NAME) == 0) { - nm_connection_add_setting(connection, - g_object_new(NM_TYPE_SETTING_VLAN, - NM_SETTING_VLAN_PARENT, - macvlan_name, - NM_SETTING_VLAN_ID, - config_data->priv.oci.vlan_tag, - NULL)); - ip4_config_method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; - } else { - g_return_val_if_reached(FALSE); - } - - nm_connection_add_setting(connection, - g_object_new(NM_TYPE_SETTING_CONNECTION, - NM_SETTING_CONNECTION_ID, - connection_id, - NM_SETTING_CONNECTION_TYPE, - connection_type, - NM_SETTING_CONNECTION_INTERFACE_NAME, - ifname, - NULL)); - nm_connection_add_setting(connection, - g_object_new(NM_TYPE_SETTING_IP4_CONFIG, - NM_SETTING_IP_CONFIG_METHOD, - ip4_config_method, - NULL)); - nm_connection_add_setting(connection, - g_object_new(NM_TYPE_SETTING_WIRED, - NM_SETTING_WIRED_MAC_ADDRESS, - parent_hwaddr, - NM_SETTING_WIRED_CLONED_MAC_ADDRESS, - hwaddr, - NULL)); - - s_user = nm_setting_user_new(); - nm_connection_add_setting(connection, s_user); - nm_setting_user_set_data(NM_SETTING_USER(s_user), - "org.freedesktop.NetworkManager.origin", - "nm-cloud-setup", - NULL); - - _nmc_mangle_connection(NULL, connection, result, config_data, NULL, NULL); - - _LOGD("config device %s: creating %s connection for VLAN %d on %s...", - hwaddr, - ifname ?: connection_type, - config_data->priv.oci.vlan_tag, - parent_hwaddr); - - active_connection = nmcs_add_and_activate(nmc, NULL, connection, &error); - if (active_connection == NULL) { - if (!nm_utils_error_is_cancelled(error)) { - _LOGD("config device %s: failure to activate connection: %s", hwaddr, error->message); - } - return FALSE; - } - - _LOGD("config device %s: connection \"%s\" (%s) created", - hwaddr, - nm_active_connection_get_id(active_connection), - nm_active_connection_get_uuid(active_connection)); - - return TRUE; -} - -static gboolean -_oci_config_vnic_dev(SigTermData *sigterm_data, - const NMCSProviderGetConfigIfaceData *config_data, - NMClient *nmc, - const NMCSProviderGetConfigResult *result, - const GType device_type, - const char *connection_type, - const char *parent_hwaddr) -{ - gs_unref_object NMDevice *device = NULL; - - device = nm_g_object_ref(_nmc_get_device_by_hwaddr(nmc, device_type, config_data->hwaddr)); - if (device) { - /* There is a device. Modify and reapply the currently applied connection. */ - return _config_existing(sigterm_data, config_data, nmc, result, connection_type, device); - } else { - /* There is no device, but we're configuring a VLAN. - * We can just go ahead and create one with a new connection. */ - return _oci_new_vlan_dev(sigterm_data, - config_data, - nmc, - result, - connection_type, - parent_hwaddr); - } -} - -static gboolean -_config_one(SigTermData *sigterm_data, - NMCSProvider *provider, - NMClient *nmc, - const NMCSProviderGetConfigResult *result, - guint idx) -{ - const NMCSProviderGetConfigIfaceData *config_data = result->iface_datas_arr[idx]; - gboolean any_changes; - - g_main_context_iteration(NULL, FALSE); - - if (g_cancellable_is_cancelled(sigterm_data->cancellable)) - return FALSE; - - if (!nmcs_provider_get_config_iface_data_is_valid(config_data)) { - _LOGD("config device %s: skip because meta data not successfully fetched", - config_data->hwaddr); - return FALSE; - } - - if (config_data->iface_idx >= 100) { - /* since we use the iface_idx to select a table number, the range is limited from - * 0 to 99. Note that the providers are required to provide increasing numbers, - * so this means we bail out after the first 100 devices. */ - _LOGD("config device %s: skip because number of supported interfaces reached", - config_data->hwaddr); - return FALSE; - } - - if (NMCS_IS_PROVIDER_OCI(provider) && config_data->priv.oci.vlan_tag != 0) { - if (config_data->priv.oci.parent_hwaddr == NULL) { - _LOGW("config device %s: has vlan id %d but no parent device", - config_data->hwaddr, - config_data->priv.oci.vlan_tag); - return FALSE; - } - - /* MACVLAN first, because VLAN is on top of it. */ - any_changes = _oci_config_vnic_dev(sigterm_data, - config_data, - nmc, - result, - NM_TYPE_DEVICE_MACVLAN, - NM_SETTING_MACVLAN_SETTING_NAME, - config_data->priv.oci.parent_hwaddr); - any_changes += _oci_config_vnic_dev(sigterm_data, - config_data, - nmc, - result, - NM_TYPE_DEVICE_VLAN, - NM_SETTING_VLAN_SETTING_NAME, - config_data->hwaddr); - - } else { - any_changes = _config_ethernet(sigterm_data, config_data, nmc, result); - } - return any_changes; } static gboolean -_config_all(SigTermData *sigterm_data, - NMCSProvider *provider, - NMClient *nmc, - const NMCSProviderGetConfigResult *result) +_config_all(SigTermData *sigterm_data, NMClient *nmc, const NMCSProviderGetConfigResult *result) { gboolean any_changes = FALSE; guint i; for (i = 0; i < result->n_iface_datas; i++) { - if (_config_one(sigterm_data, provider, nmc, result, i)) + if (_config_one(sigterm_data, nmc, result, i)) any_changes = TRUE; } @@ -1011,7 +808,7 @@ main(int argc, const char *const *argv) if (!result) goto done; - if (_config_all(&sigterm_data, provider, nmc, result)) + if (_config_all(&sigterm_data, nmc, result)) _LOGI("some changes were applied for provider %s", nmcs_provider_get_name(provider)); else _LOGD("no changes were applied for provider %s", nmcs_provider_get_name(provider));