aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/Kconfig5
-rw-r--r--net/sched/act_api.c46
-rw-r--r--net/sched/act_ipt.c1
-rw-r--r--net/sched/act_mirred.c1
-rw-r--r--net/sched/act_pedit.c1
-rw-r--r--net/sched/act_police.c1
-rw-r--r--net/sched/act_simple.c1
-rw-r--r--net/sched/cls_api.c31
-rw-r--r--net/sched/cls_basic.c1
-rw-r--r--net/sched/cls_cgroup.c37
-rw-r--r--net/sched/cls_flow.c1
-rw-r--r--net/sched/cls_fw.c1
-rw-r--r--net/sched/cls_route.c1
-rw-r--r--net/sched/cls_tcindex.c1
-rw-r--r--net/sched/cls_u32.c5
-rw-r--r--net/sched/em_meta.c1
-rw-r--r--net/sched/em_nbyte.c1
-rw-r--r--net/sched/em_text.c1
-rw-r--r--net/sched/ematch.c1
-rw-r--r--net/sched/sch_api.c113
-rw-r--r--net/sched/sch_atm.c1
-rw-r--r--net/sched/sch_cbq.c1
-rw-r--r--net/sched/sch_drr.c1
-rw-r--r--net/sched/sch_dsmark.c1
-rw-r--r--net/sched/sch_fifo.c1
-rw-r--r--net/sched/sch_generic.c16
-rw-r--r--net/sched/sch_gred.c1
-rw-r--r--net/sched/sch_htb.c1
-rw-r--r--net/sched/sch_mq.c1
-rw-r--r--net/sched/sch_multiq.c1
-rw-r--r--net/sched/sch_netem.c1
-rw-r--r--net/sched/sch_prio.c1
-rw-r--r--net/sched/sch_sfq.c1
-rw-r--r--net/sched/sch_teql.c1
34 files changed, 185 insertions, 95 deletions
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 21f9c7678aa3..2f691fb180d1 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -328,13 +328,16 @@ config NET_CLS_FLOW
328 module will be called cls_flow. 328 module will be called cls_flow.
329 329
330config NET_CLS_CGROUP 330config NET_CLS_CGROUP
331 bool "Control Group Classifier" 331 tristate "Control Group Classifier"
332 select NET_CLS 332 select NET_CLS
333 depends on CGROUPS 333 depends on CGROUPS
334 ---help--- 334 ---help---
335 Say Y here if you want to classify packets based on the control 335 Say Y here if you want to classify packets based on the control
336 cgroup of their process. 336 cgroup of their process.
337 337
338 To compile this code as a module, choose M here: the
339 module will be called cls_cgroup.
340
338config NET_EMATCH 341config NET_EMATCH
339 bool "Extended Matches" 342 bool "Extended Matches"
340 select NET_CLS 343 select NET_CLS
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 64f5e328cee9..019045174fc3 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>
@@ -667,7 +668,8 @@ nlmsg_failure:
667} 668}
668 669
669static int 670static int
670act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event) 671act_get_notify(struct net *net, u32 pid, struct nlmsghdr *n,
672 struct tc_action *a, int event)
671{ 673{
672 struct sk_buff *skb; 674 struct sk_buff *skb;
673 675
@@ -679,7 +681,7 @@ act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
679 return -EINVAL; 681 return -EINVAL;
680 } 682 }
681 683
682 return rtnl_unicast(skb, &init_net, pid); 684 return rtnl_unicast(skb, net, pid);
683} 685}
684 686
685static struct tc_action * 687static struct tc_action *
@@ -749,7 +751,8 @@ static struct tc_action *create_a(int i)
749 return act; 751 return act;
750} 752}
751 753
752static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid) 754static int tca_action_flush(struct net *net, struct nlattr *nla,
755 struct nlmsghdr *n, u32 pid)
753{ 756{
754 struct sk_buff *skb; 757 struct sk_buff *skb;
755 unsigned char *b; 758 unsigned char *b;
@@ -808,7 +811,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
808 nlh->nlmsg_flags |= NLM_F_ROOT; 811 nlh->nlmsg_flags |= NLM_F_ROOT;
809 module_put(a->ops->owner); 812 module_put(a->ops->owner);
810 kfree(a); 813 kfree(a);
811 err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 814 err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
812 if (err > 0) 815 if (err > 0)
813 return 0; 816 return 0;
814 817
@@ -825,7 +828,8 @@ noflush_out:
825} 828}
826 829
827static int 830static int
828tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event) 831tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
832 u32 pid, int event)
829{ 833{
830 int i, ret; 834 int i, ret;
831 struct nlattr *tb[TCA_ACT_MAX_PRIO+1]; 835 struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
@@ -837,7 +841,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
837 841
838 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { 842 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
839 if (tb[1] != NULL) 843 if (tb[1] != NULL)
840 return tca_action_flush(tb[1], n, pid); 844 return tca_action_flush(net, tb[1], n, pid);
841 else 845 else
842 return -EINVAL; 846 return -EINVAL;
843 } 847 }
@@ -858,7 +862,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
858 } 862 }
859 863
860 if (event == RTM_GETACTION) 864 if (event == RTM_GETACTION)
861 ret = act_get_notify(pid, n, head, event); 865 ret = act_get_notify(net, pid, n, head, event);
862 else { /* delete */ 866 else { /* delete */
863 struct sk_buff *skb; 867 struct sk_buff *skb;
864 868
@@ -877,7 +881,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
877 881
878 /* now do the delete */ 882 /* now do the delete */
879 tcf_action_destroy(head, 0); 883 tcf_action_destroy(head, 0);
880 ret = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, 884 ret = rtnetlink_send(skb, net, pid, RTNLGRP_TC,
881 n->nlmsg_flags&NLM_F_ECHO); 885 n->nlmsg_flags&NLM_F_ECHO);
882 if (ret > 0) 886 if (ret > 0)
883 return 0; 887 return 0;
@@ -888,8 +892,8 @@ err:
888 return ret; 892 return ret;
889} 893}
890 894
891static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, 895static int tcf_add_notify(struct net *net, struct tc_action *a,
892 u16 flags) 896 u32 pid, u32 seq, int event, u16 flags)
893{ 897{
894 struct tcamsg *t; 898 struct tcamsg *t;
895 struct nlmsghdr *nlh; 899 struct nlmsghdr *nlh;
@@ -922,7 +926,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; 926 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
923 NETLINK_CB(skb).dst_group = RTNLGRP_TC; 927 NETLINK_CB(skb).dst_group = RTNLGRP_TC;
924 928
925 err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, flags&NLM_F_ECHO); 929 err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
926 if (err > 0) 930 if (err > 0)
927 err = 0; 931 err = 0;
928 return err; 932 return err;
@@ -935,7 +939,8 @@ nlmsg_failure:
935 939
936 940
937static int 941static int
938tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr) 942tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
943 u32 pid, int ovr)
939{ 944{
940 int ret = 0; 945 int ret = 0;
941 struct tc_action *act; 946 struct tc_action *act;
@@ -953,7 +958,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 958 /* dump then free all the actions after update; inserted policy
954 * stays intact 959 * stays intact
955 * */ 960 * */
956 ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags); 961 ret = tcf_add_notify(net, act, pid, seq, RTM_NEWACTION, n->nlmsg_flags);
957 for (a = act; a; a = act) { 962 for (a = act; a; a = act) {
958 act = a->next; 963 act = a->next;
959 kfree(a); 964 kfree(a);
@@ -969,9 +974,6 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
969 u32 pid = skb ? NETLINK_CB(skb).pid : 0; 974 u32 pid = skb ? NETLINK_CB(skb).pid : 0;
970 int ret = 0, ovr = 0; 975 int ret = 0, ovr = 0;
971 976
972 if (!net_eq(net, &init_net))
973 return -EINVAL;
974
975 ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); 977 ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL);
976 if (ret < 0) 978 if (ret < 0)
977 return ret; 979 return ret;
@@ -994,15 +996,17 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
994 if (n->nlmsg_flags&NLM_F_REPLACE) 996 if (n->nlmsg_flags&NLM_F_REPLACE)
995 ovr = 1; 997 ovr = 1;
996replay: 998replay:
997 ret = tcf_action_add(tca[TCA_ACT_TAB], n, pid, ovr); 999 ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, pid, ovr);
998 if (ret == -EAGAIN) 1000 if (ret == -EAGAIN)
999 goto replay; 1001 goto replay;
1000 break; 1002 break;
1001 case RTM_DELACTION: 1003 case RTM_DELACTION:
1002 ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_DELACTION); 1004 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1005 pid, RTM_DELACTION);
1003 break; 1006 break;
1004 case RTM_GETACTION: 1007 case RTM_GETACTION:
1005 ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_GETACTION); 1008 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1009 pid, RTM_GETACTION);
1006 break; 1010 break;
1007 default: 1011 default:
1008 BUG(); 1012 BUG();
@@ -1042,7 +1046,6 @@ find_dump_kind(const struct nlmsghdr *n)
1042static int 1046static int
1043tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) 1047tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1044{ 1048{
1045 struct net *net = sock_net(skb->sk);
1046 struct nlmsghdr *nlh; 1049 struct nlmsghdr *nlh;
1047 unsigned char *b = skb_tail_pointer(skb); 1050 unsigned char *b = skb_tail_pointer(skb);
1048 struct nlattr *nest; 1051 struct nlattr *nest;
@@ -1052,9 +1055,6 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1052 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); 1055 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
1053 struct nlattr *kind = find_dump_kind(cb->nlh); 1056 struct nlattr *kind = find_dump_kind(cb->nlh);
1054 1057
1055 if (!net_eq(net, &init_net))
1056 return 0;
1057
1058 if (kind == NULL) { 1058 if (kind == NULL) {
1059 printk("tc_dump_action: action bad kind\n"); 1059 printk("tc_dump_action: action bad kind\n");
1060 return 0; 1060 return 0;
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 082c520b0def..da27a170b6b7 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -19,6 +19,7 @@
19#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/slab.h>
22#include <net/netlink.h> 23#include <net/netlink.h>
23#include <net/pkt_sched.h> 24#include <net/pkt_sched.h>
24#include <linux/tc_act/tc_ipt.h> 25#include <linux/tc_act/tc_ipt.h>
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index d329170243cb..c046682054eb 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -20,6 +20,7 @@
20#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/gfp.h>
23#include <net/net_namespace.h> 24#include <net/net_namespace.h>
24#include <net/netlink.h> 25#include <net/netlink.h>
25#include <net/pkt_sched.h> 26#include <net/pkt_sched.h>
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 6b0359a500e6..b7dcfedc802e 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -17,6 +17,7 @@
17#include <linux/rtnetlink.h> 17#include <linux/rtnetlink.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/slab.h>
20#include <net/netlink.h> 21#include <net/netlink.h>
21#include <net/pkt_sched.h> 22#include <net/pkt_sched.h>
22#include <linux/tc_act/tc_pedit.h> 23#include <linux/tc_act/tc_pedit.h>
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 723964c3ee4f..654f73dff7c1 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -18,6 +18,7 @@
18#include <linux/skbuff.h> 18#include <linux/skbuff.h>
19#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/slab.h>
21#include <net/act_api.h> 22#include <net/act_api.h>
22#include <net/netlink.h> 23#include <net/netlink.h>
23 24
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 8daa1ebc7413..622ca809c15c 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/slab.h>
14#include <linux/init.h> 15#include <linux/init.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/skbuff.h> 17#include <linux/skbuff.h>
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 3725d8fa29db..5fd0c28ef79a 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -24,6 +24,7 @@
24#include <linux/kmod.h> 24#include <linux/kmod.h>
25#include <linux/netlink.h> 25#include <linux/netlink.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/slab.h>
27#include <net/net_namespace.h> 28#include <net/net_namespace.h>
28#include <net/sock.h> 29#include <net/sock.h>
29#include <net/netlink.h> 30#include <net/netlink.h>
@@ -98,8 +99,9 @@ out:
98} 99}
99EXPORT_SYMBOL(unregister_tcf_proto_ops); 100EXPORT_SYMBOL(unregister_tcf_proto_ops);
100 101
101static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n, 102static int tfilter_notify(struct net *net, struct sk_buff *oskb,
102 struct tcf_proto *tp, unsigned long fh, int event); 103 struct nlmsghdr *n, struct tcf_proto *tp,
104 unsigned long fh, int event);
103 105
104 106
105/* Select new prio value from the range, managed by kernel. */ 107/* Select new prio value from the range, managed by kernel. */
@@ -137,9 +139,6 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
137 int err; 139 int err;
138 int tp_created = 0; 140 int tp_created = 0;
139 141
140 if (!net_eq(net, &init_net))
141 return -EINVAL;
142
143replay: 142replay:
144 t = NLMSG_DATA(n); 143 t = NLMSG_DATA(n);
145 protocol = TC_H_MIN(t->tcm_info); 144 protocol = TC_H_MIN(t->tcm_info);
@@ -158,7 +157,7 @@ replay:
158 /* Find head of filter chain. */ 157 /* Find head of filter chain. */
159 158
160 /* Find link */ 159 /* Find link */
161 dev = __dev_get_by_index(&init_net, t->tcm_ifindex); 160 dev = __dev_get_by_index(net, t->tcm_ifindex);
162 if (dev == NULL) 161 if (dev == NULL)
163 return -ENODEV; 162 return -ENODEV;
164 163
@@ -282,7 +281,7 @@ replay:
282 *back = tp->next; 281 *back = tp->next;
283 spin_unlock_bh(root_lock); 282 spin_unlock_bh(root_lock);
284 283
285 tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); 284 tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
286 tcf_destroy(tp); 285 tcf_destroy(tp);
287 err = 0; 286 err = 0;
288 goto errout; 287 goto errout;
@@ -305,10 +304,10 @@ replay:
305 case RTM_DELTFILTER: 304 case RTM_DELTFILTER:
306 err = tp->ops->delete(tp, fh); 305 err = tp->ops->delete(tp, fh);
307 if (err == 0) 306 if (err == 0)
308 tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); 307 tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
309 goto errout; 308 goto errout;
310 case RTM_GETTFILTER: 309 case RTM_GETTFILTER:
311 err = tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); 310 err = tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER);
312 goto errout; 311 goto errout;
313 default: 312 default:
314 err = -EINVAL; 313 err = -EINVAL;
@@ -324,7 +323,7 @@ replay:
324 *back = tp; 323 *back = tp;
325 spin_unlock_bh(root_lock); 324 spin_unlock_bh(root_lock);
326 } 325 }
327 tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); 326 tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER);
328 } else { 327 } else {
329 if (tp_created) 328 if (tp_created)
330 tcf_destroy(tp); 329 tcf_destroy(tp);
@@ -370,8 +369,9 @@ nla_put_failure:
370 return -1; 369 return -1;
371} 370}
372 371
373static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n, 372static int tfilter_notify(struct net *net, struct sk_buff *oskb,
374 struct tcf_proto *tp, unsigned long fh, int event) 373 struct nlmsghdr *n, struct tcf_proto *tp,
374 unsigned long fh, int event)
375{ 375{
376 struct sk_buff *skb; 376 struct sk_buff *skb;
377 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; 377 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
@@ -385,7 +385,7 @@ static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n,
385 return -EINVAL; 385 return -EINVAL;
386 } 386 }
387 387
388 return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, 388 return rtnetlink_send(skb, net, pid, RTNLGRP_TC,
389 n->nlmsg_flags & NLM_F_ECHO); 389 n->nlmsg_flags & NLM_F_ECHO);
390} 390}
391 391
@@ -418,12 +418,9 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
418 const struct Qdisc_class_ops *cops; 418 const struct Qdisc_class_ops *cops;
419 struct tcf_dump_args arg; 419 struct tcf_dump_args arg;
420 420
421 if (!net_eq(net, &init_net))
422 return 0;
423
424 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) 421 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
425 return skb->len; 422 return skb->len;
426 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 423 if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
427 return skb->len; 424 return skb->len;
428 425
429 if (!tcm->tcm_parent) 426 if (!tcm->tcm_parent)
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 4e2bda854119..efd4f95fd050 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/string.h> 16#include <linux/string.h>
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index e4877ca6727c..221180384fd7 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/string.h> 15#include <linux/string.h>
15#include <linux/errno.h> 16#include <linux/errno.h>
@@ -24,6 +25,25 @@ struct cgroup_cls_state
24 u32 classid; 25 u32 classid;
25}; 26};
26 27
28static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
29 struct cgroup *cgrp);
30static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
31static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp);
32
33struct cgroup_subsys net_cls_subsys = {
34 .name = "net_cls",
35 .create = cgrp_create,
36 .destroy = cgrp_destroy,
37 .populate = cgrp_populate,
38#ifdef CONFIG_NET_CLS_CGROUP
39 .subsys_id = net_cls_subsys_id,
40#else
41#define net_cls_subsys_id net_cls_subsys.subsys_id
42#endif
43 .module = THIS_MODULE,
44};
45
46
27static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp) 47static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp)
28{ 48{
29 return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id), 49 return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id),
@@ -79,14 +99,6 @@ static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
79 return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files)); 99 return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files));
80} 100}
81 101
82struct cgroup_subsys net_cls_subsys = {
83 .name = "net_cls",
84 .create = cgrp_create,
85 .destroy = cgrp_destroy,
86 .populate = cgrp_populate,
87 .subsys_id = net_cls_subsys_id,
88};
89
90struct cls_cgroup_head 102struct cls_cgroup_head
91{ 103{
92 u32 handle; 104 u32 handle;
@@ -277,12 +289,19 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = {
277 289
278static int __init init_cgroup_cls(void) 290static int __init init_cgroup_cls(void)
279{ 291{
280 return register_tcf_proto_ops(&cls_cgroup_ops); 292 int ret = register_tcf_proto_ops(&cls_cgroup_ops);
293 if (ret)
294 return ret;
295 ret = cgroup_load_subsys(&net_cls_subsys);
296 if (ret)
297 unregister_tcf_proto_ops(&cls_cgroup_ops);
298 return ret;
281} 299}
282 300
283static void __exit exit_cgroup_cls(void) 301static void __exit exit_cgroup_cls(void)
284{ 302{
285 unregister_tcf_proto_ops(&cls_cgroup_ops); 303 unregister_tcf_proto_ops(&cls_cgroup_ops);
304 cgroup_unload_subsys(&net_cls_subsys);
286} 305}
287 306
288module_init(init_cgroup_cls); 307module_init(init_cgroup_cls);
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index e054c62857e1..6ed61b10e002 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -20,6 +20,7 @@
20#include <linux/ip.h> 20#include <linux/ip.h>
21#include <linux/ipv6.h> 21#include <linux/ipv6.h>
22#include <linux/if_vlan.h> 22#include <linux/if_vlan.h>
23#include <linux/slab.h>
23 24
24#include <net/pkt_cls.h> 25#include <net/pkt_cls.h>
25#include <net/ip.h> 26#include <net/ip.h>
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 6d6e87585fb1..93b0a7b6f9b4 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/slab.h>
22#include <linux/types.h> 23#include <linux/types.h>
23#include <linux/kernel.h> 24#include <linux/kernel.h>
24#include <linux/string.h> 25#include <linux/string.h>
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index dd872d5383ef..694dcd85dec8 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/string.h> 16#include <linux/string.h>
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index e806f2314b5e..20ef330bb918 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -9,6 +9,7 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/skbuff.h> 10#include <linux/skbuff.h>
11#include <linux/errno.h> 11#include <linux/errno.h>
12#include <linux/slab.h>
12#include <net/act_api.h> 13#include <net/act_api.h>
13#include <net/netlink.h> 14#include <net/netlink.h>
14#include <net/pkt_cls.h> 15#include <net/pkt_cls.h>
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 07372f60bee3..593eac056e8d 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -31,6 +31,7 @@
31 */ 31 */
32 32
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/slab.h>
34#include <linux/types.h> 35#include <linux/types.h>
35#include <linux/kernel.h> 36#include <linux/kernel.h>
36#include <linux/string.h> 37#include <linux/string.h>
@@ -772,10 +773,10 @@ static int __init init_u32(void)
772 printk(" Performance counters on\n"); 773 printk(" Performance counters on\n");
773#endif 774#endif
774#ifdef CONFIG_NET_CLS_IND 775#ifdef CONFIG_NET_CLS_IND
775 printk(" input device check on \n"); 776 printk(" input device check on\n");
776#endif 777#endif
777#ifdef CONFIG_NET_CLS_ACT 778#ifdef CONFIG_NET_CLS_ACT
778 printk(" Actions configured \n"); 779 printk(" Actions configured\n");
779#endif 780#endif
780 return register_tcf_proto_ops(&cls_u32_ops); 781 return register_tcf_proto_ops(&cls_u32_ops);
781} 782}
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 24dce8b648a4..3bcac8aa333c 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -58,6 +58,7 @@
58 * only available if that subsystem is enabled in the kernel. 58 * only available if that subsystem is enabled in the kernel.
59 */ 59 */
60 60
61#include <linux/slab.h>
61#include <linux/module.h> 62#include <linux/module.h>
62#include <linux/types.h> 63#include <linux/types.h>
63#include <linux/kernel.h> 64#include <linux/kernel.h>
diff --git a/net/sched/em_nbyte.c b/net/sched/em_nbyte.c
index 370a1b2ea317..1a4176aee6e5 100644
--- a/net/sched/em_nbyte.c
+++ b/net/sched/em_nbyte.c
@@ -9,6 +9,7 @@
9 * Authors: Thomas Graf <tgraf@suug.ch> 9 * Authors: Thomas Graf <tgraf@suug.ch>
10 */ 10 */
11 11
12#include <linux/gfp.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
diff --git a/net/sched/em_text.c b/net/sched/em_text.c
index 853c5ead87fd..763253257411 100644
--- a/net/sched/em_text.c
+++ b/net/sched/em_text.c
@@ -9,6 +9,7 @@
9 * Authors: Thomas Graf <tgraf@suug.ch> 9 * Authors: Thomas Graf <tgraf@suug.ch>
10 */ 10 */
11 11
12#include <linux/slab.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index aab59409728b..e782bdeedc58 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -82,6 +82,7 @@
82 */ 82 */
83 83
84#include <linux/module.h> 84#include <linux/module.h>
85#include <linux/slab.h>
85#include <linux/types.h> 86#include <linux/types.h>
86#include <linux/kernel.h> 87#include <linux/kernel.h>
87#include <linux/errno.h> 88#include <linux/errno.h>
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 6cd491013b50..9839b26674f4 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -28,16 +28,19 @@
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/hrtimer.h> 29#include <linux/hrtimer.h>
30#include <linux/lockdep.h> 30#include <linux/lockdep.h>
31#include <linux/slab.h>
31 32
32#include <net/net_namespace.h> 33#include <net/net_namespace.h>
33#include <net/sock.h> 34#include <net/sock.h>
34#include <net/netlink.h> 35#include <net/netlink.h>
35#include <net/pkt_sched.h> 36#include <net/pkt_sched.h>
36 37
37static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, u32 clid, 38static int qdisc_notify(struct net *net, struct sk_buff *oskb,
39 struct nlmsghdr *n, u32 clid,
38 struct Qdisc *old, struct Qdisc *new); 40 struct Qdisc *old, struct Qdisc *new);
39static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, 41static int tclass_notify(struct net *net, struct sk_buff *oskb,
40 struct Qdisc *q, unsigned long cl, int event); 42 struct nlmsghdr *n, struct Qdisc *q,
43 unsigned long cl, int event);
41 44
42/* 45/*
43 46
@@ -638,11 +641,12 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
638} 641}
639EXPORT_SYMBOL(qdisc_tree_decrease_qlen); 642EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
640 643
641static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid, 644static void notify_and_destroy(struct net *net, struct sk_buff *skb,
645 struct nlmsghdr *n, u32 clid,
642 struct Qdisc *old, struct Qdisc *new) 646 struct Qdisc *old, struct Qdisc *new)
643{ 647{
644 if (new || old) 648 if (new || old)
645 qdisc_notify(skb, n, clid, old, new); 649 qdisc_notify(net, skb, n, clid, old, new);
646 650
647 if (old) 651 if (old)
648 qdisc_destroy(old); 652 qdisc_destroy(old);
@@ -662,6 +666,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
662 struct Qdisc *new, struct Qdisc *old) 666 struct Qdisc *new, struct Qdisc *old)
663{ 667{
664 struct Qdisc *q = old; 668 struct Qdisc *q = old;
669 struct net *net = dev_net(dev);
665 int err = 0; 670 int err = 0;
666 671
667 if (parent == NULL) { 672 if (parent == NULL) {
@@ -698,12 +703,13 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
698 } 703 }
699 704
700 if (!ingress) { 705 if (!ingress) {
701 notify_and_destroy(skb, n, classid, dev->qdisc, new); 706 notify_and_destroy(net, skb, n, classid,
707 dev->qdisc, new);
702 if (new && !new->ops->attach) 708 if (new && !new->ops->attach)
703 atomic_inc(&new->refcnt); 709 atomic_inc(&new->refcnt);
704 dev->qdisc = new ? : &noop_qdisc; 710 dev->qdisc = new ? : &noop_qdisc;
705 } else { 711 } else {
706 notify_and_destroy(skb, n, classid, old, new); 712 notify_and_destroy(net, skb, n, classid, old, new);
707 } 713 }
708 714
709 if (dev->flags & IFF_UP) 715 if (dev->flags & IFF_UP)
@@ -721,7 +727,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
721 err = -ENOENT; 727 err = -ENOENT;
722 } 728 }
723 if (!err) 729 if (!err)
724 notify_and_destroy(skb, n, classid, old, new); 730 notify_and_destroy(net, skb, n, classid, old, new);
725 } 731 }
726 return err; 732 return err;
727} 733}
@@ -947,10 +953,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
947 struct Qdisc *p = NULL; 953 struct Qdisc *p = NULL;
948 int err; 954 int err;
949 955
950 if (!net_eq(net, &init_net)) 956 if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
951 return -EINVAL;
952
953 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
954 return -ENODEV; 957 return -ENODEV;
955 958
956 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 959 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
@@ -990,7 +993,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
990 if ((err = qdisc_graft(dev, p, skb, n, clid, NULL, q)) != 0) 993 if ((err = qdisc_graft(dev, p, skb, n, clid, NULL, q)) != 0)
991 return err; 994 return err;
992 } else { 995 } else {
993 qdisc_notify(skb, n, clid, NULL, q); 996 qdisc_notify(net, skb, n, clid, NULL, q);
994 } 997 }
995 return 0; 998 return 0;
996} 999}
@@ -1009,16 +1012,13 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1009 struct Qdisc *q, *p; 1012 struct Qdisc *q, *p;
1010 int err; 1013 int err;
1011 1014
1012 if (!net_eq(net, &init_net))
1013 return -EINVAL;
1014
1015replay: 1015replay:
1016 /* Reinit, just in case something touches this. */ 1016 /* Reinit, just in case something touches this. */
1017 tcm = NLMSG_DATA(n); 1017 tcm = NLMSG_DATA(n);
1018 clid = tcm->tcm_parent; 1018 clid = tcm->tcm_parent;
1019 q = p = NULL; 1019 q = p = NULL;
1020 1020
1021 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 1021 if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
1022 return -ENODEV; 1022 return -ENODEV;
1023 1023
1024 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 1024 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
@@ -1105,7 +1105,7 @@ replay:
1105 return -EINVAL; 1105 return -EINVAL;
1106 err = qdisc_change(q, tca); 1106 err = qdisc_change(q, tca);
1107 if (err == 0) 1107 if (err == 0)
1108 qdisc_notify(skb, n, clid, NULL, q); 1108 qdisc_notify(net, skb, n, clid, NULL, q);
1109 return err; 1109 return err;
1110 1110
1111create_n_graft: 1111create_n_graft:
@@ -1195,8 +1195,9 @@ nla_put_failure:
1195 return -1; 1195 return -1;
1196} 1196}
1197 1197
1198static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, 1198static int qdisc_notify(struct net *net, struct sk_buff *oskb,
1199 u32 clid, struct Qdisc *old, struct Qdisc *new) 1199 struct nlmsghdr *n, u32 clid,
1200 struct Qdisc *old, struct Qdisc *new)
1200{ 1201{
1201 struct sk_buff *skb; 1202 struct sk_buff *skb;
1202 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; 1203 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
@@ -1215,7 +1216,7 @@ static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n,
1215 } 1216 }
1216 1217
1217 if (skb->len) 1218 if (skb->len)
1218 return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 1219 return rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
1219 1220
1220err_out: 1221err_out:
1221 kfree_skb(skb); 1222 kfree_skb(skb);
@@ -1274,15 +1275,12 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
1274 int s_idx, s_q_idx; 1275 int s_idx, s_q_idx;
1275 struct net_device *dev; 1276 struct net_device *dev;
1276 1277
1277 if (!net_eq(net, &init_net))
1278 return 0;
1279
1280 s_idx = cb->args[0]; 1278 s_idx = cb->args[0];
1281 s_q_idx = q_idx = cb->args[1]; 1279 s_q_idx = q_idx = cb->args[1];
1282 1280
1283 rcu_read_lock(); 1281 rcu_read_lock();
1284 idx = 0; 1282 idx = 0;
1285 for_each_netdev_rcu(&init_net, dev) { 1283 for_each_netdev_rcu(net, dev) {
1286 struct netdev_queue *dev_queue; 1284 struct netdev_queue *dev_queue;
1287 1285
1288 if (idx < s_idx) 1286 if (idx < s_idx)
@@ -1334,10 +1332,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1334 u32 qid = TC_H_MAJ(clid); 1332 u32 qid = TC_H_MAJ(clid);
1335 int err; 1333 int err;
1336 1334
1337 if (!net_eq(net, &init_net)) 1335 if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
1338 return -EINVAL;
1339
1340 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
1341 return -ENODEV; 1336 return -ENODEV;
1342 1337
1343 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 1338 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
@@ -1418,10 +1413,10 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1418 if (cops->delete) 1413 if (cops->delete)
1419 err = cops->delete(q, cl); 1414 err = cops->delete(q, cl);
1420 if (err == 0) 1415 if (err == 0)
1421 tclass_notify(skb, n, q, cl, RTM_DELTCLASS); 1416 tclass_notify(net, skb, n, q, cl, RTM_DELTCLASS);
1422 goto out; 1417 goto out;
1423 case RTM_GETTCLASS: 1418 case RTM_GETTCLASS:
1424 err = tclass_notify(skb, n, q, cl, RTM_NEWTCLASS); 1419 err = tclass_notify(net, skb, n, q, cl, RTM_NEWTCLASS);
1425 goto out; 1420 goto out;
1426 default: 1421 default:
1427 err = -EINVAL; 1422 err = -EINVAL;
@@ -1434,7 +1429,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1434 if (cops->change) 1429 if (cops->change)
1435 err = cops->change(q, clid, pid, tca, &new_cl); 1430 err = cops->change(q, clid, pid, tca, &new_cl);
1436 if (err == 0) 1431 if (err == 0)
1437 tclass_notify(skb, n, q, new_cl, RTM_NEWTCLASS); 1432 tclass_notify(net, skb, n, q, new_cl, RTM_NEWTCLASS);
1438 1433
1439out: 1434out:
1440 if (cl) 1435 if (cl)
@@ -1486,8 +1481,9 @@ nla_put_failure:
1486 return -1; 1481 return -1;
1487} 1482}
1488 1483
1489static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, 1484static int tclass_notify(struct net *net, struct sk_buff *oskb,
1490 struct Qdisc *q, unsigned long cl, int event) 1485 struct nlmsghdr *n, struct Qdisc *q,
1486 unsigned long cl, int event)
1491{ 1487{
1492 struct sk_buff *skb; 1488 struct sk_buff *skb;
1493 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; 1489 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
@@ -1501,7 +1497,7 @@ static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
1501 return -EINVAL; 1497 return -EINVAL;
1502 } 1498 }
1503 1499
1504 return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 1500 return rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
1505} 1501}
1506 1502
1507struct qdisc_dump_args 1503struct qdisc_dump_args
@@ -1576,12 +1572,9 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1576 struct net_device *dev; 1572 struct net_device *dev;
1577 int t, s_t; 1573 int t, s_t;
1578 1574
1579 if (!net_eq(net, &init_net))
1580 return 0;
1581
1582 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) 1575 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
1583 return 0; 1576 return 0;
1584 if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 1577 if ((dev = dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
1585 return 0; 1578 return 0;
1586 1579
1587 s_t = cb->args[0]; 1580 s_t = cb->args[0];
@@ -1691,7 +1684,7 @@ static int psched_show(struct seq_file *seq, void *v)
1691 1684
1692static int psched_open(struct inode *inode, struct file *file) 1685static int psched_open(struct inode *inode, struct file *file)
1693{ 1686{
1694 return single_open(file, psched_show, PDE(inode)->data); 1687 return single_open(file, psched_show, NULL);
1695} 1688}
1696 1689
1697static const struct file_operations psched_fops = { 1690static const struct file_operations psched_fops = {
@@ -1701,15 +1694,53 @@ static const struct file_operations psched_fops = {
1701 .llseek = seq_lseek, 1694 .llseek = seq_lseek,
1702 .release = single_release, 1695 .release = single_release,
1703}; 1696};
1697
1698static int __net_init psched_net_init(struct net *net)
1699{
1700 struct proc_dir_entry *e;
1701
1702 e = proc_net_fops_create(net, "psched", 0, &psched_fops);
1703 if (e == NULL)
1704 return -ENOMEM;
1705
1706 return 0;
1707}
1708
1709static void __net_exit psched_net_exit(struct net *net)
1710{
1711 proc_net_remove(net, "psched");
1712}
1713#else
1714static int __net_init psched_net_init(struct net *net)
1715{
1716 return 0;
1717}
1718
1719static void __net_exit psched_net_exit(struct net *net)
1720{
1721}
1704#endif 1722#endif
1705 1723
1724static struct pernet_operations psched_net_ops = {
1725 .init = psched_net_init,
1726 .exit = psched_net_exit,
1727};
1728
1706static int __init pktsched_init(void) 1729static int __init pktsched_init(void)
1707{ 1730{
1731 int err;
1732
1733 err = register_pernet_subsys(&psched_net_ops);
1734 if (err) {
1735 printk(KERN_ERR "pktsched_init: "
1736 "cannot initialize per netns operations\n");
1737 return err;
1738 }
1739
1708 register_qdisc(&pfifo_qdisc_ops); 1740 register_qdisc(&pfifo_qdisc_ops);
1709 register_qdisc(&bfifo_qdisc_ops); 1741 register_qdisc(&bfifo_qdisc_ops);
1710 register_qdisc(&pfifo_head_drop_qdisc_ops); 1742 register_qdisc(&pfifo_head_drop_qdisc_ops);
1711 register_qdisc(&mq_qdisc_ops); 1743 register_qdisc(&mq_qdisc_ops);
1712 proc_net_fops_create(&init_net, "psched", 0, &psched_fops);
1713 1744
1714 rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL); 1745 rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);
1715 rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL); 1746 rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL);
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index ab82f145f689..fcbb86a486a2 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -3,6 +3,7 @@
3/* Written 1998-2000 by Werner Almesberger, EPFL ICA */ 3/* Written 1998-2000 by Werner Almesberger, EPFL ICA */
4 4
5#include <linux/module.h> 5#include <linux/module.h>
6#include <linux/slab.h>
6#include <linux/init.h> 7#include <linux/init.h>
7#include <linux/string.h> 8#include <linux/string.h>
8#include <linux/errno.h> 9#include <linux/errno.h>
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 3846d65bc03e..28c01ef5abc8 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/slab.h>
14#include <linux/types.h> 15#include <linux/types.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/string.h> 17#include <linux/string.h>
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index a65604f8f2b8..b74046a95397 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/slab.h>
12#include <linux/init.h> 13#include <linux/init.h>
13#include <linux/errno.h> 14#include <linux/errno.h>
14#include <linux/netdevice.h> 15#include <linux/netdevice.h>
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index d303daa45d49..63d41f86679c 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -5,6 +5,7 @@
5 5
6#include <linux/module.h> 6#include <linux/module.h>
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/slab.h>
8#include <linux/types.h> 9#include <linux/types.h>
9#include <linux/string.h> 10#include <linux/string.h>
10#include <linux/errno.h> 11#include <linux/errno.h>
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 4b0a6cc44c77..5948bafa8ce2 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/errno.h> 16#include <linux/errno.h>
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 5173c1e1b19c..aeddabfb8e4e 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -24,6 +24,7 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/rcupdate.h> 25#include <linux/rcupdate.h>
26#include <linux/list.h> 26#include <linux/list.h>
27#include <linux/slab.h>
27#include <net/pkt_sched.h> 28#include <net/pkt_sched.h>
28 29
29/* Main transmission queue. */ 30/* Main transmission queue. */
@@ -528,7 +529,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
528 unsigned int size; 529 unsigned int size;
529 int err = -ENOBUFS; 530 int err = -ENOBUFS;
530 531
531 /* ensure that the Qdisc and the private data are 32-byte aligned */ 532 /* ensure that the Qdisc and the private data are 64-byte aligned */
532 size = QDISC_ALIGN(sizeof(*sch)); 533 size = QDISC_ALIGN(sizeof(*sch));
533 size += ops->priv_size + (QDISC_ALIGNTO - 1); 534 size += ops->priv_size + (QDISC_ALIGNTO - 1);
534 535
@@ -590,6 +591,13 @@ void qdisc_reset(struct Qdisc *qdisc)
590} 591}
591EXPORT_SYMBOL(qdisc_reset); 592EXPORT_SYMBOL(qdisc_reset);
592 593
594static void qdisc_rcu_free(struct rcu_head *head)
595{
596 struct Qdisc *qdisc = container_of(head, struct Qdisc, rcu_head);
597
598 kfree((char *) qdisc - qdisc->padded);
599}
600
593void qdisc_destroy(struct Qdisc *qdisc) 601void qdisc_destroy(struct Qdisc *qdisc)
594{ 602{
595 const struct Qdisc_ops *ops = qdisc->ops; 603 const struct Qdisc_ops *ops = qdisc->ops;
@@ -613,7 +621,11 @@ void qdisc_destroy(struct Qdisc *qdisc)
613 dev_put(qdisc_dev(qdisc)); 621 dev_put(qdisc_dev(qdisc));
614 622
615 kfree_skb(qdisc->gso_skb); 623 kfree_skb(qdisc->gso_skb);
616 kfree((char *) qdisc - qdisc->padded); 624 /*
625 * gen_estimator est_timer() might access qdisc->q.lock,
626 * wait a RCU grace period before freeing qdisc.
627 */
628 call_rcu(&qdisc->rcu_head, qdisc_rcu_free);
617} 629}
618EXPORT_SYMBOL(qdisc_destroy); 630EXPORT_SYMBOL(qdisc_destroy);
619 631
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index 40408d595c08..51dcc2aa5c92 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -18,6 +18,7 @@
18 * For all the glorious comments look at include/net/red.h 18 * For all the glorious comments look at include/net/red.h
19 */ 19 */
20 20
21#include <linux/slab.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/types.h> 23#include <linux/types.h>
23#include <linux/kernel.h> 24#include <linux/kernel.h>
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 508cf5f3a6d5..0b52b8de562c 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -36,6 +36,7 @@
36#include <linux/compiler.h> 36#include <linux/compiler.h>
37#include <linux/rbtree.h> 37#include <linux/rbtree.h>
38#include <linux/workqueue.h> 38#include <linux/workqueue.h>
39#include <linux/slab.h>
39#include <net/netlink.h> 40#include <net/netlink.h>
40#include <net/pkt_sched.h> 41#include <net/pkt_sched.h>
41 42
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index d1dea3d5dc92..b2aba3f5e6fa 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/slab.h>
12#include <linux/kernel.h> 13#include <linux/kernel.h>
13#include <linux/string.h> 14#include <linux/string.h>
14#include <linux/errno.h> 15#include <linux/errno.h>
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 7db2c88ce585..c50876cd8704 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h>
21#include <linux/types.h> 22#include <linux/types.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
23#include <linux/string.h> 24#include <linux/string.h>
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index d8b10e054627..4714ff162bbd 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/slab.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/kernel.h> 19#include <linux/kernel.h>
19#include <linux/errno.h> 20#include <linux/errno.h>
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 93285cecb246..81672e0c1b25 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/slab.h>
15#include <linux/types.h> 16#include <linux/types.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/string.h> 18#include <linux/string.h>
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index cb21380c0605..c5a9ac566007 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -20,6 +20,7 @@
20#include <linux/ipv6.h> 20#include <linux/ipv6.h>
21#include <linux/skbuff.h> 21#include <linux/skbuff.h>
22#include <linux/jhash.h> 22#include <linux/jhash.h>
23#include <linux/slab.h>
23#include <net/ip.h> 24#include <net/ip.h>
24#include <net/netlink.h> 25#include <net/netlink.h>
25#include <net/pkt_sched.h> 26#include <net/pkt_sched.h>
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index db69637069c4..3415b6ce1c0a 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -11,6 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/slab.h>
14#include <linux/string.h> 15#include <linux/string.h>
15#include <linux/errno.h> 16#include <linux/errno.h>
16#include <linux/if_arp.h> 17#include <linux/if_arp.h>