diff options
author | 2016-02-05 16:07:57 +0000 | |
---|---|---|
committer | 2016-02-05 16:07:57 +0000 | |
commit | 3367136c98b372b53a5ab13f9f5e5557d3be5879 (patch) | |
tree | 7cb0e786b5c5ee48bc563e1c293d5de34b103a2c | |
parent | Implement acpi_get_table_with_size(). Will soon be used to read VFCT (diff) | |
download | wireguard-openbsd-3367136c98b372b53a5ab13f9f5e5557d3be5879.tar.xz wireguard-openbsd-3367136c98b372b53a5ab13f9f5e5557d3be5879.zip |
Store ADDBA request and response parameters in the block ack record of
ieee80211_node. This way, we can keep track of the ACK policy and echo
it back to the AP as required by the standard. And use the correct bit
flag for the policy -- this code was confused between BlockAck and ADDBA,
both of which have a policy bit but in different places.
Fixes apple airport APs.
tested by tb@, krw@, sthen@, abieber@, and Henrik Friedrichsen
-rw-r--r-- | sys/net80211/ieee80211_input.c | 5 | ||||
-rw-r--r-- | sys/net80211/ieee80211_node.h | 6 | ||||
-rw-r--r-- | sys/net80211/ieee80211_output.c | 15 | ||||
-rw-r--r-- | sys/net80211/ieee80211_proto.c | 8 |
4 files changed, 21 insertions, 13 deletions
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 30dfbd0bb8a..6b8106106fb 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_input.c,v 1.156 2016/02/04 16:23:40 stsp Exp $ */ +/* $OpenBSD: ieee80211_input.c,v 1.157 2016/02/05 16:07:57 stsp Exp $ */ /*- * Copyright (c) 2001 Atsushi Onoe @@ -2504,6 +2504,9 @@ ieee80211_recv_addba_req(struct ieee80211com *ic, struct mbuf *m, ba->ba_winsize = bufsz; if (ba->ba_winsize == 0 || ba->ba_winsize > IEEE80211_BA_MAX_WINSZ) ba->ba_winsize = IEEE80211_BA_MAX_WINSZ; + ba->ba_params = (params & IEEE80211_ADDBA_BA_POLICY); + ba->ba_params |= ((ba->ba_winsize << IEEE80211_ADDBA_BUFSZ_SHIFT) | + (tid << IEEE80211_ADDBA_TID_SHIFT) | IEEE80211_ADDBA_AMSDU); ba->ba_winstart = ssn; ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff; /* allocate and setup our reordering buffer */ diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index f26304a39c4..c6ffeccb8f9 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_node.h,v 1.55 2016/02/04 16:23:40 stsp Exp $ */ +/* $OpenBSD: ieee80211_node.h,v 1.56 2016/02/05 16:07:57 stsp Exp $ */ /* $NetBSD: ieee80211_node.h,v 1.9 2004/04/30 22:57:32 dyoung Exp $ */ /*- @@ -120,6 +120,9 @@ struct ieee80211_tx_ba { #define IEEE80211_BA_REQUESTED 1 #define IEEE80211_BA_AGREED 2 + /* ADDBA parameter set field for this BA agreement. */ + u_int16_t ba_params; + /* These values are IEEE802.11 frame sequence numbers (0x0-0xfff) */ u_int16_t ba_winstart; u_int16_t ba_winend; @@ -140,6 +143,7 @@ struct ieee80211_rx_ba { struct timeout ba_to; int ba_timeout_val; int ba_state; + u_int16_t ba_params; u_int16_t ba_winstart; u_int16_t ba_winend; u_int16_t ba_winsize; diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index 961c2e0ab80..911e96b6d06 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_output.c,v 1.108 2016/01/21 20:33:20 stsp Exp $ */ +/* $OpenBSD: ieee80211_output.c,v 1.109 2016/02/05 16:07:57 stsp Exp $ */ /* $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $ */ /*- @@ -1414,7 +1414,6 @@ ieee80211_get_addba_req(struct ieee80211com *ic, struct ieee80211_node *ni, struct ieee80211_tx_ba *ba = &ni->ni_tx_ba[tid]; struct mbuf *m; u_int8_t *frm; - u_int16_t params; m = ieee80211_getmgmt(M_DONTWAIT, MT_DATA, 9); if (m == NULL) @@ -1424,12 +1423,7 @@ ieee80211_get_addba_req(struct ieee80211com *ic, struct ieee80211_node *ni, *frm++ = IEEE80211_CATEG_BA; *frm++ = IEEE80211_ACTION_ADDBA_REQ; *frm++ = ba->ba_token; - params = ba->ba_winsize << IEEE80211_ADDBA_BUFSZ_SHIFT | - tid << IEEE80211_ADDBA_TID_SHIFT | - IEEE80211_ADDBA_AMSDU; - if ((ic->ic_htcaps & IEEE80211_HTCAP_DELAYEDBA) == 0) - params |= IEEE80211_ADDBA_BA_POLICY; /* use immediate BA */ - LE_WRITE_2(frm, params); frm += 2; + LE_WRITE_2(frm, ba->ba_params); frm += 2; LE_WRITE_2(frm, ba->ba_timeout_val / IEEE80211_DUR_TU); frm += 2; LE_WRITE_2(frm, ba->ba_winstart); frm += 2; @@ -1465,9 +1459,10 @@ ieee80211_get_addba_resp(struct ieee80211com *ic, struct ieee80211_node *ni, *frm++ = IEEE80211_ACTION_ADDBA_RESP; *frm++ = token; LE_WRITE_2(frm, status); frm += 2; - params = tid << 2 | IEEE80211_BA_ACK_POLICY; if (status == 0) - params |= ba->ba_winsize << 6; + params = ba->ba_params; + else + params = tid << IEEE80211_ADDBA_TID_SHIFT; LE_WRITE_2(frm, params); frm += 2; if (status == 0) LE_WRITE_2(frm, ba->ba_timeout_val / IEEE80211_DUR_TU); diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index d86ab5e4944..a812551ca31 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_proto.c,v 1.62 2016/02/04 16:23:40 stsp Exp $ */ +/* $OpenBSD: ieee80211_proto.c,v 1.63 2016/02/05 16:07:57 stsp Exp $ */ /* $NetBSD: ieee80211_proto.c,v 1.8 2004/04/30 23:58:20 dyoung Exp $ */ /*- @@ -646,6 +646,12 @@ ieee80211_addba_request(struct ieee80211com *ic, struct ieee80211_node *ni, ba->ba_winsize = IEEE80211_BA_MAX_WINSZ; ba->ba_winstart = ssn; ba->ba_winend = (ba->ba_winstart + ba->ba_winsize - 1) & 0xfff; + ba->ba_params = + (ba->ba_winsize << IEEE80211_ADDBA_BUFSZ_SHIFT) | + (tid << IEEE80211_ADDBA_TID_SHIFT) | IEEE80211_ADDBA_AMSDU; + if ((ic->ic_htcaps & IEEE80211_HTCAP_DELAYEDBA) == 0) + /* immediate BA */ + ba->ba_params |= IEEE80211_ADDBA_BA_POLICY; timeout_add_sec(&ba->ba_to, 1); /* dot11ADDBAResponseTimeout */ IEEE80211_SEND_ACTION(ic, ni, IEEE80211_CATEG_BA, |