aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-02-13 09:39:57 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-02-15 03:41:10 -0500
commit89afe614c0c737fd40eda1f8c8ef686246cf3cb6 (patch)
tree6fc8c817ee6ebf13c60d5d4d07c2c69609fcd5d0 /net
parentcab1c7fd8024ce896119535b5b067224b0b699aa (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.h2
-rw-r--r--net/mac80211/mlme.c23
-rw-r--r--net/mac80211/sta_info.c2
-rw-r--r--net/mac80211/tx.c2
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