aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_dsmark.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_dsmark.c')
-rw-r--r--net/sched/sch_dsmark.c85
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
102static int dsmark_change(struct Qdisc *sch, u32 classid, u32 parent, 102static 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
133rtattr_failure: 138errout:
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
338static int dsmark_init(struct Qdisc *sch, struct rtattr *opt) 343static 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;
383errout: 393errout:
384rtattr_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
428rtattr_failure: 439nla_put_failure:
429 return RTA_NEST_CANCEL(skb, opts); 440 return nla_nest_cancel(skb, opts);
430} 441}
431 442
432static int dsmark_dump(struct Qdisc *sch, struct sk_buff *skb) 443static 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
448rtattr_failure: 461nla_put_failure:
449 return RTA_NEST_CANCEL(skb, opts); 462 return nla_nest_cancel(skb, opts);
450} 463}
451 464
452static const struct Qdisc_class_ops dsmark_class_ops = { 465static const struct Qdisc_class_ops dsmark_class_ops = {