Merge branch 'linus' into x86/urgent
[linux-2.6-block.git] / net / sched / act_ipt.c
index fee5282637cc0b3913d04364a9f7ffe00f34d242..d1263b3c96c37836a99379ab6911f84518eeea8e 100644 (file)
@@ -92,6 +92,13 @@ static int tcf_ipt_release(struct tcf_ipt *ipt, int bind)
        return ret;
 }
 
+static const struct nla_policy ipt_policy[TCA_IPT_MAX + 1] = {
+       [TCA_IPT_TABLE] = { .type = NLA_STRING, .len = IFNAMSIZ },
+       [TCA_IPT_HOOK]  = { .type = NLA_U32 },
+       [TCA_IPT_INDEX] = { .type = NLA_U32 },
+       [TCA_IPT_TARG]  = { .len = sizeof(struct ipt_entry_target) },
+};
+
 static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
                        struct tc_action *a, int ovr, int bind)
 {
@@ -104,22 +111,24 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
        u32 hook = 0;
        u32 index = 0;
 
-       if (nla == NULL || nla_parse_nested(tb, TCA_IPT_MAX, nla, NULL) < 0)
+       if (nla == NULL)
                return -EINVAL;
 
-       if (tb[TCA_IPT_HOOK] == NULL ||
-           nla_len(tb[TCA_IPT_HOOK]) < sizeof(u32))
+       err = nla_parse_nested(tb, TCA_IPT_MAX, nla, ipt_policy);
+       if (err < 0)
+               return err;
+
+       if (tb[TCA_IPT_HOOK] == NULL)
                return -EINVAL;
-       if (tb[TCA_IPT_TARG] == NULL ||
-           nla_len(tb[TCA_IPT_TARG]) < sizeof(*t))
+       if (tb[TCA_IPT_TARG] == NULL)
                return -EINVAL;
+
        td = (struct ipt_entry_target *)nla_data(tb[TCA_IPT_TARG]);
        if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size)
                return -EINVAL;
 
-       if (tb[TCA_IPT_INDEX] != NULL &&
-           nla_len(tb[TCA_IPT_INDEX]) >= sizeof(u32))
-               index = *(u32 *)nla_data(tb[TCA_IPT_INDEX]);
+       if (tb[TCA_IPT_INDEX] != NULL)
+               index = nla_get_u32(tb[TCA_IPT_INDEX]);
 
        pc = tcf_hash_check(index, a, bind, &ipt_hash_info);
        if (!pc) {
@@ -136,7 +145,7 @@ static int tcf_ipt_init(struct nlattr *nla, struct nlattr *est,
        }
        ipt = to_ipt(pc);
 
-       hook = *(u32 *)nla_data(tb[TCA_IPT_HOOK]);
+       hook = nla_get_u32(tb[TCA_IPT_HOOK]);
 
        err = -ENOMEM;
        tname = kmalloc(IFNAMSIZ, GFP_KERNEL);
@@ -196,7 +205,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
        spin_lock(&ipt->tcf_lock);
 
        ipt->tcf_tm.lastuse = jiffies;
-       ipt->tcf_bstats.bytes += skb->len;
+       ipt->tcf_bstats.bytes += qdisc_pkt_len(skb);
        ipt->tcf_bstats.packets++;
 
        /* yes, we have to worry about both in and out dev
@@ -250,10 +259,10 @@ static int tcf_ipt_dump(struct sk_buff *skb, struct tc_action *a, int bind, int
        strcpy(t->u.user.name, ipt->tcfi_t->u.kernel.target->name);
 
        NLA_PUT(skb, TCA_IPT_TARG, ipt->tcfi_t->u.user.target_size, t);
-       NLA_PUT(skb, TCA_IPT_INDEX, 4, &ipt->tcf_index);
-       NLA_PUT(skb, TCA_IPT_HOOK, 4, &ipt->tcfi_hook);
+       NLA_PUT_U32(skb, TCA_IPT_INDEX, ipt->tcf_index);
+       NLA_PUT_U32(skb, TCA_IPT_HOOK, ipt->tcfi_hook);
        NLA_PUT(skb, TCA_IPT_CNT, sizeof(struct tc_cnt), &c);
-       NLA_PUT(skb, TCA_IPT_TABLE, IFNAMSIZ, ipt->tcfi_tname);
+       NLA_PUT_STRING(skb, TCA_IPT_TABLE, ipt->tcfi_tname);
        tm.install = jiffies_to_clock_t(jiffies - ipt->tcf_tm.install);
        tm.lastuse = jiffies_to_clock_t(jiffies - ipt->tcf_tm.lastuse);
        tm.expires = jiffies_to_clock_t(ipt->tcf_tm.expires);