Message ID | 20200103103457.22778-1-nicolas.cavallari@green-communications.fr (mailing list archive) |
---|---|
Headers | show |
Series | Allow userspace to reset IBSS stations to fix aggregation issue | expand |
On 03.01.20 11:34, Nicolas Cavallari wrote: > I encountered the same issue in an IBSS-RSN network, where quick reboot > of a station would cause issues with aggregation because the kernel is > not aware of the reboot. > > I figured out that since wpa_supplicant already detect reboots, the > simplest way to fix it would be for wpa_supplicant to reset the entire > state of the station in the kernel, instead of just resetting keys and > port. > > This means extending NL80211_CMD_DEL_STATION to work in IBSS mode too, > just like it does in mesh point mode. > > Changes: > v2: Use a nl80211 feature flag instead of patching every driver. > > I'm more than happy to give this a thorough test on dozens of devices offshore which I suspect are suffering from this issue as they sail in-out of range, but as a new flag is defined in nl80211.h, is anything additional required at wpa_sup side to use this? If yes, please also provide a patch for that to me directly. (based on >= v2.9) Thanks, Koen
On 13/01/2020 12:45, Koen Vandeputte wrote: > I'm more than happy to give this a thorough test on dozens of devices offshore > > which I suspect are suffering from this issue as they sail in-out of range, > > but as a new flag is defined in nl80211.h, is anything additional required at wpa_sup side to use this? I use this blunt patch for now, until this issue settles. Note that it only work in IBSS RSN case, because that's the only mode where wpa_supplicant registers for auth frames (and thus the kernel doesn't handle them) and does reboot detection. diff --git a/wpa_supplicant/ibss_rsn.c b/wpa_supplicant/ibss_rsn.c index 37368c4cb..026750161 100644 --- a/wpa_supplicant/ibss_rsn.c +++ b/wpa_supplicant/ibss_rsn.c @@ -353,7 +353,11 @@ static int auth_set_key(void *ctx, int vlan_id, enum wpa_alg alg, static void ibss_rsn_disconnect(void *ctx, const u8 *addr, u16 reason) { struct ibss_rsn *ibss_rsn = ctx; - wpa_drv_sta_deauth(ibss_rsn->wpa_s, addr, reason); + struct ibss_rsn_peer *peer = ibss_rsn_get_peer(ibss_rsn, addr); + if (peer && wpa_drv_sta_remove(ibss_rsn->wpa_s, addr) == 0) + peer->authentication_status |= IBSS_RSN_PENDING_DELETION; + else + wpa_drv_sta_deauth(ibss_rsn->wpa_s, addr, reason); } @@ -810,6 +814,13 @@ int ibss_rsn_rx_eapol(struct ibss_rsn *ibss_rsn, const u8 *src_addr, return -1; peer = ibss_rsn_get_peer(ibss_rsn, src_addr); + if (peer->authentication_status & IBSS_RSN_PENDING_DELETION) { + wpa_printf(MSG_DEBUG, + "RSN: Ignoring RX EAPOL from removed peer " MACSTR, + MAC2STR(src_addr)); + return -1; + } + if (peer) return ibss_rsn_process_rx_eapol(ibss_rsn, peer, buf, len); @@ -849,6 +860,10 @@ static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn, { wpa_printf(MSG_DEBUG, "RSN: IBSS RX Auth frame (SEQ 1) from " MACSTR, MAC2STR(addr)); + if (peer && peer->authentication_status & IBSS_RSN_PENDING_DELETION) { + wpa_printf(MSG_DEBUG, "RSN: Ignoring auth from removed sta"); + return; + } if (peer && peer->authentication_status & (IBSS_RSN_SET_PTK_SUPP | @@ -883,8 +898,16 @@ static void ibss_rsn_handle_auth_1_of_2(struct ibss_rsn *ibss_rsn, wpa_printf(MSG_DEBUG, "RSN: IBSS Reinitializing station " MACSTR, MAC2STR(addr)); - ibss_rsn_stop(ibss_rsn, addr); - peer = NULL; + if (wpa_drv_sta_remove(ibss_rsn->wpa_s, addr) == 0) { + wpa_printf(MSG_DEBUG, + "RSN: IBSS sta deletion requested."); + peer->authentication_status + |= IBSS_RSN_PENDING_DELETION; + return; + } else { + ibss_rsn_stop(ibss_rsn, addr); + peer = NULL; + } } if (!peer) { @@ -935,6 +958,11 @@ void ibss_rsn_handle_auth(struct ibss_rsn *ibss_rsn, const u8 *auth_frame, "unknown STA " MACSTR, MAC2STR(header->sa)); break; } + if (peer->authentication_status & IBSS_RSN_PENDING_DELETION) { + wpa_printf(MSG_DEBUG, + "RSN: Ignoring auth from removed sta"); + break; + } /* authentication has been completed */ eloop_cancel_timeout(ibss_rsn_auth_timeout, peer, NULL); diff --git a/wpa_supplicant/ibss_rsn.h b/wpa_supplicant/ibss_rsn.h index 626c54354..17f5ca0ee 100644 --- a/wpa_supplicant/ibss_rsn.h +++ b/wpa_supplicant/ibss_rsn.h @@ -25,6 +25,8 @@ struct ibss_rsn; #define IBSS_RSN_SET_PTK_AUTH 0x10 /* PTK completion reported */ #define IBSS_RSN_REPORTED_PTK 0x20 +/* requested STA deletion to kernel */ +#define IBSS_RSN_PENDING_DELETION 0x40 struct ibss_rsn_peer { struct ibss_rsn_peer *next;