aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sched/sch_netem.c58
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)
407static int netem_change(struct Qdisc *sch, struct nlattr *opt) 407static 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;