diff --git a/src/core/nm-manager.c b/src/core/nm-manager.c index 5bc6c80038..fe899a907c 100644 --- a/src/core/nm-manager.c +++ b/src/core/nm-manager.c @@ -491,23 +491,6 @@ _version_info_get(void) /*****************************************************************************/ -static gboolean -_connection_is_vpn(NMConnection *connection) -{ - const char *type; - - type = nm_connection_get_connection_type(connection); - if (type) - return nm_streq(type, NM_SETTING_VPN_SETTING_NAME); - - /* we have an incomplete (invalid) connection at hand. That can only - * happen during AddAndActivate. Determine whether it's VPN type based - * on the existence of a [vpn] section. */ - return !!nm_connection_get_setting_vpn(connection); -} - -/*****************************************************************************/ - static gboolean concheck_enabled(NMManager *self, gboolean *out_changed) { @@ -4530,7 +4513,7 @@ _device_get_activation_prio(NMDevice *device) g_return_val_if_reached(DEVICE_ACTIVATION_PRIO_UNAVAILABLE); } -static NMDevice * +NMDevice * nm_manager_get_best_device_for_connection(NMManager *self, NMSettingsConnection *sett_conn, NMConnection *connection, @@ -6121,7 +6104,7 @@ _new_active_connection(NMManager *self, nm_assert((!incompl_conn) ^ (!sett_conn)); nm_assert(NM_IS_AUTH_SUBJECT(subject)); nm_assert(is_vpn - == _connection_is_vpn(sett_conn ? nm_settings_connection_get_connection(sett_conn) + == nm_connection_is_vpn(sett_conn ? nm_settings_connection_get_connection(sett_conn) : incompl_conn)); nm_assert(is_vpn || NM_IS_DEVICE(device)); nm_assert(!nm_streq0(specific_object, "/")); @@ -6196,28 +6179,6 @@ _new_active_connection(NMManager *self, activation_reason, initial_state_flags, subject); - } else if (nm_connection_is_valid_secondary(sett_conn ? nm_settings_connection_get_connection(sett_conn) - : incompl_conn)) { - /** - * For non-plugin VPN connections, re-validate the corresponding device. - * Wireguard, for example, needs its own (virtual) device. - * If it, however, gets activated as secondary device, - * 'device' points to the primary device that is currently starting. - * Bringing up a WG tunnel this way will fail. - */ - NMDevice *_device = NULL; - gs_free_error GError *local = NULL; - _device = - nm_manager_get_best_device_for_connection(self, sett_conn, applied, TRUE, NULL, &local); - if (!_device) { - g_set_error(error, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_UNKNOWN_DEVICE, - "No suitable device found for non-plugin VPN connection (%s).", - local->message); - return NULL; - } - device = _device; } return (NMActiveConnection *) nm_act_request_new(sett_conn, @@ -6372,7 +6333,7 @@ nm_manager_activate_connection(NMManager *self, g_return_val_if_fail(NM_IS_MANAGER(self), NULL); g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(sett_conn), NULL); - is_vpn = _connection_is_vpn(nm_settings_connection_get_connection(sett_conn)); + is_vpn = nm_connection_is_vpn(nm_settings_connection_get_connection(sett_conn)); g_return_val_if_fail(is_vpn || NM_IS_DEVICE(device), NULL); g_return_val_if_fail(!error || !*error, NULL); nm_assert(!nm_streq0(specific_object, "/")); @@ -6524,7 +6485,7 @@ find_device_for_activation(NMManager *self, if (!connection) connection = nm_settings_connection_get_connection(sett_conn); - is_vpn = _connection_is_vpn(connection); + is_vpn = nm_connection_is_vpn(connection); if (*out_device) { device = *out_device; diff --git a/src/core/nm-manager.h b/src/core/nm-manager.h index e10ca0d110..12f57f9e68 100644 --- a/src/core/nm-manager.h +++ b/src/core/nm-manager.h @@ -271,6 +271,13 @@ gboolean nm_manager_devcon_autoconnect_blocked_reason_set(NMManager * NMSettingsAutoconnectBlockedReason value, gboolean set); +NMDevice *nm_manager_get_best_device_for_connection(NMManager *self, + NMSettingsConnection *sett_conn, + NMConnection *connection, + gboolean for_user_request, + GHashTable *exclude_devices, + GError **error); + NMConfig *nm_manager_get_config(NMManager *self); #endif /* __NETWORKMANAGER_MANAGER_H__ */ diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index be6e1c19bc..e433d7ec4c 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -2153,6 +2153,7 @@ activate_secondary_connections(NMPolicy *self, NMConnection *connection, NMDevic NMSettingsConnection *sett_conn; const char *sec_uuid = nm_setting_connection_get_secondary(s_con, i); NMActRequest *req; + NMConnection *nm_conn; sett_conn = nm_settings_get_connection_by_uuid(priv->settings, sec_uuid); if (!sett_conn) { @@ -2162,25 +2163,47 @@ activate_secondary_connections(NMPolicy *self, NMConnection *connection, NMDevic success = FALSE; break; } + nm_conn = nm_settings_connection_get_connection(sett_conn); - if (!nm_connection_is_valid_secondary(nm_settings_connection_get_connection(sett_conn))) { + if (!nm_connection_is_valid_secondary(nm_conn)) { _LOGW(LOGD_DEVICE, - "secondary connection '%s (%s)' auto-activation failed: The connection is not a " - "valid secondary.", + "secondary connection '%s (%s)' auto-activation failed: The connection is neither a " + "valid VPN nor a Wireguard connection.", nm_settings_connection_get_id(sett_conn), sec_uuid); success = FALSE; break; } + if (!nm_connection_is_vpn(nm_conn)) { + /** + * For non-plugin VPN connections, re-validate the corresponding device. + * Wireguard, for example, needs its own (virtual) device. + * If it, however, gets activated as secondary device, + * 'device' points to the primary device that is currently starting. + * Bringing up a WG tunnel this way will fail. + */ + NMDevice *_device = NULL; + gs_free_error GError *local = NULL; + _device = + nm_manager_get_best_device_for_connection(priv->manager, sett_conn, nm_conn, TRUE, NULL, &local); + if (!_device) { + _LOGW(LOGD_DEVICE, + "No suitable device found for non-plugin VPN connection (%s).", + local->message); + success = FALSE; + break; + } + device = _device; + } req = nm_device_get_act_request(device); _LOGD(LOGD_DEVICE, - "activating secondary connection '%s (%s)' for base connection '%s (%s)'", + "activating secondary connection '%s (%s)' for base connection '%s (%s), real: %d, sw:%d, iface: %s'", nm_settings_connection_get_id(sett_conn), sec_uuid, nm_connection_get_id(connection), - nm_connection_get_uuid(connection)); + nm_connection_get_uuid(connection), nm_device_is_real(device), nm_device_is_software(device), nm_device_get_iface(device)); ac = nm_manager_activate_connection( priv->manager, sett_conn, @@ -2195,6 +2218,10 @@ activate_secondary_connections(NMPolicy *self, NMConnection *connection, NMDevic if (ac) secondary_ac_list = g_slist_append(secondary_ac_list, g_object_ref(ac)); else { + _LOGW(LOGD_DEVICE, + "secondary connection '%s (%s)' auto-activation failed:", + nm_settings_connection_get_id(sett_conn), + sec_uuid); _LOGW(LOGD_DEVICE, "secondary connection '%s (%s)' auto-activation failed: (%d) %s", nm_settings_connection_get_id(sett_conn), diff --git a/src/libnm-core-impl/nm-connection.c b/src/libnm-core-impl/nm-connection.c index 80a515e25f..d2049538af 100644 --- a/src/libnm-core-impl/nm-connection.c +++ b/src/libnm-core-impl/nm-connection.c @@ -2877,6 +2877,33 @@ nm_connection_is_type(NMConnection *connection, const char *type) return nm_streq0(type, nm_connection_get_connection_type(connection)); } +/** + * nm_connection_is_vpn: + * @connection: the #NMConnection + * + * Checks whether the given connection is VPN connection. + * This applies to a connection belonging to a VPN plugin, + * e.g., OpenVPN. + * + * Returns: %TRUE if the connection is a valid secondary. + * + * Since: 1.57 +*/ +gboolean +nm_connection_is_vpn(NMConnection *connection) +{ + const char *type; + + type = nm_connection_get_connection_type(connection); + if (type) + return nm_streq(type, NM_SETTING_VPN_SETTING_NAME); + + /* we have an incomplete (invalid) connection at hand. That can only + * happen during AddAndActivate. Determine whether it's VPN type based + * on the existence of a [vpn] section. */ + return !!nm_connection_get_setting_vpn(connection); +} + /** * nm_connection_is_valid_secondary: * @connection: the #NMConnection @@ -2887,7 +2914,7 @@ nm_connection_is_type(NMConnection *connection, const char *type) * * Returns: %TRUE if the connection is a valid secondary. * - * Since: 1.52 + * Since: 1.57 */ gboolean nm_connection_is_valid_secondary(NMConnection *connection) diff --git a/src/libnm-core-public/nm-connection.h b/src/libnm-core-public/nm-connection.h index 3b8c60b3e6..03d7be6c20 100644 --- a/src/libnm-core-public/nm-connection.h +++ b/src/libnm-core-public/nm-connection.h @@ -249,6 +249,7 @@ NMSettingVxlan *nm_connection_get_setting_vxlan(NMConnection *connection); NM_AVAILABLE_IN_1_52 gboolean nm_connection_is_valid_secondary(NMConnection *connection); +gboolean nm_connection_is_vpn(NMConnection *connection); G_END_DECLS