mirror of
https://github.com/openwrt/openwrt.git
synced 2026-10-12 06:57:57 +04:00
hostapd: continue a pending interface setup from the event loop
The bss_remove hook of hostapd.uc sends a service event with a synchronous ubus call. While libubus waits for that reply, it runs the completion callbacks of other pending requests, among them the wpa_supplicant phy_status or phy_set_state request of an interface setup in progress. The callback advanced the setup to hostapd.add_iface() nested inside the teardown that called the hook. With an AP MLD, a config_set for radio 0 followed by one for radio 1 added the radio 0 link while the radio 1 link was half removed and still held its driver BSS and management frame registrations. The add failed with "Match already configured", and its cleanup crashed hostapd in hostapd_wpa_event(). This happened on the first such reconfiguration after a bring-up. Run the next step of the pending setup from a uloop timer instead, and cancel the timer where the pending request is aborted. Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
1 parent
0e1e3a0919
commit
a75b4c405f
1 file changed
+13
-1
@@ -275,6 +275,9 @@ function __iface_pending_next(pending, state, ret, data)
|
||||
if (pending.defer)
|
||||
pending.defer.abort();
|
||||
delete pending.defer;
|
||||
if (pending.timer)
|
||||
pending.timer.cancel();
|
||||
delete pending.timer;
|
||||
switch (state) {
|
||||
case "init":
|
||||
return "create_bss";
|
||||
@@ -357,7 +360,16 @@ function iface_pending_ubus_call(obj, method, arg)
|
||||
{
|
||||
let ubus = hostapd.data.ubus;
|
||||
let pending = this;
|
||||
this.defer = ubus.defer(obj, method, arg, (ret, data) => { delete pending.defer; pending.next(ret, data) });
|
||||
|
||||
/* libubus can run this from inside a synchronous ubus call, so continue
|
||||
* from the event loop */
|
||||
this.defer = ubus.defer(obj, method, arg, (ret, data) => {
|
||||
delete pending.defer;
|
||||
pending.timer = uloop.timer(0, () => {
|
||||
delete pending.timer;
|
||||
pending.next(ret, data);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const iface_pending_proto = {
|
||||
|
||||
Reference in new issue
Block a user