From feed1f17241d26261e77ddb5f2fc2a91a3c16739 Mon Sep 17 00:00:00 2001 From: Changli Gao Date: Tue, 17 Nov 2009 04:14:00 -0800 Subject: [PATCH] act_mirred: cleanup 1. don't let go back using goto. 2. don't call skb_act_clone() until it is necessary. 3. one exit of the critical context. Signed-off-by: Changli Gao Signed-off-by: Jamal Hadi Salim Signed-off-by: David S. Miller --- net/sched/act_mirred.c | 63 +++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 28 deletions(-) diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index b9aaab4e035..b812c20b66c 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c @@ -148,47 +148,39 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a, { struct tcf_mirred *m = a->priv; struct net_device *dev; - struct sk_buff *skb2 = NULL; - u32 at = G_TC_AT(skb->tc_verd); + struct sk_buff *skb2; + u32 at; + int retval, err = 1; spin_lock(&m->tcf_lock); - - dev = m->tcfm_dev; m->tcf_tm.lastuse = jiffies; - - if (!(dev->flags&IFF_UP) ) { - if (net_ratelimit()) - printk("mirred to Houston: device %s is gone!\n", - dev->name); -bad_mirred: - if (skb2 != NULL) - kfree_skb(skb2); - m->tcf_qstats.overlimits++; - m->tcf_bstats.bytes += qdisc_pkt_len(skb); - m->tcf_bstats.packets++; - spin_unlock(&m->tcf_lock); - /* should we be asking for packet to be dropped? - * may make sense for redirect case only - */ - return TC_ACT_SHOT; - } - - skb2 = skb_act_clone(skb, GFP_ATOMIC); - if (skb2 == NULL) - goto bad_mirred; if (m->tcfm_eaction != TCA_EGRESS_MIRROR && m->tcfm_eaction != TCA_EGRESS_REDIR) { if (net_ratelimit()) printk("tcf_mirred unknown action %d\n", m->tcfm_eaction); - goto bad_mirred; + goto out; } + dev = m->tcfm_dev; + if (!(dev->flags & IFF_UP)) { + if (net_ratelimit()) + printk("mirred to Houston: device %s is gone!\n", + dev->name); + goto out; + } + + skb2 = skb_act_clone(skb, GFP_ATOMIC); + if (skb2 == NULL) + goto out; + m->tcf_bstats.bytes += qdisc_pkt_len(skb2); m->tcf_bstats.packets++; - if (!(at & AT_EGRESS)) + at = G_TC_AT(skb->tc_verd); + if (!(at & AT_EGRESS)) { if (m->tcfm_ok_push) skb_push(skb2, skb2->dev->hard_header_len); + } /* mirror is always swallowed */ if (m->tcfm_eaction != TCA_EGRESS_MIRROR) @@ -197,8 +189,23 @@ bad_mirred: skb2->dev = dev; skb2->iif = skb->dev->ifindex; dev_queue_xmit(skb2); + err = 0; + +out: + if (err) { + m->tcf_qstats.overlimits++; + m->tcf_bstats.bytes += qdisc_pkt_len(skb); + m->tcf_bstats.packets++; + /* should we be asking for packet to be dropped? + * may make sense for redirect case only + */ + retval = TC_ACT_SHOT; + } else { + retval = m->tcf_action; + } spin_unlock(&m->tcf_lock); - return m->tcf_action; + + return retval; } static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)