SKB handling code cleanup:

* Convert last SKB_CB()->ni to SKB_NI
 * Lots of comments
 * Refactor various pieces of code for consistency, readability, and removal of goto


git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@3666 0192ed92-7a03-0410-a25b-9323aeb14dbd
This commit is contained in:
mentor 2008-05-22 12:58:24 +00:00
parent 04084c023d
commit 18682f3d29
7 changed files with 78 additions and 96 deletions

View File

@ -6638,22 +6638,21 @@ rx_accept:
skb_trim(skb, skb->len - IEEE80211_CRC_LEN);
if (mic_fail) {
struct ieee80211_frame *frm = (struct ieee80211_frame *)
skb->data;
/* Ignore control frames which are reported with MIC
* error. */
if ((((struct ieee80211_frame *)skb->data)->i_fc[0] &
IEEE80211_FC0_TYPE_MASK) ==
IEEE80211_FC0_TYPE_CTL)
goto drop_micfail;
ni = ieee80211_find_rxnode(ic, (const struct
ieee80211_frame_min *)skb->data);
if ((frm->i_fc[0] & IEEE80211_FC0_TYPE_MASK) !=
IEEE80211_FC0_TYPE_CTL) {
ni = ieee80211_find_rxnode(ic,
(struct ieee80211_frame_min *)frm);
if (ni) {
if (ni->ni_table)
ieee80211_check_mic(ni, skb);
ieee80211_unref_node(&ni);
}
}
drop_micfail:
mic_fail = 0;
ieee80211_dev_kfree_skb(&skb);

View File

@ -745,11 +745,11 @@ ieee80211_input(struct ieee80211vap *vap, struct ieee80211_node *ni_or_null,
goto err;
}
/* deliver the frames */
/* Deliver the frames. */
ieee80211_deliver_data(ni, skb);
ieee80211_deliver_data(ni, skb1);
} else {
/* assume non-atheros llc type */
/* Assume non-atheros LLC type. */
ieee80211_deliver_data(ni, skb);
}
#else /* !ATH_SUPERG_FF */
@ -757,14 +757,13 @@ ieee80211_input(struct ieee80211vap *vap, struct ieee80211_node *ni_or_null,
#endif
if (ni_or_null == NULL)
ieee80211_unref_node(&ni);
/* XXX: Why doesn't this use goto out?
* If I do, we access skb after we have given it to
* ieee80211_deliver_data and we get crashes/errors. */
/* XXX: Why doesn't this use 'goto out'?
* If it did, then the SKB would be accessed after we
* have given it to ieee80211_deliver_data and we get
* crashes/errors. */
return IEEE80211_FC0_TYPE_DATA;
case IEEE80211_FC0_TYPE_MGT:
/*
* WDS opmode do not support management frames
*/
/* WDS opmode does not support management frames. */
if (vap->iv_opmode == IEEE80211_M_WDS) {
vap->iv_stats.is_rx_mgtdiscard++;
goto out;
@ -1105,6 +1104,8 @@ ieee80211_deliver_data(struct ieee80211_node *ni, struct sk_buff *skb)
struct ieee80211vap *vap = ni->ni_vap;
struct net_device *dev = vap->iv_dev;
struct ether_header *eh = (struct ether_header *) skb->data;
struct ieee80211_node *tni;
int ret;
#ifdef ATH_SUPERG_XR
/*
@ -1126,87 +1127,73 @@ ieee80211_deliver_data(struct ieee80211_node *ni, struct sk_buff *skb)
/* Create a SKB for the BSS to send out. */
skb1 = skb_copy(skb, GFP_ATOMIC);
if (skb1)
SKB_CB(skb1)->ni = ieee80211_ref_node(vap->iv_bss);
SKB_NI(skb1) = ieee80211_ref_node(vap->iv_bss);
}
else {
/*
* Check if destination is associated with the
* same vap and authorized to receive traffic.
* Beware of traffic destined for the vap itself;
/* Check if destination is associated with the
* same VAP and authorized to receive traffic.
* Beware of traffic destined for the VAP itself;
* sending it will not work; just let it be
* delivered normally.
*/
* delivered normally. */
struct ieee80211_node *ni1 = ieee80211_find_node(
&vap->iv_ic->ic_sta, eh->ether_dhost);
if (ni1 != NULL) {
if (ni1->ni_vap == vap &&
ieee80211_node_is_authorized(ni1) &&
ni1 != vap->iv_bss) {
if ((ni1->ni_vap == vap) &&
(ni1 != vap->iv_bss) &&
ieee80211_node_is_authorized(ni1)) {
skb1 = skb;
skb = NULL;
}
/* XXX statistic? */
/* XXX: statistic? */
ieee80211_unref_node(&ni1);
}
}
if (skb1 != NULL) {
struct ieee80211_node *ni_tmp;
struct ieee80211_node *tni;
skb1->dev = dev;
skb_reset_mac_header(skb1);
skb_set_network_header(skb1, sizeof(struct ether_header));
skb1->protocol = __constant_htons(ETH_P_802_2);
/* XXX insert vlan tag before queue it? */
ni_tmp = SKB_CB(skb1)->ni; /* remember node so we can free it */
/* XXX: Insert vlan tag before queuing it? */
tni = SKB_NI(skb1); /* Remember node so we can free it. */
if (dev_queue_xmit(skb1) == NET_XMIT_DROP) {
/* If queue dropped the packet because device was
* too busy */
/* If queue dropped the packet because device
* was too busy */
vap->iv_devstats.tx_dropped++;
/* node reference was leaked */
if (ni_tmp != NULL)
ieee80211_unref_node(&ni_tmp);
if (tni != NULL)
ieee80211_unref_node(&tni);
}
/* skb is no longer ours, either way after dev_queue_xmit */
/* SKB is no longer ours, either way after dev_queue_xmit. */
skb1 = NULL;
}
}
if (skb != NULL) {
skb->dev = dev;
#ifdef USE_HEADERLEN_RESV
skb->protocol = ath_eth_type_trans(skb, dev);
#else
skb->protocol = eth_type_trans(skb, dev);
#endif
tni = SKB_NI(skb);
if ((ni->ni_vlan != 0) && (vap->iv_vlgrp != NULL))
/* Attach VLAN tag. */
ret = vlan_hwaccel_receive_skb(skb,
vap->iv_vlgrp, ni->ni_vlan);
else
ret = netif_rx(skb);
if (ret == NET_RX_DROP) {
/* Cleanup if passing SKB to ourselves failed. */
if (tni != NULL)
ieee80211_unref_node(&tni);
vap->iv_devstats.rx_dropped++;
}
skb = NULL; /* SKB is no longer ours */
vap->iv_devstats.rx_packets++;
vap->iv_devstats.rx_bytes += skb->len;
if (ni->ni_vlan != 0 && vap->iv_vlgrp != NULL) {
/* attach vlan tag */
struct ieee80211_node *ni_tmp = SKB_NI(skb);
if (vlan_hwaccel_receive_skb(skb, vap->iv_vlgrp, ni->ni_vlan) == 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++;
}
skb = NULL; /* SKB is no longer ours */
} else {
struct ieee80211_node *ni_tmp = SKB_NI(skb);
if (netif_rx(skb) == 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++;
}
skb = NULL; /* SKB is no longer ours */
}
dev->last_rx = jiffies;
}
}
@ -2294,7 +2281,7 @@ forward_mgmt_to_app(struct ieee80211vap *vap, int subtype, struct sk_buff *skb,
if (filter_type && ((vap->app_filter & filter_type) == filter_type)) {
struct sk_buff *skb1;
struct ieee80211_node *ni_tmp;
struct ieee80211_node *tni;
skb1 = skb_copy(skb, GFP_ATOMIC);
if (skb1 == NULL)
@ -2308,13 +2295,13 @@ forward_mgmt_to_app(struct ieee80211vap *vap, int subtype, struct sk_buff *skb,
skb1->pkt_type = PACKET_OTHERHOST;
skb1->protocol = __constant_htons(0x0019); /* ETH_P_80211_RAW */
ni_tmp = SKB_CB(skb1)->ni;
tni = SKB_NI(skb1);
if (netif_rx(skb1) == NET_RX_DROP) {
/* If netif_rx dropped the packet because
* device was too busy */
if (ni_tmp != NULL) {
if (tni != NULL) {
/* node reference was leaked */
ieee80211_unref_node(&ni_tmp);
ieee80211_unref_node(&tni);
}
vap->iv_devstats.rx_dropped++;
}

View File

@ -578,8 +578,8 @@ ieee80211_input_monitor(struct ieee80211com *ic, struct sk_buff *skb,
/* If netif_rx dropped the packet because
* device was too busy, reclaim the ref. in
* the skb. */
if (SKB_CB(skb1)->ni != NULL)
ieee80211_unref_node(&SKB_CB(skb1)->ni);
if (SKB_NI(skb1) != NULL)
ieee80211_unref_node(&SKB_NI(skb1));
vap->iv_devstats.rx_dropped++;
}

View File

@ -207,20 +207,19 @@ ieee80211_hardstart(struct sk_buff *skb, struct net_device *dev)
struct ieee80211_node *ni = NULL;
struct ether_header *eh;
/* reset the skb of new frames reaching this layer BEFORE
/* Reset the SKB of new frames reaching this layer BEFORE
* we invoke ieee80211_skb_track. */
memset(SKB_CB(skb), 0, sizeof(struct ieee80211_cb));
/* If an skb is passed in directly from the kernel,
* we take responsibility for the reference */
/* If an SKB is passed in directly from the kernel,
* we take responsibility for the reference. */
ieee80211_skb_track(skb);
/* NB: parent must be up and running */
/* NB: parent must be up and running. */
if ((parent->flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
goto bad;
/*
* No data frames go out unless we're running.
*/
/* No data frames go out unless we're running. */
if (vap->iv_state != IEEE80211_S_RUN) {
IEEE80211_DPRINTF(vap, IEEE80211_MSG_OUTPUT,
"%s: ignore data packet, state %u\n",
@ -240,10 +239,8 @@ ieee80211_hardstart(struct sk_buff *skb, struct net_device *dev)
/* Cancel any running BG scan */
ieee80211_cancel_scan(vap);
/*
* Find the node for the destination so we can do
* things like power save.
*/
/* Find the node for the destination so we can do
* things like power save. */
eh = (struct ether_header *)skb->data;
if (vap->iv_opmode == IEEE80211_M_WDS)
ni = ieee80211_find_txnode(vap, vap->wds_mac);
@ -254,7 +251,7 @@ ieee80211_hardstart(struct sk_buff *skb, struct net_device *dev)
goto bad;
}
/* calculate priority so drivers can find the TX queue */
/* Calculate priority so drivers can find the TX queue. */
if (ieee80211_classify(ni, skb)) {
IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni,
"%s: discard, classification failure", __func__);
@ -263,7 +260,7 @@ ieee80211_hardstart(struct sk_buff *skb, struct net_device *dev)
SKB_NI(skb) = ieee80211_ref_node(ni);
/* power-save checks */
/* Power-save checks. */
if (WME_UAPSD_AC_CAN_TRIGGER(skb->priority, ni)) {
/* U-APSD power save queue */
/* XXXAPSD: assuming triggerable means deliverable */
@ -289,7 +286,7 @@ ieee80211_hardstart(struct sk_buff *skb, struct net_device *dev)
#ifdef IEEE80211_DEBUG_REFCNT
M_FLAG_SET(skb1, M_SKB_TRACKED);
#endif /* #ifdef IEEE80211_DEBUG_REFCNT */
SKB_CB(skb1)->ni = ieee80211_find_txnode(vap->iv_xrvap,
SKB_NI(skb1) = ieee80211_find_txnode(vap->iv_xrvap,
eh->ether_dhost);
/* Ignore this return code. */
ieee80211_parent_queue_xmit(skb1);
@ -309,9 +306,8 @@ bad:
}
/*
* skb is consumed in all cases
* SKB is consumed in all cases.
*/
void ieee80211_parent_queue_xmit(struct sk_buff *skb) {
struct ieee80211vap *vap = skb->dev->priv;

View File

@ -226,8 +226,8 @@ ieee80211_pwrsave(struct sk_buff *skb)
if (ieee80211_msg_dumppkts(vap))
ieee80211_dump_pkt(ni->ni_ic, skb->data, skb->len, -1, -1);
#endif
if (SKB_CB(skb)->ni != NULL)
ieee80211_unref_node(&SKB_CB(skb)->ni);
if (SKB_NI(skb) != NULL)
ieee80211_unref_node(&SKB_NI(skb));
ieee80211_dev_kfree_skb(&skb);
return NETDEV_TX_OK;
}

View File

@ -199,11 +199,11 @@ ref_skb(struct sk_buff *skb,
static void skb_destructor(struct sk_buff* skb) {
/* Report any node reference leaks - caused by kernel net device queue
* dropping buffer, rather than passing it to the driver. */
if (SKB_CB(skb)->ni != NULL) {
if (SKB_NI(skb) != NULL) {
printk(KERN_ERR "%s:%d - ERROR: non-NULL node pointer in %p, %p<" MAC_FMT ">! "
"Leak Detected!\n",
__func__, __LINE__,
skb, SKB_CB(skb)->ni, MAC_ADDR(SKB_CB(skb)->ni->ni_macaddr));
skb, SKB_NI(skb), MAC_ADDR(SKB_NI(skb)->ni_macaddr));
dump_stack();
}
if (SKB_CB(skb)->next_destructor != NULL) {

View File

@ -92,8 +92,8 @@ void ieee80211_dev_kfree_skb(struct sk_buff** pskb);
static inline void ieee80211_skb_copy_noderef(struct sk_buff *src,
struct sk_buff *dst)
{
if (SKB_CB(src)->ni != NULL)
SKB_CB(dst)->ni = ieee80211_ref_node(SKB_CB(src)->ni);
if (SKB_NI(src) != NULL)
SKB_NI(dst) = ieee80211_ref_node(SKB_NI(src));
}
/*