aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/act_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/act_api.c')
-rw-r--r--net/sched/act_api.c77
1 files changed, 44 insertions, 33 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 64f5e328cee9..23b25f89e7e0 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -15,6 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/slab.h>
18#include <linux/skbuff.h> 19#include <linux/skbuff.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/kmod.h> 21#include <linux/kmod.h>
@@ -25,6 +26,11 @@
25#include <net/act_api.h> 26#include <net/act_api.h>
26#include <net/netlink.h> 27#include <net/netlink.h>
27 28
29static void tcf_common_free_rcu(struct rcu_head *head)
30{
31 kfree(container_of(head, struct tcf_common, tcfc_rcu));
32}
33
28void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo) 34void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
29{ 35{
30 unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask); 36 unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
@@ -37,7 +43,11 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
37 write_unlock_bh(hinfo->lock); 43 write_unlock_bh(hinfo->lock);
38 gen_kill_estimator(&p->tcfc_bstats, 44 gen_kill_estimator(&p->tcfc_bstats,
39 &p->tcfc_rate_est); 45 &p->tcfc_rate_est);
40 kfree(p); 46 /*
47 * gen_estimator est_timer() might access p->tcfc_lock
48 * or bstats, wait a RCU grace period before freeing p
49 */
50 call_rcu(&p->tcfc_rcu, tcf_common_free_rcu);
41 return; 51 return;
42 } 52 }
43 } 53 }
@@ -152,7 +162,7 @@ int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb,
152 } else if (type == RTM_GETACTION) { 162 } else if (type == RTM_GETACTION) {
153 return tcf_dump_walker(skb, cb, a, hinfo); 163 return tcf_dump_walker(skb, cb, a, hinfo);
154 } else { 164 } else {
155 printk("tcf_generic_walker: unknown action %d\n", type); 165 WARN(1, "tcf_generic_walker: unknown action %d\n", type);
156 return -EINVAL; 166 return -EINVAL;
157 } 167 }
158} 168}
@@ -402,8 +412,9 @@ void tcf_action_destroy(struct tc_action *act, int bind)
402 module_put(a->ops->owner); 412 module_put(a->ops->owner);
403 act = act->next; 413 act = act->next;
404 kfree(a); 414 kfree(a);
405 } else { /*FIXME: Remove later - catch insertion bugs*/ 415 } else {
406 printk("tcf_action_destroy: BUG? destroying NULL ops\n"); 416 /*FIXME: Remove later - catch insertion bugs*/
417 WARN(1, "tcf_action_destroy: BUG? destroying NULL ops\n");
407 act = act->next; 418 act = act->next;
408 kfree(a); 419 kfree(a);
409 } 420 }
@@ -667,7 +678,8 @@ nlmsg_failure:
667} 678}
668 679
669static int 680static int
670act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event) 681act_get_notify(struct net *net, u32 pid, struct nlmsghdr *n,
682 struct tc_action *a, int event)
671{ 683{
672 struct sk_buff *skb; 684 struct sk_buff *skb;
673 685
@@ -679,7 +691,7 @@ act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
679 return -EINVAL; 691 return -EINVAL;
680 } 692 }
681 693
682 return rtnl_unicast(skb, &init_net, pid); 694 return rtnl_unicast(skb, net, pid);
683} 695}
684 696
685static struct tc_action * 697static struct tc_action *
@@ -742,14 +754,15 @@ static struct tc_action *create_a(int i)
742 754
743 act = kzalloc(sizeof(*act), GFP_KERNEL); 755 act = kzalloc(sizeof(*act), GFP_KERNEL);
744 if (act == NULL) { 756 if (act == NULL) {
745 printk("create_a: failed to alloc!\n"); 757 pr_debug("create_a: failed to alloc!\n");
746 return NULL; 758 return NULL;
747 } 759 }
748 act->order = i; 760 act->order = i;
749 return act; 761 return act;
750} 762}
751 763
752static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid) 764static int tca_action_flush(struct net *net, struct nlattr *nla,
765 struct nlmsghdr *n, u32 pid)
753{ 766{
754 struct sk_buff *skb; 767 struct sk_buff *skb;
755 unsigned char *b; 768 unsigned char *b;
@@ -763,13 +776,13 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
763 int err = -ENOMEM; 776 int err = -ENOMEM;
764 777
765 if (a == NULL) { 778 if (a == NULL) {
766 printk("tca_action_flush: couldnt create tc_action\n"); 779 pr_debug("tca_action_flush: couldnt create tc_action\n");
767 return err; 780 return err;
768 } 781 }
769 782
770 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 783 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
771 if (!skb) { 784 if (!skb) {
772 printk("tca_action_flush: failed skb alloc\n"); 785 pr_debug("tca_action_flush: failed skb alloc\n");
773 kfree(a); 786 kfree(a);
774 return err; 787 return err;
775 } 788 }
@@ -808,7 +821,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
808 nlh->nlmsg_flags |= NLM_F_ROOT; 821 nlh->nlmsg_flags |= NLM_F_ROOT;
809 module_put(a->ops->owner); 822 module_put(a->ops->owner);
810 kfree(a); 823 kfree(a);
811 err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 824 err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
812 if (err > 0) 825 if (err > 0)
813 return 0; 826 return 0;
814 827
@@ -825,7 +838,8 @@ noflush_out:
825} 838}
826 839
827static int 840static int
828tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event) 841tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
842 u32 pid, int event)
829{ 843{
830 int i, ret; 844 int i, ret;
831 struct nlattr *tb[TCA_ACT_MAX_PRIO+1]; 845 struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
@@ -837,7 +851,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
837 851
838 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { 852 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
839 if (tb[1] != NULL) 853 if (tb[1] != NULL)
840 return tca_action_flush(tb[1], n, pid); 854 return tca_action_flush(net, tb[1], n, pid);
841 else 855 else
842 return -EINVAL; 856 return -EINVAL;
843 } 857 }
@@ -858,7 +872,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
858 } 872 }
859 873
860 if (event == RTM_GETACTION) 874 if (event == RTM_GETACTION)
861 ret = act_get_notify(pid, n, head, event); 875 ret = act_get_notify(net, pid, n, head, event);
862 else { /* delete */ 876 else { /* delete */
863 struct sk_buff *skb; 877 struct sk_buff *skb;
864 878
@@ -877,7 +891,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
877 891
878 /* now do the delete */ 892 /* now do the delete */
879 tcf_action_destroy(head, 0); 893 tcf_action_destroy(head, 0);
880 ret = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, 894 ret = rtnetlink_send(skb, net, pid, RTNLGRP_TC,
881 n->nlmsg_flags&NLM_F_ECHO); 895 n->nlmsg_flags&NLM_F_ECHO);
882 if (ret > 0) 896 if (ret > 0)
883 return 0; 897 return 0;
@@ -888,8 +902,8 @@ err:
888 return ret; 902 return ret;
889} 903}
890 904
891static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, 905static int tcf_add_notify(struct net *net, struct tc_action *a,
892 u16 flags) 906 u32 pid, u32 seq, int event, u16 flags)
893{ 907{
894 struct tcamsg *t; 908 struct tcamsg *t;
895 struct nlmsghdr *nlh; 909 struct nlmsghdr *nlh;
@@ -922,7 +936,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
922 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 936 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
923 NETLINK_CB(skb).dst_group = RTNLGRP_TC; 937 NETLINK_CB(skb).dst_group = RTNLGRP_TC;
924 938
925 err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, flags&NLM_F_ECHO); 939 err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
926 if (err > 0) 940 if (err > 0)
927 err = 0; 941 err = 0;
928 return err; 942 return err;
@@ -935,7 +949,8 @@ nlmsg_failure:
935 949
936 950
937static int 951static int
938tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr) 952tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
953 u32 pid, int ovr)
939{ 954{
940 int ret = 0; 955 int ret = 0;
941 struct tc_action *act; 956 struct tc_action *act;
@@ -953,7 +968,7 @@ tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr)
953 /* dump then free all the actions after update; inserted policy 968 /* dump then free all the actions after update; inserted policy
954 * stays intact 969 * stays intact
955 * */ 970 * */
956 ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags); 971 ret = tcf_add_notify(net, act, pid, seq, RTM_NEWACTION, n->nlmsg_flags);
957 for (a = act; a; a = act) { 972 for (a = act; a; a = act) {
958 act = a->next; 973 act = a->next;
959 kfree(a); 974 kfree(a);
@@ -969,15 +984,12 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
969 u32 pid = skb ? NETLINK_CB(skb).pid : 0; 984 u32 pid = skb ? NETLINK_CB(skb).pid : 0;
970 int ret = 0, ovr = 0; 985 int ret = 0, ovr = 0;
971 986
972 if (!net_eq(net, &init_net))
973 return -EINVAL;
974
975 ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); 987 ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL);
976 if (ret < 0) 988 if (ret < 0)
977 return ret; 989 return ret;
978 990
979 if (tca[TCA_ACT_TAB] == NULL) { 991 if (tca[TCA_ACT_TAB] == NULL) {
980 printk("tc_ctl_action: received NO action attribs\n"); 992 pr_notice("tc_ctl_action: received NO action attribs\n");
981 return -EINVAL; 993 return -EINVAL;
982 } 994 }
983 995
@@ -994,15 +1006,17 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
994 if (n->nlmsg_flags&NLM_F_REPLACE) 1006 if (n->nlmsg_flags&NLM_F_REPLACE)
995 ovr = 1; 1007 ovr = 1;
996replay: 1008replay:
997 ret = tcf_action_add(tca[TCA_ACT_TAB], n, pid, ovr); 1009 ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, pid, ovr);
998 if (ret == -EAGAIN) 1010 if (ret == -EAGAIN)
999 goto replay; 1011 goto replay;
1000 break; 1012 break;
1001 case RTM_DELACTION: 1013 case RTM_DELACTION:
1002 ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_DELACTION); 1014 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1015 pid, RTM_DELACTION);
1003 break; 1016 break;
1004 case RTM_GETACTION: 1017 case RTM_GETACTION:
1005 ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_GETACTION); 1018 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1019 pid, RTM_GETACTION);
1006 break; 1020 break;
1007 default: 1021 default:
1008 BUG(); 1022 BUG();
@@ -1042,7 +1056,6 @@ find_dump_kind(const struct nlmsghdr *n)
1042static int 1056static int
1043tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) 1057tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1044{ 1058{
1045 struct net *net = sock_net(skb->sk);
1046 struct nlmsghdr *nlh; 1059 struct nlmsghdr *nlh;
1047 unsigned char *b = skb_tail_pointer(skb); 1060 unsigned char *b = skb_tail_pointer(skb);
1048 struct nlattr *nest; 1061 struct nlattr *nest;
@@ -1052,11 +1065,8 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1052 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); 1065 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
1053 struct nlattr *kind = find_dump_kind(cb->nlh); 1066 struct nlattr *kind = find_dump_kind(cb->nlh);
1054 1067
1055 if (!net_eq(net, &init_net))
1056 return 0;
1057
1058 if (kind == NULL) { 1068 if (kind == NULL) {
1059 printk("tc_dump_action: action bad kind\n"); 1069 pr_info("tc_dump_action: action bad kind\n");
1060 return 0; 1070 return 0;
1061 } 1071 }
1062 1072
@@ -1069,7 +1079,8 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1069 a.ops = a_o; 1079 a.ops = a_o;
1070 1080
1071 if (a_o->walk == NULL) { 1081 if (a_o->walk == NULL) {
1072 printk("tc_dump_action: %s !capable of dumping table\n", a_o->kind); 1082 WARN(1, "tc_dump_action: %s !capable of dumping table\n",
1083 a_o->kind);
1073 goto nla_put_failure; 1084 goto nla_put_failure;
1074 } 1085 }
1075 1086