Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / net / sched / act_simple.c
index 269ab51..8daa1eb 100644 (file)
@@ -41,7 +41,7 @@ static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result
 
        spin_lock(&d->tcf_lock);
        d->tcf_tm.lastuse = jiffies;
-       d->tcf_bstats.bytes += skb->len;
+       d->tcf_bstats.bytes += qdisc_pkt_len(skb);
        d->tcf_bstats.packets++;
 
        /* print policy string followed by _ then packet count
@@ -79,10 +79,14 @@ static int alloc_defdata(struct tcf_defact *d, char *defdata)
        return 0;
 }
 
-static int realloc_defdata(struct tcf_defact *d, char *defdata)
+static void reset_policy(struct tcf_defact *d, char *defdata,
+                        struct tc_defact *p)
 {
-       kfree(d->tcfd_defdata);
-       return alloc_defdata(d, defdata);
+       spin_lock_bh(&d->tcf_lock);
+       d->tcf_action = p->action;
+       memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
+       strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
+       spin_unlock_bh(&d->tcf_lock);
 }
 
 static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
@@ -120,8 +124,8 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
        if (!pc) {
                pc = tcf_hash_create(parm->index, est, a, sizeof(*d), bind,
                                     &simp_idx_gen, &simp_hash_info);
-               if (unlikely(!pc))
-                       return -ENOMEM;
+               if (IS_ERR(pc))
+                   return PTR_ERR(pc);
 
                d = to_defact(pc);
                ret = alloc_defdata(d, defdata);
@@ -129,6 +133,7 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
                        kfree(pc);
                        return ret;
                }
+               d->tcf_action = parm->action;
                ret = ACT_P_CREATED;
        } else {
                d = to_defact(pc);
@@ -136,13 +141,9 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
                        tcf_simp_release(d, bind);
                        return -EEXIST;
                }
-               realloc_defdata(d, defdata);
+               reset_policy(d, defdata, parm);
        }
 
-       spin_lock_bh(&d->tcf_lock);
-       d->tcf_action = parm->action;
-       spin_unlock_bh(&d->tcf_lock);
-
        if (ret == ACT_P_CREATED)
                tcf_hash_insert(pc, &simp_hash_info);
        return ret;