net_cls_act: Make act_simple use of netlink policy.

Convert to netlink helpers by using netlink policy validation.
As a side effect fixes a leak.

Signed-off-by: Jamal Hadi Salim <hadi@cyberus.ca>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Jamal Hadi Salim and committed by
David S. Miller
fa1b1cff 5ffc02a1

+16 -18
+16 -18
net/sched/act_simple.c
··· 6 6 * as published by the Free Software Foundation; either version 7 7 * 2 of the License, or (at your option) any later version. 8 8 * 9 - * Authors: Jamal Hadi Salim (2005) 9 + * Authors: Jamal Hadi Salim (2005-8) 10 10 * 11 11 */ 12 12 ··· 34 34 .lock = &simp_lock, 35 35 }; 36 36 37 + #define SIMP_MAX_DATA 32 37 38 static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res) 38 39 { 39 40 struct tcf_defact *d = a->priv; ··· 70 69 return ret; 71 70 } 72 71 73 - static int alloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) 72 + static int alloc_defdata(struct tcf_defact *d, char *defdata) 74 73 { 75 - d->tcfd_defdata = kmemdup(defdata, datalen, GFP_KERNEL); 74 + d->tcfd_defdata = kstrndup(defdata, SIMP_MAX_DATA, GFP_KERNEL); 76 75 if (unlikely(!d->tcfd_defdata)) 77 76 return -ENOMEM; 78 - d->tcfd_datalen = datalen; 77 + 79 78 return 0; 80 79 } 81 80 82 - static int realloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) 81 + static int realloc_defdata(struct tcf_defact *d, char *defdata) 83 82 { 84 83 kfree(d->tcfd_defdata); 85 - return alloc_defdata(d, datalen, defdata); 84 + return alloc_defdata(d, defdata); 86 85 } 87 86 88 87 static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = { 89 88 [TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) }, 89 + [TCA_DEF_DATA] = { .type = NLA_STRING, .len = SIMP_MAX_DATA }, 90 90 }; 91 91 92 92 static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, ··· 97 95 struct tc_defact *parm; 98 96 struct tcf_defact *d; 99 97 struct tcf_common *pc; 100 - void *defdata; 101 - u32 datalen = 0; 98 + char *defdata; 102 99 int ret = 0, err; 103 100 104 101 if (nla == NULL) 105 102 return -EINVAL; 106 103 107 - err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL); 104 + err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy); 108 105 if (err < 0) 109 106 return err; 110 107 111 108 if (tb[TCA_DEF_PARMS] == NULL) 112 109 return -EINVAL; 113 110 114 - parm = nla_data(tb[TCA_DEF_PARMS]); 115 - defdata = nla_data(tb[TCA_DEF_DATA]); 116 - if (defdata == NULL) 111 + if (tb[TCA_DEF_DATA] == NULL) 117 112 return -EINVAL; 118 113 119 - datalen = nla_len(tb[TCA_DEF_DATA]); 120 - if (datalen == 0) 121 - return -EINVAL; 114 + parm = nla_data(tb[TCA_DEF_PARMS]); 115 + defdata = nla_data(tb[TCA_DEF_DATA]); 122 116 123 117 pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); 124 118 if (!pc) { ··· 124 126 return -ENOMEM; 125 127 126 128 d = to_defact(pc); 127 - ret = alloc_defdata(d, datalen, defdata); 129 + ret = alloc_defdata(d, defdata); 128 130 if (ret < 0) { 129 131 kfree(pc); 130 132 return ret; ··· 136 138 tcf_simp_release(d, bind); 137 139 return -EEXIST; 138 140 } 139 - realloc_defdata(d, datalen, defdata); 141 + realloc_defdata(d, defdata); 140 142 } 141 143 142 144 spin_lock_bh(&d->tcf_lock); ··· 170 172 opt.bindcnt = d->tcf_bindcnt - bind; 171 173 opt.action = d->tcf_action; 172 174 NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt); 173 - NLA_PUT(skb, TCA_DEF_DATA, d->tcfd_datalen, d->tcfd_defdata); 175 + NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata); 174 176 t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install); 175 177 t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse); 176 178 t.expires = jiffies_to_clock_t(d->tcf_tm.expires);