aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJamal Hadi Salim <hadi@cyberus.ca>2008-05-05 03:22:35 -0400
committerDavid S. Miller <davem@davemloft.net>2008-05-05 03:22:35 -0400
commitfa1b1cff3d06550d23ef540c4f97ca83c021b473 (patch)
treed5e0a25956873293a3fc65b6538ee0b31fa6981b /net
parent5ffc02a158997b1eb91ade8d02bcf521ff79a218 (diff)
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>
Diffstat (limited to 'net')
-rw-r--r--net/sched/act_simple.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 64b2d136c78e..269ab51cd9b2 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -6,7 +6,7 @@
6 * as published by the Free Software Foundation; either version 6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version. 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,6 +34,7 @@ static struct tcf_hashinfo simp_hash_info = {
34 .lock = &simp_lock, 34 .lock = &simp_lock,
35}; 35};
36 36
37#define SIMP_MAX_DATA 32
37static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res) 38static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
38{ 39{
39 struct tcf_defact *d = a->priv; 40 struct tcf_defact *d = a->priv;
@@ -69,23 +70,24 @@ static int tcf_simp_release(struct tcf_defact *d, int bind)
69 return ret; 70 return ret;
70} 71}
71 72
72static int alloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) 73static int alloc_defdata(struct tcf_defact *d, char *defdata)
73{ 74{
74 d->tcfd_defdata = kmemdup(defdata, datalen, GFP_KERNEL); 75 d->tcfd_defdata = kstrndup(defdata, SIMP_MAX_DATA, GFP_KERNEL);
75 if (unlikely(!d->tcfd_defdata)) 76 if (unlikely(!d->tcfd_defdata))
76 return -ENOMEM; 77 return -ENOMEM;
77 d->tcfd_datalen = datalen; 78
78 return 0; 79 return 0;
79} 80}
80 81
81static int realloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) 82static int realloc_defdata(struct tcf_defact *d, char *defdata)
82{ 83{
83 kfree(d->tcfd_defdata); 84 kfree(d->tcfd_defdata);
84 return alloc_defdata(d, datalen, defdata); 85 return alloc_defdata(d, defdata);
85} 86}
86 87
87static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = { 88static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
88 [TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) }, 89 [TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) },
90 [TCA_DEF_DATA] = { .type = NLA_STRING, .len = SIMP_MAX_DATA },
89}; 91};
90 92
91static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, 93static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
@@ -95,28 +97,24 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
95 struct tc_defact *parm; 97 struct tc_defact *parm;
96 struct tcf_defact *d; 98 struct tcf_defact *d;
97 struct tcf_common *pc; 99 struct tcf_common *pc;
98 void *defdata; 100 char *defdata;
99 u32 datalen = 0;
100 int ret = 0, err; 101 int ret = 0, err;
101 102
102 if (nla == NULL) 103 if (nla == NULL)
103 return -EINVAL; 104 return -EINVAL;
104 105
105 err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL); 106 err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy);
106 if (err < 0) 107 if (err < 0)
107 return err; 108 return err;
108 109
109 if (tb[TCA_DEF_PARMS] == NULL) 110 if (tb[TCA_DEF_PARMS] == NULL)
110 return -EINVAL; 111 return -EINVAL;
111 112
112 parm = nla_data(tb[TCA_DEF_PARMS]); 113 if (tb[TCA_DEF_DATA] == NULL)
113 defdata = nla_data(tb[TCA_DEF_DATA]);
114 if (defdata == NULL)
115 return -EINVAL; 114 return -EINVAL;
116 115
117 datalen = nla_len(tb[TCA_DEF_DATA]); 116 parm = nla_data(tb[TCA_DEF_PARMS]);
118 if (datalen == 0) 117 defdata = nla_data(tb[TCA_DEF_DATA]);
119 return -EINVAL;
120 118
121 pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); 119 pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info);
122 if (!pc) { 120 if (!pc) {
@@ -126,7 +124,7 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
126 return -ENOMEM; 124 return -ENOMEM;
127 125
128 d = to_defact(pc); 126 d = to_defact(pc);
129 ret = alloc_defdata(d, datalen, defdata); 127 ret = alloc_defdata(d, defdata);
130 if (ret < 0) { 128 if (ret < 0) {
131 kfree(pc); 129 kfree(pc);
132 return ret; 130 return ret;
@@ -138,7 +136,7 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
138 tcf_simp_release(d, bind); 136 tcf_simp_release(d, bind);
139 return -EEXIST; 137 return -EEXIST;
140 } 138 }
141 realloc_defdata(d, datalen, defdata); 139 realloc_defdata(d, defdata);
142 } 140 }
143 141
144 spin_lock_bh(&d->tcf_lock); 142 spin_lock_bh(&d->tcf_lock);
@@ -172,7 +170,7 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
172 opt.bindcnt = d->tcf_bindcnt - bind; 170 opt.bindcnt = d->tcf_bindcnt - bind;
173 opt.action = d->tcf_action; 171 opt.action = d->tcf_action;
174 NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt); 172 NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
175 NLA_PUT(skb, TCA_DEF_DATA, d->tcfd_datalen, d->tcfd_defdata); 173 NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
176 t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install); 174 t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
177 t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse); 175 t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
178 t.expires = jiffies_to_clock_t(d->tcf_tm.expires); 176 t.expires = jiffies_to_clock_t(d->tcf_tm.expires);