diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/act_api.c | 52 | ||||
-rw-r--r-- | net/sched/act_mirred.c | 11 | ||||
-rw-r--r-- | net/sched/cls_api.c | 16 | ||||
-rw-r--r-- | net/sched/cls_basic.c | 3 | ||||
-rw-r--r-- | net/sched/cls_cgroup.c | 25 | ||||
-rw-r--r-- | net/sched/cls_flow.c | 19 | ||||
-rw-r--r-- | net/sched/cls_fw.c | 3 | ||||
-rw-r--r-- | net/sched/cls_route.c | 3 | ||||
-rw-r--r-- | net/sched/cls_rsvp.h | 3 | ||||
-rw-r--r-- | net/sched/cls_tcindex.c | 3 | ||||
-rw-r--r-- | net/sched/cls_u32.c | 3 | ||||
-rw-r--r-- | net/sched/em_meta.c | 2 | ||||
-rw-r--r-- | net/sched/sch_api.c | 44 | ||||
-rw-r--r-- | net/sched/sch_cbq.c | 5 | ||||
-rw-r--r-- | net/sched/sch_drr.c | 2 | ||||
-rw-r--r-- | net/sched/sch_fq_codel.c | 2 | ||||
-rw-r--r-- | net/sched/sch_generic.c | 27 | ||||
-rw-r--r-- | net/sched/sch_gred.c | 38 | ||||
-rw-r--r-- | net/sched/sch_qfq.c | 7 |
19 files changed, 139 insertions, 129 deletions
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index e3d2c78cb52..102761d294c 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -644,7 +644,7 @@ errout: | |||
644 | } | 644 | } |
645 | 645 | ||
646 | static int | 646 | static int |
647 | tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, | 647 | tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 portid, u32 seq, |
648 | u16 flags, int event, int bind, int ref) | 648 | u16 flags, int event, int bind, int ref) |
649 | { | 649 | { |
650 | struct tcamsg *t; | 650 | struct tcamsg *t; |
@@ -652,7 +652,7 @@ tca_get_fill(struct sk_buff *skb, struct tc_action *a, u32 pid, u32 seq, | |||
652 | unsigned char *b = skb_tail_pointer(skb); | 652 | unsigned char *b = skb_tail_pointer(skb); |
653 | struct nlattr *nest; | 653 | struct nlattr *nest; |
654 | 654 | ||
655 | nlh = nlmsg_put(skb, pid, seq, event, sizeof(*t), flags); | 655 | nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags); |
656 | if (!nlh) | 656 | if (!nlh) |
657 | goto out_nlmsg_trim; | 657 | goto out_nlmsg_trim; |
658 | t = nlmsg_data(nlh); | 658 | t = nlmsg_data(nlh); |
@@ -678,7 +678,7 @@ out_nlmsg_trim: | |||
678 | } | 678 | } |
679 | 679 | ||
680 | static int | 680 | static int |
681 | act_get_notify(struct net *net, u32 pid, struct nlmsghdr *n, | 681 | act_get_notify(struct net *net, u32 portid, struct nlmsghdr *n, |
682 | struct tc_action *a, int event) | 682 | struct tc_action *a, int event) |
683 | { | 683 | { |
684 | struct sk_buff *skb; | 684 | struct sk_buff *skb; |
@@ -686,16 +686,16 @@ act_get_notify(struct net *net, u32 pid, struct nlmsghdr *n, | |||
686 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 686 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
687 | if (!skb) | 687 | if (!skb) |
688 | return -ENOBUFS; | 688 | return -ENOBUFS; |
689 | if (tca_get_fill(skb, a, pid, n->nlmsg_seq, 0, event, 0, 0) <= 0) { | 689 | if (tca_get_fill(skb, a, portid, n->nlmsg_seq, 0, event, 0, 0) <= 0) { |
690 | kfree_skb(skb); | 690 | kfree_skb(skb); |
691 | return -EINVAL; | 691 | return -EINVAL; |
692 | } | 692 | } |
693 | 693 | ||
694 | return rtnl_unicast(skb, net, pid); | 694 | return rtnl_unicast(skb, net, portid); |
695 | } | 695 | } |
696 | 696 | ||
697 | static struct tc_action * | 697 | static struct tc_action * |
698 | tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 pid) | 698 | tcf_action_get_1(struct nlattr *nla, struct nlmsghdr *n, u32 portid) |
699 | { | 699 | { |
700 | struct nlattr *tb[TCA_ACT_MAX + 1]; | 700 | struct nlattr *tb[TCA_ACT_MAX + 1]; |
701 | struct tc_action *a; | 701 | struct tc_action *a; |
@@ -762,7 +762,7 @@ static struct tc_action *create_a(int i) | |||
762 | } | 762 | } |
763 | 763 | ||
764 | static int tca_action_flush(struct net *net, struct nlattr *nla, | 764 | static int tca_action_flush(struct net *net, struct nlattr *nla, |
765 | struct nlmsghdr *n, u32 pid) | 765 | struct nlmsghdr *n, u32 portid) |
766 | { | 766 | { |
767 | struct sk_buff *skb; | 767 | struct sk_buff *skb; |
768 | unsigned char *b; | 768 | unsigned char *b; |
@@ -799,7 +799,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, | |||
799 | if (a->ops == NULL) | 799 | if (a->ops == NULL) |
800 | goto err_out; | 800 | goto err_out; |
801 | 801 | ||
802 | nlh = nlmsg_put(skb, pid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t), 0); | 802 | nlh = nlmsg_put(skb, portid, n->nlmsg_seq, RTM_DELACTION, sizeof(*t), 0); |
803 | if (!nlh) | 803 | if (!nlh) |
804 | goto out_module_put; | 804 | goto out_module_put; |
805 | t = nlmsg_data(nlh); | 805 | t = nlmsg_data(nlh); |
@@ -823,7 +823,7 @@ static int tca_action_flush(struct net *net, struct nlattr *nla, | |||
823 | nlh->nlmsg_flags |= NLM_F_ROOT; | 823 | nlh->nlmsg_flags |= NLM_F_ROOT; |
824 | module_put(a->ops->owner); | 824 | module_put(a->ops->owner); |
825 | kfree(a); | 825 | kfree(a); |
826 | err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, | 826 | err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, |
827 | n->nlmsg_flags & NLM_F_ECHO); | 827 | n->nlmsg_flags & NLM_F_ECHO); |
828 | if (err > 0) | 828 | if (err > 0) |
829 | return 0; | 829 | return 0; |
@@ -841,7 +841,7 @@ noflush_out: | |||
841 | 841 | ||
842 | static int | 842 | static int |
843 | tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, | 843 | tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, |
844 | u32 pid, int event) | 844 | u32 portid, int event) |
845 | { | 845 | { |
846 | int i, ret; | 846 | int i, ret; |
847 | struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; | 847 | struct nlattr *tb[TCA_ACT_MAX_PRIO + 1]; |
@@ -853,13 +853,13 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, | |||
853 | 853 | ||
854 | if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) { | 854 | if (event == RTM_DELACTION && n->nlmsg_flags & NLM_F_ROOT) { |
855 | if (tb[1] != NULL) | 855 | if (tb[1] != NULL) |
856 | return tca_action_flush(net, tb[1], n, pid); | 856 | return tca_action_flush(net, tb[1], n, portid); |
857 | else | 857 | else |
858 | return -EINVAL; | 858 | return -EINVAL; |
859 | } | 859 | } |
860 | 860 | ||
861 | for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { | 861 | for (i = 1; i <= TCA_ACT_MAX_PRIO && tb[i]; i++) { |
862 | act = tcf_action_get_1(tb[i], n, pid); | 862 | act = tcf_action_get_1(tb[i], n, portid); |
863 | if (IS_ERR(act)) { | 863 | if (IS_ERR(act)) { |
864 | ret = PTR_ERR(act); | 864 | ret = PTR_ERR(act); |
865 | goto err; | 865 | goto err; |
@@ -874,7 +874,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, | |||
874 | } | 874 | } |
875 | 875 | ||
876 | if (event == RTM_GETACTION) | 876 | if (event == RTM_GETACTION) |
877 | ret = act_get_notify(net, pid, n, head, event); | 877 | ret = act_get_notify(net, portid, n, head, event); |
878 | else { /* delete */ | 878 | else { /* delete */ |
879 | struct sk_buff *skb; | 879 | struct sk_buff *skb; |
880 | 880 | ||
@@ -884,7 +884,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, | |||
884 | goto err; | 884 | goto err; |
885 | } | 885 | } |
886 | 886 | ||
887 | if (tca_get_fill(skb, head, pid, n->nlmsg_seq, 0, event, | 887 | if (tca_get_fill(skb, head, portid, n->nlmsg_seq, 0, event, |
888 | 0, 1) <= 0) { | 888 | 0, 1) <= 0) { |
889 | kfree_skb(skb); | 889 | kfree_skb(skb); |
890 | ret = -EINVAL; | 890 | ret = -EINVAL; |
@@ -893,7 +893,7 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n, | |||
893 | 893 | ||
894 | /* now do the delete */ | 894 | /* now do the delete */ |
895 | tcf_action_destroy(head, 0); | 895 | tcf_action_destroy(head, 0); |
896 | ret = rtnetlink_send(skb, net, pid, RTNLGRP_TC, | 896 | ret = rtnetlink_send(skb, net, portid, RTNLGRP_TC, |
897 | n->nlmsg_flags & NLM_F_ECHO); | 897 | n->nlmsg_flags & NLM_F_ECHO); |
898 | if (ret > 0) | 898 | if (ret > 0) |
899 | return 0; | 899 | return 0; |
@@ -905,7 +905,7 @@ err: | |||
905 | } | 905 | } |
906 | 906 | ||
907 | static int tcf_add_notify(struct net *net, struct tc_action *a, | 907 | static int tcf_add_notify(struct net *net, struct tc_action *a, |
908 | u32 pid, u32 seq, int event, u16 flags) | 908 | u32 portid, u32 seq, int event, u16 flags) |
909 | { | 909 | { |
910 | struct tcamsg *t; | 910 | struct tcamsg *t; |
911 | struct nlmsghdr *nlh; | 911 | struct nlmsghdr *nlh; |
@@ -920,7 +920,7 @@ static int tcf_add_notify(struct net *net, struct tc_action *a, | |||
920 | 920 | ||
921 | b = skb_tail_pointer(skb); | 921 | b = skb_tail_pointer(skb); |
922 | 922 | ||
923 | nlh = nlmsg_put(skb, pid, seq, event, sizeof(*t), flags); | 923 | nlh = nlmsg_put(skb, portid, seq, event, sizeof(*t), flags); |
924 | if (!nlh) | 924 | if (!nlh) |
925 | goto out_kfree_skb; | 925 | goto out_kfree_skb; |
926 | t = nlmsg_data(nlh); | 926 | t = nlmsg_data(nlh); |
@@ -940,7 +940,7 @@ static int tcf_add_notify(struct net *net, struct tc_action *a, | |||
940 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; | 940 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; |
941 | NETLINK_CB(skb).dst_group = RTNLGRP_TC; | 941 | NETLINK_CB(skb).dst_group = RTNLGRP_TC; |
942 | 942 | ||
943 | err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, flags & NLM_F_ECHO); | 943 | err = rtnetlink_send(skb, net, portid, RTNLGRP_TC, flags & NLM_F_ECHO); |
944 | if (err > 0) | 944 | if (err > 0) |
945 | err = 0; | 945 | err = 0; |
946 | return err; | 946 | return err; |
@@ -953,7 +953,7 @@ out_kfree_skb: | |||
953 | 953 | ||
954 | static int | 954 | static int |
955 | tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n, | 955 | tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n, |
956 | u32 pid, int ovr) | 956 | u32 portid, int ovr) |
957 | { | 957 | { |
958 | int ret = 0; | 958 | int ret = 0; |
959 | struct tc_action *act; | 959 | struct tc_action *act; |
@@ -971,7 +971,7 @@ tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n, | |||
971 | /* dump then free all the actions after update; inserted policy | 971 | /* dump then free all the actions after update; inserted policy |
972 | * stays intact | 972 | * stays intact |
973 | */ | 973 | */ |
974 | ret = tcf_add_notify(net, act, pid, seq, RTM_NEWACTION, n->nlmsg_flags); | 974 | ret = tcf_add_notify(net, act, portid, seq, RTM_NEWACTION, n->nlmsg_flags); |
975 | for (a = act; a; a = act) { | 975 | for (a = act; a; a = act) { |
976 | act = a->next; | 976 | act = a->next; |
977 | kfree(a); | 977 | kfree(a); |
@@ -984,7 +984,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
984 | { | 984 | { |
985 | struct net *net = sock_net(skb->sk); | 985 | struct net *net = sock_net(skb->sk); |
986 | struct nlattr *tca[TCA_ACT_MAX + 1]; | 986 | struct nlattr *tca[TCA_ACT_MAX + 1]; |
987 | u32 pid = skb ? NETLINK_CB(skb).pid : 0; | 987 | u32 portid = skb ? NETLINK_CB(skb).portid : 0; |
988 | int ret = 0, ovr = 0; | 988 | int ret = 0, ovr = 0; |
989 | 989 | ||
990 | ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); | 990 | ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); |
@@ -1008,17 +1008,17 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1008 | if (n->nlmsg_flags & NLM_F_REPLACE) | 1008 | if (n->nlmsg_flags & NLM_F_REPLACE) |
1009 | ovr = 1; | 1009 | ovr = 1; |
1010 | replay: | 1010 | replay: |
1011 | ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, pid, ovr); | 1011 | ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, portid, ovr); |
1012 | if (ret == -EAGAIN) | 1012 | if (ret == -EAGAIN) |
1013 | goto replay; | 1013 | goto replay; |
1014 | break; | 1014 | break; |
1015 | case RTM_DELACTION: | 1015 | case RTM_DELACTION: |
1016 | ret = tca_action_gd(net, tca[TCA_ACT_TAB], n, | 1016 | ret = tca_action_gd(net, tca[TCA_ACT_TAB], n, |
1017 | pid, RTM_DELACTION); | 1017 | portid, RTM_DELACTION); |
1018 | break; | 1018 | break; |
1019 | case RTM_GETACTION: | 1019 | case RTM_GETACTION: |
1020 | ret = tca_action_gd(net, tca[TCA_ACT_TAB], n, | 1020 | ret = tca_action_gd(net, tca[TCA_ACT_TAB], n, |
1021 | pid, RTM_GETACTION); | 1021 | portid, RTM_GETACTION); |
1022 | break; | 1022 | break; |
1023 | default: | 1023 | default: |
1024 | BUG(); | 1024 | BUG(); |
@@ -1085,7 +1085,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) | |||
1085 | goto out_module_put; | 1085 | goto out_module_put; |
1086 | } | 1086 | } |
1087 | 1087 | ||
1088 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).pid, cb->nlh->nlmsg_seq, | 1088 | nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, |
1089 | cb->nlh->nlmsg_type, sizeof(*t), 0); | 1089 | cb->nlh->nlmsg_type, sizeof(*t), 0); |
1090 | if (!nlh) | 1090 | if (!nlh) |
1091 | goto out_module_put; | 1091 | goto out_module_put; |
@@ -1109,7 +1109,7 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) | |||
1109 | nla_nest_cancel(skb, nest); | 1109 | nla_nest_cancel(skb, nest); |
1110 | 1110 | ||
1111 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; | 1111 | nlh->nlmsg_len = skb_tail_pointer(skb) - b; |
1112 | if (NETLINK_CB(cb->skb).pid && ret) | 1112 | if (NETLINK_CB(cb->skb).portid && ret) |
1113 | nlh->nlmsg_flags |= NLM_F_MULTI; | 1113 | nlh->nlmsg_flags |= NLM_F_MULTI; |
1114 | module_put(a_o->owner); | 1114 | module_put(a_o->owner); |
1115 | return skb->len; | 1115 | return skb->len; |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index fe81cc18e9e..9c0fd0c7881 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -200,13 +200,12 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, | |||
200 | out: | 200 | out: |
201 | if (err) { | 201 | if (err) { |
202 | m->tcf_qstats.overlimits++; | 202 | m->tcf_qstats.overlimits++; |
203 | /* should we be asking for packet to be dropped? | 203 | if (m->tcfm_eaction != TCA_EGRESS_MIRROR) |
204 | * may make sense for redirect case only | 204 | retval = TC_ACT_SHOT; |
205 | */ | 205 | else |
206 | retval = TC_ACT_SHOT; | 206 | retval = m->tcf_action; |
207 | } else { | 207 | } else |
208 | retval = m->tcf_action; | 208 | retval = m->tcf_action; |
209 | } | ||
210 | spin_unlock(&m->tcf_lock); | 209 | spin_unlock(&m->tcf_lock); |
211 | 210 | ||
212 | return retval; | 211 | return retval; |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 6dd1131f2ec..7ae02892437 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -319,7 +319,7 @@ replay: | |||
319 | } | 319 | } |
320 | } | 320 | } |
321 | 321 | ||
322 | err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh); | 322 | err = tp->ops->change(skb, tp, cl, t->tcm_handle, tca, &fh); |
323 | if (err == 0) { | 323 | if (err == 0) { |
324 | if (tp_created) { | 324 | if (tp_created) { |
325 | spin_lock_bh(root_lock); | 325 | spin_lock_bh(root_lock); |
@@ -343,13 +343,13 @@ errout: | |||
343 | } | 343 | } |
344 | 344 | ||
345 | static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, | 345 | static int tcf_fill_node(struct sk_buff *skb, struct tcf_proto *tp, |
346 | unsigned long fh, u32 pid, u32 seq, u16 flags, int event) | 346 | unsigned long fh, u32 portid, u32 seq, u16 flags, int event) |
347 | { | 347 | { |
348 | struct tcmsg *tcm; | 348 | struct tcmsg *tcm; |
349 | struct nlmsghdr *nlh; | 349 | struct nlmsghdr *nlh; |
350 | unsigned char *b = skb_tail_pointer(skb); | 350 | unsigned char *b = skb_tail_pointer(skb); |
351 | 351 | ||
352 | nlh = nlmsg_put(skb, pid, seq, event, sizeof(*tcm), flags); | 352 | nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); |
353 | if (!nlh) | 353 | if (!nlh) |
354 | goto out_nlmsg_trim; | 354 | goto out_nlmsg_trim; |
355 | tcm = nlmsg_data(nlh); | 355 | tcm = nlmsg_data(nlh); |
@@ -381,18 +381,18 @@ static int tfilter_notify(struct net *net, struct sk_buff *oskb, | |||
381 | unsigned long fh, int event) | 381 | unsigned long fh, int event) |
382 | { | 382 | { |
383 | struct sk_buff *skb; | 383 | struct sk_buff *skb; |
384 | u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; | 384 | u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; |
385 | 385 | ||
386 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 386 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
387 | if (!skb) | 387 | if (!skb) |
388 | return -ENOBUFS; | 388 | return -ENOBUFS; |
389 | 389 | ||
390 | if (tcf_fill_node(skb, tp, fh, pid, n->nlmsg_seq, 0, event) <= 0) { | 390 | if (tcf_fill_node(skb, tp, fh, portid, n->nlmsg_seq, 0, event) <= 0) { |
391 | kfree_skb(skb); | 391 | kfree_skb(skb); |
392 | return -EINVAL; | 392 | return -EINVAL; |
393 | } | 393 | } |
394 | 394 | ||
395 | return rtnetlink_send(skb, net, pid, RTNLGRP_TC, | 395 | return rtnetlink_send(skb, net, portid, RTNLGRP_TC, |
396 | n->nlmsg_flags & NLM_F_ECHO); | 396 | n->nlmsg_flags & NLM_F_ECHO); |
397 | } | 397 | } |
398 | 398 | ||
@@ -407,7 +407,7 @@ static int tcf_node_dump(struct tcf_proto *tp, unsigned long n, | |||
407 | { | 407 | { |
408 | struct tcf_dump_args *a = (void *)arg; | 408 | struct tcf_dump_args *a = (void *)arg; |
409 | 409 | ||
410 | return tcf_fill_node(a->skb, tp, n, NETLINK_CB(a->cb->skb).pid, | 410 | return tcf_fill_node(a->skb, tp, n, NETLINK_CB(a->cb->skb).portid, |
411 | a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER); | 411 | a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTFILTER); |
412 | } | 412 | } |
413 | 413 | ||
@@ -465,7 +465,7 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) | |||
465 | if (t > s_t) | 465 | if (t > s_t) |
466 | memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0])); | 466 | memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0])); |
467 | if (cb->args[1] == 0) { | 467 | if (cb->args[1] == 0) { |
468 | if (tcf_fill_node(skb, tp, 0, NETLINK_CB(cb->skb).pid, | 468 | if (tcf_fill_node(skb, tp, 0, NETLINK_CB(cb->skb).portid, |
469 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 469 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
470 | RTM_NEWTFILTER) <= 0) | 470 | RTM_NEWTFILTER) <= 0) |
471 | break; | 471 | break; |
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c index 590960a22a7..344a11b342e 100644 --- a/net/sched/cls_basic.c +++ b/net/sched/cls_basic.c | |||
@@ -162,7 +162,8 @@ errout: | |||
162 | return err; | 162 | return err; |
163 | } | 163 | } |
164 | 164 | ||
165 | static int basic_change(struct tcf_proto *tp, unsigned long base, u32 handle, | 165 | static int basic_change(struct sk_buff *in_skb, |
166 | struct tcf_proto *tp, unsigned long base, u32 handle, | ||
166 | struct nlattr **tca, unsigned long *arg) | 167 | struct nlattr **tca, unsigned long *arg) |
167 | { | 168 | { |
168 | int err; | 169 | int err; |
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index 7743ea8d1d3..2ecde225ae6 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
@@ -77,11 +77,18 @@ struct cgroup_subsys net_cls_subsys = { | |||
77 | .name = "net_cls", | 77 | .name = "net_cls", |
78 | .create = cgrp_create, | 78 | .create = cgrp_create, |
79 | .destroy = cgrp_destroy, | 79 | .destroy = cgrp_destroy, |
80 | #ifdef CONFIG_NET_CLS_CGROUP | ||
81 | .subsys_id = net_cls_subsys_id, | 80 | .subsys_id = net_cls_subsys_id, |
82 | #endif | ||
83 | .base_cftypes = ss_files, | 81 | .base_cftypes = ss_files, |
84 | .module = THIS_MODULE, | 82 | .module = THIS_MODULE, |
83 | |||
84 | /* | ||
85 | * While net_cls cgroup has the rudimentary hierarchy support of | ||
86 | * inheriting the parent's classid on cgroup creation, it doesn't | ||
87 | * properly propagates config changes in ancestors to their | ||
88 | * descendents. A child should follow the parent's configuration | ||
89 | * but be allowed to override it. Fix it and remove the following. | ||
90 | */ | ||
91 | .broken_hierarchy = true, | ||
85 | }; | 92 | }; |
86 | 93 | ||
87 | struct cls_cgroup_head { | 94 | struct cls_cgroup_head { |
@@ -151,7 +158,8 @@ static const struct nla_policy cgroup_policy[TCA_CGROUP_MAX + 1] = { | |||
151 | [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, | 158 | [TCA_CGROUP_EMATCHES] = { .type = NLA_NESTED }, |
152 | }; | 159 | }; |
153 | 160 | ||
154 | static int cls_cgroup_change(struct tcf_proto *tp, unsigned long base, | 161 | static int cls_cgroup_change(struct sk_buff *in_skb, |
162 | struct tcf_proto *tp, unsigned long base, | ||
155 | u32 handle, struct nlattr **tca, | 163 | u32 handle, struct nlattr **tca, |
156 | unsigned long *arg) | 164 | unsigned long *arg) |
157 | { | 165 | { |
@@ -283,12 +291,6 @@ static int __init init_cgroup_cls(void) | |||
283 | if (ret) | 291 | if (ret) |
284 | goto out; | 292 | goto out; |
285 | 293 | ||
286 | #ifndef CONFIG_NET_CLS_CGROUP | ||
287 | /* We can't use rcu_assign_pointer because this is an int. */ | ||
288 | smp_wmb(); | ||
289 | net_cls_subsys_id = net_cls_subsys.subsys_id; | ||
290 | #endif | ||
291 | |||
292 | ret = register_tcf_proto_ops(&cls_cgroup_ops); | 294 | ret = register_tcf_proto_ops(&cls_cgroup_ops); |
293 | if (ret) | 295 | if (ret) |
294 | cgroup_unload_subsys(&net_cls_subsys); | 296 | cgroup_unload_subsys(&net_cls_subsys); |
@@ -301,11 +303,6 @@ static void __exit exit_cgroup_cls(void) | |||
301 | { | 303 | { |
302 | unregister_tcf_proto_ops(&cls_cgroup_ops); | 304 | unregister_tcf_proto_ops(&cls_cgroup_ops); |
303 | 305 | ||
304 | #ifndef CONFIG_NET_CLS_CGROUP | ||
305 | net_cls_subsys_id = -1; | ||
306 | synchronize_rcu(); | ||
307 | #endif | ||
308 | |||
309 | cgroup_unload_subsys(&net_cls_subsys); | 306 | cgroup_unload_subsys(&net_cls_subsys); |
310 | } | 307 | } |
311 | 308 | ||
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c index ccd08c8dc6a..ce82d0cb1b4 100644 --- a/net/sched/cls_flow.c +++ b/net/sched/cls_flow.c | |||
@@ -193,15 +193,19 @@ static u32 flow_get_rtclassid(const struct sk_buff *skb) | |||
193 | 193 | ||
194 | static u32 flow_get_skuid(const struct sk_buff *skb) | 194 | static u32 flow_get_skuid(const struct sk_buff *skb) |
195 | { | 195 | { |
196 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) | 196 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { |
197 | return skb->sk->sk_socket->file->f_cred->fsuid; | 197 | kuid_t skuid = skb->sk->sk_socket->file->f_cred->fsuid; |
198 | return from_kuid(&init_user_ns, skuid); | ||
199 | } | ||
198 | return 0; | 200 | return 0; |
199 | } | 201 | } |
200 | 202 | ||
201 | static u32 flow_get_skgid(const struct sk_buff *skb) | 203 | static u32 flow_get_skgid(const struct sk_buff *skb) |
202 | { | 204 | { |
203 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) | 205 | if (skb->sk && skb->sk->sk_socket && skb->sk->sk_socket->file) { |
204 | return skb->sk->sk_socket->file->f_cred->fsgid; | 206 | kgid_t skgid = skb->sk->sk_socket->file->f_cred->fsgid; |
207 | return from_kgid(&init_user_ns, skgid); | ||
208 | } | ||
205 | return 0; | 209 | return 0; |
206 | } | 210 | } |
207 | 211 | ||
@@ -347,7 +351,8 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = { | |||
347 | [TCA_FLOW_PERTURB] = { .type = NLA_U32 }, | 351 | [TCA_FLOW_PERTURB] = { .type = NLA_U32 }, |
348 | }; | 352 | }; |
349 | 353 | ||
350 | static int flow_change(struct tcf_proto *tp, unsigned long base, | 354 | static int flow_change(struct sk_buff *in_skb, |
355 | struct tcf_proto *tp, unsigned long base, | ||
351 | u32 handle, struct nlattr **tca, | 356 | u32 handle, struct nlattr **tca, |
352 | unsigned long *arg) | 357 | unsigned long *arg) |
353 | { | 358 | { |
@@ -386,6 +391,10 @@ static int flow_change(struct tcf_proto *tp, unsigned long base, | |||
386 | 391 | ||
387 | if (fls(keymask) - 1 > FLOW_KEY_MAX) | 392 | if (fls(keymask) - 1 > FLOW_KEY_MAX) |
388 | return -EOPNOTSUPP; | 393 | return -EOPNOTSUPP; |
394 | |||
395 | if ((keymask & (FLOW_KEY_SKUID|FLOW_KEY_SKGID)) && | ||
396 | sk_user_ns(NETLINK_CB(in_skb).ssk) != &init_user_ns) | ||
397 | return -EOPNOTSUPP; | ||
389 | } | 398 | } |
390 | 399 | ||
391 | err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map); | 400 | err = tcf_exts_validate(tp, tb, tca[TCA_RATE], &e, &flow_ext_map); |
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 8384a479724..4075a0aef2a 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c | |||
@@ -233,7 +233,8 @@ errout: | |||
233 | return err; | 233 | return err; |
234 | } | 234 | } |
235 | 235 | ||
236 | static int fw_change(struct tcf_proto *tp, unsigned long base, | 236 | static int fw_change(struct sk_buff *in_skb, |
237 | struct tcf_proto *tp, unsigned long base, | ||
237 | u32 handle, | 238 | u32 handle, |
238 | struct nlattr **tca, | 239 | struct nlattr **tca, |
239 | unsigned long *arg) | 240 | unsigned long *arg) |
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c index 44f405cb9aa..c10d57bf98f 100644 --- a/net/sched/cls_route.c +++ b/net/sched/cls_route.c | |||
@@ -427,7 +427,8 @@ errout: | |||
427 | return err; | 427 | return err; |
428 | } | 428 | } |
429 | 429 | ||
430 | static int route4_change(struct tcf_proto *tp, unsigned long base, | 430 | static int route4_change(struct sk_buff *in_skb, |
431 | struct tcf_proto *tp, unsigned long base, | ||
431 | u32 handle, | 432 | u32 handle, |
432 | struct nlattr **tca, | 433 | struct nlattr **tca, |
433 | unsigned long *arg) | 434 | unsigned long *arg) |
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h index 18ab93ec8d7..494bbb90924 100644 --- a/net/sched/cls_rsvp.h +++ b/net/sched/cls_rsvp.h | |||
@@ -416,7 +416,8 @@ static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = { | |||
416 | [TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) }, | 416 | [TCA_RSVP_PINFO] = { .len = sizeof(struct tc_rsvp_pinfo) }, |
417 | }; | 417 | }; |
418 | 418 | ||
419 | static int rsvp_change(struct tcf_proto *tp, unsigned long base, | 419 | static int rsvp_change(struct sk_buff *in_skb, |
420 | struct tcf_proto *tp, unsigned long base, | ||
420 | u32 handle, | 421 | u32 handle, |
421 | struct nlattr **tca, | 422 | struct nlattr **tca, |
422 | unsigned long *arg) | 423 | unsigned long *arg) |
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index fe29420d0b0..a1293b4ab7a 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c | |||
@@ -332,7 +332,8 @@ errout: | |||
332 | } | 332 | } |
333 | 333 | ||
334 | static int | 334 | static int |
335 | tcindex_change(struct tcf_proto *tp, unsigned long base, u32 handle, | 335 | tcindex_change(struct sk_buff *in_skb, |
336 | struct tcf_proto *tp, unsigned long base, u32 handle, | ||
336 | struct nlattr **tca, unsigned long *arg) | 337 | struct nlattr **tca, unsigned long *arg) |
337 | { | 338 | { |
338 | struct nlattr *opt = tca[TCA_OPTIONS]; | 339 | struct nlattr *opt = tca[TCA_OPTIONS]; |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index d45373fb00b..c7c27bc91b5 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
@@ -544,7 +544,8 @@ errout: | |||
544 | return err; | 544 | return err; |
545 | } | 545 | } |
546 | 546 | ||
547 | static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle, | 547 | static int u32_change(struct sk_buff *in_skb, |
548 | struct tcf_proto *tp, unsigned long base, u32 handle, | ||
548 | struct nlattr **tca, | 549 | struct nlattr **tca, |
549 | unsigned long *arg) | 550 | unsigned long *arg) |
550 | { | 551 | { |
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c index 4ab6e332557..7c3de6ffa51 100644 --- a/net/sched/em_meta.c +++ b/net/sched/em_meta.c | |||
@@ -461,7 +461,7 @@ META_COLLECTOR(int_sk_sndtimeo) | |||
461 | META_COLLECTOR(int_sk_sendmsg_off) | 461 | META_COLLECTOR(int_sk_sendmsg_off) |
462 | { | 462 | { |
463 | SKIP_NONLOCAL(skb); | 463 | SKIP_NONLOCAL(skb); |
464 | dst->value = skb->sk->sk_sndmsg_off; | 464 | dst->value = skb->sk->sk_frag.offset; |
465 | } | 465 | } |
466 | 466 | ||
467 | META_COLLECTOR(int_sk_write_pend) | 467 | META_COLLECTOR(int_sk_write_pend) |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index a08b4ab3e42..a18d975db59 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -1185,7 +1185,7 @@ graft: | |||
1185 | } | 1185 | } |
1186 | 1186 | ||
1187 | static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, | 1187 | static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, |
1188 | u32 pid, u32 seq, u16 flags, int event) | 1188 | u32 portid, u32 seq, u16 flags, int event) |
1189 | { | 1189 | { |
1190 | struct tcmsg *tcm; | 1190 | struct tcmsg *tcm; |
1191 | struct nlmsghdr *nlh; | 1191 | struct nlmsghdr *nlh; |
@@ -1193,7 +1193,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, | |||
1193 | struct gnet_dump d; | 1193 | struct gnet_dump d; |
1194 | struct qdisc_size_table *stab; | 1194 | struct qdisc_size_table *stab; |
1195 | 1195 | ||
1196 | nlh = nlmsg_put(skb, pid, seq, event, sizeof(*tcm), flags); | 1196 | nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); |
1197 | if (!nlh) | 1197 | if (!nlh) |
1198 | goto out_nlmsg_trim; | 1198 | goto out_nlmsg_trim; |
1199 | tcm = nlmsg_data(nlh); | 1199 | tcm = nlmsg_data(nlh); |
@@ -1248,25 +1248,25 @@ static int qdisc_notify(struct net *net, struct sk_buff *oskb, | |||
1248 | struct Qdisc *old, struct Qdisc *new) | 1248 | struct Qdisc *old, struct Qdisc *new) |
1249 | { | 1249 | { |
1250 | struct sk_buff *skb; | 1250 | struct sk_buff *skb; |
1251 | u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; | 1251 | u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; |
1252 | 1252 | ||
1253 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 1253 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
1254 | if (!skb) | 1254 | if (!skb) |
1255 | return -ENOBUFS; | 1255 | return -ENOBUFS; |
1256 | 1256 | ||
1257 | if (old && !tc_qdisc_dump_ignore(old)) { | 1257 | if (old && !tc_qdisc_dump_ignore(old)) { |
1258 | if (tc_fill_qdisc(skb, old, clid, pid, n->nlmsg_seq, | 1258 | if (tc_fill_qdisc(skb, old, clid, portid, n->nlmsg_seq, |
1259 | 0, RTM_DELQDISC) < 0) | 1259 | 0, RTM_DELQDISC) < 0) |
1260 | goto err_out; | 1260 | goto err_out; |
1261 | } | 1261 | } |
1262 | if (new && !tc_qdisc_dump_ignore(new)) { | 1262 | if (new && !tc_qdisc_dump_ignore(new)) { |
1263 | if (tc_fill_qdisc(skb, new, clid, pid, n->nlmsg_seq, | 1263 | if (tc_fill_qdisc(skb, new, clid, portid, n->nlmsg_seq, |
1264 | old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0) | 1264 | old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0) |
1265 | goto err_out; | 1265 | goto err_out; |
1266 | } | 1266 | } |
1267 | 1267 | ||
1268 | if (skb->len) | 1268 | if (skb->len) |
1269 | return rtnetlink_send(skb, net, pid, RTNLGRP_TC, | 1269 | return rtnetlink_send(skb, net, portid, RTNLGRP_TC, |
1270 | n->nlmsg_flags & NLM_F_ECHO); | 1270 | n->nlmsg_flags & NLM_F_ECHO); |
1271 | 1271 | ||
1272 | err_out: | 1272 | err_out: |
@@ -1289,7 +1289,7 @@ static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb, | |||
1289 | q_idx++; | 1289 | q_idx++; |
1290 | } else { | 1290 | } else { |
1291 | if (!tc_qdisc_dump_ignore(q) && | 1291 | if (!tc_qdisc_dump_ignore(q) && |
1292 | tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid, | 1292 | tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).portid, |
1293 | cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) | 1293 | cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) |
1294 | goto done; | 1294 | goto done; |
1295 | q_idx++; | 1295 | q_idx++; |
@@ -1300,7 +1300,7 @@ static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb, | |||
1300 | continue; | 1300 | continue; |
1301 | } | 1301 | } |
1302 | if (!tc_qdisc_dump_ignore(q) && | 1302 | if (!tc_qdisc_dump_ignore(q) && |
1303 | tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid, | 1303 | tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).portid, |
1304 | cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) | 1304 | cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0) |
1305 | goto done; | 1305 | goto done; |
1306 | q_idx++; | 1306 | q_idx++; |
@@ -1375,7 +1375,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1375 | const struct Qdisc_class_ops *cops; | 1375 | const struct Qdisc_class_ops *cops; |
1376 | unsigned long cl = 0; | 1376 | unsigned long cl = 0; |
1377 | unsigned long new_cl; | 1377 | unsigned long new_cl; |
1378 | u32 pid = tcm->tcm_parent; | 1378 | u32 portid = tcm->tcm_parent; |
1379 | u32 clid = tcm->tcm_handle; | 1379 | u32 clid = tcm->tcm_handle; |
1380 | u32 qid = TC_H_MAJ(clid); | 1380 | u32 qid = TC_H_MAJ(clid); |
1381 | int err; | 1381 | int err; |
@@ -1403,8 +1403,8 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1403 | 1403 | ||
1404 | /* Step 1. Determine qdisc handle X:0 */ | 1404 | /* Step 1. Determine qdisc handle X:0 */ |
1405 | 1405 | ||
1406 | if (pid != TC_H_ROOT) { | 1406 | if (portid != TC_H_ROOT) { |
1407 | u32 qid1 = TC_H_MAJ(pid); | 1407 | u32 qid1 = TC_H_MAJ(portid); |
1408 | 1408 | ||
1409 | if (qid && qid1) { | 1409 | if (qid && qid1) { |
1410 | /* If both majors are known, they must be identical. */ | 1410 | /* If both majors are known, they must be identical. */ |
@@ -1418,10 +1418,10 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1418 | /* Now qid is genuine qdisc handle consistent | 1418 | /* Now qid is genuine qdisc handle consistent |
1419 | * both with parent and child. | 1419 | * both with parent and child. |
1420 | * | 1420 | * |
1421 | * TC_H_MAJ(pid) still may be unspecified, complete it now. | 1421 | * TC_H_MAJ(portid) still may be unspecified, complete it now. |
1422 | */ | 1422 | */ |
1423 | if (pid) | 1423 | if (portid) |
1424 | pid = TC_H_MAKE(qid, pid); | 1424 | portid = TC_H_MAKE(qid, portid); |
1425 | } else { | 1425 | } else { |
1426 | if (qid == 0) | 1426 | if (qid == 0) |
1427 | qid = dev->qdisc->handle; | 1427 | qid = dev->qdisc->handle; |
@@ -1439,7 +1439,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1439 | 1439 | ||
1440 | /* Now try to get class */ | 1440 | /* Now try to get class */ |
1441 | if (clid == 0) { | 1441 | if (clid == 0) { |
1442 | if (pid == TC_H_ROOT) | 1442 | if (portid == TC_H_ROOT) |
1443 | clid = qid; | 1443 | clid = qid; |
1444 | } else | 1444 | } else |
1445 | clid = TC_H_MAKE(qid, clid); | 1445 | clid = TC_H_MAKE(qid, clid); |
@@ -1478,7 +1478,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
1478 | new_cl = cl; | 1478 | new_cl = cl; |
1479 | err = -EOPNOTSUPP; | 1479 | err = -EOPNOTSUPP; |
1480 | if (cops->change) | 1480 | if (cops->change) |
1481 | err = cops->change(q, clid, pid, tca, &new_cl); | 1481 | err = cops->change(q, clid, portid, tca, &new_cl); |
1482 | if (err == 0) | 1482 | if (err == 0) |
1483 | tclass_notify(net, skb, n, q, new_cl, RTM_NEWTCLASS); | 1483 | tclass_notify(net, skb, n, q, new_cl, RTM_NEWTCLASS); |
1484 | 1484 | ||
@@ -1492,7 +1492,7 @@ out: | |||
1492 | 1492 | ||
1493 | static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q, | 1493 | static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q, |
1494 | unsigned long cl, | 1494 | unsigned long cl, |
1495 | u32 pid, u32 seq, u16 flags, int event) | 1495 | u32 portid, u32 seq, u16 flags, int event) |
1496 | { | 1496 | { |
1497 | struct tcmsg *tcm; | 1497 | struct tcmsg *tcm; |
1498 | struct nlmsghdr *nlh; | 1498 | struct nlmsghdr *nlh; |
@@ -1500,7 +1500,7 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q, | |||
1500 | struct gnet_dump d; | 1500 | struct gnet_dump d; |
1501 | const struct Qdisc_class_ops *cl_ops = q->ops->cl_ops; | 1501 | const struct Qdisc_class_ops *cl_ops = q->ops->cl_ops; |
1502 | 1502 | ||
1503 | nlh = nlmsg_put(skb, pid, seq, event, sizeof(*tcm), flags); | 1503 | nlh = nlmsg_put(skb, portid, seq, event, sizeof(*tcm), flags); |
1504 | if (!nlh) | 1504 | if (!nlh) |
1505 | goto out_nlmsg_trim; | 1505 | goto out_nlmsg_trim; |
1506 | tcm = nlmsg_data(nlh); | 1506 | tcm = nlmsg_data(nlh); |
@@ -1540,18 +1540,18 @@ static int tclass_notify(struct net *net, struct sk_buff *oskb, | |||
1540 | unsigned long cl, int event) | 1540 | unsigned long cl, int event) |
1541 | { | 1541 | { |
1542 | struct sk_buff *skb; | 1542 | struct sk_buff *skb; |
1543 | u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; | 1543 | u32 portid = oskb ? NETLINK_CB(oskb).portid : 0; |
1544 | 1544 | ||
1545 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 1545 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
1546 | if (!skb) | 1546 | if (!skb) |
1547 | return -ENOBUFS; | 1547 | return -ENOBUFS; |
1548 | 1548 | ||
1549 | if (tc_fill_tclass(skb, q, cl, pid, n->nlmsg_seq, 0, event) < 0) { | 1549 | if (tc_fill_tclass(skb, q, cl, portid, n->nlmsg_seq, 0, event) < 0) { |
1550 | kfree_skb(skb); | 1550 | kfree_skb(skb); |
1551 | return -EINVAL; | 1551 | return -EINVAL; |
1552 | } | 1552 | } |
1553 | 1553 | ||
1554 | return rtnetlink_send(skb, net, pid, RTNLGRP_TC, | 1554 | return rtnetlink_send(skb, net, portid, RTNLGRP_TC, |
1555 | n->nlmsg_flags & NLM_F_ECHO); | 1555 | n->nlmsg_flags & NLM_F_ECHO); |
1556 | } | 1556 | } |
1557 | 1557 | ||
@@ -1565,7 +1565,7 @@ static int qdisc_class_dump(struct Qdisc *q, unsigned long cl, struct qdisc_walk | |||
1565 | { | 1565 | { |
1566 | struct qdisc_dump_args *a = (struct qdisc_dump_args *)arg; | 1566 | struct qdisc_dump_args *a = (struct qdisc_dump_args *)arg; |
1567 | 1567 | ||
1568 | return tc_fill_tclass(a->skb, q, cl, NETLINK_CB(a->cb->skb).pid, | 1568 | return tc_fill_tclass(a->skb, q, cl, NETLINK_CB(a->cb->skb).portid, |
1569 | a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTCLASS); | 1569 | a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTCLASS); |
1570 | } | 1570 | } |
1571 | 1571 | ||
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c index 6aabd77d1cf..564b9fc8efd 100644 --- a/net/sched/sch_cbq.c +++ b/net/sched/sch_cbq.c | |||
@@ -250,10 +250,11 @@ cbq_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) | |||
250 | else if ((cl = defmap[res.classid & TC_PRIO_MAX]) == NULL) | 250 | else if ((cl = defmap[res.classid & TC_PRIO_MAX]) == NULL) |
251 | cl = defmap[TC_PRIO_BESTEFFORT]; | 251 | cl = defmap[TC_PRIO_BESTEFFORT]; |
252 | 252 | ||
253 | if (cl == NULL || cl->level >= head->level) | 253 | if (cl == NULL) |
254 | goto fallback; | 254 | goto fallback; |
255 | } | 255 | } |
256 | 256 | if (cl->level >= head->level) | |
257 | goto fallback; | ||
257 | #ifdef CONFIG_NET_CLS_ACT | 258 | #ifdef CONFIG_NET_CLS_ACT |
258 | switch (result) { | 259 | switch (result) { |
259 | case TC_ACT_QUEUED: | 260 | case TC_ACT_QUEUED: |
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c index 9ce0b4fe23f..71e50c80315 100644 --- a/net/sched/sch_drr.c +++ b/net/sched/sch_drr.c | |||
@@ -352,7 +352,7 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
352 | { | 352 | { |
353 | struct drr_sched *q = qdisc_priv(sch); | 353 | struct drr_sched *q = qdisc_priv(sch); |
354 | struct drr_class *cl; | 354 | struct drr_class *cl; |
355 | int err; | 355 | int err = 0; |
356 | 356 | ||
357 | cl = drr_classify(skb, sch, &err); | 357 | cl = drr_classify(skb, sch, &err); |
358 | if (cl == NULL) { | 358 | if (cl == NULL) { |
diff --git a/net/sched/sch_fq_codel.c b/net/sched/sch_fq_codel.c index 9fc1c62ec80..4e606fcb253 100644 --- a/net/sched/sch_fq_codel.c +++ b/net/sched/sch_fq_codel.c | |||
@@ -191,7 +191,6 @@ static int fq_codel_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
191 | 191 | ||
192 | if (list_empty(&flow->flowchain)) { | 192 | if (list_empty(&flow->flowchain)) { |
193 | list_add_tail(&flow->flowchain, &q->new_flows); | 193 | list_add_tail(&flow->flowchain, &q->new_flows); |
194 | codel_vars_init(&flow->cvars); | ||
195 | q->new_flow_count++; | 194 | q->new_flow_count++; |
196 | flow->deficit = q->quantum; | 195 | flow->deficit = q->quantum; |
197 | flow->dropped = 0; | 196 | flow->dropped = 0; |
@@ -418,6 +417,7 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) | |||
418 | struct fq_codel_flow *flow = q->flows + i; | 417 | struct fq_codel_flow *flow = q->flows + i; |
419 | 418 | ||
420 | INIT_LIST_HEAD(&flow->flowchain); | 419 | INIT_LIST_HEAD(&flow->flowchain); |
420 | codel_vars_init(&flow->cvars); | ||
421 | } | 421 | } |
422 | } | 422 | } |
423 | if (sch->limit >= 1) | 423 | if (sch->limit >= 1) |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 511323e89ce..aefc1504dc8 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -324,24 +324,6 @@ void netif_carrier_off(struct net_device *dev) | |||
324 | } | 324 | } |
325 | EXPORT_SYMBOL(netif_carrier_off); | 325 | EXPORT_SYMBOL(netif_carrier_off); |
326 | 326 | ||
327 | /** | ||
328 | * netif_notify_peers - notify network peers about existence of @dev | ||
329 | * @dev: network device | ||
330 | * | ||
331 | * Generate traffic such that interested network peers are aware of | ||
332 | * @dev, such as by generating a gratuitous ARP. This may be used when | ||
333 | * a device wants to inform the rest of the network about some sort of | ||
334 | * reconfiguration such as a failover event or virtual machine | ||
335 | * migration. | ||
336 | */ | ||
337 | void netif_notify_peers(struct net_device *dev) | ||
338 | { | ||
339 | rtnl_lock(); | ||
340 | call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, dev); | ||
341 | rtnl_unlock(); | ||
342 | } | ||
343 | EXPORT_SYMBOL(netif_notify_peers); | ||
344 | |||
345 | /* "NOOP" scheduler: the best scheduler, recommended for all interfaces | 327 | /* "NOOP" scheduler: the best scheduler, recommended for all interfaces |
346 | under all circumstances. It is difficult to invent anything faster or | 328 | under all circumstances. It is difficult to invent anything faster or |
347 | cheaper. | 329 | cheaper. |
@@ -545,6 +527,8 @@ struct Qdisc_ops pfifo_fast_ops __read_mostly = { | |||
545 | }; | 527 | }; |
546 | EXPORT_SYMBOL(pfifo_fast_ops); | 528 | EXPORT_SYMBOL(pfifo_fast_ops); |
547 | 529 | ||
530 | static struct lock_class_key qdisc_tx_busylock; | ||
531 | |||
548 | struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, | 532 | struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, |
549 | struct Qdisc_ops *ops) | 533 | struct Qdisc_ops *ops) |
550 | { | 534 | { |
@@ -552,6 +536,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, | |||
552 | struct Qdisc *sch; | 536 | struct Qdisc *sch; |
553 | unsigned int size = QDISC_ALIGN(sizeof(*sch)) + ops->priv_size; | 537 | unsigned int size = QDISC_ALIGN(sizeof(*sch)) + ops->priv_size; |
554 | int err = -ENOBUFS; | 538 | int err = -ENOBUFS; |
539 | struct net_device *dev = dev_queue->dev; | ||
555 | 540 | ||
556 | p = kzalloc_node(size, GFP_KERNEL, | 541 | p = kzalloc_node(size, GFP_KERNEL, |
557 | netdev_queue_numa_node_read(dev_queue)); | 542 | netdev_queue_numa_node_read(dev_queue)); |
@@ -571,12 +556,16 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, | |||
571 | } | 556 | } |
572 | INIT_LIST_HEAD(&sch->list); | 557 | INIT_LIST_HEAD(&sch->list); |
573 | skb_queue_head_init(&sch->q); | 558 | skb_queue_head_init(&sch->q); |
559 | |||
574 | spin_lock_init(&sch->busylock); | 560 | spin_lock_init(&sch->busylock); |
561 | lockdep_set_class(&sch->busylock, | ||
562 | dev->qdisc_tx_busylock ?: &qdisc_tx_busylock); | ||
563 | |||
575 | sch->ops = ops; | 564 | sch->ops = ops; |
576 | sch->enqueue = ops->enqueue; | 565 | sch->enqueue = ops->enqueue; |
577 | sch->dequeue = ops->dequeue; | 566 | sch->dequeue = ops->dequeue; |
578 | sch->dev_queue = dev_queue; | 567 | sch->dev_queue = dev_queue; |
579 | dev_hold(qdisc_dev(sch)); | 568 | dev_hold(dev); |
580 | atomic_set(&sch->refcnt, 1); | 569 | atomic_set(&sch->refcnt, 1); |
581 | 570 | ||
582 | return sch; | 571 | return sch; |
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c index e901583e4ea..d42234c0f13 100644 --- a/net/sched/sch_gred.c +++ b/net/sched/sch_gred.c | |||
@@ -102,9 +102,8 @@ static inline int gred_wred_mode_check(struct Qdisc *sch) | |||
102 | if (q == NULL) | 102 | if (q == NULL) |
103 | continue; | 103 | continue; |
104 | 104 | ||
105 | for (n = 0; n < table->DPs; n++) | 105 | for (n = i + 1; n < table->DPs; n++) |
106 | if (table->tab[n] && table->tab[n] != q && | 106 | if (table->tab[n] && table->tab[n]->prio == q->prio) |
107 | table->tab[n]->prio == q->prio) | ||
108 | return 1; | 107 | return 1; |
109 | } | 108 | } |
110 | 109 | ||
@@ -137,6 +136,7 @@ static inline void gred_store_wred_set(struct gred_sched *table, | |||
137 | struct gred_sched_data *q) | 136 | struct gred_sched_data *q) |
138 | { | 137 | { |
139 | table->wred_set.qavg = q->vars.qavg; | 138 | table->wred_set.qavg = q->vars.qavg; |
139 | table->wred_set.qidlestart = q->vars.qidlestart; | ||
140 | } | 140 | } |
141 | 141 | ||
142 | static inline int gred_use_ecn(struct gred_sched *t) | 142 | static inline int gred_use_ecn(struct gred_sched *t) |
@@ -176,7 +176,7 @@ static int gred_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
176 | skb->tc_index = (skb->tc_index & ~GRED_VQ_MASK) | dp; | 176 | skb->tc_index = (skb->tc_index & ~GRED_VQ_MASK) | dp; |
177 | } | 177 | } |
178 | 178 | ||
179 | /* sum up all the qaves of prios <= to ours to get the new qave */ | 179 | /* sum up all the qaves of prios < ours to get the new qave */ |
180 | if (!gred_wred_mode(t) && gred_rio_mode(t)) { | 180 | if (!gred_wred_mode(t) && gred_rio_mode(t)) { |
181 | int i; | 181 | int i; |
182 | 182 | ||
@@ -260,16 +260,18 @@ static struct sk_buff *gred_dequeue(struct Qdisc *sch) | |||
260 | } else { | 260 | } else { |
261 | q->backlog -= qdisc_pkt_len(skb); | 261 | q->backlog -= qdisc_pkt_len(skb); |
262 | 262 | ||
263 | if (!q->backlog && !gred_wred_mode(t)) | 263 | if (gred_wred_mode(t)) { |
264 | red_start_of_idle_period(&q->vars); | 264 | if (!sch->qstats.backlog) |
265 | red_start_of_idle_period(&t->wred_set); | ||
266 | } else { | ||
267 | if (!q->backlog) | ||
268 | red_start_of_idle_period(&q->vars); | ||
269 | } | ||
265 | } | 270 | } |
266 | 271 | ||
267 | return skb; | 272 | return skb; |
268 | } | 273 | } |
269 | 274 | ||
270 | if (gred_wred_mode(t) && !red_is_idling(&t->wred_set)) | ||
271 | red_start_of_idle_period(&t->wred_set); | ||
272 | |||
273 | return NULL; | 275 | return NULL; |
274 | } | 276 | } |
275 | 277 | ||
@@ -291,19 +293,20 @@ static unsigned int gred_drop(struct Qdisc *sch) | |||
291 | q->backlog -= len; | 293 | q->backlog -= len; |
292 | q->stats.other++; | 294 | q->stats.other++; |
293 | 295 | ||
294 | if (!q->backlog && !gred_wred_mode(t)) | 296 | if (gred_wred_mode(t)) { |
295 | red_start_of_idle_period(&q->vars); | 297 | if (!sch->qstats.backlog) |
298 | red_start_of_idle_period(&t->wred_set); | ||
299 | } else { | ||
300 | if (!q->backlog) | ||
301 | red_start_of_idle_period(&q->vars); | ||
302 | } | ||
296 | } | 303 | } |
297 | 304 | ||
298 | qdisc_drop(skb, sch); | 305 | qdisc_drop(skb, sch); |
299 | return len; | 306 | return len; |
300 | } | 307 | } |
301 | 308 | ||
302 | if (gred_wred_mode(t) && !red_is_idling(&t->wred_set)) | ||
303 | red_start_of_idle_period(&t->wred_set); | ||
304 | |||
305 | return 0; | 309 | return 0; |
306 | |||
307 | } | 310 | } |
308 | 311 | ||
309 | static void gred_reset(struct Qdisc *sch) | 312 | static void gred_reset(struct Qdisc *sch) |
@@ -535,6 +538,7 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
535 | for (i = 0; i < MAX_DPs; i++) { | 538 | for (i = 0; i < MAX_DPs; i++) { |
536 | struct gred_sched_data *q = table->tab[i]; | 539 | struct gred_sched_data *q = table->tab[i]; |
537 | struct tc_gred_qopt opt; | 540 | struct tc_gred_qopt opt; |
541 | unsigned long qavg; | ||
538 | 542 | ||
539 | memset(&opt, 0, sizeof(opt)); | 543 | memset(&opt, 0, sizeof(opt)); |
540 | 544 | ||
@@ -566,7 +570,9 @@ static int gred_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
566 | if (gred_wred_mode(table)) | 570 | if (gred_wred_mode(table)) |
567 | gred_load_wred_set(table, q); | 571 | gred_load_wred_set(table, q); |
568 | 572 | ||
569 | opt.qave = red_calc_qavg(&q->parms, &q->vars, q->vars.qavg); | 573 | qavg = red_calc_qavg(&q->parms, &q->vars, |
574 | q->vars.qavg >> q->parms.Wlog); | ||
575 | opt.qave = qavg >> q->parms.Wlog; | ||
570 | 576 | ||
571 | append_opt: | 577 | append_opt: |
572 | if (nla_append(skb, sizeof(opt), &opt) < 0) | 578 | if (nla_append(skb, sizeof(opt), &opt) < 0) |
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index e4723d31fdd..f0dd83cff90 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c | |||
@@ -865,7 +865,10 @@ static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl) | |||
865 | if (mask) { | 865 | if (mask) { |
866 | struct qfq_group *next = qfq_ffs(q, mask); | 866 | struct qfq_group *next = qfq_ffs(q, mask); |
867 | if (qfq_gt(roundedF, next->F)) { | 867 | if (qfq_gt(roundedF, next->F)) { |
868 | cl->S = next->F; | 868 | if (qfq_gt(limit, next->F)) |
869 | cl->S = next->F; | ||
870 | else /* preserve timestamp correctness */ | ||
871 | cl->S = limit; | ||
869 | return; | 872 | return; |
870 | } | 873 | } |
871 | } | 874 | } |
@@ -878,7 +881,7 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
878 | { | 881 | { |
879 | struct qfq_sched *q = qdisc_priv(sch); | 882 | struct qfq_sched *q = qdisc_priv(sch); |
880 | struct qfq_class *cl; | 883 | struct qfq_class *cl; |
881 | int err; | 884 | int err = 0; |
882 | 885 | ||
883 | cl = qfq_classify(skb, sch, &err); | 886 | cl = qfq_classify(skb, sch, &err); |
884 | if (cl == NULL) { | 887 | if (cl == NULL) { |