diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2016-09-01 12:33:46 -0400 |
commit | 0cb7bf61b1e9f05027de58c80f9b46a714d24e35 (patch) | |
tree | 41fb55cf62d07b425122f9a8b96412c0d8eb99c5 /net/sched/cls_api.c | |
parent | aa877175e7a9982233ed8f10cb4bfddd78d82741 (diff) | |
parent | 3eab887a55424fc2c27553b7bfe32330df83f7b8 (diff) |
Merge branch 'linus' into smp/hotplug
Apply upstream changes to avoid conflicts with pending patches.
Diffstat (limited to 'net/sched/cls_api.c')
-rw-r--r-- | net/sched/cls_api.c | 51 |
1 files changed, 36 insertions, 15 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 843a716a4303..a7c5645373af 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -541,8 +541,12 @@ out: | |||
541 | void tcf_exts_destroy(struct tcf_exts *exts) | 541 | void tcf_exts_destroy(struct tcf_exts *exts) |
542 | { | 542 | { |
543 | #ifdef CONFIG_NET_CLS_ACT | 543 | #ifdef CONFIG_NET_CLS_ACT |
544 | tcf_action_destroy(&exts->actions, TCA_ACT_UNBIND); | 544 | LIST_HEAD(actions); |
545 | INIT_LIST_HEAD(&exts->actions); | 545 | |
546 | tcf_exts_to_list(exts, &actions); | ||
547 | tcf_action_destroy(&actions, TCA_ACT_UNBIND); | ||
548 | kfree(exts->actions); | ||
549 | exts->nr_actions = 0; | ||
546 | #endif | 550 | #endif |
547 | } | 551 | } |
548 | EXPORT_SYMBOL(tcf_exts_destroy); | 552 | EXPORT_SYMBOL(tcf_exts_destroy); |
@@ -554,7 +558,6 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, | |||
554 | { | 558 | { |
555 | struct tc_action *act; | 559 | struct tc_action *act; |
556 | 560 | ||
557 | INIT_LIST_HEAD(&exts->actions); | ||
558 | if (exts->police && tb[exts->police]) { | 561 | if (exts->police && tb[exts->police]) { |
559 | act = tcf_action_init_1(net, tb[exts->police], rate_tlv, | 562 | act = tcf_action_init_1(net, tb[exts->police], rate_tlv, |
560 | "police", ovr, | 563 | "police", ovr, |
@@ -563,14 +566,20 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb, | |||
563 | return PTR_ERR(act); | 566 | return PTR_ERR(act); |
564 | 567 | ||
565 | act->type = exts->type = TCA_OLD_COMPAT; | 568 | act->type = exts->type = TCA_OLD_COMPAT; |
566 | list_add(&act->list, &exts->actions); | 569 | exts->actions[0] = act; |
570 | exts->nr_actions = 1; | ||
567 | } else if (exts->action && tb[exts->action]) { | 571 | } else if (exts->action && tb[exts->action]) { |
568 | int err; | 572 | LIST_HEAD(actions); |
573 | int err, i = 0; | ||
574 | |||
569 | err = tcf_action_init(net, tb[exts->action], rate_tlv, | 575 | err = tcf_action_init(net, tb[exts->action], rate_tlv, |
570 | NULL, ovr, | 576 | NULL, ovr, |
571 | TCA_ACT_BIND, &exts->actions); | 577 | TCA_ACT_BIND, &actions); |
572 | if (err) | 578 | if (err) |
573 | return err; | 579 | return err; |
580 | list_for_each_entry(act, &actions, list) | ||
581 | exts->actions[i++] = act; | ||
582 | exts->nr_actions = i; | ||
574 | } | 583 | } |
575 | } | 584 | } |
576 | #else | 585 | #else |
@@ -587,37 +596,49 @@ void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst, | |||
587 | struct tcf_exts *src) | 596 | struct tcf_exts *src) |
588 | { | 597 | { |
589 | #ifdef CONFIG_NET_CLS_ACT | 598 | #ifdef CONFIG_NET_CLS_ACT |
590 | LIST_HEAD(tmp); | 599 | struct tcf_exts old = *dst; |
600 | |||
591 | tcf_tree_lock(tp); | 601 | tcf_tree_lock(tp); |
592 | list_splice_init(&dst->actions, &tmp); | 602 | dst->nr_actions = src->nr_actions; |
593 | list_splice(&src->actions, &dst->actions); | 603 | dst->actions = src->actions; |
594 | dst->type = src->type; | 604 | dst->type = src->type; |
595 | tcf_tree_unlock(tp); | 605 | tcf_tree_unlock(tp); |
596 | tcf_action_destroy(&tmp, TCA_ACT_UNBIND); | 606 | |
607 | tcf_exts_destroy(&old); | ||
597 | #endif | 608 | #endif |
598 | } | 609 | } |
599 | EXPORT_SYMBOL(tcf_exts_change); | 610 | EXPORT_SYMBOL(tcf_exts_change); |
600 | 611 | ||
601 | #define tcf_exts_first_act(ext) \ | 612 | #ifdef CONFIG_NET_CLS_ACT |
602 | list_first_entry_or_null(&(exts)->actions, \ | 613 | static struct tc_action *tcf_exts_first_act(struct tcf_exts *exts) |
603 | struct tc_action, list) | 614 | { |
615 | if (exts->nr_actions == 0) | ||
616 | return NULL; | ||
617 | else | ||
618 | return exts->actions[0]; | ||
619 | } | ||
620 | #endif | ||
604 | 621 | ||
605 | int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts) | 622 | int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts) |
606 | { | 623 | { |
607 | #ifdef CONFIG_NET_CLS_ACT | 624 | #ifdef CONFIG_NET_CLS_ACT |
608 | struct nlattr *nest; | 625 | struct nlattr *nest; |
609 | 626 | ||
610 | if (exts->action && !list_empty(&exts->actions)) { | 627 | if (exts->action && exts->nr_actions) { |
611 | /* | 628 | /* |
612 | * again for backward compatible mode - we want | 629 | * again for backward compatible mode - we want |
613 | * to work with both old and new modes of entering | 630 | * to work with both old and new modes of entering |
614 | * tc data even if iproute2 was newer - jhs | 631 | * tc data even if iproute2 was newer - jhs |
615 | */ | 632 | */ |
616 | if (exts->type != TCA_OLD_COMPAT) { | 633 | if (exts->type != TCA_OLD_COMPAT) { |
634 | LIST_HEAD(actions); | ||
635 | |||
617 | nest = nla_nest_start(skb, exts->action); | 636 | nest = nla_nest_start(skb, exts->action); |
618 | if (nest == NULL) | 637 | if (nest == NULL) |
619 | goto nla_put_failure; | 638 | goto nla_put_failure; |
620 | if (tcf_action_dump(skb, &exts->actions, 0, 0) < 0) | 639 | |
640 | tcf_exts_to_list(exts, &actions); | ||
641 | if (tcf_action_dump(skb, &actions, 0, 0) < 0) | ||
621 | goto nla_put_failure; | 642 | goto nla_put_failure; |
622 | nla_nest_end(skb, nest); | 643 | nla_nest_end(skb, nest); |
623 | } else if (exts->police) { | 644 | } else if (exts->police) { |