mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-12-22 21:22:37 +01:00
dpp: fix dpp_offchannel_start corner cases
The purpose of this was to have a single utility to both cancel an existing offchannel operation (if one exists) and start a new one. The problem was the previous offchannel operation was being canceled first which opened up the radio work queue to other items. This is not desireable as, for example, a scan would end up breaking the DPP protocol most likely. Starting the new offchannel then canceling is the correct order of operations but to do this required saving the new ID, canceling, then setting offchannel_id to the new ID so dpp_presence_timeout wouldn't overwrite the new ID to zero. This also removes an explicit call to offchannel_cancel which is already done by dpp_offchannel_start.
This commit is contained in:
parent
8ce491fbb2
commit
76b6aa66b3
23
src/dpp.c
23
src/dpp.c
@ -1353,12 +1353,28 @@ protocol_failed:
|
|||||||
|
|
||||||
static void dpp_start_offchannel(struct dpp_sm *dpp, uint32_t freq)
|
static void dpp_start_offchannel(struct dpp_sm *dpp, uint32_t freq)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* This needs to be handled carefully for a few reasons:
|
||||||
|
*
|
||||||
|
* First, the next offchannel operation needs to be started prior to
|
||||||
|
* canceling an existing one. This is so the offchannel work can
|
||||||
|
* continue uninterrupted without any other work items starting in
|
||||||
|
* between canceling and starting the next (e.g. if a scan request is
|
||||||
|
* sitting in the queue).
|
||||||
|
*
|
||||||
|
* Second, dpp_presence_timeout resets dpp->offchannel_id to zero which
|
||||||
|
* is why the new ID is saved and only set to dpp->offchannel_id once
|
||||||
|
* the previous offchannel work is cancelled (i.e. destroy() has been
|
||||||
|
* called).
|
||||||
|
*/
|
||||||
|
uint32_t id = offchannel_start(netdev_get_wdev_id(dpp->netdev),
|
||||||
|
freq, dpp->dwell, dpp_roc_started,
|
||||||
|
dpp, dpp_presence_timeout);
|
||||||
|
|
||||||
if (dpp->offchannel_id)
|
if (dpp->offchannel_id)
|
||||||
offchannel_cancel(dpp->wdev_id, dpp->offchannel_id);
|
offchannel_cancel(dpp->wdev_id, dpp->offchannel_id);
|
||||||
|
|
||||||
dpp->offchannel_id = offchannel_start(netdev_get_wdev_id(dpp->netdev),
|
dpp->offchannel_id = id;
|
||||||
freq, dpp->dwell, dpp_roc_started,
|
|
||||||
dpp, dpp_presence_timeout);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void authenticate_request(struct dpp_sm *dpp, const uint8_t *from,
|
static void authenticate_request(struct dpp_sm *dpp, const uint8_t *from,
|
||||||
@ -1451,7 +1467,6 @@ static void authenticate_request(struct dpp_sm *dpp, const uint8_t *from,
|
|||||||
l_debug("Configurator requested a new frequency %u",
|
l_debug("Configurator requested a new frequency %u",
|
||||||
dpp->new_freq);
|
dpp->new_freq);
|
||||||
|
|
||||||
offchannel_cancel(dpp->wdev_id, dpp->offchannel_id);
|
|
||||||
dpp_start_offchannel(dpp, dpp->new_freq);
|
dpp_start_offchannel(dpp, dpp->new_freq);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user