diff options
author | Johannes Berg <johannes.berg@intel.com> | 2013-02-13 09:39:57 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-02-15 03:41:10 -0500 |
commit | 89afe614c0c737fd40eda1f8c8ef686246cf3cb6 (patch) | |
tree | 6fc8c817ee6ebf13c60d5d4d07c2c69609fcd5d0 /net | |
parent | cab1c7fd8024ce896119535b5b067224b0b699aa (diff) |
mac80211: fix auth/assoc timeout handling
In my commit 1672c0e31917f49d31d30d79067103432bc20cc7
("mac80211: start auth/assoc timeout on frame status")
I broke auth/assoc timeout handling: in case we wait
for the TX status, it now leaves the timeout field set
to 0, which is a valid time and can compare as being
before now ("jiffies"). Thus, if the work struct runs
for some other reason, the auth/assoc is treated as
having timed out.
Fix this by introducing a separate "timeout_started"
variable that tracks whether the timeout has started
and is checked before timing out.
Additionally, for proper TX status handling the change
requires that the skb->dev pointer is set up for all
the frames, so set it up for all frames in mac80211.
Reported-by: Wojciech Dubowik <Wojciech.Dubowik@neratec.com>
Tested-by: Wojciech Dubowik <Wojciech.Dubowik@neratec.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 23 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 2 | ||||
-rw-r--r-- | net/mac80211/tx.c | 2 |
4 files changed, 25 insertions, 4 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 0e0a9776be39..52bf954ef61c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -343,6 +343,7 @@ struct ieee80211_mgd_auth_data { | |||
343 | u8 key[WLAN_KEY_LEN_WEP104]; | 343 | u8 key[WLAN_KEY_LEN_WEP104]; |
344 | u8 key_len, key_idx; | 344 | u8 key_len, key_idx; |
345 | bool done; | 345 | bool done; |
346 | bool timeout_started; | ||
346 | 347 | ||
347 | u16 sae_trans, sae_status; | 348 | u16 sae_trans, sae_status; |
348 | size_t data_len; | 349 | size_t data_len; |
@@ -364,6 +365,7 @@ struct ieee80211_mgd_assoc_data { | |||
364 | bool wmm, uapsd; | 365 | bool wmm, uapsd; |
365 | bool have_beacon, need_beacon; | 366 | bool have_beacon, need_beacon; |
366 | bool synced; | 367 | bool synced; |
368 | bool timeout_started; | ||
367 | 369 | ||
368 | u8 ap_ht_param; | 370 | u8 ap_ht_param; |
369 | 371 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index c156573ea3d0..a7fb276d87cb 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -2000,6 +2000,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2000 | sdata_info(sdata, "authenticated\n"); | 2000 | sdata_info(sdata, "authenticated\n"); |
2001 | ifmgd->auth_data->done = true; | 2001 | ifmgd->auth_data->done = true; |
2002 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; | 2002 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; |
2003 | ifmgd->auth_data->timeout_started = true; | ||
2003 | run_again(ifmgd, ifmgd->auth_data->timeout); | 2004 | run_again(ifmgd, ifmgd->auth_data->timeout); |
2004 | 2005 | ||
2005 | if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && | 2006 | if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && |
@@ -2334,6 +2335,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2334 | "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n", | 2335 | "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n", |
2335 | mgmt->sa, tu, ms); | 2336 | mgmt->sa, tu, ms); |
2336 | assoc_data->timeout = jiffies + msecs_to_jiffies(ms); | 2337 | assoc_data->timeout = jiffies + msecs_to_jiffies(ms); |
2338 | assoc_data->timeout_started = true; | ||
2337 | if (ms > IEEE80211_ASSOC_TIMEOUT) | 2339 | if (ms > IEEE80211_ASSOC_TIMEOUT) |
2338 | run_again(ifmgd, assoc_data->timeout); | 2340 | run_again(ifmgd, assoc_data->timeout); |
2339 | return RX_MGMT_NONE; | 2341 | return RX_MGMT_NONE; |
@@ -2457,6 +2459,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
2457 | sdata_info(sdata, "direct probe responded\n"); | 2459 | sdata_info(sdata, "direct probe responded\n"); |
2458 | ifmgd->auth_data->tries = 0; | 2460 | ifmgd->auth_data->tries = 0; |
2459 | ifmgd->auth_data->timeout = jiffies; | 2461 | ifmgd->auth_data->timeout = jiffies; |
2462 | ifmgd->auth_data->timeout_started = true; | ||
2460 | run_again(ifmgd, ifmgd->auth_data->timeout); | 2463 | run_again(ifmgd, ifmgd->auth_data->timeout); |
2461 | } | 2464 | } |
2462 | } | 2465 | } |
@@ -2542,6 +2545,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2542 | } | 2545 | } |
2543 | /* continue assoc process */ | 2546 | /* continue assoc process */ |
2544 | ifmgd->assoc_data->timeout = jiffies; | 2547 | ifmgd->assoc_data->timeout = jiffies; |
2548 | ifmgd->assoc_data->timeout_started = true; | ||
2545 | run_again(ifmgd, ifmgd->assoc_data->timeout); | 2549 | run_again(ifmgd, ifmgd->assoc_data->timeout); |
2546 | return; | 2550 | return; |
2547 | } | 2551 | } |
@@ -2934,7 +2938,10 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2934 | 2938 | ||
2935 | if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { | 2939 | if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { |
2936 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; | 2940 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; |
2941 | ifmgd->auth_data->timeout_started = true; | ||
2937 | run_again(ifmgd, auth_data->timeout); | 2942 | run_again(ifmgd, auth_data->timeout); |
2943 | } else { | ||
2944 | auth_data->timeout_started = false; | ||
2938 | } | 2945 | } |
2939 | 2946 | ||
2940 | return 0; | 2947 | return 0; |
@@ -2968,7 +2975,10 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) | |||
2968 | 2975 | ||
2969 | if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { | 2976 | if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { |
2970 | assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; | 2977 | assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; |
2978 | assoc_data->timeout_started = true; | ||
2971 | run_again(&sdata->u.mgd, assoc_data->timeout); | 2979 | run_again(&sdata->u.mgd, assoc_data->timeout); |
2980 | } else { | ||
2981 | assoc_data->timeout_started = false; | ||
2972 | } | 2982 | } |
2973 | 2983 | ||
2974 | return 0; | 2984 | return 0; |
@@ -3007,6 +3017,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3007 | } else { | 3017 | } else { |
3008 | ifmgd->auth_data->timeout = jiffies - 1; | 3018 | ifmgd->auth_data->timeout = jiffies - 1; |
3009 | } | 3019 | } |
3020 | ifmgd->auth_data->timeout_started = true; | ||
3010 | } else if (ifmgd->assoc_data && | 3021 | } else if (ifmgd->assoc_data && |
3011 | (ieee80211_is_assoc_req(fc) || | 3022 | (ieee80211_is_assoc_req(fc) || |
3012 | ieee80211_is_reassoc_req(fc))) { | 3023 | ieee80211_is_reassoc_req(fc))) { |
@@ -3017,10 +3028,11 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3017 | } else { | 3028 | } else { |
3018 | ifmgd->assoc_data->timeout = jiffies - 1; | 3029 | ifmgd->assoc_data->timeout = jiffies - 1; |
3019 | } | 3030 | } |
3031 | ifmgd->assoc_data->timeout_started = true; | ||
3020 | } | 3032 | } |
3021 | } | 3033 | } |
3022 | 3034 | ||
3023 | if (ifmgd->auth_data && | 3035 | if (ifmgd->auth_data && ifmgd->auth_data->timeout_started && |
3024 | time_after(jiffies, ifmgd->auth_data->timeout)) { | 3036 | time_after(jiffies, ifmgd->auth_data->timeout)) { |
3025 | if (ifmgd->auth_data->done) { | 3037 | if (ifmgd->auth_data->done) { |
3026 | /* | 3038 | /* |
@@ -3039,10 +3051,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3039 | cfg80211_send_auth_timeout(sdata->dev, bssid); | 3051 | cfg80211_send_auth_timeout(sdata->dev, bssid); |
3040 | mutex_lock(&ifmgd->mtx); | 3052 | mutex_lock(&ifmgd->mtx); |
3041 | } | 3053 | } |
3042 | } else if (ifmgd->auth_data) | 3054 | } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) |
3043 | run_again(ifmgd, ifmgd->auth_data->timeout); | 3055 | run_again(ifmgd, ifmgd->auth_data->timeout); |
3044 | 3056 | ||
3045 | if (ifmgd->assoc_data && | 3057 | if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && |
3046 | time_after(jiffies, ifmgd->assoc_data->timeout)) { | 3058 | time_after(jiffies, ifmgd->assoc_data->timeout)) { |
3047 | if ((ifmgd->assoc_data->need_beacon && | 3059 | if ((ifmgd->assoc_data->need_beacon && |
3048 | !ifmgd->assoc_data->have_beacon) || | 3060 | !ifmgd->assoc_data->have_beacon) || |
@@ -3057,7 +3069,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3057 | cfg80211_send_assoc_timeout(sdata->dev, bssid); | 3069 | cfg80211_send_assoc_timeout(sdata->dev, bssid); |
3058 | mutex_lock(&ifmgd->mtx); | 3070 | mutex_lock(&ifmgd->mtx); |
3059 | } | 3071 | } |
3060 | } else if (ifmgd->assoc_data) | 3072 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) |
3061 | run_again(ifmgd, ifmgd->assoc_data->timeout); | 3073 | run_again(ifmgd, ifmgd->assoc_data->timeout); |
3062 | 3074 | ||
3063 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | 3075 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | |
@@ -4032,6 +4044,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4032 | sdata_info(sdata, "waiting for beacon from %pM\n", | 4044 | sdata_info(sdata, "waiting for beacon from %pM\n", |
4033 | ifmgd->bssid); | 4045 | ifmgd->bssid); |
4034 | assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); | 4046 | assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); |
4047 | assoc_data->timeout_started = true; | ||
4035 | assoc_data->need_beacon = true; | 4048 | assoc_data->need_beacon = true; |
4036 | } else if (beacon_ies) { | 4049 | } else if (beacon_ies) { |
4037 | const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM, | 4050 | const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM, |
@@ -4047,6 +4060,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4047 | } | 4060 | } |
4048 | assoc_data->have_beacon = true; | 4061 | assoc_data->have_beacon = true; |
4049 | assoc_data->timeout = jiffies; | 4062 | assoc_data->timeout = jiffies; |
4063 | assoc_data->timeout_started = true; | ||
4050 | 4064 | ||
4051 | if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) { | 4065 | if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) { |
4052 | sdata->vif.bss_conf.sync_tsf = beacon_ies->tsf; | 4066 | sdata->vif.bss_conf.sync_tsf = beacon_ies->tsf; |
@@ -4056,6 +4070,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4056 | } | 4070 | } |
4057 | } else { | 4071 | } else { |
4058 | assoc_data->timeout = jiffies; | 4072 | assoc_data->timeout = jiffies; |
4073 | assoc_data->timeout_started = true; | ||
4059 | } | 4074 | } |
4060 | rcu_read_unlock(); | 4075 | rcu_read_unlock(); |
4061 | 4076 | ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 19db20a58e23..fb3b5865fc39 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1120,6 +1120,8 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1120 | 1120 | ||
1121 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false); | 1121 | drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false); |
1122 | 1122 | ||
1123 | skb->dev = sdata->dev; | ||
1124 | |||
1123 | rcu_read_lock(); | 1125 | rcu_read_lock(); |
1124 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | 1126 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
1125 | if (WARN_ON(!chanctx_conf)) { | 1127 | if (WARN_ON(!chanctx_conf)) { |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 71385bfc15d6..f4c89f506e9d 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -2818,6 +2818,8 @@ void __ieee80211_tx_skb_tid_band(struct ieee80211_sub_if_data *sdata, | |||
2818 | skb_set_queue_mapping(skb, ac); | 2818 | skb_set_queue_mapping(skb, ac); |
2819 | skb->priority = tid; | 2819 | skb->priority = tid; |
2820 | 2820 | ||
2821 | skb->dev = sdata->dev; | ||
2822 | |||
2821 | /* | 2823 | /* |
2822 | * The other path calling ieee80211_xmit is from the tasklet, | 2824 | * The other path calling ieee80211_xmit is from the tasklet, |
2823 | * and while we can handle concurrent transmissions locking | 2825 | * and while we can handle concurrent transmissions locking |