summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorstsp <stsp@openbsd.org>2016-02-05 16:07:57 +0000
committerstsp <stsp@openbsd.org>2016-02-05 16:07:57 +0000
commit3367136c98b372b53a5ab13f9f5e5557d3be5879 (patch)
tree7cb0e786b5c5ee48bc563e1c293d5de34b103a2c
parentImplement acpi_get_table_with_size(). Will soon be used to read VFCT (diff)
downloadwireguard-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.c5
-rw-r--r--sys/net80211/ieee80211_node.h6
-rw-r--r--sys/net80211/ieee80211_output.c15
-rw-r--r--sys/net80211/ieee80211_proto.c8
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,