diff options
Diffstat (limited to 'net/sched/sch_dsmark.c')
-rw-r--r-- | net/sched/sch_dsmark.c | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c index 40e06a6890da..f183ab768873 100644 --- a/net/sched/sch_dsmark.c +++ b/net/sched/sch_dsmark.c | |||
@@ -100,11 +100,11 @@ static void dsmark_put(struct Qdisc *sch, unsigned long cl) | |||
100 | } | 100 | } |
101 | 101 | ||
102 | static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, | 102 | static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, |
103 | struct rtattr **tca, unsigned long *arg) | 103 | struct nlattr **tca, unsigned long *arg) |
104 | { | 104 | { |
105 | struct dsmark_qdisc_data *p = qdisc_priv(sch); | 105 | struct dsmark_qdisc_data *p = qdisc_priv(sch); |
106 | struct rtattr *opt = tca[TCA_OPTIONS-1]; | 106 | struct nlattr *opt = tca[TCA_OPTIONS]; |
107 | struct rtattr *tb[TCA_DSMARK_MAX]; | 107 | struct nlattr *tb[TCA_DSMARK_MAX + 1]; |
108 | int err = -EINVAL; | 108 | int err = -EINVAL; |
109 | u8 mask = 0; | 109 | u8 mask = 0; |
110 | 110 | ||
@@ -113,24 +113,29 @@ static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, | |||
113 | 113 | ||
114 | if (!dsmark_valid_index(p, *arg)) { | 114 | if (!dsmark_valid_index(p, *arg)) { |
115 | err = -ENOENT; | 115 | err = -ENOENT; |
116 | goto rtattr_failure; | 116 | goto errout; |
117 | } | 117 | } |
118 | 118 | ||
119 | if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt)) | 119 | if (!opt || nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL)) |
120 | goto rtattr_failure; | 120 | goto errout; |
121 | |||
122 | if (tb[TCA_DSMARK_MASK-1]) | ||
123 | mask = RTA_GET_U8(tb[TCA_DSMARK_MASK-1]); | ||
124 | 121 | ||
125 | if (tb[TCA_DSMARK_VALUE-1]) | 122 | if (tb[TCA_DSMARK_MASK]) { |
126 | p->value[*arg-1] = RTA_GET_U8(tb[TCA_DSMARK_VALUE-1]); | 123 | if (nla_len(tb[TCA_DSMARK_MASK]) < sizeof(u8)) |
124 | goto errout; | ||
125 | mask = nla_get_u8(tb[TCA_DSMARK_MASK]); | ||
126 | } | ||
127 | if (tb[TCA_DSMARK_VALUE]) { | ||
128 | if (nla_len(tb[TCA_DSMARK_VALUE]) < sizeof(u8)) | ||
129 | goto errout; | ||
130 | p->value[*arg-1] = nla_get_u8(tb[TCA_DSMARK_VALUE]); | ||
131 | } | ||
127 | 132 | ||
128 | if (tb[TCA_DSMARK_MASK-1]) | 133 | if (tb[TCA_DSMARK_MASK]) |
129 | p->mask[*arg-1] = mask; | 134 | p->mask[*arg-1] = mask; |
130 | 135 | ||
131 | err = 0; | 136 | err = 0; |
132 | 137 | ||
133 | rtattr_failure: | 138 | errout: |
134 | return err; | 139 | return err; |
135 | } | 140 | } |
136 | 141 | ||
@@ -335,10 +340,10 @@ static unsigned int dsmark_drop(struct Qdisc *sch) | |||
335 | return len; | 340 | return len; |
336 | } | 341 | } |
337 | 342 | ||
338 | static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) | 343 | static int dsmark_init(struct Qdisc *sch, struct nlattr *opt) |
339 | { | 344 | { |
340 | struct dsmark_qdisc_data *p = qdisc_priv(sch); | 345 | struct dsmark_qdisc_data *p = qdisc_priv(sch); |
341 | struct rtattr *tb[TCA_DSMARK_MAX]; | 346 | struct nlattr *tb[TCA_DSMARK_MAX + 1]; |
342 | int err = -EINVAL; | 347 | int err = -EINVAL; |
343 | u32 default_index = NO_DEFAULT_INDEX; | 348 | u32 default_index = NO_DEFAULT_INDEX; |
344 | u16 indices; | 349 | u16 indices; |
@@ -346,16 +351,21 @@ static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) | |||
346 | 351 | ||
347 | pr_debug("dsmark_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt); | 352 | pr_debug("dsmark_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt); |
348 | 353 | ||
349 | if (!opt || rtattr_parse_nested(tb, TCA_DSMARK_MAX, opt) < 0) | 354 | if (!opt || nla_parse_nested(tb, TCA_DSMARK_MAX, opt, NULL) < 0) |
350 | goto errout; | 355 | goto errout; |
351 | 356 | ||
352 | indices = RTA_GET_U16(tb[TCA_DSMARK_INDICES-1]); | 357 | if (nla_len(tb[TCA_DSMARK_INDICES]) < sizeof(u16)) |
358 | goto errout; | ||
359 | indices = nla_get_u16(tb[TCA_DSMARK_INDICES]); | ||
353 | 360 | ||
354 | if (hweight32(indices) != 1) | 361 | if (hweight32(indices) != 1) |
355 | goto errout; | 362 | goto errout; |
356 | 363 | ||
357 | if (tb[TCA_DSMARK_DEFAULT_INDEX-1]) | 364 | if (tb[TCA_DSMARK_DEFAULT_INDEX]) { |
358 | default_index = RTA_GET_U16(tb[TCA_DSMARK_DEFAULT_INDEX-1]); | 365 | if (nla_len(tb[TCA_DSMARK_DEFAULT_INDEX]) < sizeof(u16)) |
366 | goto errout; | ||
367 | default_index = nla_get_u16(tb[TCA_DSMARK_DEFAULT_INDEX]); | ||
368 | } | ||
359 | 369 | ||
360 | mask = kmalloc(indices * 2, GFP_KERNEL); | 370 | mask = kmalloc(indices * 2, GFP_KERNEL); |
361 | if (mask == NULL) { | 371 | if (mask == NULL) { |
@@ -371,7 +381,7 @@ static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) | |||
371 | 381 | ||
372 | p->indices = indices; | 382 | p->indices = indices; |
373 | p->default_index = default_index; | 383 | p->default_index = default_index; |
374 | p->set_tc_index = RTA_GET_FLAG(tb[TCA_DSMARK_SET_TC_INDEX-1]); | 384 | p->set_tc_index = nla_get_flag(tb[TCA_DSMARK_SET_TC_INDEX]); |
375 | 385 | ||
376 | p->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, sch->handle); | 386 | p->q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops, sch->handle); |
377 | if (p->q == NULL) | 387 | if (p->q == NULL) |
@@ -381,7 +391,6 @@ static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) | |||
381 | 391 | ||
382 | err = 0; | 392 | err = 0; |
383 | errout: | 393 | errout: |
384 | rtattr_failure: | ||
385 | return err; | 394 | return err; |
386 | } | 395 | } |
387 | 396 | ||
@@ -409,7 +418,7 @@ static int dsmark_dump_class(struct Qdisc *sch, unsigned long cl, | |||
409 | struct sk_buff *skb, struct tcmsg *tcm) | 418 | struct sk_buff *skb, struct tcmsg *tcm) |
410 | { | 419 | { |
411 | struct dsmark_qdisc_data *p = qdisc_priv(sch); | 420 | struct dsmark_qdisc_data *p = qdisc_priv(sch); |
412 | struct rtattr *opts = NULL; | 421 | struct nlattr *opts = NULL; |
413 | 422 | ||
414 | pr_debug("dsmark_dump_class(sch %p,[qdisc %p],class %ld\n", sch, p, cl); | 423 | pr_debug("dsmark_dump_class(sch %p,[qdisc %p],class %ld\n", sch, p, cl); |
415 | 424 | ||
@@ -419,34 +428,38 @@ static int dsmark_dump_class(struct Qdisc *sch, unsigned long cl, | |||
419 | tcm->tcm_handle = TC_H_MAKE(TC_H_MAJ(sch->handle), cl-1); | 428 | tcm->tcm_handle = TC_H_MAKE(TC_H_MAJ(sch->handle), cl-1); |
420 | tcm->tcm_info = p->q->handle; | 429 | tcm->tcm_info = p->q->handle; |
421 | 430 | ||
422 | opts = RTA_NEST(skb, TCA_OPTIONS); | 431 | opts = nla_nest_start(skb, TCA_OPTIONS); |
423 | RTA_PUT_U8(skb, TCA_DSMARK_MASK, p->mask[cl-1]); | 432 | if (opts == NULL) |
424 | RTA_PUT_U8(skb, TCA_DSMARK_VALUE, p->value[cl-1]); | 433 | goto nla_put_failure; |
434 | NLA_PUT_U8(skb, TCA_DSMARK_MASK, p->mask[cl-1]); | ||
435 | NLA_PUT_U8(skb, TCA_DSMARK_VALUE, p->value[cl-1]); | ||
425 | 436 | ||
426 | return RTA_NEST_END(skb, opts); | 437 | return nla_nest_end(skb, opts); |
427 | 438 | ||
428 | rtattr_failure: | 439 | nla_put_failure: |
429 | return RTA_NEST_CANCEL(skb, opts); | 440 | return nla_nest_cancel(skb, opts); |
430 | } | 441 | } |
431 | 442 | ||
432 | static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb) | 443 | static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb) |
433 | { | 444 | { |
434 | struct dsmark_qdisc_data *p = qdisc_priv(sch); | 445 | struct dsmark_qdisc_data *p = qdisc_priv(sch); |
435 | struct rtattr *opts = NULL; | 446 | struct nlattr *opts = NULL; |
436 | 447 | ||
437 | opts = RTA_NEST(skb, TCA_OPTIONS); | 448 | opts = nla_nest_start(skb, TCA_OPTIONS); |
438 | RTA_PUT_U16(skb, TCA_DSMARK_INDICES, p->indices); | 449 | if (opts == NULL) |
450 | goto nla_put_failure; | ||
451 | NLA_PUT_U16(skb, TCA_DSMARK_INDICES, p->indices); | ||
439 | 452 | ||
440 | if (p->default_index != NO_DEFAULT_INDEX) | 453 | if (p->default_index != NO_DEFAULT_INDEX) |
441 | RTA_PUT_U16(skb, TCA_DSMARK_DEFAULT_INDEX, p->default_index); | 454 | NLA_PUT_U16(skb, TCA_DSMARK_DEFAULT_INDEX, p->default_index); |
442 | 455 | ||
443 | if (p->set_tc_index) | 456 | if (p->set_tc_index) |
444 | RTA_PUT_FLAG(skb, TCA_DSMARK_SET_TC_INDEX); | 457 | NLA_PUT_FLAG(skb, TCA_DSMARK_SET_TC_INDEX); |
445 | 458 | ||
446 | return RTA_NEST_END(skb, opts); | 459 | return nla_nest_end(skb, opts); |
447 | 460 | ||
448 | rtattr_failure: | 461 | nla_put_failure: |
449 | return RTA_NEST_CANCEL(skb, opts); | 462 | return nla_nest_cancel(skb, opts); |
450 | } | 463 | } |
451 | 464 | ||
452 | static const struct Qdisc_class_ops dsmark_class_ops = { | 465 | static const struct Qdisc_class_ops dsmark_class_ops = { |