diff options
| author | Tom Goff <thomas.goff@boeing.com> | 2010-03-19 11:40:13 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-03-22 23:26:25 -0400 |
| commit | 7316ae88c43d47f6503f4c29b4973204e33c3411 (patch) | |
| tree | 442b265d3fd083065330e355cf8e9c73196cc443 | |
| parent | 300bc0602489d9f09f7b548f790afd2952f6070b (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>
| -rw-r--r-- | net/sched/act_api.c | 45 | ||||
| -rw-r--r-- | net/sched/cls_api.c | 30 | ||||
| -rw-r--r-- | net/sched/sch_api.c | 112 |
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 | ||
| 669 | static int | 669 | static int |
| 670 | act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event) | 670 | act_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 | ||
| 685 | static struct tc_action * | 686 | static 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 | ||
| 752 | static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid) | 753 | static 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 | ||
| 827 | static int | 829 | static int |
| 828 | tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event) | 830 | tca_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 | ||
| 891 | static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, | 894 | static 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 | ||
| 937 | static int | 940 | static int |
| 938 | tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr) | 941 | tcf_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; |
| 996 | replay: | 997 | replay: |
| 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) | |||
| 1042 | static int | 1045 | static int |
| 1043 | tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) | 1046 | tc_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 | } |
| 99 | EXPORT_SYMBOL(unregister_tcf_proto_ops); | 99 | EXPORT_SYMBOL(unregister_tcf_proto_ops); |
| 100 | 100 | ||
| 101 | static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n, | 101 | static 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 | |||
| 143 | replay: | 141 | replay: |
| 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 | ||
| 373 | static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n, | 371 | static 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 | ||
| 37 | static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, u32 clid, | 37 | static 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); |
| 39 | static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, | 40 | static 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 | } |
| 639 | EXPORT_SYMBOL(qdisc_tree_decrease_qlen); | 641 | EXPORT_SYMBOL(qdisc_tree_decrease_qlen); |
| 640 | 642 | ||
| 641 | static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid, | 643 | static 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 | |||
| 1015 | replay: | 1014 | replay: |
| 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 | ||
| 1111 | create_n_graft: | 1110 | create_n_graft: |
| @@ -1195,8 +1194,9 @@ nla_put_failure: | |||
| 1195 | return -1; | 1194 | return -1; |
| 1196 | } | 1195 | } |
| 1197 | 1196 | ||
| 1198 | static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, | 1197 | static 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 | ||
| 1220 | err_out: | 1220 | err_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 | ||
| 1439 | out: | 1433 | out: |
| 1440 | if (cl) | 1434 | if (cl) |
| @@ -1486,8 +1480,9 @@ nla_put_failure: | |||
| 1486 | return -1; | 1480 | return -1; |
| 1487 | } | 1481 | } |
| 1488 | 1482 | ||
| 1489 | static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, | 1483 | static 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 | ||
| 1507 | struct qdisc_dump_args | 1502 | struct 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 | |||
| 1697 | static 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 | |||
| 1708 | static void __net_exit psched_net_exit(struct net *net) | ||
| 1709 | { | ||
| 1710 | proc_net_remove(net, "psched"); | ||
| 1711 | |||
| 1712 | return; | ||
| 1713 | } | ||
| 1714 | #else | ||
| 1715 | static int __net_init psched_net_init(struct net *net) | ||
| 1716 | { | ||
| 1717 | return 0; | ||
| 1718 | } | ||
| 1719 | |||
| 1720 | static void __net_exit psched_net_exit(struct net *net) | ||
| 1721 | { | ||
| 1722 | } | ||
| 1704 | #endif | 1723 | #endif |
| 1705 | 1724 | ||
| 1725 | static struct pernet_operations psched_net_ops = { | ||
| 1726 | .init = psched_net_init, | ||
| 1727 | .exit = psched_net_exit, | ||
| 1728 | }; | ||
| 1729 | |||
| 1706 | static int __init pktsched_init(void) | 1730 | static 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); |
