提交 63a5ab82 编写于 作者: J Jouni Malinen 提交者: John W. Linville

mac80211: 802.11w - Implement Association Comeback processing

When MFP is enabled, the AP does not allow a STA to associate if an
existing security association exists without first going through SA
Query process. When this happens, the association request is denied
with a new status code ("temporarily rejected") ans Association
Comeback IE is used to notify when the association may be tried again
(i.e., when the SA Query procedure has timed out).

Use the comeback time to update the mac80211 client MLME timer for
next association attempt to minimize waiting time if association is
temporarily rejected.
Signed-off-by: NJouni Malinen <jouni.malinen@atheros.com>
Acked-by: NJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 97ebe12a
...@@ -914,6 +914,9 @@ enum ieee80211_statuscode { ...@@ -914,6 +914,9 @@ enum ieee80211_statuscode {
/* 802.11g */ /* 802.11g */
WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25, WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25,
WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26, WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26,
/* 802.11w */
WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY = 30,
WLAN_STATUS_ROBUST_MGMT_FRAME_POLICY_VIOLATION = 31,
/* 802.11i */ /* 802.11i */
WLAN_STATUS_INVALID_IE = 40, WLAN_STATUS_INVALID_IE = 40,
WLAN_STATUS_INVALID_GROUP_CIPHER = 41, WLAN_STATUS_INVALID_GROUP_CIPHER = 41,
...@@ -1034,6 +1037,7 @@ enum ieee80211_eid { ...@@ -1034,6 +1037,7 @@ enum ieee80211_eid {
/* 802.11i */ /* 802.11i */
WLAN_EID_RSN = 48, WLAN_EID_RSN = 48,
WLAN_EID_MMIE = 76 /* 802.11w */, WLAN_EID_MMIE = 76 /* 802.11w */,
WLAN_EID_ASSOC_COMEBACK_TIME = 77,
WLAN_EID_WPA = 221, WLAN_EID_WPA = 221,
WLAN_EID_GENERIC = 221, WLAN_EID_GENERIC = 221,
WLAN_EID_VENDOR_SPECIFIC = 221, WLAN_EID_VENDOR_SPECIFIC = 221,
......
...@@ -820,6 +820,7 @@ struct ieee802_11_elems { ...@@ -820,6 +820,7 @@ struct ieee802_11_elems {
u8 *country_elem; u8 *country_elem;
u8 *pwr_constr_elem; u8 *pwr_constr_elem;
u8 *quiet_elem; /* first quite element */ u8 *quiet_elem; /* first quite element */
u8 *assoc_comeback;
/* length of them, respectively */ /* length of them, respectively */
u8 ssid_len; u8 ssid_len;
...@@ -847,6 +848,7 @@ struct ieee802_11_elems { ...@@ -847,6 +848,7 @@ struct ieee802_11_elems {
u8 pwr_constr_elem_len; u8 pwr_constr_elem_len;
u8 quiet_elem_len; u8 quiet_elem_len;
u8 num_of_quiet_elem; /* can be more the one */ u8 num_of_quiet_elem; /* can be more the one */
u8 assoc_comeback_len;
}; };
static inline struct ieee80211_local *hw_to_local( static inline struct ieee80211_local *hw_to_local(
......
...@@ -1275,6 +1275,23 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, ...@@ -1275,6 +1275,23 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
sdata->dev->name, reassoc ? "Rea" : "A", mgmt->sa, sdata->dev->name, reassoc ? "Rea" : "A", mgmt->sa,
capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
pos = mgmt->u.assoc_resp.variable;
ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
elems.assoc_comeback && elems.assoc_comeback_len == 4) {
u32 tu, ms;
tu = get_unaligned_le32(elems.assoc_comeback);
ms = tu * 1024 / 1000;
printk(KERN_DEBUG "%s: AP rejected association temporarily; "
"comeback duration %u TU (%u ms)\n",
sdata->dev->name, tu, ms);
if (ms > IEEE80211_ASSOC_TIMEOUT)
mod_timer(&ifsta->timer,
jiffies + msecs_to_jiffies(ms));
return;
}
if (status_code != WLAN_STATUS_SUCCESS) { if (status_code != WLAN_STATUS_SUCCESS) {
printk(KERN_DEBUG "%s: AP denied association (code=%d)\n", printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
sdata->dev->name, status_code); sdata->dev->name, status_code);
...@@ -1290,9 +1307,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, ...@@ -1290,9 +1307,6 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
"set\n", sdata->dev->name, aid); "set\n", sdata->dev->name, aid);
aid &= ~(BIT(15) | BIT(14)); aid &= ~(BIT(15) | BIT(14));
pos = mgmt->u.assoc_resp.variable;
ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
if (!elems.supp_rates) { if (!elems.supp_rates) {
printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
sdata->dev->name); sdata->dev->name);
......
...@@ -653,6 +653,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len, ...@@ -653,6 +653,10 @@ void ieee802_11_parse_elems(u8 *start, size_t len,
elems->pwr_constr_elem = pos; elems->pwr_constr_elem = pos;
elems->pwr_constr_elem_len = elen; elems->pwr_constr_elem_len = elen;
break; break;
case WLAN_EID_ASSOC_COMEBACK_TIME:
elems->assoc_comeback = pos;
elems->assoc_comeback_len = elen;
break;
default: default:
break; break;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册