}
+static int send_event_marker(struct wpa_driver_nl80211_data *drv)
+{
+ struct nl_sock *handle;
+ struct nl_msg *msg;
+ struct nlmsghdr *hdr;
+ int res = 0;
+ int err = -NLE_NOMEM;
+
+ msg = nlmsg_alloc();
+ if (!msg)
+ goto out;
+
+ /* We only care about the returned sequence number for matching. */
+ if (!nl80211_cmd(drv, msg, 0, NL80211_CMD_GET_PROTOCOL_FEATURES))
+ goto out;
+
+ handle = (void *) (((intptr_t) drv->global->nl_event) ^
+ ELOOP_SOCKET_INVALID);
+
+ err = nl_send_auto_complete(handle, msg);
+ if (err < 0)
+ goto out;
+
+ hdr = nlmsg_hdr(msg);
+ res = hdr->nlmsg_seq;
+
+out:
+ nlmsg_free(msg);
+ if (err)
+ wpa_printf(MSG_INFO, "nl80211: %s failed: %s",
+ __func__, nl_geterror(err));
+ return res;
+}
+
+
static int send_and_recv(struct nl80211_global *global,
struct nl_sock *nl_handle, struct nl_msg *msg,
int (*valid_handler)(struct nl_msg *, void *),
struct i802_bss *bss)
{
int ret;
- int drv_associated = drv->associated;
wpa_printf(MSG_DEBUG, "%s(reason_code=%d)", __func__, reason_code);
nl80211_mark_disconnected(drv);
* For locally generated disconnect, supplicant already generates a
* DEAUTH event, so ignore the event from NL80211.
*/
- drv->ignore_next_local_disconnect = drv_associated && (ret == 0);
+ if (ret == 0)
+ drv->ignore_next_local_disconnect = send_event_marker(drv);
return ret;
}
{
struct wpa_driver_nl80211_data *drv = bss->drv;
int ret;
- int drv_associated = drv->associated;
if (drv->nlmode == NL80211_IFTYPE_ADHOC) {
nl80211_mark_disconnected(drv);
* For locally generated deauthenticate, supplicant already generates a
* DEAUTH event, so ignore the event from NL80211.
*/
- drv->ignore_next_local_deauth = drv_associated && (ret == 0);
+ if (ret == 0)
+ drv->ignore_next_local_deauth = send_event_marker(drv);
return ret;
}
drv->retry_auth ? "retry_auth=1\n" : "",
drv->use_monitor ? "use_monitor=1\n" : "",
drv->ignore_next_local_disconnect ?
- "ignore_next_local_disconnect=1\n" : "",
+ "ignore_next_local_disconnect\n" : "",
drv->ignore_next_local_deauth ?
- "ignore_next_local_deauth=1\n" : "");
+ "ignore_next_local_deauth\n" : "");
if (os_snprintf_error(end - pos, res))
return pos - buf;
pos += res;
unsigned int scan_for_auth:1;
unsigned int retry_auth:1;
unsigned int use_monitor:1;
- unsigned int ignore_next_local_disconnect:1;
- unsigned int ignore_next_local_deauth:1;
unsigned int hostapd:1;
unsigned int start_mode_sta:1;
unsigned int start_iface_up:1;
unsigned int puncturing:1;
unsigned int qca_ap_allowed_freqs:1;
+ u32 ignore_next_local_disconnect;
+ u32 ignore_next_local_deauth;
+
u64 vendor_scan_cookie;
u64 remain_on_chan_cookie;
u64 send_frame_cookie;
int wdev_id_set = 0;
int wiphy_idx_set = 0;
+ /* Event marker, all prior events have been processed */
+ if (gnlh->cmd == NL80211_CMD_GET_PROTOCOL_FEATURES) {
+ u32 seq = nlmsg_hdr(msg)->nlmsg_seq;
+
+ dl_list_for_each_safe(drv, tmp, &global->interfaces,
+ struct wpa_driver_nl80211_data, list) {
+ if (drv->ignore_next_local_deauth > 0 &&
+ drv->ignore_next_local_deauth <= seq) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: No DEAUTHENTICATE event was ignored");
+ drv->ignore_next_local_deauth = 0;
+ }
+
+ if (drv->ignore_next_local_disconnect > 0 &&
+ drv->ignore_next_local_disconnect <= seq) {
+ wpa_printf(MSG_DEBUG,
+ "nl80211: No DISCONNECT event was ignored");
+ drv->ignore_next_local_disconnect = 0;
+ }
+ }
+
+ return NL_SKIP;
+ }
+
nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
genlmsg_attrlen(gnlh, 0), NULL);