| From 28a1bcdb57d50f3038a255741ecc83e391e5282e Mon Sep 17 00:00:00 2001 |
| From: Johannes Berg <johannes.berg@intel.com> |
| Date: Tue, 4 Oct 2011 18:27:10 +0200 |
| Subject: mac80211: fix offchannel TX cookie matching |
| |
| From: Johannes Berg <johannes.berg@intel.com> |
| |
| commit 28a1bcdb57d50f3038a255741ecc83e391e5282e upstream. |
| |
| When I introduced in-kernel off-channel TX I |
| introduced a bug -- the work can't be canceled |
| again because the code clear the skb pointer. |
| Fix this by keeping track separately of whether |
| TX status has already been reported. |
| |
| Reported-by: Jouni Malinen <j@w1.fi> |
| Tested-by: Jouni Malinen <j@w1.fi> |
| Signed-off-by: Johannes Berg <johannes.berg@intel.com> |
| Signed-off-by: John W. Linville <linville@tuxdriver.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| net/mac80211/cfg.c | 2 +- |
| net/mac80211/ieee80211_i.h | 1 + |
| net/mac80211/status.c | 2 +- |
| net/mac80211/work.c | 2 +- |
| 4 files changed, 4 insertions(+), 3 deletions(-) |
| |
| --- a/net/mac80211/cfg.c |
| +++ b/net/mac80211/cfg.c |
| @@ -1821,7 +1821,7 @@ ieee80211_offchan_tx_done(struct ieee802 |
| * so in that case userspace will have to deal with it. |
| */ |
| |
| - if (wk->offchan_tx.wait && wk->offchan_tx.frame) |
| + if (wk->offchan_tx.wait && !wk->offchan_tx.status) |
| cfg80211_mgmt_tx_status(wk->sdata->dev, |
| (unsigned long) wk->offchan_tx.frame, |
| wk->ie, wk->ie_len, false, GFP_KERNEL); |
| --- a/net/mac80211/ieee80211_i.h |
| +++ b/net/mac80211/ieee80211_i.h |
| @@ -345,6 +345,7 @@ struct ieee80211_work { |
| struct { |
| struct sk_buff *frame; |
| u32 wait; |
| + bool status; |
| } offchan_tx; |
| }; |
| |
| --- a/net/mac80211/status.c |
| +++ b/net/mac80211/status.c |
| @@ -336,7 +336,7 @@ void ieee80211_tx_status(struct ieee8021 |
| continue; |
| if (wk->offchan_tx.frame != skb) |
| continue; |
| - wk->offchan_tx.frame = NULL; |
| + wk->offchan_tx.status = true; |
| break; |
| } |
| rcu_read_unlock(); |
| --- a/net/mac80211/work.c |
| +++ b/net/mac80211/work.c |
| @@ -579,7 +579,7 @@ ieee80211_offchannel_tx(struct ieee80211 |
| /* |
| * After this, offchan_tx.frame remains but now is no |
| * longer a valid pointer -- we still need it as the |
| - * cookie for canceling this work. |
| + * cookie for canceling this work/status matching. |
| */ |
| ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame); |
| |