diff options
author | Patrick McHardy <kaber@trash.net> | 2008-01-23 23:36:12 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:11:23 -0500 |
commit | 6fa8c0144b770dac941cf2c15053b6e24f046c8a (patch) | |
tree | 7c91cd0e9a98f0532df30a9d8549e2c76a3ce716 | |
parent | 27a3421e4821734bc19496faa77b380605dc3b23 (diff) |
[NET_SCHED]: Use nla_policy for attribute validation in classifiers
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/sched/cls_basic.c | 12 | ||||
-rw-r--r-- | net/sched/cls_fw.c | 17 | ||||
-rw-r--r-- | net/sched/cls_route.c | 19 | ||||
-rw-r--r-- | net/sched/cls_rsvp.h | 26 | ||||
-rw-r--r-- | net/sched/cls_tcindex.c | 31 | ||||
-rw-r--r-- | net/sched/cls_u32.c | 22 |
6 files changed, 59 insertions, 68 deletions
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 0c872a76c4b0..bfb4342ea88c 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c | |||
@@ -129,6 +129,11 @@ static int basic_delete(struct tcf_proto *tp, unsigned long arg) | |||
129 | return -ENOENT; | 129 | return -ENOENT; |
130 | } | 130 | } |
131 | 131 | ||
132 | static const struct nla_policy basic_policy[TCA_BASIC_MAX + 1] = { | ||
133 | [TCA_BASIC_CLASSID] = { .type = NLA_U32 }, | ||
134 | [TCA_BASIC_EMATCHES] = { .type = NLA_NESTED }, | ||
135 | }; | ||
136 | |||
132 | static inline int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f, | 137 | static inline int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f, |
133 | unsigned long base, struct nlattr **tb, | 138 | unsigned long base, struct nlattr **tb, |
134 | struct nlattr *est) | 139 | struct nlattr *est) |
@@ -137,10 +142,6 @@ static inline int basic_set_parms(struct tcf_proto *tp, struct basic_filter *f, | |||
137 | struct tcf_exts e; | 142 | struct tcf_exts e; |
138 | struct tcf_ematch_tree t; | 143 | struct tcf_ematch_tree t; |
139 | 144 | ||
140 | if (tb[TCA_BASIC_CLASSID]) | ||
141 | if (nla_len(tb[TCA_BASIC_CLASSID]) < sizeof(u32)) | ||
142 | return err; | ||
143 | |||
144 | err = tcf_exts_validate(tp, tb, est, &e, &basic_ext_map); | 145 | err = tcf_exts_validate(tp, tb, est, &e, &basic_ext_map); |
145 | if (err < 0) | 146 | if (err < 0) |
146 | return err; | 147 | return err; |
@@ -174,7 +175,8 @@ static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, | |||
174 | if (tca[TCA_OPTIONS] == NULL) | 175 | if (tca[TCA_OPTIONS] == NULL) |
175 | return -EINVAL; | 176 | return -EINVAL; |
176 | 177 | ||
177 | err = nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS], NULL); | 178 | err = nla_parse_nested(tb, TCA_BASIC_MAX, tca[TCA_OPTIONS], |
179 | basic_policy); | ||
178 | if (err < 0) | 180 | if (err < 0) |
179 | return err; | 181 | return err; |
180 | 182 | ||
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index b75696d67ec2..436a6e7c438e 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c | |||
@@ -186,6 +186,12 @@ out: | |||
186 | return -EINVAL; | 186 | return -EINVAL; |
187 | } | 187 | } |
188 | 188 | ||
189 | static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = { | ||
190 | [TCA_FW_CLASSID] = { .type = NLA_U32 }, | ||
191 | [TCA_FW_INDEV] = { .type = NLA_STRING, .len = IFNAMSIZ }, | ||
192 | [TCA_FW_MASK] = { .type = NLA_U32 }, | ||
193 | }; | ||
194 | |||
189 | static int | 195 | static int |
190 | fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, | 196 | fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, |
191 | struct nlattr **tb, struct nlattr **tca, unsigned long base) | 197 | struct nlattr **tb, struct nlattr **tca, unsigned long base) |
@@ -201,8 +207,6 @@ fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, | |||
201 | 207 | ||
202 | err = -EINVAL; | 208 | err = -EINVAL; |
203 | if (tb[TCA_FW_CLASSID]) { | 209 | if (tb[TCA_FW_CLASSID]) { |
204 | if (nla_len(tb[TCA_FW_CLASSID]) != sizeof(u32)) | ||
205 | goto errout; | ||
206 | f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); | 210 | f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); |
207 | tcf_bind_filter(tp, &f->res, base); | 211 | tcf_bind_filter(tp, &f->res, base); |
208 | } | 212 | } |
@@ -216,8 +220,6 @@ fw_change_attrs(struct tcf_proto *tp, struct fw_filter *f, | |||
216 | #endif /* CONFIG_NET_CLS_IND */ | 220 | #endif /* CONFIG_NET_CLS_IND */ |
217 | 221 | ||
218 | if (tb[TCA_FW_MASK]) { | 222 | if (tb[TCA_FW_MASK]) { |
219 | if (nla_len(tb[TCA_FW_MASK]) != sizeof(u32)) | ||
220 | goto errout; | ||
221 | mask = nla_get_u32(tb[TCA_FW_MASK]); | 223 | mask = nla_get_u32(tb[TCA_FW_MASK]); |
222 | if (mask != head->mask) | 224 | if (mask != head->mask) |
223 | goto errout; | 225 | goto errout; |
@@ -246,7 +248,7 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, | |||
246 | if (!opt) | 248 | if (!opt) |
247 | return handle ? -EINVAL : 0; | 249 | return handle ? -EINVAL : 0; |
248 | 250 | ||
249 | err = nla_parse_nested(tb, TCA_FW_MAX, opt, NULL); | 251 | err = nla_parse_nested(tb, TCA_FW_MAX, opt, fw_policy); |
250 | if (err < 0) | 252 | if (err < 0) |
251 | return err; | 253 | return err; |
252 | 254 | ||
@@ -261,11 +263,8 @@ static int fw_change(struct tcf_proto *tp, unsigned long base, | |||
261 | 263 | ||
262 | if (head == NULL) { | 264 | if (head == NULL) { |
263 | u32 mask = 0xFFFFFFFF; | 265 | u32 mask = 0xFFFFFFFF; |
264 | if (tb[TCA_FW_MASK]) { | 266 | if (tb[TCA_FW_MASK]) |
265 | if (nla_len(tb[TCA_FW_MASK]) != sizeof(u32)) | ||
266 | return -EINVAL; | ||
267 | mask = nla_get_u32(tb[TCA_FW_MASK]); | 267 | mask = nla_get_u32(tb[TCA_FW_MASK]); |
268 | } | ||
269 | 268 | ||
270 | head = kzalloc(sizeof(struct fw_head), GFP_KERNEL); | 269 | head = kzalloc(sizeof(struct fw_head), GFP_KERNEL); |
271 | if (head == NULL) | 270 | if (head == NULL) |
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index ae97238c57ad..f7e7d3955d28 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c | |||
@@ -323,6 +323,13 @@ static int route4_delete(struct tcf_proto *tp, unsigned long arg) | |||
323 | return 0; | 323 | return 0; |
324 | } | 324 | } |
325 | 325 | ||
326 | static const struct nla_policy route4_policy[TCA_ROUTE4_MAX + 1] = { | ||
327 | [TCA_ROUTE4_CLASSID] = { .type = NLA_U32 }, | ||
328 | [TCA_ROUTE4_TO] = { .type = NLA_U32 }, | ||
329 | [TCA_ROUTE4_FROM] = { .type = NLA_U32 }, | ||
330 | [TCA_ROUTE4_IIF] = { .type = NLA_U32 }, | ||
331 | }; | ||
332 | |||
326 | static int route4_set_parms(struct tcf_proto *tp, unsigned long base, | 333 | static int route4_set_parms(struct tcf_proto *tp, unsigned long base, |
327 | struct route4_filter *f, u32 handle, struct route4_head *head, | 334 | struct route4_filter *f, u32 handle, struct route4_head *head, |
328 | struct nlattr **tb, struct nlattr *est, int new) | 335 | struct nlattr **tb, struct nlattr *est, int new) |
@@ -339,15 +346,9 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, | |||
339 | return err; | 346 | return err; |
340 | 347 | ||
341 | err = -EINVAL; | 348 | err = -EINVAL; |
342 | if (tb[TCA_ROUTE4_CLASSID]) | ||
343 | if (nla_len(tb[TCA_ROUTE4_CLASSID]) < sizeof(u32)) | ||
344 | goto errout; | ||
345 | |||
346 | if (tb[TCA_ROUTE4_TO]) { | 349 | if (tb[TCA_ROUTE4_TO]) { |
347 | if (new && handle & 0x8000) | 350 | if (new && handle & 0x8000) |
348 | goto errout; | 351 | goto errout; |
349 | if (nla_len(tb[TCA_ROUTE4_TO]) < sizeof(u32)) | ||
350 | goto errout; | ||
351 | to = nla_get_u32(tb[TCA_ROUTE4_TO]); | 352 | to = nla_get_u32(tb[TCA_ROUTE4_TO]); |
352 | if (to > 0xFF) | 353 | if (to > 0xFF) |
353 | goto errout; | 354 | goto errout; |
@@ -357,15 +358,11 @@ static int route4_set_parms(struct tcf_proto *tp, unsigned long base, | |||
357 | if (tb[TCA_ROUTE4_FROM]) { | 358 | if (tb[TCA_ROUTE4_FROM]) { |
358 | if (tb[TCA_ROUTE4_IIF]) | 359 | if (tb[TCA_ROUTE4_IIF]) |
359 | goto errout; | 360 | goto errout; |
360 | if (nla_len(tb[TCA_ROUTE4_FROM]) < sizeof(u32)) | ||
361 | goto errout; | ||
362 | id = nla_get_u32(tb[TCA_ROUTE4_FROM]); | 361 | id = nla_get_u32(tb[TCA_ROUTE4_FROM]); |
363 | if (id > 0xFF) | 362 | if (id > 0xFF) |
364 | goto errout; | 363 | goto errout; |
365 | nhandle |= id << 16; | 364 | nhandle |= id << 16; |
366 | } else if (tb[TCA_ROUTE4_IIF]) { | 365 | } else if (tb[TCA_ROUTE4_IIF]) { |
367 | if (nla_len(tb[TCA_ROUTE4_IIF]) < sizeof(u32)) | ||
368 | goto errout; | ||
369 | id = nla_get_u32(tb[TCA_ROUTE4_IIF]); | 366 | id = nla_get_u32(tb[TCA_ROUTE4_IIF]); |
370 | if (id > 0x7FFF) | 367 | if (id > 0x7FFF) |
371 | goto errout; | 368 | goto errout; |
@@ -440,7 +437,7 @@ static int route4_change(struct tcf_proto *tp, unsigned long base, | |||
440 | if (opt == NULL) | 437 | if (opt == NULL) |
441 | return handle ? -EINVAL : 0; | 438 | return handle ? -EINVAL : 0; |
442 | 439 | ||
443 | err = nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, NULL); | 440 | err = nla_parse_nested(tb, TCA_ROUTE4_MAX, opt, route4_policy); |
444 | if (err < 0) | 441 | if (err < 0) |
445 | return err; | 442 | return err; |
446 | 443 | ||
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 61286a0f7a3e..7034ea4530e5 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h | |||
@@ -397,6 +397,15 @@ static u32 gen_tunnel(struct rsvp_head *data) | |||
397 | return 0; | 397 | return 0; |
398 | } | 398 | } |
399 | 399 | ||
400 | static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = { | ||
401 | [TCA_RSVP_CLASSID] = { .type = NLA_U32 }, | ||
402 | [TCA_RSVP_DST] = { .type = NLA_BINARY, | ||
403 | .len = RSVP_DST_LEN * sizeof(u32) }, | ||
404 | [TCA_RSVP_SRC] = { .type = NLA_BINARY, | ||
405 | .len = RSVP_DST_LEN * sizeof(u32) }, | ||
406 | [TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) }, | ||
407 | }; | ||
408 | |||
400 | static int rsvp_change(struct tcf_proto *tp, unsigned long base, | 409 | static int rsvp_change(struct tcf_proto *tp, unsigned long base, |
401 | u32 handle, | 410 | u32 handle, |
402 | struct nlattr **tca, | 411 | struct nlattr **tca, |
@@ -416,7 +425,7 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, | |||
416 | if (opt == NULL) | 425 | if (opt == NULL) |
417 | return handle ? -EINVAL : 0; | 426 | return handle ? -EINVAL : 0; |
418 | 427 | ||
419 | err = nla_parse_nested(tb, TCA_RSVP_MAX, opt, NULL); | 428 | err = nla_parse_nested(tb, TCA_RSVP_MAX, opt, rsvp_policy); |
420 | if (err < 0) | 429 | if (err < 0) |
421 | return err; | 430 | return err; |
422 | 431 | ||
@@ -452,30 +461,17 @@ static int rsvp_change(struct tcf_proto *tp, unsigned long base, | |||
452 | 461 | ||
453 | h2 = 16; | 462 | h2 = 16; |
454 | if (tb[TCA_RSVP_SRC-1]) { | 463 | if (tb[TCA_RSVP_SRC-1]) { |
455 | err = -EINVAL; | ||
456 | if (nla_len(tb[TCA_RSVP_SRC-1]) != sizeof(f->src)) | ||
457 | goto errout; | ||
458 | memcpy(f->src, nla_data(tb[TCA_RSVP_SRC-1]), sizeof(f->src)); | 464 | memcpy(f->src, nla_data(tb[TCA_RSVP_SRC-1]), sizeof(f->src)); |
459 | h2 = hash_src(f->src); | 465 | h2 = hash_src(f->src); |
460 | } | 466 | } |
461 | if (tb[TCA_RSVP_PINFO-1]) { | 467 | if (tb[TCA_RSVP_PINFO-1]) { |
462 | err = -EINVAL; | ||
463 | if (nla_len(tb[TCA_RSVP_PINFO-1]) < sizeof(struct tc_rsvp_pinfo)) | ||
464 | goto errout; | ||
465 | pinfo = nla_data(tb[TCA_RSVP_PINFO-1]); | 468 | pinfo = nla_data(tb[TCA_RSVP_PINFO-1]); |
466 | f->spi = pinfo->spi; | 469 | f->spi = pinfo->spi; |
467 | f->tunnelhdr = pinfo->tunnelhdr; | 470 | f->tunnelhdr = pinfo->tunnelhdr; |
468 | } | 471 | } |
469 | if (tb[TCA_RSVP_CLASSID-1]) { | 472 | if (tb[TCA_RSVP_CLASSID-1]) |
470 | err = -EINVAL; | ||
471 | if (nla_len(tb[TCA_RSVP_CLASSID-1]) != 4) | ||
472 | goto errout; | ||
473 | f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]); | 473 | f->res.classid = nla_get_u32(tb[TCA_RSVP_CLASSID-1]); |
474 | } | ||
475 | 474 | ||
476 | err = -EINVAL; | ||
477 | if (nla_len(tb[TCA_RSVP_DST-1]) != sizeof(f->src)) | ||
478 | goto errout; | ||
479 | dst = nla_data(tb[TCA_RSVP_DST-1]); | 475 | dst = nla_data(tb[TCA_RSVP_DST-1]); |
480 | h1 = hash_dst(dst, pinfo ? pinfo->protocol : 0, pinfo ? pinfo->tunnelid : 0); | 476 | h1 = hash_dst(dst, pinfo ? pinfo->protocol : 0, pinfo ? pinfo->tunnelid : 0); |
481 | 477 | ||
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 28098564b4d7..ee60b2d1705d 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c | |||
@@ -193,6 +193,14 @@ valid_perfect_hash(struct tcindex_data *p) | |||
193 | return p->hash > (p->mask >> p->shift); | 193 | return p->hash > (p->mask >> p->shift); |
194 | } | 194 | } |
195 | 195 | ||
196 | static const struct nla_policy tcindex_policy[TCA_TCINDEX_MAX + 1] = { | ||
197 | [TCA_TCINDEX_HASH] = { .type = NLA_U32 }, | ||
198 | [TCA_TCINDEX_MASK] = { .type = NLA_U16 }, | ||
199 | [TCA_TCINDEX_SHIFT] = { .type = NLA_U32 }, | ||
200 | [TCA_TCINDEX_FALL_THROUGH] = { .type = NLA_U32 }, | ||
201 | [TCA_TCINDEX_CLASSID] = { .type = NLA_U32 }, | ||
202 | }; | ||
203 | |||
196 | static int | 204 | static int |
197 | tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, | 205 | tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, |
198 | struct tcindex_data *p, struct tcindex_filter_result *r, | 206 | struct tcindex_data *p, struct tcindex_filter_result *r, |
@@ -217,24 +225,14 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, | |||
217 | else | 225 | else |
218 | memset(&cr, 0, sizeof(cr)); | 226 | memset(&cr, 0, sizeof(cr)); |
219 | 227 | ||
220 | err = -EINVAL; | 228 | if (tb[TCA_TCINDEX_HASH]) |
221 | if (tb[TCA_TCINDEX_HASH]) { | ||
222 | if (nla_len(tb[TCA_TCINDEX_HASH]) < sizeof(u32)) | ||
223 | goto errout; | ||
224 | cp.hash = nla_get_u32(tb[TCA_TCINDEX_HASH]); | 229 | cp.hash = nla_get_u32(tb[TCA_TCINDEX_HASH]); |
225 | } | ||
226 | 230 | ||
227 | if (tb[TCA_TCINDEX_MASK]) { | 231 | if (tb[TCA_TCINDEX_MASK]) |
228 | if (nla_len(tb[TCA_TCINDEX_MASK]) < sizeof(u16)) | ||
229 | goto errout; | ||
230 | cp.mask = nla_get_u16(tb[TCA_TCINDEX_MASK]); | 232 | cp.mask = nla_get_u16(tb[TCA_TCINDEX_MASK]); |
231 | } | ||
232 | 233 | ||
233 | if (tb[TCA_TCINDEX_SHIFT]) { | 234 | if (tb[TCA_TCINDEX_SHIFT]) |
234 | if (nla_len(tb[TCA_TCINDEX_SHIFT]) < sizeof(int)) | ||
235 | goto errout; | ||
236 | cp.shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]); | 235 | cp.shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]); |
237 | } | ||
238 | 236 | ||
239 | err = -EBUSY; | 237 | err = -EBUSY; |
240 | /* Hash already allocated, make sure that we still meet the | 238 | /* Hash already allocated, make sure that we still meet the |
@@ -248,11 +246,8 @@ tcindex_set_parms(struct tcf_proto *tp, unsigned long base, u32 handle, | |||
248 | goto errout; | 246 | goto errout; |
249 | 247 | ||
250 | err = -EINVAL; | 248 | err = -EINVAL; |
251 | if (tb[TCA_TCINDEX_FALL_THROUGH]) { | 249 | if (tb[TCA_TCINDEX_FALL_THROUGH]) |
252 | if (nla_len(tb[TCA_TCINDEX_FALL_THROUGH]) < sizeof(u32)) | ||
253 | goto errout; | ||
254 | cp.fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]); | 250 | cp.fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]); |
255 | } | ||
256 | 251 | ||
257 | if (!cp.hash) { | 252 | if (!cp.hash) { |
258 | /* Hash not specified, use perfect hash if the upper limit | 253 | /* Hash not specified, use perfect hash if the upper limit |
@@ -358,7 +353,7 @@ tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle, | |||
358 | if (!opt) | 353 | if (!opt) |
359 | return 0; | 354 | return 0; |
360 | 355 | ||
361 | err = nla_parse_nested(tb, TCA_TCINDEX_MAX, opt, NULL); | 356 | err = nla_parse_nested(tb, TCA_TCINDEX_MAX, opt, tcindex_policy); |
362 | if (err < 0) | 357 | if (err < 0) |
363 | return err; | 358 | return err; |
364 | 359 | ||
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index a4e72e8a882f..e8a775689123 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
@@ -460,6 +460,16 @@ static u32 gen_new_kid(struct tc_u_hnode *ht, u32 handle) | |||
460 | return handle|(i>0xFFF ? 0xFFF : i); | 460 | return handle|(i>0xFFF ? 0xFFF : i); |
461 | } | 461 | } |
462 | 462 | ||
463 | static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = { | ||
464 | [TCA_U32_CLASSID] = { .type = NLA_U32 }, | ||
465 | [TCA_U32_HASH] = { .type = NLA_U32 }, | ||
466 | [TCA_U32_LINK] = { .type = NLA_U32 }, | ||
467 | [TCA_U32_DIVISOR] = { .type = NLA_U32 }, | ||
468 | [TCA_U32_SEL] = { .len = sizeof(struct tc_u32_sel) }, | ||
469 | [TCA_U32_INDEV] = { .type = NLA_STRING, .len = IFNAMSIZ }, | ||
470 | [TCA_U32_MARK] = { .len = sizeof(struct tc_u32_mark) }, | ||
471 | }; | ||
472 | |||
463 | static int u32_set_parms(struct tcf_proto *tp, unsigned long base, | 473 | static int u32_set_parms(struct tcf_proto *tp, unsigned long base, |
464 | struct tc_u_hnode *ht, | 474 | struct tc_u_hnode *ht, |
465 | struct tc_u_knode *n, struct nlattr **tb, | 475 | struct tc_u_knode *n, struct nlattr **tb, |
@@ -531,7 +541,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, | |||
531 | if (opt == NULL) | 541 | if (opt == NULL) |
532 | return handle ? -EINVAL : 0; | 542 | return handle ? -EINVAL : 0; |
533 | 543 | ||
534 | err = nla_parse_nested(tb, TCA_U32_MAX, opt, NULL); | 544 | err = nla_parse_nested(tb, TCA_U32_MAX, opt, u32_policy); |
535 | if (err < 0) | 545 | if (err < 0) |
536 | return err; | 546 | return err; |
537 | 547 | ||
@@ -593,8 +603,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, | |||
593 | } else | 603 | } else |
594 | handle = gen_new_kid(ht, htid); | 604 | handle = gen_new_kid(ht, htid); |
595 | 605 | ||
596 | if (tb[TCA_U32_SEL] == NULL || | 606 | if (tb[TCA_U32_SEL] == NULL) |
597 | nla_len(tb[TCA_U32_SEL]) < sizeof(struct tc_u32_sel)) | ||
598 | return -EINVAL; | 607 | return -EINVAL; |
599 | 608 | ||
600 | s = nla_data(tb[TCA_U32_SEL]); | 609 | s = nla_data(tb[TCA_U32_SEL]); |
@@ -620,13 +629,6 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, | |||
620 | if (tb[TCA_U32_MARK]) { | 629 | if (tb[TCA_U32_MARK]) { |
621 | struct tc_u32_mark *mark; | 630 | struct tc_u32_mark *mark; |
622 | 631 | ||
623 | if (nla_len(tb[TCA_U32_MARK]) < sizeof(struct tc_u32_mark)) { | ||
624 | #ifdef CONFIG_CLS_U32_PERF | ||
625 | kfree(n->pf); | ||
626 | #endif | ||
627 | kfree(n); | ||
628 | return -EINVAL; | ||
629 | } | ||
630 | mark = nla_data(tb[TCA_U32_MARK]); | 632 | mark = nla_data(tb[TCA_U32_MARK]); |
631 | memcpy(&n->mark, mark, sizeof(struct tc_u32_mark)); | 633 | memcpy(&n->mark, mark, sizeof(struct tc_u32_mark)); |
632 | n->mark.success = 0; | 634 | n->mark.success = 0; |