diff options
-rw-r--r-- | net/mac80211/ieee80211.c | 9 | ||||
-rw-r--r-- | net/mac80211/rx.c | 3 |
2 files changed, 12 insertions, 0 deletions
diff --git a/net/mac80211/ieee80211.c b/net/mac80211/ieee80211.c index 5fc2402..00df2a9 100644 --- a/net/mac80211/ieee80211.c +++ b/net/mac80211/ieee80211.c @@ -493,7 +493,16 @@ static void ieee80211_if_shutdown(struct net_device *dev) case IEEE80211_IF_TYPE_IBSS: sdata->u.sta.state = IEEE80211_DISABLED; del_timer_sync(&sdata->u.sta.timer); + /* + * Holding the sub_if_lock for writing here blocks + * out the receive path and makes sure it's not + * currently processing a packet that may get + * added to the queue. + */ + write_lock_bh(&local->sub_if_lock); skb_queue_purge(&sdata->u.sta.skb_queue); + write_unlock_bh(&local->sub_if_lock); + if (!local->ops->hw_scan && local->scan_dev == sdata->dev) { local->sta_scanning = 0; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 95a00eb..01176ba 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -1380,6 +1380,9 @@ void __ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb, list_for_each_entry(sdata, &local->sub_if_list, list) { rx.u.rx.ra_match = 1; + if (!netif_running(sdata->dev)) + continue; + prepres = prepare_for_handlers(sdata, bssid, &rx, hdr); /* prepare_for_handlers can change sta */ sta = rx.sta; |