diff options
author | Andrew Zaborowski <andrew.zaborowski@intel.com> | 2020-11-04 09:46:41 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-11-12 15:04:56 +0100 |
commit | 33b9fa3a3cafa2eddea3bd1774847ce9424f921d (patch) | |
tree | 4751067479dc26ed90105677f288be311894ce6c /src/nm-manager.c | |
parent | a68903f05a098eaae2cfc2984cf12686a63bf6fd (diff) | |
download | NetworkManager-33b9fa3a3cafa2eddea3bd1774847ce9424f921d.tar.gz |
manager: Keep volatile/external connections while referenced by async_op_lst
If an NMSettingsConnection with the VOLATILE or EXTENRAL flags is created
and passed to nm_manager_activate_connection, it's immediately scheduled
for deletion in an idle callback and will likely be deleted before the
authorization step in nm_manager_activate_connection finishes and the
connection will be aborted. This is because there's no
NMActiveConnection in priv->active_connection_lst_head referencing it
until _internal_activate_device(). Change
active_connection_find_by_connection to also look for connections in
priv->async_op_lst_head.
New _delete_volatile_connection_do() calls are added. Previously it
would be called when an active connection may have been removed from
priv->active_connection_lst_head, now also call it when an active
connection may have been removed from priv->async_op_lst_head without
being added to priv->active_connection_lst_head.
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/671
Diffstat (limited to 'src/nm-manager.c')
-rw-r--r-- | src/nm-manager.c | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/src/nm-manager.c b/src/nm-manager.c index 9a97c43f13..1075daf337 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -1013,8 +1013,37 @@ active_connection_find( g_ptr_array_add(all, g_object_ref(ac)); } - if (!best_ac) - return NULL; + if (!best_ac) { + AsyncOpData * async_op_data; + + c_list_for_each_entry (async_op_data, &priv->async_op_lst_head, async_op_lst) { + NMSettingsConnection *ac_conn; + + ac = async_op_data->ac_auth.active; + ac_conn = nm_active_connection_get_settings_connection(ac); + if (sett_conn && sett_conn != ac_conn) + continue; + if (uuid && !nm_streq0(uuid, nm_settings_connection_get_uuid(ac_conn))) + continue; + + if (!out_all_matching) + return ac; + + if (!best_ac) { + best_ac = ac; + continue; + } + + if (!all) { + all = g_ptr_array_new_with_free_func(g_object_unref); + g_ptr_array_add(all, g_object_ref(best_ac)); + } + g_ptr_array_add(all, g_object_ref(ac)); + } + + if (!best_ac) + return NULL; + } /* as an optimization, we only allocate out_all_matching, if there are more * than one result. If there is only one result, we only return the single @@ -5170,6 +5199,7 @@ _internal_activation_auth_done(NMManager * self, return; fail: + _delete_volatile_connection_do(self, nm_active_connection_get_settings_connection(active)); nm_assert(error_desc || error); nm_active_connection_set_state_fail(active, NM_ACTIVE_CONNECTION_STATE_REASON_UNKNOWN, @@ -5438,6 +5468,8 @@ _activation_auth_done(NMManager * self, return; fail: + _delete_volatile_connection_do(self, connection); + nm_audit_log_connection_op(NM_AUDIT_OP_CONN_ACTIVATE, connection, FALSE, |