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