Commit feed1f17 authored by Changli Gao's avatar Changli Gao Committed by David S. Miller

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: default avatarChangli Gao <xiaosuo@gmail.com>
Signed-off-by: default avatarJamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent b2a5decd
...@@ -148,47 +148,39 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a, ...@@ -148,47 +148,39 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,
{ {
struct tcf_mirred *m = a->priv; struct tcf_mirred *m = a->priv;
struct net_device *dev; struct net_device *dev;
struct sk_buff *skb2 = NULL; struct sk_buff *skb2;
u32 at = G_TC_AT(skb->tc_verd); u32 at;
int retval, err = 1;
spin_lock(&m->tcf_lock); spin_lock(&m->tcf_lock);
dev = m->tcfm_dev;
m->tcf_tm.lastuse = jiffies; m->tcf_tm.lastuse = jiffies;
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 out;
}
if (!(dev->flags&IFF_UP) ) { dev = m->tcfm_dev;
if (!(dev->flags & IFF_UP)) {
if (net_ratelimit()) if (net_ratelimit())
printk("mirred to Houston: device %s is gone!\n", printk("mirred to Houston: device %s is gone!\n",
dev->name); dev->name);
bad_mirred: goto out;
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); skb2 = skb_act_clone(skb, GFP_ATOMIC);
if (skb2 == NULL) if (skb2 == NULL)
goto bad_mirred; goto out;
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;
}
m->tcf_bstats.bytes += qdisc_pkt_len(skb2); m->tcf_bstats.bytes += qdisc_pkt_len(skb2);
m->tcf_bstats.packets++; m->tcf_bstats.packets++;
if (!(at & AT_EGRESS)) at = G_TC_AT(skb->tc_verd);
if (!(at & AT_EGRESS)) {
if (m->tcfm_ok_push) if (m->tcfm_ok_push)
skb_push(skb2, skb2->dev->hard_header_len); skb_push(skb2, skb2->dev->hard_header_len);
}
/* mirror is always swallowed */ /* mirror is always swallowed */
if (m->tcfm_eaction != TCA_EGRESS_MIRROR) if (m->tcfm_eaction != TCA_EGRESS_MIRROR)
...@@ -197,8 +189,23 @@ bad_mirred: ...@@ -197,8 +189,23 @@ bad_mirred:
skb2->dev = dev; skb2->dev = dev;
skb2->iif = skb->dev->ifindex; skb2->iif = skb->dev->ifindex;
dev_queue_xmit(skb2); 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); 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) static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment