From: Felix Fietkau <nbd@openwrt.org>
Date: Sun, 7 Oct 2012 21:35:29 +0000 (+0000)
Subject: mac80211: use ieee80211_free_txskb in a few more places to prevent skb leaks
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=e1ceb94c2f85f67c487898c59df5ca751489c7af;p=openwrt%2Fstaging%2Fblocktrron.git

mac80211: use ieee80211_free_txskb in a few more places to prevent skb leaks

SVN-Revision: 33635
---

diff --git a/package/mac80211/patches/527-mac80211_use_ieee80211_free_txskb.patch b/package/mac80211/patches/527-mac80211_use_ieee80211_free_txskb.patch
new file mode 100644
index 0000000000..e6db104849
--- /dev/null
+++ b/package/mac80211/patches/527-mac80211_use_ieee80211_free_txskb.patch
@@ -0,0 +1,107 @@
+--- a/net/mac80211/tx.c
++++ b/net/mac80211/tx.c
+@@ -354,7 +354,7 @@ static void purge_old_ps_buffers(struct 
+ 			total += skb_queue_len(&sta->ps_tx_buf[ac]);
+ 			if (skb) {
+ 				purged++;
+-				dev_kfree_skb(skb);
++				ieee80211_free_txskb(&local->hw, skb);
+ 				break;
+ 			}
+ 		}
+@@ -466,7 +466,7 @@ ieee80211_tx_h_unicast_ps_buf(struct iee
+ 			ps_dbg(tx->sdata,
+ 			       "STA %pM TX buffer for AC %d full - dropping oldest frame\n",
+ 			       sta->sta.addr, ac);
+-			dev_kfree_skb(old);
++			ieee80211_free_txskb(&local->hw, old);
+ 		} else
+ 			tx->local->total_ps_buffered++;
+ 
+@@ -1103,7 +1103,7 @@ static bool ieee80211_tx_prep_agg(struct
+ 		spin_unlock(&tx->sta->lock);
+ 
+ 		if (purge_skb)
+-			dev_kfree_skb(purge_skb);
++			ieee80211_free_txskb(&tx->local->hw, purge_skb);
+ 	}
+ 
+ 	/* reset session timer */
+@@ -1214,7 +1214,7 @@ static bool ieee80211_tx_frags(struct ie
+ #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
+ 		if (WARN_ON_ONCE(q >= local->hw.queues)) {
+ 			__skb_unlink(skb, skbs);
+-			dev_kfree_skb(skb);
++			ieee80211_free_txskb(&local->hw, skb);
+ 			continue;
+ 		}
+ #endif
+@@ -1356,7 +1356,7 @@ static int invoke_tx_handlers(struct iee
+ 	if (unlikely(res == TX_DROP)) {
+ 		I802_DEBUG_INC(tx->local->tx_handlers_drop);
+ 		if (tx->skb)
+-			dev_kfree_skb(tx->skb);
++			ieee80211_free_txskb(&tx->local->hw, tx->skb);
+ 		else
+ 			__skb_queue_purge(&tx->skbs);
+ 		return -1;
+@@ -1393,7 +1393,7 @@ static bool ieee80211_tx(struct ieee8021
+ 	res_prepare = ieee80211_tx_prepare(sdata, &tx, skb);
+ 
+ 	if (unlikely(res_prepare == TX_DROP)) {
+-		dev_kfree_skb(skb);
++		ieee80211_free_txskb(&local->hw, skb);
+ 		goto out;
+ 	} else if (unlikely(res_prepare == TX_QUEUED)) {
+ 		goto out;
+@@ -1465,7 +1465,7 @@ void ieee80211_xmit(struct ieee80211_sub
+ 	headroom = max_t(int, 0, headroom);
+ 
+ 	if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) {
+-		dev_kfree_skb(skb);
++		ieee80211_free_txskb(&local->hw, skb);
+ 		rcu_read_unlock();
+ 		return;
+ 	}
+@@ -2056,8 +2056,10 @@ netdev_tx_t ieee80211_subif_start_xmit(s
+ 		head_need += IEEE80211_ENCRYPT_HEADROOM;
+ 		head_need += local->tx_headroom;
+ 		head_need = max_t(int, 0, head_need);
+-		if (ieee80211_skb_resize(sdata, skb, head_need, true))
+-			goto fail;
++		if (ieee80211_skb_resize(sdata, skb, head_need, true)) {
++			ieee80211_free_txskb(&local->hw, skb);
++			return NETDEV_TX_OK;
++		}
+ 	}
+ 
+ 	if (encaps_data) {
+@@ -2190,7 +2192,7 @@ void ieee80211_tx_pending(unsigned long 
+ 			struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ 
+ 			if (WARN_ON(!info->control.vif)) {
+-				kfree_skb(skb);
++				ieee80211_free_txskb(&local->hw, skb);
+ 				continue;
+ 			}
+ 
+--- a/net/mac80211/status.c
++++ b/net/mac80211/status.c
+@@ -34,7 +34,7 @@ void ieee80211_tx_status_irqsafe(struct 
+ 		skb_queue_len(&local->skb_queue_unreliable);
+ 	while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT &&
+ 	       (skb = skb_dequeue(&local->skb_queue_unreliable))) {
+-		dev_kfree_skb_irq(skb);
++		ieee80211_free_txskb(hw, skb);
+ 		tmp--;
+ 		I802_DEBUG_INC(local->tx_status_drop);
+ 	}
+@@ -159,7 +159,7 @@ static void ieee80211_handle_filtered_fr
+ 			   "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n",
+ 			   skb_queue_len(&sta->tx_filtered[ac]),
+ 			   !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies);
+-	dev_kfree_skb(skb);
++	ieee80211_free_txskb(&local->hw, skb);
+ }
+ 
+ static void ieee80211_check_pending_bar(struct sta_info *sta, u8 *addr, u8 tid)
diff --git a/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch b/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch
index 53889d19ca..f778338092 100644
--- a/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch
+++ b/package/mac80211/patches/550-mac80211_optimize_mcs_rate_mask.patch
@@ -69,7 +69,7 @@
  	txrc.bss = (tx->sdata->vif.type == NL80211_IFTYPE_AP ||
  		    tx->sdata->vif.type == NL80211_IFTYPE_MESH_POINT ||
  		    tx->sdata->vif.type == NL80211_IFTYPE_ADHOC);
-@@ -2447,8 +2449,6 @@ struct sk_buff *ieee80211_beacon_get_tim
+@@ -2449,8 +2451,6 @@ struct sk_buff *ieee80211_beacon_get_tim
  		txrc.max_rate_idx = -1;
  	else
  		txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;