diff options
author | WANG Cong <xiyou.wangcong@gmail.com> | 2014-02-11 20:07:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-02-12 19:23:32 -0500 |
commit | 03701d6ebd1fd1871b5965356f6d8e90ebe53699 (patch) | |
tree | 1b24773d7fc90d14ecc682d407e1b2560e755c77 /net/sched/act_api.c | |
parent | 55334a5db5cd32b207ac697cec3ec8e078f345d4 (diff) |
net_sched: act: clean up tca_action_flush()
We could allocate tc_action on stack in tca_action_flush(),
since it is not large.
Also, we could use create_a() in tcf_action_get_1().
Cc: Jamal Hadi Salim <jhs@mojatatu.com>
Cc: David S. Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/act_api.c')
-rw-r--r-- | net/sched/act_api.c | 53 |
1 files changed, 23 insertions, 30 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 27e4c531ade1..8a5ba5add4bc 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -685,6 +685,20 @@ act_get_notify(struct net *net, u32 portid, struct nlmsghdr *n, | |||
685 | return rtnl_unicast(skb, net, portid); | 685 | return rtnl_unicast(skb, net, portid); |
686 | } | 686 | } |
687 | 687 | ||
688 | static struct tc_action *create_a(int i) | ||
689 | { | ||
690 | struct tc_action *act; | ||
691 | |||
692 | act = kzalloc(sizeof(*act), GFP_KERNEL); | ||
693 | if (act == NULL) { | ||
694 | pr_debug("create_a: failed to alloc!\n"); | ||
695 | return NULL; | ||
696 | } | ||
697 | act->order = i; | ||
698 | INIT_LIST_HEAD(&act->list); | ||
699 | return act; | ||
700 | } | ||
701 | |||
688 | static struct tc_action * | 702 | static struct tc_action * |
689 | tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid) | 703 | tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid) |
690 | { | 704 | { |
@@ -704,11 +718,10 @@ tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid) | |||
704 | index = nla_get_u32(tb[TCA_ACT_INDEX]); | 718 | index = nla_get_u32(tb[TCA_ACT_INDEX]); |
705 | 719 | ||
706 | err = -ENOMEM; | 720 | err = -ENOMEM; |
707 | a = kzalloc(sizeof(struct tc_action), GFP_KERNEL); | 721 | a = create_a(0); |
708 | if (a == NULL) | 722 | if (a == NULL) |
709 | goto err_out; | 723 | goto err_out; |
710 | 724 | ||
711 | INIT_LIST_HEAD(&a->list); | ||
712 | err = -EINVAL; | 725 | err = -EINVAL; |
713 | a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); | 726 | a->ops = tc_lookup_action(tb[TCA_ACT_KIND]); |
714 | if (a->ops == NULL) /* could happen in batch of actions */ | 727 | if (a->ops == NULL) /* could happen in batch of actions */ |
@@ -738,20 +751,6 @@ static void cleanup_a(struct list_head *actions) | |||
738 | } | 751 | } |
739 | } | 752 | } |
740 | 753 | ||
741 | static struct tc_action *create_a(int i) | ||
742 | { | ||
743 | struct tc_action *act; | ||
744 | |||
745 | act = kzalloc(sizeof(*act), GFP_KERNEL); | ||
746 | if (act == NULL) { | ||
747 | pr_debug("create_a: failed to alloc!\n"); | ||
748 | return NULL; | ||
749 | } | ||
750 | act->order = i; | ||
751 | INIT_LIST_HEAD(&act->list); | ||
752 | return act; | ||
753 | } | ||
754 | |||
755 | static int tca_action_flush(struct net *net, struct nlattr *nla, | 754 | static int tca_action_flush(struct net *net, struct nlattr *nla, |
756 | struct nlmsghdr *n, u32 portid) | 755 | struct nlmsghdr *n, u32 portid) |
757 | { | 756 | { |
@@ -763,18 +762,12 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, | |||
763 | struct nlattr *nest; | 762 | struct nlattr *nest; |
764 | struct nlattr *tb[TCA_ACT_MAX + 1]; | 763 | struct nlattr *tb[TCA_ACT_MAX + 1]; |
765 | struct nlattr *kind; | 764 | struct nlattr *kind; |
766 | struct tc_action *a = create_a(0); | 765 | struct tc_action a; |
767 | int err = -ENOMEM; | 766 | int err = -ENOMEM; |
768 | 767 | ||
769 | if (a == NULL) { | ||
770 | pr_debug("tca_action_flush: couldnt create tc_action\n"); | ||
771 | return err; | ||
772 | } | ||
773 | |||
774 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 768 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
775 | if (!skb) { | 769 | if (!skb) { |
776 | pr_debug("tca_action_flush: failed skb alloc\n"); | 770 | pr_debug("tca_action_flush: failed skb alloc\n"); |
777 | kfree(a); | ||
778 | return err; | 771 | return err; |
779 | } | 772 | } |
780 | 773 | ||
@@ -786,8 +779,10 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, | |||
786 | 779 | ||
787 | err = -EINVAL; | 780 | err = -EINVAL; |
788 | kind = tb[TCA_ACT_KIND]; | 781 | kind = tb[TCA_ACT_KIND]; |
789 | a->ops = tc_lookup_action(kind); | 782 | memset(&a, 0, sizeof(struct tc_action)); |
790 | if (a->ops == NULL) /*some idjot trying to flush unknown action */ | 783 | INIT_LIST_HEAD(&a.list); |
784 | a.ops = tc_lookup_action(kind); | ||
785 | if (a.ops == NULL) /*some idjot trying to flush unknown action */ | ||
791 | goto err_out; | 786 | goto err_out; |
792 | 787 | ||
793 | nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t), 0); | 788 | nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t), 0); |
@@ -802,7 +797,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, | |||
802 | if (nest == NULL) | 797 | if (nest == NULL) |
803 | goto out_module_put; | 798 | goto out_module_put; |
804 | 799 | ||
805 | err = a->ops->walk(skb, &dcb, RTM_DELACTION, a); | 800 | err = a.ops->walk(skb, &dcb, RTM_DELACTION, &a); |
806 | if (err < 0) | 801 | if (err < 0) |
807 | goto out_module_put; | 802 | goto out_module_put; |
808 | if (err == 0) | 803 | if (err == 0) |
@@ -812,8 +807,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, | |||
812 | 807 | ||
813 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; | 808 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; |
814 | nlh->nlmsg_flags |= NLM_F_ROOT; | 809 | nlh->nlmsg_flags |= NLM_F_ROOT; |
815 | module_put(a->ops->owner); | 810 | module_put(a.ops->owner); |
816 | kfree(a); | ||
817 | err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, | 811 | err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, |
818 | n->nlmsg_flags & NLM_F_ECHO); | 812 | n->nlmsg_flags & NLM_F_ECHO); |
819 | if (err > 0) | 813 | if (err > 0) |
@@ -822,11 +816,10 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, | |||
822 | return err; | 816 | return err; |
823 | 817 | ||
824 | out_module_put: | 818 | out_module_put: |
825 | module_put(a->ops->owner); | 819 | module_put(a.ops->owner); |
826 | err_out: | 820 | err_out: |
827 | noflush_out: | 821 | noflush_out: |
828 | kfree_skb(skb); | 822 | kfree_skb(skb); |
829 | kfree(a); | ||
830 | return err; | 823 | return err; |
831 | } | 824 | } |
832 | 825 | ||