mbox series

[v2,0/2] Allow userspace to reset IBSS stations to fix aggregation issue

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

Message

Nicolas Cavallari Jan. 3, 2020, 10:34 a.m. UTC
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.

Comments

Koen Vandeputte Jan. 13, 2020, 11:45 a.m. UTC | #1
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
Nicolas Cavallari Jan. 14, 2020, 9:27 a.m. UTC | #2
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;