diff options
-rw-r--r-- | net/sched/sch_netem.c | 58 |
1 files changed, 26 insertions, 32 deletions
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index a7b58df4546d..1a755799ffb8 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
@@ -407,13 +407,18 @@ static int get_corrupt(struct Qdisc *sch, const struct nlattr *attr) | |||
407 | static int netem_change(struct Qdisc *sch, struct nlattr *opt) | 407 | static int netem_change(struct Qdisc *sch, struct nlattr *opt) |
408 | { | 408 | { |
409 | struct netem_sched_data *q = qdisc_priv(sch); | 409 | struct netem_sched_data *q = qdisc_priv(sch); |
410 | struct nlattr *tb[TCA_NETEM_MAX + 1]; | ||
410 | struct tc_netem_qopt *qopt; | 411 | struct tc_netem_qopt *qopt; |
411 | int ret; | 412 | int ret; |
412 | 413 | ||
413 | if (opt == NULL || nla_len(opt) < sizeof(*qopt)) | 414 | if (opt == NULL) |
414 | return -EINVAL; | 415 | return -EINVAL; |
415 | 416 | ||
416 | qopt = nla_data(opt); | 417 | ret = nla_parse_nested_compat(tb, TCA_NETEM_MAX, opt, NULL, qopt, |
418 | sizeof(*qopt)); | ||
419 | if (ret < 0) | ||
420 | return ret; | ||
421 | |||
417 | ret = set_fifo_limit(q->qdisc, qopt->limit); | 422 | ret = set_fifo_limit(q->qdisc, qopt->limit); |
418 | if (ret) { | 423 | if (ret) { |
419 | pr_debug("netem: can't set fifo limit\n"); | 424 | pr_debug("netem: can't set fifo limit\n"); |
@@ -434,39 +439,28 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt) | |||
434 | if (q->gap) | 439 | if (q->gap) |
435 | q->reorder = ~0; | 440 | q->reorder = ~0; |
436 | 441 | ||
437 | /* Handle nested options after initial queue options. | 442 | if (tb[TCA_NETEM_CORR]) { |
438 | * Should have put all options in nested format but too late now. | 443 | ret = get_correlation(sch, tb[TCA_NETEM_CORR]); |
439 | */ | 444 | if (ret) |
440 | if (nla_len(opt) > sizeof(*qopt)) { | 445 | return ret; |
441 | struct nlattr *tb[TCA_NETEM_MAX + 1]; | 446 | } |
442 | if (nla_parse(tb, TCA_NETEM_MAX, | ||
443 | nla_data(opt) + sizeof(*qopt), | ||
444 | nla_len(opt) - sizeof(*qopt), NULL)) | ||
445 | return -EINVAL; | ||
446 | |||
447 | if (tb[TCA_NETEM_CORR]) { | ||
448 | ret = get_correlation(sch, tb[TCA_NETEM_CORR]); | ||
449 | if (ret) | ||
450 | return ret; | ||
451 | } | ||
452 | 447 | ||
453 | if (tb[TCA_NETEM_DELAY_DIST]) { | 448 | if (tb[TCA_NETEM_DELAY_DIST]) { |
454 | ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST]); | 449 | ret = get_dist_table(sch, tb[TCA_NETEM_DELAY_DIST]); |
455 | if (ret) | 450 | if (ret) |
456 | return ret; | 451 | return ret; |
457 | } | 452 | } |
458 | 453 | ||
459 | if (tb[TCA_NETEM_REORDER]) { | 454 | if (tb[TCA_NETEM_REORDER]) { |
460 | ret = get_reorder(sch, tb[TCA_NETEM_REORDER]); | 455 | ret = get_reorder(sch, tb[TCA_NETEM_REORDER]); |
461 | if (ret) | 456 | if (ret) |
462 | return ret; | 457 | return ret; |
463 | } | 458 | } |
464 | 459 | ||
465 | if (tb[TCA_NETEM_CORRUPT]) { | 460 | if (tb[TCA_NETEM_CORRUPT]) { |
466 | ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT]); | 461 | ret = get_corrupt(sch, tb[TCA_NETEM_CORRUPT]); |
467 | if (ret) | 462 | if (ret) |
468 | return ret; | 463 | return ret; |
469 | } | ||
470 | } | 464 | } |
471 | 465 | ||
472 | return 0; | 466 | return 0; |