From 0624a5b03e1bdf5dc5b6c7fd77a0196d4ee69dfe Mon Sep 17 00:00:00 2001 From: mtaylor Date: Wed, 21 Nov 2007 11:47:50 +0000 Subject: [PATCH] More SKB_CB macro use and cleanup of dropped references from kernel dropped skbuff structures. More refcount bumps due to skb_clone/skb_copy. git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@2896 0192ed92-7a03-0410-a25b-9323aeb14dbd --- net80211/ieee80211_linux.c | 22 +++------------------- net80211/ieee80211_monitor.c | 19 ++++++++++++++++--- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/net80211/ieee80211_linux.c b/net80211/ieee80211_linux.c index 5e0fe23..9509080 100644 --- a/net80211/ieee80211_linux.c +++ b/net80211/ieee80211_linux.c @@ -137,7 +137,6 @@ struct sk_buff * ieee80211_getmgtframe(u_int8_t **frm, u_int pktlen) { const u_int align = sizeof(u_int32_t); - struct ieee80211_cb *cb; struct sk_buff *skb; u_int len; @@ -148,10 +147,9 @@ ieee80211_getmgtframe(u_int8_t **frm, u_int pktlen) if (off != 0) skb_reserve(skb, align - off); - cb = (struct ieee80211_cb *)skb->cb; - cb->ni = NULL; - cb->flags = 0; - cb->next = NULL; + SKB_CB(skb)->ni = NULL; + SKB_CB(skb)->flags = 0; + SKB_CB(skb)->next = NULL; skb_reserve(skb, sizeof(struct ieee80211_frame)); *frm = skb_put(skb, pktlen); @@ -159,20 +157,6 @@ ieee80211_getmgtframe(u_int8_t **frm, u_int pktlen) return skb; } -#if 0 -/* - * Drain a queue of sk_buffs. - */ -void -__skb_queue_drain(struct sk_buff_head *q) -{ - struct sk_buff *skb; - - while ((skb = __skb_dequeue(q)) != NULL) - dev_kfree_skb(skb); -} -#endif - #if IEEE80211_VLAN_TAG_USED /* * VLAN support. diff --git a/net80211/ieee80211_monitor.c b/net80211/ieee80211_monitor.c index e20871c..aa4f5fe 100644 --- a/net80211/ieee80211_monitor.c +++ b/net80211/ieee80211_monitor.c @@ -373,6 +373,10 @@ ieee80211_input_monitor(struct ieee80211com *ic, struct sk_buff *skb, /* XXX stat+msg */ continue; } + /* We duplicate the reference after skb_copy */ + if (SKB_CB(skb)->ni != NULL) { + SKB_CB(skb1)->ni = ieee80211_ref_node(SKB_CB(skb)->ni); + } if (vap->iv_monitor_txf_len && tx) { /* truncate transmit feedback packets */ skb_trim(skb1, vap->iv_monitor_txf_len); @@ -553,7 +557,8 @@ ieee80211_input_monitor(struct ieee80211com *ic, struct sk_buff *skb, default: break; } - if (skb1) { + if (skb1 != NULL) { + struct ieee80211_node *ni_tmp; if (!tx && (vap->iv_dev->type != ARPHRD_IEEE80211_RADIOTAP) && (skb1->len >= IEEE80211_CRC_LEN)) { /* Remove FCS from end of rx frames when * delivering to non-Radiotap VAPs */ @@ -566,8 +571,16 @@ ieee80211_input_monitor(struct ieee80211com *ic, struct sk_buff *skb, skb1->pkt_type = pkttype; skb1->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */ - netif_rx(skb1); - + ni_tmp = SKB_CB(skb1)->ni; + if (netif_rx(skb1) == NET_RX_DROP) { + /* If netif_rx dropped the packet because + * device was too busy */ + if (ni_tmp != NULL) { + /* node reference was leaked */ + ieee80211_unref_node(&ni_tmp); + } + vap->iv_devstats.rx_dropped++; + } vap->iv_devstats.rx_packets++; vap->iv_devstats.rx_bytes += skb1->len; } -- 2.35.1