aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
authorTom Goff <thomas.goff@boeing.com>2010-03-19 11:40:13 -0400
committerDavid S. Miller <davem@davemloft.net>2010-03-22 23:26:25 -0400
commit7316ae88c43d47f6503f4c29b4973204e33c3411 (patch)
tree442b265d3fd083065330e355cf8e9c73196cc443 /net/sched
parent300bc0602489d9f09f7b548f790afd2952f6070b (diff)
net_sched: make traffic control network namespace aware
Mostly minor changes to add a net argument to various functions and remove initial network namespace checks. Make /proc/net/psched per network namespace. Signed-off-by: Tom Goff <thomas.goff@boeing.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/act_api.c45
-rw-r--r--net/sched/cls_api.c30
-rw-r--r--net/sched/sch_api.c112
3 files changed, 107 insertions, 80 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 64f5e328cee9..7a558da99bb6 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -667,7 +667,8 @@ nlmsg_failure:
667} 667}
668 668
669static int 669static int
670act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event) 670act_get_notify(struct net *net, u32 pid, struct nlmsghdr *n,
671 struct tc_action *a, int event)
671{ 672{
672 struct sk_buff *skb; 673 struct sk_buff *skb;
673 674
@@ -679,7 +680,7 @@ act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
679 return -EINVAL; 680 return -EINVAL;
680 } 681 }
681 682
682 return rtnl_unicast(skb, &init_net, pid); 683 return rtnl_unicast(skb, net, pid);
683} 684}
684 685
685static struct tc_action * 686static struct tc_action *
@@ -749,7 +750,8 @@ static struct tc_action *create_a(int i)
749 return act; 750 return act;
750} 751}
751 752
752static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid) 753static int tca_action_flush(struct net *net, struct nlattr *nla,
754 struct nlmsghdr *n, u32 pid)
753{ 755{
754 struct sk_buff *skb; 756 struct sk_buff *skb;
755 unsigned char *b; 757 unsigned char *b;
@@ -808,7 +810,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
808 nlh->nlmsg_flags |= NLM_F_ROOT; 810 nlh->nlmsg_flags |= NLM_F_ROOT;
809 module_put(a->ops->owner); 811 module_put(a->ops->owner);
810 kfree(a); 812 kfree(a);
811 err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 813 err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
812 if (err > 0) 814 if (err > 0)
813 return 0; 815 return 0;
814 816
@@ -825,7 +827,8 @@ noflush_out:
825} 827}
826 828
827static int 829static int
828tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event) 830tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
831 u32 pid, int event)
829{ 832{
830 int i, ret; 833 int i, ret;
831 struct nlattr *tb[TCA_ACT_MAX_PRIO+1]; 834 struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
@@ -837,7 +840,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
837 840
838 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { 841 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
839 if (tb[1] != NULL) 842 if (tb[1] != NULL)
840 return tca_action_flush(tb[1], n, pid); 843 return tca_action_flush(net, tb[1], n, pid);
841 else 844 else
842 return -EINVAL; 845 return -EINVAL;
843 } 846 }
@@ -858,7 +861,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
858 } 861 }
859 862
860 if (event == RTM_GETACTION) 863 if (event == RTM_GETACTION)
861 ret = act_get_notify(pid, n, head, event); 864 ret = act_get_notify(net, pid, n, head, event);
862 else { /* delete */ 865 else { /* delete */
863 struct sk_buff *skb; 866 struct sk_buff *skb;
864 867
@@ -877,7 +880,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
877 880
878 /* now do the delete */ 881 /* now do the delete */
879 tcf_action_destroy(head, 0); 882 tcf_action_destroy(head, 0);
880 ret = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, 883 ret = rtnetlink_send(skb, net, pid, RTNLGRP_TC,
881 n->nlmsg_flags&NLM_F_ECHO); 884 n->nlmsg_flags&NLM_F_ECHO);
882 if (ret > 0) 885 if (ret > 0)
883 return 0; 886 return 0;
@@ -888,8 +891,8 @@ err:
888 return ret; 891 return ret;
889} 892}
890 893
891static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, 894static int tcf_add_notify(struct net *net, struct tc_action *a,
892 u16 flags) 895 u32 pid, u32 seq, int event, u16 flags)
893{ 896{
894 struct tcamsg *t; 897 struct tcamsg *t;
895 struct nlmsghdr *nlh; 898 struct nlmsghdr *nlh;
@@ -922,7 +925,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; 925 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
923 NETLINK_CB(skb).dst_group = RTNLGRP_TC; 926 NETLINK_CB(skb).dst_group = RTNLGRP_TC;
924 927
925 err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, flags&NLM_F_ECHO); 928 err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
926 if (err > 0) 929 if (err > 0)
927 err = 0; 930 err = 0;
928 return err; 931 return err;
@@ -935,7 +938,8 @@ nlmsg_failure:
935 938
936 939
937static int 940static int
938tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr) 941tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
942 u32 pid, int ovr)
939{ 943{
940 int ret = 0; 944 int ret = 0;
941 struct tc_action *act; 945 struct tc_action *act;
@@ -953,7 +957,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 957 /* dump then free all the actions after update; inserted policy
954 * stays intact 958 * stays intact
955 * */ 959 * */
956 ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags); 960 ret = tcf_add_notify(net, act, pid, seq, RTM_NEWACTION, n->nlmsg_flags);
957 for (a = act; a; a = act) { 961 for (a = act; a; a = act) {
958 act = a->next; 962 act = a->next;
959 kfree(a); 963 kfree(a);
@@ -969,9 +973,6 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
969 u32 pid = skb ? NETLINK_CB(skb).pid : 0; 973 u32 pid = skb ? NETLINK_CB(skb).pid : 0;
970 int ret = 0, ovr = 0; 974 int ret = 0, ovr = 0;
971 975
972 if (!net_eq(net, &init_net))
973 return -EINVAL;
974
975 ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); 976 ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL);
976 if (ret < 0) 977 if (ret < 0)
977 return ret; 978 return ret;
@@ -994,15 +995,17 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
994 if (n->nlmsg_flags&NLM_F_REPLACE) 995 if (n->nlmsg_flags&NLM_F_REPLACE)
995 ovr = 1; 996 ovr = 1;
996replay: 997replay:
997 ret = tcf_action_add(tca[TCA_ACT_TAB], n, pid, ovr); 998 ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, pid, ovr);
998 if (ret == -EAGAIN) 999 if (ret == -EAGAIN)
999 goto replay; 1000 goto replay;
1000 break; 1001 break;
1001 case RTM_DELACTION: 1002 case RTM_DELACTION:
1002 ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_DELACTION); 1003 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1004 pid, RTM_DELACTION);
1003 break; 1005 break;
1004 case RTM_GETACTION: 1006 case RTM_GETACTION:
1005 ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_GETACTION); 1007 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1008 pid, RTM_GETACTION);
1006 break; 1009 break;
1007 default: 1010 default:
1008 BUG(); 1011 BUG();
@@ -1042,7 +1045,6 @@ find_dump_kind(const struct nlmsghdr *n)
1042static int 1045static int
1043tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) 1046tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1044{ 1047{
1045 struct net *net = sock_net(skb->sk);
1046 struct nlmsghdr *nlh; 1048 struct nlmsghdr *nlh;
1047 unsigned char *b = skb_tail_pointer(skb); 1049 unsigned char *b = skb_tail_pointer(skb);
1048 struct nlattr *nest; 1050 struct nlattr *nest;
@@ -1052,9 +1054,6 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1052 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); 1054 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
1053 struct nlattr *kind = find_dump_kind(cb->nlh); 1055 struct nlattr *kind = find_dump_kind(cb->nlh);
1054 1056
1055 if (!net_eq(net, &init_net))
1056 return 0;
1057
1058 if (kind == NULL) { 1057 if (kind == NULL) {
1059 printk("tc_dump_action: action bad kind\n"); 1058 printk("tc_dump_action: action bad kind\n");
1060 return 0; 1059 return 0;
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 3725d8fa29db..4a795d966172 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -98,8 +98,9 @@ out:
98} 98}
99EXPORT_SYMBOL(unregister_tcf_proto_ops); 99EXPORT_SYMBOL(unregister_tcf_proto_ops);
100 100
101static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n, 101static int tfilter_notify(struct net *net, struct sk_buff *oskb,
102 struct tcf_proto *tp, unsigned long fh, int event); 102 struct nlmsghdr *n, struct tcf_proto *tp,
103 unsigned long fh, int event);
103 104
104 105
105/* Select new prio value from the range, managed by kernel. */ 106/* Select new prio value from the range, managed by kernel. */
@@ -137,9 +138,6 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
137 int err; 138 int err;
138 int tp_created = 0; 139 int tp_created = 0;
139 140
140 if (!net_eq(net, &init_net))
141 return -EINVAL;
142
143replay: 141replay:
144 t = NLMSG_DATA(n); 142 t = NLMSG_DATA(n);
145 protocol = TC_H_MIN(t->tcm_info); 143 protocol = TC_H_MIN(t->tcm_info);
@@ -158,7 +156,7 @@ replay:
158 /* Find head of filter chain. */ 156 /* Find head of filter chain. */
159 157
160 /* Find link */ 158 /* Find link */
161 dev = __dev_get_by_index(&init_net, t->tcm_ifindex); 159 dev = __dev_get_by_index(net, t->tcm_ifindex);
162 if (dev == NULL) 160 if (dev == NULL)
163 return -ENODEV; 161 return -ENODEV;
164 162
@@ -282,7 +280,7 @@ replay:
282 *back = tp->next; 280 *back = tp->next;
283 spin_unlock_bh(root_lock); 281 spin_unlock_bh(root_lock);
284 282
285 tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); 283 tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
286 tcf_destroy(tp); 284 tcf_destroy(tp);
287 err = 0; 285 err = 0;
288 goto errout; 286 goto errout;
@@ -305,10 +303,10 @@ replay:
305 case RTM_DELTFILTER: 303 case RTM_DELTFILTER:
306 err = tp->ops->delete(tp, fh); 304 err = tp->ops->delete(tp, fh);
307 if (err == 0) 305 if (err == 0)
308 tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); 306 tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
309 goto errout; 307 goto errout;
310 case RTM_GETTFILTER: 308 case RTM_GETTFILTER:
311 err = tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); 309 err = tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER);
312 goto errout; 310 goto errout;
313 default: 311 default:
314 err = -EINVAL; 312 err = -EINVAL;
@@ -324,7 +322,7 @@ replay:
324 *back = tp; 322 *back = tp;
325 spin_unlock_bh(root_lock); 323 spin_unlock_bh(root_lock);
326 } 324 }
327 tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); 325 tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER);
328 } else { 326 } else {
329 if (tp_created) 327 if (tp_created)
330 tcf_destroy(tp); 328 tcf_destroy(tp);
@@ -370,8 +368,9 @@ nla_put_failure:
370 return -1; 368 return -1;
371} 369}
372 370
373static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n, 371static int tfilter_notify(struct net *net, struct sk_buff *oskb,
374 struct tcf_proto *tp, unsigned long fh, int event) 372 struct nlmsghdr *n, struct tcf_proto *tp,
373 unsigned long fh, int event)
375{ 374{
376 struct sk_buff *skb; 375 struct sk_buff *skb;
377 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; 376 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
@@ -385,7 +384,7 @@ static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n,
385 return -EINVAL; 384 return -EINVAL;
386 } 385 }
387 386
388 return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, 387 return rtnetlink_send(skb, net, pid, RTNLGRP_TC,
389 n->nlmsg_flags & NLM_F_ECHO); 388 n->nlmsg_flags & NLM_F_ECHO);
390} 389}
391 390
@@ -418,12 +417,9 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
418 const struct Qdisc_class_ops *cops; 417 const struct Qdisc_class_ops *cops;
419 struct tcf_dump_args arg; 418 struct tcf_dump_args arg;
420 419
421 if (!net_eq(net, &init_net))
422 return 0;
423
424 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) 420 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
425 return skb->len; 421 return skb->len;
426 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 422 if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
427 return skb->len; 423 return skb->len;
428 424
429 if (!tcm->tcm_parent) 425 if (!tcm->tcm_parent)
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 6cd491013b50..6d6fe16289f3 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -34,10 +34,12 @@
34#include <net/netlink.h> 34#include <net/netlink.h>
35#include <net/pkt_sched.h> 35#include <net/pkt_sched.h>
36 36
37static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, u32 clid, 37static int qdisc_notify(struct net *net, struct sk_buff *oskb,
38 struct nlmsghdr *n, u32 clid,
38 struct Qdisc *old, struct Qdisc *new); 39 struct Qdisc *old, struct Qdisc *new);
39static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, 40static int tclass_notify(struct net *net, struct sk_buff *oskb,
40 struct Qdisc *q, unsigned long cl, int event); 41 struct nlmsghdr *n, struct Qdisc *q,
42 unsigned long cl, int event);
41 43
42/* 44/*
43 45
@@ -638,11 +640,12 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
638} 640}
639EXPORT_SYMBOL(qdisc_tree_decrease_qlen); 641EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
640 642
641static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid, 643static void notify_and_destroy(struct net *net, struct sk_buff *skb,
644 struct nlmsghdr *n, u32 clid,
642 struct Qdisc *old, struct Qdisc *new) 645 struct Qdisc *old, struct Qdisc *new)
643{ 646{
644 if (new || old) 647 if (new || old)
645 qdisc_notify(skb, n, clid, old, new); 648 qdisc_notify(net, skb, n, clid, old, new);
646 649
647 if (old) 650 if (old)
648 qdisc_destroy(old); 651 qdisc_destroy(old);
@@ -662,6 +665,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
662 struct Qdisc *new, struct Qdisc *old) 665 struct Qdisc *new, struct Qdisc *old)
663{ 666{
664 struct Qdisc *q = old; 667 struct Qdisc *q = old;
668 struct net *net = dev_net(dev);
665 int err = 0; 669 int err = 0;
666 670
667 if (parent == NULL) { 671 if (parent == NULL) {
@@ -698,12 +702,13 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
698 } 702 }
699 703
700 if (!ingress) { 704 if (!ingress) {
701 notify_and_destroy(skb, n, classid, dev->qdisc, new); 705 notify_and_destroy(net, skb, n, classid,
706 dev->qdisc, new);
702 if (new && !new->ops->attach) 707 if (new && !new->ops->attach)
703 atomic_inc(&new->refcnt); 708 atomic_inc(&new->refcnt);
704 dev->qdisc = new ? : &noop_qdisc; 709 dev->qdisc = new ? : &noop_qdisc;
705 } else { 710 } else {
706 notify_and_destroy(skb, n, classid, old, new); 711 notify_and_destroy(net, skb, n, classid, old, new);
707 } 712 }
708 713
709 if (dev->flags & IFF_UP) 714 if (dev->flags & IFF_UP)
@@ -721,7 +726,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
721 err = -ENOENT; 726 err = -ENOENT;
722 } 727 }
723 if (!err) 728 if (!err)
724 notify_and_destroy(skb, n, classid, old, new); 729 notify_and_destroy(net, skb, n, classid, old, new);
725 } 730 }
726 return err; 731 return err;
727} 732}
@@ -947,10 +952,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
947 struct Qdisc *p = NULL; 952 struct Qdisc *p = NULL;
948 int err; 953 int err;
949 954
950 if (!net_eq(net, &init_net)) 955 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; 956 return -ENODEV;
955 957
956 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 958 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
@@ -990,7 +992,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) 992 if ((err = qdisc_graft(dev, p, skb, n, clid, NULL, q)) != 0)
991 return err; 993 return err;
992 } else { 994 } else {
993 qdisc_notify(skb, n, clid, NULL, q); 995 qdisc_notify(net, skb, n, clid, NULL, q);
994 } 996 }
995 return 0; 997 return 0;
996} 998}
@@ -1009,16 +1011,13 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1009 struct Qdisc *q, *p; 1011 struct Qdisc *q, *p;
1010 int err; 1012 int err;
1011 1013
1012 if (!net_eq(net, &init_net))
1013 return -EINVAL;
1014
1015replay: 1014replay:
1016 /* Reinit, just in case something touches this. */ 1015 /* Reinit, just in case something touches this. */
1017 tcm = NLMSG_DATA(n); 1016 tcm = NLMSG_DATA(n);
1018 clid = tcm->tcm_parent; 1017 clid = tcm->tcm_parent;
1019 q = p = NULL; 1018 q = p = NULL;
1020 1019
1021 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 1020 if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
1022 return -ENODEV; 1021 return -ENODEV;
1023 1022
1024 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 1023 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
@@ -1105,7 +1104,7 @@ replay:
1105 return -EINVAL; 1104 return -EINVAL;
1106 err = qdisc_change(q, tca); 1105 err = qdisc_change(q, tca);
1107 if (err == 0) 1106 if (err == 0)
1108 qdisc_notify(skb, n, clid, NULL, q); 1107 qdisc_notify(net, skb, n, clid, NULL, q);
1109 return err; 1108 return err;
1110 1109
1111create_n_graft: 1110create_n_graft:
@@ -1195,8 +1194,9 @@ nla_put_failure:
1195 return -1; 1194 return -1;
1196} 1195}
1197 1196
1198static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, 1197static int qdisc_notify(struct net *net, struct sk_buff *oskb,
1199 u32 clid, struct Qdisc *old, struct Qdisc *new) 1198 struct nlmsghdr *n, u32 clid,
1199 struct Qdisc *old, struct Qdisc *new)
1200{ 1200{
1201 struct sk_buff *skb; 1201 struct sk_buff *skb;
1202 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; 1202 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
@@ -1215,7 +1215,7 @@ static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n,
1215 } 1215 }
1216 1216
1217 if (skb->len) 1217 if (skb->len)
1218 return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 1218 return rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
1219 1219
1220err_out: 1220err_out:
1221 kfree_skb(skb); 1221 kfree_skb(skb);
@@ -1274,15 +1274,12 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
1274 int s_idx, s_q_idx; 1274 int s_idx, s_q_idx;
1275 struct net_device *dev; 1275 struct net_device *dev;
1276 1276
1277 if (!net_eq(net, &init_net))
1278 return 0;
1279
1280 s_idx = cb->args[0]; 1277 s_idx = cb->args[0];
1281 s_q_idx = q_idx = cb->args[1]; 1278 s_q_idx = q_idx = cb->args[1];
1282 1279
1283 rcu_read_lock(); 1280 rcu_read_lock();
1284 idx = 0; 1281 idx = 0;
1285 for_each_netdev_rcu(&init_net, dev) { 1282 for_each_netdev_rcu(net, dev) {
1286 struct netdev_queue *dev_queue; 1283 struct netdev_queue *dev_queue;
1287 1284
1288 if (idx < s_idx) 1285 if (idx < s_idx)
@@ -1334,10 +1331,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1334 u32 qid = TC_H_MAJ(clid); 1331 u32 qid = TC_H_MAJ(clid);
1335 int err; 1332 int err;
1336 1333
1337 if (!net_eq(net, &init_net)) 1334 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; 1335 return -ENODEV;
1342 1336
1343 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 1337 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
@@ -1418,10 +1412,10 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1418 if (cops->delete) 1412 if (cops->delete)
1419 err = cops->delete(q, cl); 1413 err = cops->delete(q, cl);
1420 if (err == 0) 1414 if (err == 0)
1421 tclass_notify(skb, n, q, cl, RTM_DELTCLASS); 1415 tclass_notify(net, skb, n, q, cl, RTM_DELTCLASS);
1422 goto out; 1416 goto out;
1423 case RTM_GETTCLASS: 1417 case RTM_GETTCLASS:
1424 err = tclass_notify(skb, n, q, cl, RTM_NEWTCLASS); 1418 err = tclass_notify(net, skb, n, q, cl, RTM_NEWTCLASS);
1425 goto out; 1419 goto out;
1426 default: 1420 default:
1427 err = -EINVAL; 1421 err = -EINVAL;
@@ -1434,7 +1428,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1434 if (cops->change) 1428 if (cops->change)
1435 err = cops->change(q, clid, pid, tca, &new_cl); 1429 err = cops->change(q, clid, pid, tca, &new_cl);
1436 if (err == 0) 1430 if (err == 0)
1437 tclass_notify(skb, n, q, new_cl, RTM_NEWTCLASS); 1431 tclass_notify(net, skb, n, q, new_cl, RTM_NEWTCLASS);
1438 1432
1439out: 1433out:
1440 if (cl) 1434 if (cl)
@@ -1486,8 +1480,9 @@ nla_put_failure:
1486 return -1; 1480 return -1;
1487} 1481}
1488 1482
1489static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, 1483static int tclass_notify(struct net *net, struct sk_buff *oskb,
1490 struct Qdisc *q, unsigned long cl, int event) 1484 struct nlmsghdr *n, struct Qdisc *q,
1485 unsigned long cl, int event)
1491{ 1486{
1492 struct sk_buff *skb; 1487 struct sk_buff *skb;
1493 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; 1488 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
@@ -1501,7 +1496,7 @@ static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
1501 return -EINVAL; 1496 return -EINVAL;
1502 } 1497 }
1503 1498
1504 return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 1499 return rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
1505} 1500}
1506 1501
1507struct qdisc_dump_args 1502struct qdisc_dump_args
@@ -1576,12 +1571,9 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1576 struct net_device *dev; 1571 struct net_device *dev;
1577 int t, s_t; 1572 int t, s_t;
1578 1573
1579 if (!net_eq(net, &init_net))
1580 return 0;
1581
1582 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) 1574 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
1583 return 0; 1575 return 0;
1584 if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 1576 if ((dev = dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
1585 return 0; 1577 return 0;
1586 1578
1587 s_t = cb->args[0]; 1579 s_t = cb->args[0];
@@ -1701,15 +1693,55 @@ static const struct file_operations psched_fops = {
1701 .llseek = seq_lseek, 1693 .llseek = seq_lseek,
1702 .release = single_release, 1694 .release = single_release,
1703}; 1695};
1696
1697static int __net_init psched_net_init(struct net *net)
1698{
1699 struct proc_dir_entry *e;
1700
1701 e = proc_net_fops_create(net, "psched", 0, &psched_fops);
1702 if (e == NULL)
1703 return -ENOMEM;
1704
1705 return 0;
1706}
1707
1708static void __net_exit psched_net_exit(struct net *net)
1709{
1710 proc_net_remove(net, "psched");
1711
1712 return;
1713}
1714#else
1715static int __net_init psched_net_init(struct net *net)
1716{
1717 return 0;
1718}
1719
1720static void __net_exit psched_net_exit(struct net *net)
1721{
1722}
1704#endif 1723#endif
1705 1724
1725static struct pernet_operations psched_net_ops = {
1726 .init = psched_net_init,
1727 .exit = psched_net_exit,
1728};
1729
1706static int __init pktsched_init(void) 1730static int __init pktsched_init(void)
1707{ 1731{
1732 int err;
1733
1734 err = register_pernet_subsys(&psched_net_ops);
1735 if (err) {
1736 printk(KERN_ERR "pktsched_init: "
1737 "cannot initialize per netns operations\n");
1738 return err;
1739 }
1740
1708 register_qdisc(&pfifo_qdisc_ops); 1741 register_qdisc(&pfifo_qdisc_ops);
1709 register_qdisc(&bfifo_qdisc_ops); 1742 register_qdisc(&bfifo_qdisc_ops);
1710 register_qdisc(&pfifo_head_drop_qdisc_ops); 1743 register_qdisc(&pfifo_head_drop_qdisc_ops);
1711 register_qdisc(&mq_qdisc_ops); 1744 register_qdisc(&mq_qdisc_ops);
1712 proc_net_fops_create(&init_net, "psched", 0, &psched_fops);
1713 1745
1714 rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL); 1746 rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);
1715 rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL); 1747 rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL);