More SKB_CB macro use and cleanup of dropped references from kernel dropped skbuff
authormtaylor <mtaylor@0192ed92-7a03-0410-a25b-9323aeb14dbd>
Wed, 21 Nov 2007 11:47:50 +0000 (11:47 +0000)
committermtaylor <mtaylor@0192ed92-7a03-0410-a25b-9323aeb14dbd>
Wed, 21 Nov 2007 11:47:50 +0000 (11:47 +0000)
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
net80211/ieee80211_monitor.c

index 5e0fe23d87a54a8fb092ad6573262605183e41b8..950908020d52b50307d8da0fc4fa176b58dc43f9 100644 (file)
@@ -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.
index e20871c82c8067c92d3c2ae85e2f2b91a9ce3642..aa4f5fe5fc846b26f3b2c0bab81fce5774126ac0 100644 (file)
@@ -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;
                }