hostapd: backport a few upstream fixes
Fixes reassoc issues with WDS mode Fixes reassoc issues in AP mode Fixes IBSS reauthentication issues Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
parent
a206394efa
commit
40e4c342fd
5 changed files with 163 additions and 4 deletions
|
@ -0,0 +1,83 @@
|
||||||
|
From: Jouni Malinen <jouni@qca.qualcomm.com>
|
||||||
|
Date: Tue, 20 Dec 2016 01:30:09 +0200
|
||||||
|
Subject: [PATCH] Fix race condition between AssocResp callback and 4addr event
|
||||||
|
|
||||||
|
It is apparently possible for the NL80211_CMD_UNEXPECTED_4ADDR_FRAME
|
||||||
|
event to be delivered to hostapd before the NL80211_CMD_FRAME_TX_STATUS
|
||||||
|
event for (Re)Association Response frame. This resulted in the 4-address
|
||||||
|
WDS mode not getting enabled for a STA. This could occur in particular
|
||||||
|
when operating under heavy load and the STA is reconnecting to the same
|
||||||
|
AP in a sequence where Deauthentication frame is followed immediately by
|
||||||
|
Authentication frame and the driver event processing gets delayed due to
|
||||||
|
removal of the previous netdev taking time in the middle of this
|
||||||
|
sequence.
|
||||||
|
|
||||||
|
Fix this by recording a pending item for 4-address WDS enabling if the
|
||||||
|
NL80211_CMD_UNEXPECTED_4ADDR_FRAME event would have been dropped due to
|
||||||
|
incompleted association and then process this pending item if the TX
|
||||||
|
status for the (Re)Association Response frame is received and it shows
|
||||||
|
that the frame was acknowledged.
|
||||||
|
|
||||||
|
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/src/ap/ieee802_11.c
|
||||||
|
+++ b/src/ap/ieee802_11.c
|
||||||
|
@@ -2634,6 +2634,8 @@ static void handle_assoc(struct hostapd_
|
||||||
|
taxonomy_sta_info_assoc_req(hapd, sta, pos, left);
|
||||||
|
#endif /* CONFIG_TAXONOMY */
|
||||||
|
|
||||||
|
+ sta->pending_wds_enable = 0;
|
||||||
|
+
|
||||||
|
fail:
|
||||||
|
/*
|
||||||
|
* In case of a successful response, add the station to the driver.
|
||||||
|
@@ -3248,6 +3250,14 @@ static void handle_assoc_cb(struct hosta
|
||||||
|
|
||||||
|
hostapd_set_sta_flags(hapd, sta);
|
||||||
|
|
||||||
|
+ if (!(sta->flags & WLAN_STA_WDS) && sta->pending_wds_enable) {
|
||||||
|
+ wpa_printf(MSG_DEBUG, "Enable 4-address WDS mode for STA "
|
||||||
|
+ MACSTR " based on pending request",
|
||||||
|
+ MAC2STR(sta->addr));
|
||||||
|
+ sta->pending_wds_enable = 0;
|
||||||
|
+ sta->flags |= WLAN_STA_WDS;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (sta->flags & WLAN_STA_WDS) {
|
||||||
|
int ret;
|
||||||
|
char ifname_wds[IFNAMSIZ + 1];
|
||||||
|
@@ -3512,10 +3522,22 @@ void ieee802_11_rx_from_unknown(struct h
|
||||||
|
struct sta_info *sta;
|
||||||
|
|
||||||
|
sta = ap_get_sta(hapd, src);
|
||||||
|
- if (sta && (sta->flags & WLAN_STA_ASSOC)) {
|
||||||
|
+ if (sta &&
|
||||||
|
+ ((sta->flags & WLAN_STA_ASSOC) ||
|
||||||
|
+ ((sta->flags & WLAN_STA_ASSOC_REQ_OK) && wds))) {
|
||||||
|
if (!hapd->conf->wds_sta)
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ if ((sta->flags & (WLAN_STA_ASSOC | WLAN_STA_ASSOC_REQ_OK)) ==
|
||||||
|
+ WLAN_STA_ASSOC_REQ_OK) {
|
||||||
|
+ wpa_printf(MSG_DEBUG,
|
||||||
|
+ "Postpone 4-address WDS mode enabling for STA "
|
||||||
|
+ MACSTR " since TX status for AssocResp is not yet known",
|
||||||
|
+ MAC2STR(sta->addr));
|
||||||
|
+ sta->pending_wds_enable = 1;
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (wds && !(sta->flags & WLAN_STA_WDS)) {
|
||||||
|
int ret;
|
||||||
|
char ifname_wds[IFNAMSIZ + 1];
|
||||||
|
--- a/src/ap/sta_info.h
|
||||||
|
+++ b/src/ap/sta_info.h
|
||||||
|
@@ -115,6 +115,7 @@ struct sta_info {
|
||||||
|
unsigned int radius_das_match:1;
|
||||||
|
unsigned int ecsa_supported:1;
|
||||||
|
unsigned int added_unassoc:1;
|
||||||
|
+ unsigned int pending_wds_enable:1;
|
||||||
|
|
||||||
|
u16 auth_alg;
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
From: Jouni Malinen <jouni@qca.qualcomm.com>
|
||||||
|
Date: Sat, 14 Jan 2017 01:04:31 +0200
|
||||||
|
Subject: [PATCH] Fix duplicate Reassociation Request frame dropping
|
||||||
|
|
||||||
|
Relational operators (==) have higher precedence than the ternary
|
||||||
|
conditional in C. The last_subtype check for association/reassociation
|
||||||
|
was broken due to incorrect assumption about the precedence. Fix this by
|
||||||
|
adding parenthesis around the ternary conditional.
|
||||||
|
|
||||||
|
The previous implementation worked for Association Request frames by
|
||||||
|
accident since WLAN_FC_STYPE_ASSOC_REQ happens to have value 0 and when
|
||||||
|
the last receive frame was an Association Request frame, the
|
||||||
|
sta->last_subtype == reassoc check was true and non-zero
|
||||||
|
WLAN_FC_STYPE_REASSOC_REQ was interpreted as true. However, this was
|
||||||
|
broken for Reassociation Request frame. reassoc == 1 in that case could
|
||||||
|
have matched received Association Response frame (subtype == 1), but
|
||||||
|
those are not received in AP mode and as such, this did not break other
|
||||||
|
behavior apart from not being able to drop duplicated Reassociation
|
||||||
|
Request frames.
|
||||||
|
|
||||||
|
Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/src/ap/ieee802_11.c
|
||||||
|
+++ b/src/ap/ieee802_11.c
|
||||||
|
@@ -2485,8 +2485,8 @@ static void handle_assoc(struct hostapd_
|
||||||
|
if ((fc & WLAN_FC_RETRY) &&
|
||||||
|
sta->last_seq_ctrl != WLAN_INVALID_MGMT_SEQ &&
|
||||||
|
sta->last_seq_ctrl == seq_ctrl &&
|
||||||
|
- sta->last_subtype == reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
|
||||||
|
- WLAN_FC_STYPE_ASSOC_REQ) {
|
||||||
|
+ sta->last_subtype == (reassoc ? WLAN_FC_STYPE_REASSOC_REQ :
|
||||||
|
+ WLAN_FC_STYPE_ASSOC_REQ)) {
|
||||||
|
hostapd_logger(hapd, sta->addr, HOSTAPD_MODULE_IEEE80211,
|
||||||
|
HOSTAPD_LEVEL_DEBUG,
|
||||||
|
"Drop repeated association frame seq_ctrl=0x%x",
|
|
@ -0,0 +1,40 @@
|
||||||
|
From: Jouni Malinen <j@w1.fi>
|
||||||
|
Date: Sat, 14 Jan 2017 13:56:18 +0200
|
||||||
|
Subject: [PATCH] RSN IBSS: Fix TK clearing on Authentication frame RX
|
||||||
|
|
||||||
|
When wpa_supplicant was processing a received Authentication frame (seq
|
||||||
|
1) from a peer STA for which there was already a TK configured to the
|
||||||
|
driver, debug log claimed that the PTK gets cleared, but the actual
|
||||||
|
call to clear the key was actually dropped due to AUTH vs. SUPP set_key
|
||||||
|
selection. Fix this by explicitly clearing the TK in case it was set
|
||||||
|
and an Authentication frame (seq 1) is received.
|
||||||
|
|
||||||
|
This fixes some cases where EAPOL-Key frames were sent encrypted using
|
||||||
|
the old key when a peer STA restarted itself and lost the key and had to
|
||||||
|
re-join the IBSS. Previously, that state required timing out the 4-way
|
||||||
|
handshake and Deauthentication frame exchange to recover.
|
||||||
|
|
||||||
|
Signed-off-by: Jouni Malinen <j@w1.fi>
|
||||||
|
---
|
||||||
|
|
||||||
|
--- a/wpa_supplicant/ibss_rsn.c
|
||||||
|
+++ b/wpa_supplicant/ibss_rsn.c
|
||||||
|
@@ -838,6 +838,18 @@ static void ibss_rsn_handle_auth_1_of_2(
|
||||||
|
MAC2STR(addr));
|
||||||
|
|
||||||
|
if (peer &&
|
||||||
|
+ peer->authentication_status & (IBSS_RSN_SET_PTK_SUPP |
|
||||||
|
+ IBSS_RSN_SET_PTK_AUTH)) {
|
||||||
|
+ /* Clear the TK for this pair to allow recovery from the case
|
||||||
|
+ * where the peer STA has restarted and lost its key while we
|
||||||
|
+ * still have a pairwise key configured. */
|
||||||
|
+ wpa_printf(MSG_DEBUG, "RSN: Clear pairwise key for peer "
|
||||||
|
+ MACSTR, MAC2STR(addr));
|
||||||
|
+ wpa_drv_set_key(ibss_rsn->wpa_s, WPA_ALG_NONE, addr, 0, 0,
|
||||||
|
+ NULL, 0, NULL, 0);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (peer &&
|
||||||
|
peer->authentication_status & IBSS_RSN_AUTH_EAPOL_BY_PEER) {
|
||||||
|
if (peer->own_auth_tx.sec) {
|
||||||
|
struct os_reltime now, diff;
|
|
@ -60,13 +60,13 @@
|
||||||
+ if (chdir("/") < 0)
|
+ if (chdir("/") < 0)
|
||||||
return -1;
|
return -1;
|
||||||
- }
|
- }
|
||||||
-
|
|
||||||
- return 0;
|
- return 0;
|
||||||
-}
|
-}
|
||||||
-#else /* __APPLE__ */
|
-#else /* __APPLE__ */
|
||||||
-#define os_daemon daemon
|
-#define os_daemon daemon
|
||||||
-#endif /* __APPLE__ */
|
-#endif /* __APPLE__ */
|
||||||
|
-
|
||||||
-
|
-
|
||||||
-int os_daemonize(const char *pid_file)
|
-int os_daemonize(const char *pid_file)
|
||||||
-{
|
-{
|
||||||
|
|
|
@ -156,7 +156,7 @@
|
||||||
/*
|
/*
|
||||||
* sta->capability is used in check_assoc_ies() for RRM enabled
|
* sta->capability is used in check_assoc_ies() for RRM enabled
|
||||||
* capability element.
|
* capability element.
|
||||||
@@ -3023,7 +3049,7 @@ int ieee802_11_mgmt(struct hostapd_data
|
@@ -3025,7 +3051,7 @@ int ieee802_11_mgmt(struct hostapd_data
|
||||||
|
|
||||||
|
|
||||||
if (stype == WLAN_FC_STYPE_PROBE_REQ) {
|
if (stype == WLAN_FC_STYPE_PROBE_REQ) {
|
||||||
|
@ -165,7 +165,7 @@
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3041,17 +3067,17 @@ int ieee802_11_mgmt(struct hostapd_data
|
@@ -3043,17 +3069,17 @@ int ieee802_11_mgmt(struct hostapd_data
|
||||||
switch (stype) {
|
switch (stype) {
|
||||||
case WLAN_FC_STYPE_AUTH:
|
case WLAN_FC_STYPE_AUTH:
|
||||||
wpa_printf(MSG_DEBUG, "mgmt::auth");
|
wpa_printf(MSG_DEBUG, "mgmt::auth");
|
||||||
|
|
Loading…
Reference in a new issue