summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancisco Blas Izquierdo Riera (klondike) <klondike@klondike.es>2022-04-05 22:41:51 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2022-04-29 17:31:18 +0200
commit9d3fc1e3b29396d9bfc2efc225fe7938ae15a11a (patch)
tree16d112d3c1c2fe1b8cc6f8de541b6b883fb32336
parent52221a5736eaca1adfbe21b7f6350f3faf26ea5a (diff)
downloadNetworkManager-9d3fc1e3b29396d9bfc2efc225fe7938ae15a11a.tar.gz
bridge: fix reentrant call for bluetooth NAP bridge
Currently NetworkManager fails to establish a NAP bridge because it never gets out of the stage2. This is caused because when making the BlueZ callback reentrant we return NM_ACT_STAGE_RETURN_POSTPONE even after registration has succeeded. This patch changes registration to a three state automaton instead of a boolean. This allows distinguishing when we are waiting for registration to finish and when it is done and therefore ensures that when the stage2 is called again by the callback the result is success so NetworkManager can proceed to the IP configuration. https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1181 (cherry picked from commit 8f7e295cbf98ca220fbd13336bb0cdd4d477bd27)
-rw-r--r--src/core/devices/nm-device-bridge.c31
1 files changed, 21 insertions, 10 deletions
diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c
index 4e4c263717..f7af39825d 100644
--- a/src/core/devices/nm-device-bridge.c
+++ b/src/core/devices/nm-device-bridge.c
@@ -22,11 +22,17 @@
/*****************************************************************************/
+enum _NMBtCbState {
+ _NM_BT_CB_STATE_NONE = 0, /* Registration not done */
+ _NM_BT_CB_STATE_WAIT = 1, /* Waiting for the callback */
+ _NM_BT_CB_STATE_SUCCESS = 2, /* Callback succeeded */
+};
+
struct _NMDeviceBridge {
NMDevice parent;
GCancellable *bt_cancellable;
bool vlan_configured : 1;
- bool bt_registered : 1;
+ unsigned bt_cb_state : 2;
};
struct _NMDeviceBridgeClass {
@@ -76,7 +82,8 @@ check_connection_available(NMDevice *device,
if (!nm_bt_vtable_network_server->is_available(
nm_bt_vtable_network_server,
bdaddr,
- (self->bt_cancellable || self->bt_registered) ? device : NULL)) {
+ (self->bt_cancellable || self->bt_cb_state != _NM_BT_CB_STATE_NONE) ? device
+ : NULL)) {
if (bdaddr)
nm_utils_error_set(error,
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
@@ -835,6 +842,7 @@ _bt_register_bridge_cb(GError *error, gpointer user_data)
return;
}
+ self->bt_cb_state = _NM_BT_CB_STATE_SUCCESS;
nm_device_activate_schedule_stage2_device_config(NM_DEVICE(self), FALSE);
}
@@ -846,12 +854,12 @@ _nm_device_bridge_notify_unregister_bt_nap(NMDevice *device, const char *reason)
_LOGD(LOGD_DEVICE,
"bluetooth NAP server unregistered from bridge: %s%s",
reason,
- self->bt_registered ? "" : " (was no longer registered)");
+ self->bt_cb_state != _NM_BT_CB_STATE_NONE ? "" : " (was no longer registered)");
nm_clear_g_cancellable(&self->bt_cancellable);
- if (self->bt_registered) {
- self->bt_registered = FALSE;
+ if (self->bt_cb_state != _NM_BT_CB_STATE_NONE) {
+ self->bt_cb_state = _NM_BT_CB_STATE_NONE;
nm_device_state_changed(device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_BT_FAILED);
}
}
@@ -879,9 +887,12 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
if (self->bt_cancellable)
return NM_ACT_STAGE_RETURN_POSTPONE;
- if (self->bt_registered)
+ if (self->bt_cb_state == _NM_BT_CB_STATE_WAIT)
return NM_ACT_STAGE_RETURN_POSTPONE;
+ if (self->bt_cb_state == _NM_BT_CB_STATE_SUCCESS)
+ return NM_ACT_STAGE_RETURN_SUCCESS;
+
self->bt_cancellable = g_cancellable_new();
if (!nm_bt_vtable_network_server->register_bridge(nm_bt_vtable_network_server,
nm_setting_bluetooth_get_bdaddr(s_bt),
@@ -895,7 +906,7 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
return NM_ACT_STAGE_RETURN_FAILURE;
}
- self->bt_registered = TRUE;
+ self->bt_cb_state = _NM_BT_CB_STATE_WAIT;
return NM_ACT_STAGE_RETURN_POSTPONE;
}
@@ -906,14 +917,14 @@ deactivate(NMDevice *device)
_LOGD(LOGD_DEVICE,
"deactivate bridge%s",
- self->bt_registered ? " (registered as NAP bluetooth device)" : "");
+ self->bt_cb_state != _NM_BT_CB_STATE_NONE ? " (registered as NAP bluetooth device)" : "");
self->vlan_configured = FALSE;
nm_clear_g_cancellable(&self->bt_cancellable);
- if (self->bt_registered) {
- self->bt_registered = FALSE;
+ if (self->bt_cb_state != _NM_BT_CB_STATE_NONE) {
+ self->bt_cb_state = _NM_BT_CB_STATE_NONE;
nm_bt_vtable_network_server->unregister_bridge(nm_bt_vtable_network_server, device);
}
}