aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/Kconfig21
-rw-r--r--net/sched/act_api.c77
-rw-r--r--net/sched/act_gact.c25
-rw-r--r--net/sched/act_ipt.c10
-rw-r--r--net/sched/act_mirred.c75
-rw-r--r--net/sched/act_nat.c66
-rw-r--r--net/sched/act_pedit.c39
-rw-r--r--net/sched/act_police.c34
-rw-r--r--net/sched/act_simple.c20
-rw-r--r--net/sched/act_skbedit.c11
-rw-r--r--net/sched/cls_api.c31
-rw-r--r--net/sched/cls_basic.c1
-rw-r--r--net/sched/cls_cgroup.c75
-rw-r--r--net/sched/cls_flow.c98
-rw-r--r--net/sched/cls_fw.c1
-rw-r--r--net/sched/cls_route.c1
-rw-r--r--net/sched/cls_rsvp.h12
-rw-r--r--net/sched/cls_tcindex.c1
-rw-r--r--net/sched/cls_u32.c60
-rw-r--r--net/sched/em_meta.c1
-rw-r--r--net/sched/em_nbyte.c1
-rw-r--r--net/sched/em_text.c1
-rw-r--r--net/sched/ematch.c4
-rw-r--r--net/sched/sch_api.c159
-rw-r--r--net/sched/sch_atm.c105
-rw-r--r--net/sched/sch_cbq.c1
-rw-r--r--net/sched/sch_drr.c1
-rw-r--r--net/sched/sch_dsmark.c1
-rw-r--r--net/sched/sch_fifo.c35
-rw-r--r--net/sched/sch_generic.c45
-rw-r--r--net/sched/sch_gred.c1
-rw-r--r--net/sched/sch_hfsc.c9
-rw-r--r--net/sched/sch_htb.c3
-rw-r--r--net/sched/sch_ingress.c1
-rw-r--r--net/sched/sch_mq.c2
-rw-r--r--net/sched/sch_multiq.c2
-rw-r--r--net/sched/sch_netem.c1
-rw-r--r--net/sched/sch_prio.c2
-rw-r--r--net/sched/sch_red.c1
-rw-r--r--net/sched/sch_sfq.c61
-rw-r--r--net/sched/sch_tbf.c10
-rw-r--r--net/sched/sch_teql.c4
42 files changed, 706 insertions, 403 deletions
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index 929218a47620..2f691fb180d1 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -328,13 +328,16 @@ config NET_CLS_FLOW
328 module will be called cls_flow. 328 module will be called cls_flow.
329 329
330config NET_CLS_CGROUP 330config NET_CLS_CGROUP
331 bool "Control Group Classifier" 331 tristate "Control Group Classifier"
332 select NET_CLS 332 select NET_CLS
333 depends on CGROUPS 333 depends on CGROUPS
334 ---help--- 334 ---help---
335 Say Y here if you want to classify packets based on the control 335 Say Y here if you want to classify packets based on the control
336 cgroup of their process. 336 cgroup of their process.
337 337
338 To compile this code as a module, choose M here: the
339 module will be called cls_cgroup.
340
338config NET_EMATCH 341config NET_EMATCH
339 bool "Extended Matches" 342 bool "Extended Matches"
340 select NET_CLS 343 select NET_CLS
@@ -433,7 +436,7 @@ config NET_ACT_POLICE
433 module. 436 module.
434 437
435 To compile this code as a module, choose M here: the 438 To compile this code as a module, choose M here: the
436 module will be called police. 439 module will be called act_police.
437 440
438config NET_ACT_GACT 441config NET_ACT_GACT
439 tristate "Generic actions" 442 tristate "Generic actions"
@@ -443,7 +446,7 @@ config NET_ACT_GACT
443 accepting packets. 446 accepting packets.
444 447
445 To compile this code as a module, choose M here: the 448 To compile this code as a module, choose M here: the
446 module will be called gact. 449 module will be called act_gact.
447 450
448config GACT_PROB 451config GACT_PROB
449 bool "Probability support" 452 bool "Probability support"
@@ -459,7 +462,7 @@ config NET_ACT_MIRRED
459 other devices. 462 other devices.
460 463
461 To compile this code as a module, choose M here: the 464 To compile this code as a module, choose M here: the
462 module will be called mirred. 465 module will be called act_mirred.
463 466
464config NET_ACT_IPT 467config NET_ACT_IPT
465 tristate "IPtables targets" 468 tristate "IPtables targets"
@@ -469,7 +472,7 @@ config NET_ACT_IPT
469 classification. 472 classification.
470 473
471 To compile this code as a module, choose M here: the 474 To compile this code as a module, choose M here: the
472 module will be called ipt. 475 module will be called act_ipt.
473 476
474config NET_ACT_NAT 477config NET_ACT_NAT
475 tristate "Stateless NAT" 478 tristate "Stateless NAT"
@@ -479,7 +482,7 @@ config NET_ACT_NAT
479 netfilter for NAT unless you know what you are doing. 482 netfilter for NAT unless you know what you are doing.
480 483
481 To compile this code as a module, choose M here: the 484 To compile this code as a module, choose M here: the
482 module will be called nat. 485 module will be called act_nat.
483 486
484config NET_ACT_PEDIT 487config NET_ACT_PEDIT
485 tristate "Packet Editing" 488 tristate "Packet Editing"
@@ -488,7 +491,7 @@ config NET_ACT_PEDIT
488 Say Y here if you want to mangle the content of packets. 491 Say Y here if you want to mangle the content of packets.
489 492
490 To compile this code as a module, choose M here: the 493 To compile this code as a module, choose M here: the
491 module will be called pedit. 494 module will be called act_pedit.
492 495
493config NET_ACT_SIMP 496config NET_ACT_SIMP
494 tristate "Simple Example (Debug)" 497 tristate "Simple Example (Debug)"
@@ -502,7 +505,7 @@ config NET_ACT_SIMP
502 If unsure, say N. 505 If unsure, say N.
503 506
504 To compile this code as a module, choose M here: the 507 To compile this code as a module, choose M here: the
505 module will be called simple. 508 module will be called act_simple.
506 509
507config NET_ACT_SKBEDIT 510config NET_ACT_SKBEDIT
508 tristate "SKB Editing" 511 tristate "SKB Editing"
@@ -513,7 +516,7 @@ config NET_ACT_SKBEDIT
513 If unsure, say N. 516 If unsure, say N.
514 517
515 To compile this code as a module, choose M here: the 518 To compile this code as a module, choose M here: the
516 module will be called skbedit. 519 module will be called act_skbedit.
517 520
518config NET_CLS_IND 521config NET_CLS_IND
519 bool "Incoming device classification" 522 bool "Incoming device classification"
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 64f5e328cee9..23b25f89e7e0 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -15,6 +15,7 @@
15#include <linux/kernel.h> 15#include <linux/kernel.h>
16#include <linux/string.h> 16#include <linux/string.h>
17#include <linux/errno.h> 17#include <linux/errno.h>
18#include <linux/slab.h>
18#include <linux/skbuff.h> 19#include <linux/skbuff.h>
19#include <linux/init.h> 20#include <linux/init.h>
20#include <linux/kmod.h> 21#include <linux/kmod.h>
@@ -25,6 +26,11 @@
25#include <net/act_api.h> 26#include <net/act_api.h>
26#include <net/netlink.h> 27#include <net/netlink.h>
27 28
29static void tcf_common_free_rcu(struct rcu_head *head)
30{
31 kfree(container_of(head, struct tcf_common, tcfc_rcu));
32}
33
28void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo) 34void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
29{ 35{
30 unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask); 36 unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
@@ -37,7 +43,11 @@ void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
37 write_unlock_bh(hinfo->lock); 43 write_unlock_bh(hinfo->lock);
38 gen_kill_estimator(&p->tcfc_bstats, 44 gen_kill_estimator(&p->tcfc_bstats,
39 &p->tcfc_rate_est); 45 &p->tcfc_rate_est);
40 kfree(p); 46 /*
47 * gen_estimator est_timer() might access p->tcfc_lock
48 * or bstats, wait a RCU grace period before freeing p
49 */
50 call_rcu(&p->tcfc_rcu, tcf_common_free_rcu);
41 return; 51 return;
42 } 52 }
43 } 53 }
@@ -152,7 +162,7 @@ int tcf_generic_walker(struct sk_buff *skb, struct netlink_callback *cb,
152 } else if (type == RTM_GETACTION) { 162 } else if (type == RTM_GETACTION) {
153 return tcf_dump_walker(skb, cb, a, hinfo); 163 return tcf_dump_walker(skb, cb, a, hinfo);
154 } else { 164 } else {
155 printk("tcf_generic_walker: unknown action %d\n", type); 165 WARN(1, "tcf_generic_walker: unknown action %d\n", type);
156 return -EINVAL; 166 return -EINVAL;
157 } 167 }
158} 168}
@@ -402,8 +412,9 @@ void tcf_action_destroy(struct tc_action *act, int bind)
402 module_put(a->ops->owner); 412 module_put(a->ops->owner);
403 act = act->next; 413 act = act->next;
404 kfree(a); 414 kfree(a);
405 } else { /*FIXME: Remove later - catch insertion bugs*/ 415 } else {
406 printk("tcf_action_destroy: BUG? destroying NULL ops\n"); 416 /*FIXME: Remove later - catch insertion bugs*/
417 WARN(1, "tcf_action_destroy: BUG? destroying NULL ops\n");
407 act = act->next; 418 act = act->next;
408 kfree(a); 419 kfree(a);
409 } 420 }
@@ -667,7 +678,8 @@ nlmsg_failure:
667} 678}
668 679
669static int 680static int
670act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event) 681act_get_notify(struct net *net, u32 pid, struct nlmsghdr *n,
682 struct tc_action *a, int event)
671{ 683{
672 struct sk_buff *skb; 684 struct sk_buff *skb;
673 685
@@ -679,7 +691,7 @@ act_get_notify(u32 pid, struct nlmsghdr *n, struct tc_action *a, int event)
679 return -EINVAL; 691 return -EINVAL;
680 } 692 }
681 693
682 return rtnl_unicast(skb, &init_net, pid); 694 return rtnl_unicast(skb, net, pid);
683} 695}
684 696
685static struct tc_action * 697static struct tc_action *
@@ -742,14 +754,15 @@ static struct tc_action *create_a(int i)
742 754
743 act = kzalloc(sizeof(*act), GFP_KERNEL); 755 act = kzalloc(sizeof(*act), GFP_KERNEL);
744 if (act == NULL) { 756 if (act == NULL) {
745 printk("create_a: failed to alloc!\n"); 757 pr_debug("create_a: failed to alloc!\n");
746 return NULL; 758 return NULL;
747 } 759 }
748 act->order = i; 760 act->order = i;
749 return act; 761 return act;
750} 762}
751 763
752static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid) 764static int tca_action_flush(struct net *net, struct nlattr *nla,
765 struct nlmsghdr *n, u32 pid)
753{ 766{
754 struct sk_buff *skb; 767 struct sk_buff *skb;
755 unsigned char *b; 768 unsigned char *b;
@@ -763,13 +776,13 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
763 int err = -ENOMEM; 776 int err = -ENOMEM;
764 777
765 if (a == NULL) { 778 if (a == NULL) {
766 printk("tca_action_flush: couldnt create tc_action\n"); 779 pr_debug("tca_action_flush: couldnt create tc_action\n");
767 return err; 780 return err;
768 } 781 }
769 782
770 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 783 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
771 if (!skb) { 784 if (!skb) {
772 printk("tca_action_flush: failed skb alloc\n"); 785 pr_debug("tca_action_flush: failed skb alloc\n");
773 kfree(a); 786 kfree(a);
774 return err; 787 return err;
775 } 788 }
@@ -808,7 +821,7 @@ static int tca_action_flush(struct nlattr *nla, struct nlmsghdr *n, u32 pid)
808 nlh->nlmsg_flags |= NLM_F_ROOT; 821 nlh->nlmsg_flags |= NLM_F_ROOT;
809 module_put(a->ops->owner); 822 module_put(a->ops->owner);
810 kfree(a); 823 kfree(a);
811 err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 824 err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
812 if (err > 0) 825 if (err > 0)
813 return 0; 826 return 0;
814 827
@@ -825,7 +838,8 @@ noflush_out:
825} 838}
826 839
827static int 840static int
828tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event) 841tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
842 u32 pid, int event)
829{ 843{
830 int i, ret; 844 int i, ret;
831 struct nlattr *tb[TCA_ACT_MAX_PRIO+1]; 845 struct nlattr *tb[TCA_ACT_MAX_PRIO+1];
@@ -837,7 +851,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
837 851
838 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) { 852 if (event == RTM_DELACTION && n->nlmsg_flags&NLM_F_ROOT) {
839 if (tb[1] != NULL) 853 if (tb[1] != NULL)
840 return tca_action_flush(tb[1], n, pid); 854 return tca_action_flush(net, tb[1], n, pid);
841 else 855 else
842 return -EINVAL; 856 return -EINVAL;
843 } 857 }
@@ -858,7 +872,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
858 } 872 }
859 873
860 if (event == RTM_GETACTION) 874 if (event == RTM_GETACTION)
861 ret = act_get_notify(pid, n, head, event); 875 ret = act_get_notify(net, pid, n, head, event);
862 else { /* delete */ 876 else { /* delete */
863 struct sk_buff *skb; 877 struct sk_buff *skb;
864 878
@@ -877,7 +891,7 @@ tca_action_gd(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int event)
877 891
878 /* now do the delete */ 892 /* now do the delete */
879 tcf_action_destroy(head, 0); 893 tcf_action_destroy(head, 0);
880 ret = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, 894 ret = rtnetlink_send(skb, net, pid, RTNLGRP_TC,
881 n->nlmsg_flags&NLM_F_ECHO); 895 n->nlmsg_flags&NLM_F_ECHO);
882 if (ret > 0) 896 if (ret > 0)
883 return 0; 897 return 0;
@@ -888,8 +902,8 @@ err:
888 return ret; 902 return ret;
889} 903}
890 904
891static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event, 905static int tcf_add_notify(struct net *net, struct tc_action *a,
892 u16 flags) 906 u32 pid, u32 seq, int event, u16 flags)
893{ 907{
894 struct tcamsg *t; 908 struct tcamsg *t;
895 struct nlmsghdr *nlh; 909 struct nlmsghdr *nlh;
@@ -922,7 +936,7 @@ static int tcf_add_notify(struct tc_action *a, u32 pid, u32 seq, int event,
922 nlh->nlmsg_len = skb_tail_pointer(skb) - b; 936 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
923 NETLINK_CB(skb).dst_group = RTNLGRP_TC; 937 NETLINK_CB(skb).dst_group = RTNLGRP_TC;
924 938
925 err = rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, flags&NLM_F_ECHO); 939 err = rtnetlink_send(skb, net, pid, RTNLGRP_TC, flags&NLM_F_ECHO);
926 if (err > 0) 940 if (err > 0)
927 err = 0; 941 err = 0;
928 return err; 942 return err;
@@ -935,7 +949,8 @@ nlmsg_failure:
935 949
936 950
937static int 951static int
938tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr) 952tcf_action_add(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
953 u32 pid, int ovr)
939{ 954{
940 int ret = 0; 955 int ret = 0;
941 struct tc_action *act; 956 struct tc_action *act;
@@ -953,7 +968,7 @@ tcf_action_add(struct nlattr *nla, struct nlmsghdr *n, u32 pid, int ovr)
953 /* dump then free all the actions after update; inserted policy 968 /* dump then free all the actions after update; inserted policy
954 * stays intact 969 * stays intact
955 * */ 970 * */
956 ret = tcf_add_notify(act, pid, seq, RTM_NEWACTION, n->nlmsg_flags); 971 ret = tcf_add_notify(net, act, pid, seq, RTM_NEWACTION, n->nlmsg_flags);
957 for (a = act; a; a = act) { 972 for (a = act; a; a = act) {
958 act = a->next; 973 act = a->next;
959 kfree(a); 974 kfree(a);
@@ -969,15 +984,12 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
969 u32 pid = skb ? NETLINK_CB(skb).pid : 0; 984 u32 pid = skb ? NETLINK_CB(skb).pid : 0;
970 int ret = 0, ovr = 0; 985 int ret = 0, ovr = 0;
971 986
972 if (!net_eq(net, &init_net))
973 return -EINVAL;
974
975 ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); 987 ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL);
976 if (ret < 0) 988 if (ret < 0)
977 return ret; 989 return ret;
978 990
979 if (tca[TCA_ACT_TAB] == NULL) { 991 if (tca[TCA_ACT_TAB] == NULL) {
980 printk("tc_ctl_action: received NO action attribs\n"); 992 pr_notice("tc_ctl_action: received NO action attribs\n");
981 return -EINVAL; 993 return -EINVAL;
982 } 994 }
983 995
@@ -994,15 +1006,17 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
994 if (n->nlmsg_flags&NLM_F_REPLACE) 1006 if (n->nlmsg_flags&NLM_F_REPLACE)
995 ovr = 1; 1007 ovr = 1;
996replay: 1008replay:
997 ret = tcf_action_add(tca[TCA_ACT_TAB], n, pid, ovr); 1009 ret = tcf_action_add(net, tca[TCA_ACT_TAB], n, pid, ovr);
998 if (ret == -EAGAIN) 1010 if (ret == -EAGAIN)
999 goto replay; 1011 goto replay;
1000 break; 1012 break;
1001 case RTM_DELACTION: 1013 case RTM_DELACTION:
1002 ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_DELACTION); 1014 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1015 pid, RTM_DELACTION);
1003 break; 1016 break;
1004 case RTM_GETACTION: 1017 case RTM_GETACTION:
1005 ret = tca_action_gd(tca[TCA_ACT_TAB], n, pid, RTM_GETACTION); 1018 ret = tca_action_gd(net, tca[TCA_ACT_TAB], n,
1019 pid, RTM_GETACTION);
1006 break; 1020 break;
1007 default: 1021 default:
1008 BUG(); 1022 BUG();
@@ -1042,7 +1056,6 @@ find_dump_kind(const struct nlmsghdr *n)
1042static int 1056static int
1043tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb) 1057tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1044{ 1058{
1045 struct net *net = sock_net(skb->sk);
1046 struct nlmsghdr *nlh; 1059 struct nlmsghdr *nlh;
1047 unsigned char *b = skb_tail_pointer(skb); 1060 unsigned char *b = skb_tail_pointer(skb);
1048 struct nlattr *nest; 1061 struct nlattr *nest;
@@ -1052,11 +1065,8 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1052 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh); 1065 struct tcamsg *t = (struct tcamsg *) NLMSG_DATA(cb->nlh);
1053 struct nlattr *kind = find_dump_kind(cb->nlh); 1066 struct nlattr *kind = find_dump_kind(cb->nlh);
1054 1067
1055 if (!net_eq(net, &init_net))
1056 return 0;
1057
1058 if (kind == NULL) { 1068 if (kind == NULL) {
1059 printk("tc_dump_action: action bad kind\n"); 1069 pr_info("tc_dump_action: action bad kind\n");
1060 return 0; 1070 return 0;
1061 } 1071 }
1062 1072
@@ -1069,7 +1079,8 @@ tc_dump_action(struct sk_buff *skb, struct netlink_callback *cb)
1069 a.ops = a_o; 1079 a.ops = a_o;
1070 1080
1071 if (a_o->walk == NULL) { 1081 if (a_o->walk == NULL) {
1072 printk("tc_dump_action: %s !capable of dumping table\n", a_o->kind); 1082 WARN(1, "tc_dump_action: %s !capable of dumping table\n",
1083 a_o->kind);
1073 goto nla_put_failure; 1084 goto nla_put_failure;
1074 } 1085 }
1075 1086
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c
index e7f796aec657..c2ed90a4c0b4 100644
--- a/net/sched/act_gact.c
+++ b/net/sched/act_gact.c
@@ -152,21 +152,24 @@ static int tcf_gact(struct sk_buff *skb, struct tc_action *a, struct tcf_result
152static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) 152static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
153{ 153{
154 unsigned char *b = skb_tail_pointer(skb); 154 unsigned char *b = skb_tail_pointer(skb);
155 struct tc_gact opt;
156 struct tcf_gact *gact = a->priv; 155 struct tcf_gact *gact = a->priv;
156 struct tc_gact opt = {
157 .index = gact->tcf_index,
158 .refcnt = gact->tcf_refcnt - ref,
159 .bindcnt = gact->tcf_bindcnt - bind,
160 .action = gact->tcf_action,
161 };
157 struct tcf_t t; 162 struct tcf_t t;
158 163
159 opt.index = gact->tcf_index;
160 opt.refcnt = gact->tcf_refcnt - ref;
161 opt.bindcnt = gact->tcf_bindcnt - bind;
162 opt.action = gact->tcf_action;
163 NLA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt); 164 NLA_PUT(skb, TCA_GACT_PARMS, sizeof(opt), &opt);
164#ifdef CONFIG_GACT_PROB 165#ifdef CONFIG_GACT_PROB
165 if (gact->tcfg_ptype) { 166 if (gact->tcfg_ptype) {
166 struct tc_gact_p p_opt; 167 struct tc_gact_p p_opt = {
167 p_opt.paction = gact->tcfg_paction; 168 .paction = gact->tcfg_paction,
168 p_opt.pval = gact->tcfg_pval; 169 .pval = gact->tcfg_pval,
169 p_opt.ptype = gact->tcfg_ptype; 170 .ptype = gact->tcfg_ptype,
171 };
172
170 NLA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt); 173 NLA_PUT(skb, TCA_GACT_PROB, sizeof(p_opt), &p_opt);
171 } 174 }
172#endif 175#endif
@@ -202,9 +205,9 @@ MODULE_LICENSE("GPL");
202static int __init gact_init_module(void) 205static int __init gact_init_module(void)
203{ 206{
204#ifdef CONFIG_GACT_PROB 207#ifdef CONFIG_GACT_PROB
205 printk("GACT probability on\n"); 208 printk(KERN_INFO "GACT probability on\n");
206#else 209#else
207 printk("GACT probability NOT on\n"); 210 printk(KERN_INFO "GACT probability NOT on\n");
208#endif 211#endif
209 return tcf_register_action(&act_gact_ops); 212 return tcf_register_action(&act_gact_ops);
210} 213}
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
index 082c520b0def..c7e59e6ec349 100644
--- a/net/sched/act_ipt.c
+++ b/net/sched/act_ipt.c
@@ -19,6 +19,7 @@
19#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/slab.h>
22#include <net/netlink.h> 23#include <net/netlink.h>
23#include <net/pkt_sched.h> 24#include <net/pkt_sched.h>
24#include <linux/tc_act/tc_ipt.h> 25#include <linux/tc_act/tc_ipt.h>
@@ -46,8 +47,8 @@ static int ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int
46 47
47 target = xt_request_find_target(AF_INET, t->u.user.name, 48 target = xt_request_find_target(AF_INET, t->u.user.name,
48 t->u.user.revision); 49 t->u.user.revision);
49 if (!target) 50 if (IS_ERR(target))
50 return -ENOENT; 51 return PTR_ERR(target);
51 52
52 t->u.kernel.target = target; 53 t->u.kernel.target = target;
53 par.table = table; 54 par.table = table;
@@ -198,7 +199,7 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
198{ 199{
199 int ret = 0, result = 0; 200 int ret = 0, result = 0;
200 struct tcf_ipt *ipt = a->priv; 201 struct tcf_ipt *ipt = a->priv;
201 struct xt_target_param par; 202 struct xt_action_param par;
202 203
203 if (skb_cloned(skb)) { 204 if (skb_cloned(skb)) {
204 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 205 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
@@ -234,7 +235,8 @@ static int tcf_ipt(struct sk_buff *skb, struct tc_action *a,
234 break; 235 break;
235 default: 236 default:
236 if (net_ratelimit()) 237 if (net_ratelimit())
237 printk("Bogus netfilter code %d assume ACCEPT\n", ret); 238 pr_notice("tc filter: Bogus netfilter code"
239 " %d assume ACCEPT\n", ret);
238 result = TC_POLICE_OK; 240 result = TC_POLICE_OK;
239 break; 241 break;
240 } 242 }
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
index d329170243cb..0c311be92827 100644
--- a/net/sched/act_mirred.c
+++ b/net/sched/act_mirred.c
@@ -20,6 +20,7 @@
20#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/gfp.h>
23#include <net/net_namespace.h> 24#include <net/net_namespace.h>
24#include <net/netlink.h> 25#include <net/netlink.h>
25#include <net/pkt_sched.h> 26#include <net/pkt_sched.h>
@@ -32,6 +33,7 @@
32static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1]; 33static struct tcf_common *tcf_mirred_ht[MIRRED_TAB_MASK + 1];
33static u32 mirred_idx_gen; 34static u32 mirred_idx_gen;
34static DEFINE_RWLOCK(mirred_lock); 35static DEFINE_RWLOCK(mirred_lock);
36static LIST_HEAD(mirred_list);
35 37
36static struct tcf_hashinfo mirred_hash_info = { 38static struct tcf_hashinfo mirred_hash_info = {
37 .htab = tcf_mirred_ht, 39 .htab = tcf_mirred_ht,
@@ -46,7 +48,9 @@ static inline int tcf_mirred_release(struct tcf_mirred *m, int bind)
46 m->tcf_bindcnt--; 48 m->tcf_bindcnt--;
47 m->tcf_refcnt--; 49 m->tcf_refcnt--;
48 if(!m->tcf_bindcnt && m->tcf_refcnt <= 0) { 50 if(!m->tcf_bindcnt && m->tcf_refcnt <= 0) {
49 dev_put(m->tcfm_dev); 51 list_del(&m->tcfm_list);
52 if (m->tcfm_dev)
53 dev_put(m->tcfm_dev);
50 tcf_hash_destroy(&m->common, &mirred_hash_info); 54 tcf_hash_destroy(&m->common, &mirred_hash_info);
51 return 1; 55 return 1;
52 } 56 }
@@ -133,8 +137,10 @@ static int tcf_mirred_init(struct nlattr *nla, struct nlattr *est,
133 m->tcfm_ok_push = ok_push; 137 m->tcfm_ok_push = ok_push;
134 } 138 }
135 spin_unlock_bh(&m->tcf_lock); 139 spin_unlock_bh(&m->tcf_lock);
136 if (ret == ACT_P_CREATED) 140 if (ret == ACT_P_CREATED) {
141 list_add(&m->tcfm_list, &mirred_list);
137 tcf_hash_insert(pc, &mirred_hash_info); 142 tcf_hash_insert(pc, &mirred_hash_info);
143 }
138 144
139 return ret; 145 return ret;
140} 146}
@@ -159,22 +165,27 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,
159 165
160 spin_lock(&m->tcf_lock); 166 spin_lock(&m->tcf_lock);
161 m->tcf_tm.lastuse = jiffies; 167 m->tcf_tm.lastuse = jiffies;
168 m->tcf_bstats.bytes += qdisc_pkt_len(skb);
169 m->tcf_bstats.packets++;
162 170
163 dev = m->tcfm_dev; 171 dev = m->tcfm_dev;
172 if (!dev) {
173 printk_once(KERN_NOTICE "tc mirred: target device is gone\n");
174 goto out;
175 }
176
164 if (!(dev->flags & IFF_UP)) { 177 if (!(dev->flags & IFF_UP)) {
165 if (net_ratelimit()) 178 if (net_ratelimit())
166 printk("mirred to Houston: device %s is gone!\n", 179 pr_notice("tc mirred to Houston: device %s is down\n",
167 dev->name); 180 dev->name);
168 goto out; 181 goto out;
169 } 182 }
170 183
171 skb2 = skb_act_clone(skb, GFP_ATOMIC); 184 at = G_TC_AT(skb->tc_verd);
185 skb2 = skb_act_clone(skb, GFP_ATOMIC, m->tcf_action);
172 if (skb2 == NULL) 186 if (skb2 == NULL)
173 goto out; 187 goto out;
174 188
175 m->tcf_bstats.bytes += qdisc_pkt_len(skb2);
176 m->tcf_bstats.packets++;
177 at = G_TC_AT(skb->tc_verd);
178 if (!(at & AT_EGRESS)) { 189 if (!(at & AT_EGRESS)) {
179 if (m->tcfm_ok_push) 190 if (m->tcfm_ok_push)
180 skb_push(skb2, skb2->dev->hard_header_len); 191 skb_push(skb2, skb2->dev->hard_header_len);
@@ -184,16 +195,14 @@ static int tcf_mirred(struct sk_buff *skb, struct tc_action *a,
184 if (m->tcfm_eaction != TCA_EGRESS_MIRROR) 195 if (m->tcfm_eaction != TCA_EGRESS_MIRROR)
185 skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at); 196 skb2->tc_verd = SET_TC_FROM(skb2->tc_verd, at);
186 197
187 skb2->dev = dev;
188 skb2->skb_iif = skb->dev->ifindex; 198 skb2->skb_iif = skb->dev->ifindex;
199 skb2->dev = dev;
189 dev_queue_xmit(skb2); 200 dev_queue_xmit(skb2);
190 err = 0; 201 err = 0;
191 202
192out: 203out:
193 if (err) { 204 if (err) {
194 m->tcf_qstats.overlimits++; 205 m->tcf_qstats.overlimits++;
195 m->tcf_bstats.bytes += qdisc_pkt_len(skb);
196 m->tcf_bstats.packets++;
197 /* should we be asking for packet to be dropped? 206 /* should we be asking for packet to be dropped?
198 * may make sense for redirect case only 207 * may make sense for redirect case only
199 */ 208 */
@@ -210,15 +219,16 @@ static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, i
210{ 219{
211 unsigned char *b = skb_tail_pointer(skb); 220 unsigned char *b = skb_tail_pointer(skb);
212 struct tcf_mirred *m = a->priv; 221 struct tcf_mirred *m = a->priv;
213 struct tc_mirred opt; 222 struct tc_mirred opt = {
223 .index = m->tcf_index,
224 .action = m->tcf_action,
225 .refcnt = m->tcf_refcnt - ref,
226 .bindcnt = m->tcf_bindcnt - bind,
227 .eaction = m->tcfm_eaction,
228 .ifindex = m->tcfm_ifindex,
229 };
214 struct tcf_t t; 230 struct tcf_t t;
215 231
216 opt.index = m->tcf_index;
217 opt.action = m->tcf_action;
218 opt.refcnt = m->tcf_refcnt - ref;
219 opt.bindcnt = m->tcf_bindcnt - bind;
220 opt.eaction = m->tcfm_eaction;
221 opt.ifindex = m->tcfm_ifindex;
222 NLA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt); 232 NLA_PUT(skb, TCA_MIRRED_PARMS, sizeof(opt), &opt);
223 t.install = jiffies_to_clock_t(jiffies - m->tcf_tm.install); 233 t.install = jiffies_to_clock_t(jiffies - m->tcf_tm.install);
224 t.lastuse = jiffies_to_clock_t(jiffies - m->tcf_tm.lastuse); 234 t.lastuse = jiffies_to_clock_t(jiffies - m->tcf_tm.lastuse);
@@ -231,6 +241,28 @@ nla_put_failure:
231 return -1; 241 return -1;
232} 242}
233 243
244static int mirred_device_event(struct notifier_block *unused,
245 unsigned long event, void *ptr)
246{
247 struct net_device *dev = ptr;
248 struct tcf_mirred *m;
249
250 if (event == NETDEV_UNREGISTER)
251 list_for_each_entry(m, &mirred_list, tcfm_list) {
252 if (m->tcfm_dev == dev) {
253 dev_put(dev);
254 m->tcfm_dev = NULL;
255 }
256 }
257
258 return NOTIFY_DONE;
259}
260
261static struct notifier_block mirred_device_notifier = {
262 .notifier_call = mirred_device_event,
263};
264
265
234static struct tc_action_ops act_mirred_ops = { 266static struct tc_action_ops act_mirred_ops = {
235 .kind = "mirred", 267 .kind = "mirred",
236 .hinfo = &mirred_hash_info, 268 .hinfo = &mirred_hash_info,
@@ -251,12 +283,17 @@ MODULE_LICENSE("GPL");
251 283
252static int __init mirred_init_module(void) 284static int __init mirred_init_module(void)
253{ 285{
254 printk("Mirror/redirect action on\n"); 286 int err = register_netdevice_notifier(&mirred_device_notifier);
287 if (err)
288 return err;
289
290 pr_info("Mirror/redirect action on\n");
255 return tcf_register_action(&act_mirred_ops); 291 return tcf_register_action(&act_mirred_ops);
256} 292}
257 293
258static void __exit mirred_cleanup_module(void) 294static void __exit mirred_cleanup_module(void)
259{ 295{
296 unregister_netdevice_notifier(&mirred_device_notifier);
260 tcf_unregister_action(&act_mirred_ops); 297 tcf_unregister_action(&act_mirred_ops);
261} 298}
262 299
diff --git a/net/sched/act_nat.c b/net/sched/act_nat.c
index d885ba311564..186eb837e600 100644
--- a/net/sched/act_nat.c
+++ b/net/sched/act_nat.c
@@ -114,6 +114,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
114 int egress; 114 int egress;
115 int action; 115 int action;
116 int ihl; 116 int ihl;
117 int noff;
117 118
118 spin_lock(&p->tcf_lock); 119 spin_lock(&p->tcf_lock);
119 120
@@ -132,7 +133,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
132 if (unlikely(action == TC_ACT_SHOT)) 133 if (unlikely(action == TC_ACT_SHOT))
133 goto drop; 134 goto drop;
134 135
135 if (!pskb_may_pull(skb, sizeof(*iph))) 136 noff = skb_network_offset(skb);
137 if (!pskb_may_pull(skb, sizeof(*iph) + noff))
136 goto drop; 138 goto drop;
137 139
138 iph = ip_hdr(skb); 140 iph = ip_hdr(skb);
@@ -144,7 +146,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
144 146
145 if (!((old_addr ^ addr) & mask)) { 147 if (!((old_addr ^ addr) & mask)) {
146 if (skb_cloned(skb) && 148 if (skb_cloned(skb) &&
147 !skb_clone_writable(skb, sizeof(*iph)) && 149 !skb_clone_writable(skb, sizeof(*iph) + noff) &&
148 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 150 pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
149 goto drop; 151 goto drop;
150 152
@@ -159,6 +161,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
159 iph->daddr = new_addr; 161 iph->daddr = new_addr;
160 162
161 csum_replace4(&iph->check, addr, new_addr); 163 csum_replace4(&iph->check, addr, new_addr);
164 } else if ((iph->frag_off & htons(IP_OFFSET)) ||
165 iph->protocol != IPPROTO_ICMP) {
166 goto out;
162 } 167 }
163 168
164 ihl = iph->ihl * 4; 169 ihl = iph->ihl * 4;
@@ -169,9 +174,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
169 { 174 {
170 struct tcphdr *tcph; 175 struct tcphdr *tcph;
171 176
172 if (!pskb_may_pull(skb, ihl + sizeof(*tcph)) || 177 if (!pskb_may_pull(skb, ihl + sizeof(*tcph) + noff) ||
173 (skb_cloned(skb) && 178 (skb_cloned(skb) &&
174 !skb_clone_writable(skb, ihl + sizeof(*tcph)) && 179 !skb_clone_writable(skb, ihl + sizeof(*tcph) + noff) &&
175 pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) 180 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
176 goto drop; 181 goto drop;
177 182
@@ -183,9 +188,9 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
183 { 188 {
184 struct udphdr *udph; 189 struct udphdr *udph;
185 190
186 if (!pskb_may_pull(skb, ihl + sizeof(*udph)) || 191 if (!pskb_may_pull(skb, ihl + sizeof(*udph) + noff) ||
187 (skb_cloned(skb) && 192 (skb_cloned(skb) &&
188 !skb_clone_writable(skb, ihl + sizeof(*udph)) && 193 !skb_clone_writable(skb, ihl + sizeof(*udph) + noff) &&
189 pskb_expand_head(skb, 0, 0, GFP_ATOMIC))) 194 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)))
190 goto drop; 195 goto drop;
191 196
@@ -202,7 +207,7 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
202 { 207 {
203 struct icmphdr *icmph; 208 struct icmphdr *icmph;
204 209
205 if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph))) 210 if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + noff))
206 goto drop; 211 goto drop;
207 212
208 icmph = (void *)(skb_network_header(skb) + ihl); 213 icmph = (void *)(skb_network_header(skb) + ihl);
@@ -212,6 +217,11 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
212 (icmph->type != ICMP_PARAMETERPROB)) 217 (icmph->type != ICMP_PARAMETERPROB))
213 break; 218 break;
214 219
220 if (!pskb_may_pull(skb, ihl + sizeof(*icmph) + sizeof(*iph) +
221 noff))
222 goto drop;
223
224 icmph = (void *)(skb_network_header(skb) + ihl);
215 iph = (void *)(icmph + 1); 225 iph = (void *)(icmph + 1);
216 if (egress) 226 if (egress)
217 addr = iph->daddr; 227 addr = iph->daddr;
@@ -222,8 +232,8 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
222 break; 232 break;
223 233
224 if (skb_cloned(skb) && 234 if (skb_cloned(skb) &&
225 !skb_clone_writable(skb, 235 !skb_clone_writable(skb, ihl + sizeof(*icmph) +
226 ihl + sizeof(*icmph) + sizeof(*iph)) && 236 sizeof(*iph) + noff) &&
227 pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) 237 pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
228 goto drop; 238 goto drop;
229 239
@@ -240,13 +250,14 @@ static int tcf_nat(struct sk_buff *skb, struct tc_action *a,
240 iph->saddr = new_addr; 250 iph->saddr = new_addr;
241 251
242 inet_proto_csum_replace4(&icmph->checksum, skb, addr, new_addr, 252 inet_proto_csum_replace4(&icmph->checksum, skb, addr, new_addr,
243 1); 253 0);
244 break; 254 break;
245 } 255 }
246 default: 256 default:
247 break; 257 break;
248 } 258 }
249 259
260out:
250 return action; 261 return action;
251 262
252drop: 263drop:
@@ -261,40 +272,29 @@ static int tcf_nat_dump(struct sk_buff *skb, struct tc_action *a,
261{ 272{
262 unsigned char *b = skb_tail_pointer(skb); 273 unsigned char *b = skb_tail_pointer(skb);
263 struct tcf_nat *p = a->priv; 274 struct tcf_nat *p = a->priv;
264 struct tc_nat *opt; 275 struct tc_nat opt = {
276 .old_addr = p->old_addr,
277 .new_addr = p->new_addr,
278 .mask = p->mask,
279 .flags = p->flags,
280
281 .index = p->tcf_index,
282 .action = p->tcf_action,
283 .refcnt = p->tcf_refcnt - ref,
284 .bindcnt = p->tcf_bindcnt - bind,
285 };
265 struct tcf_t t; 286 struct tcf_t t;
266 int s;
267
268 s = sizeof(*opt);
269 287
270 /* netlink spinlocks held above us - must use ATOMIC */ 288 NLA_PUT(skb, TCA_NAT_PARMS, sizeof(opt), &opt);
271 opt = kzalloc(s, GFP_ATOMIC);
272 if (unlikely(!opt))
273 return -ENOBUFS;
274
275 opt->old_addr = p->old_addr;
276 opt->new_addr = p->new_addr;
277 opt->mask = p->mask;
278 opt->flags = p->flags;
279
280 opt->index = p->tcf_index;
281 opt->action = p->tcf_action;
282 opt->refcnt = p->tcf_refcnt - ref;
283 opt->bindcnt = p->tcf_bindcnt - bind;
284
285 NLA_PUT(skb, TCA_NAT_PARMS, s, opt);
286 t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install); 289 t.install = jiffies_to_clock_t(jiffies - p->tcf_tm.install);
287 t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse); 290 t.lastuse = jiffies_to_clock_t(jiffies - p->tcf_tm.lastuse);
288 t.expires = jiffies_to_clock_t(p->tcf_tm.expires); 291 t.expires = jiffies_to_clock_t(p->tcf_tm.expires);
289 NLA_PUT(skb, TCA_NAT_TM, sizeof(t), &t); 292 NLA_PUT(skb, TCA_NAT_TM, sizeof(t), &t);
290 293
291 kfree(opt);
292
293 return skb->len; 294 return skb->len;
294 295
295nla_put_failure: 296nla_put_failure:
296 nlmsg_trim(skb, b); 297 nlmsg_trim(skb, b);
297 kfree(opt);
298 return -1; 298 return -1;
299} 299}
300 300
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
index 6b0359a500e6..a0593c9640db 100644
--- a/net/sched/act_pedit.c
+++ b/net/sched/act_pedit.c
@@ -17,6 +17,7 @@
17#include <linux/rtnetlink.h> 17#include <linux/rtnetlink.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/slab.h>
20#include <net/netlink.h> 21#include <net/netlink.h>
21#include <net/pkt_sched.h> 22#include <net/pkt_sched.h>
22#include <linux/tc_act/tc_pedit.h> 23#include <linux/tc_act/tc_pedit.h>
@@ -124,16 +125,15 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
124{ 125{
125 struct tcf_pedit *p = a->priv; 126 struct tcf_pedit *p = a->priv;
126 int i, munged = 0; 127 int i, munged = 0;
127 u8 *pptr; 128 unsigned int off;
128 129
129 if (!(skb->tc_verd & TC_OK2MUNGE)) { 130 if (skb_cloned(skb)) {
130 /* should we set skb->cloned? */
131 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { 131 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
132 return p->tcf_action; 132 return p->tcf_action;
133 } 133 }
134 } 134 }
135 135
136 pptr = skb_network_header(skb); 136 off = skb_network_offset(skb);
137 137
138 spin_lock(&p->tcf_lock); 138 spin_lock(&p->tcf_lock);
139 139
@@ -143,41 +143,46 @@ static int tcf_pedit(struct sk_buff *skb, struct tc_action *a,
143 struct tc_pedit_key *tkey = p->tcfp_keys; 143 struct tc_pedit_key *tkey = p->tcfp_keys;
144 144
145 for (i = p->tcfp_nkeys; i > 0; i--, tkey++) { 145 for (i = p->tcfp_nkeys; i > 0; i--, tkey++) {
146 u32 *ptr; 146 u32 *ptr, _data;
147 int offset = tkey->off; 147 int offset = tkey->off;
148 148
149 if (tkey->offmask) { 149 if (tkey->offmask) {
150 if (skb->len > tkey->at) { 150 char *d, _d;
151 char *j = pptr + tkey->at; 151
152 offset += ((*j & tkey->offmask) >> 152 d = skb_header_pointer(skb, off + tkey->at, 1,
153 tkey->shift); 153 &_d);
154 } else { 154 if (!d)
155 goto bad; 155 goto bad;
156 } 156 offset += (*d & tkey->offmask) >> tkey->shift;
157 } 157 }
158 158
159 if (offset % 4) { 159 if (offset % 4) {
160 printk("offset must be on 32 bit boundaries\n"); 160 pr_info("tc filter pedit"
161 " offset must be on 32 bit boundaries\n");
161 goto bad; 162 goto bad;
162 } 163 }
163 if (offset > 0 && offset > skb->len) { 164 if (offset > 0 && offset > skb->len) {
164 printk("offset %d cant exceed pkt length %d\n", 165 pr_info("tc filter pedit"
166 " offset %d cant exceed pkt length %d\n",
165 offset, skb->len); 167 offset, skb->len);
166 goto bad; 168 goto bad;
167 } 169 }
168 170
169 ptr = (u32 *)(pptr+offset); 171 ptr = skb_header_pointer(skb, off + offset, 4, &_data);
172 if (!ptr)
173 goto bad;
170 /* just do it, baby */ 174 /* just do it, baby */
171 *ptr = ((*ptr & tkey->mask) ^ tkey->val); 175 *ptr = ((*ptr & tkey->mask) ^ tkey->val);
176 if (ptr == &_data)
177 skb_store_bits(skb, off + offset, ptr, 4);
172 munged++; 178 munged++;
173 } 179 }
174 180
175 if (munged) 181 if (munged)
176 skb->tc_verd = SET_TC_MUNGED(skb->tc_verd); 182 skb->tc_verd = SET_TC_MUNGED(skb->tc_verd);
177 goto done; 183 goto done;
178 } else { 184 } else
179 printk("pedit BUG: index %d\n", p->tcf_index); 185 WARN(1, "pedit BUG: index %d\n", p->tcf_index);
180 }
181 186
182bad: 187bad:
183 p->tcf_qstats.overlimits++; 188 p->tcf_qstats.overlimits++;
diff --git a/net/sched/act_police.c b/net/sched/act_police.c
index 723964c3ee4f..7ebf7439b478 100644
--- a/net/sched/act_police.c
+++ b/net/sched/act_police.c
@@ -18,6 +18,7 @@
18#include <linux/skbuff.h> 18#include <linux/skbuff.h>
19#include <linux/rtnetlink.h> 19#include <linux/rtnetlink.h>
20#include <linux/init.h> 20#include <linux/init.h>
21#include <linux/slab.h>
21#include <net/act_api.h> 22#include <net/act_api.h>
22#include <net/netlink.h> 23#include <net/netlink.h>
23 24
@@ -96,6 +97,11 @@ nla_put_failure:
96 goto done; 97 goto done;
97} 98}
98 99
100static void tcf_police_free_rcu(struct rcu_head *head)
101{
102 kfree(container_of(head, struct tcf_police, tcf_rcu));
103}
104
99static void tcf_police_destroy(struct tcf_police *p) 105static void tcf_police_destroy(struct tcf_police *p)
100{ 106{
101 unsigned int h = tcf_hash(p->tcf_index, POL_TAB_MASK); 107 unsigned int h = tcf_hash(p->tcf_index, POL_TAB_MASK);
@@ -112,7 +118,11 @@ static void tcf_police_destroy(struct tcf_police *p)
112 qdisc_put_rtab(p->tcfp_R_tab); 118 qdisc_put_rtab(p->tcfp_R_tab);
113 if (p->tcfp_P_tab) 119 if (p->tcfp_P_tab)
114 qdisc_put_rtab(p->tcfp_P_tab); 120 qdisc_put_rtab(p->tcfp_P_tab);
115 kfree(p); 121 /*
122 * gen_estimator est_timer() might access p->tcf_lock
123 * or bstats, wait a RCU grace period before freeing p
124 */
125 call_rcu(&p->tcf_rcu, tcf_police_free_rcu);
116 return; 126 return;
117 } 127 }
118 } 128 }
@@ -340,22 +350,19 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref)
340{ 350{
341 unsigned char *b = skb_tail_pointer(skb); 351 unsigned char *b = skb_tail_pointer(skb);
342 struct tcf_police *police = a->priv; 352 struct tcf_police *police = a->priv;
343 struct tc_police opt; 353 struct tc_police opt = {
344 354 .index = police->tcf_index,
345 opt.index = police->tcf_index; 355 .action = police->tcf_action,
346 opt.action = police->tcf_action; 356 .mtu = police->tcfp_mtu,
347 opt.mtu = police->tcfp_mtu; 357 .burst = police->tcfp_burst,
348 opt.burst = police->tcfp_burst; 358 .refcnt = police->tcf_refcnt - ref,
349 opt.refcnt = police->tcf_refcnt - ref; 359 .bindcnt = police->tcf_bindcnt - bind,
350 opt.bindcnt = police->tcf_bindcnt - bind; 360 };
361
351 if (police->tcfp_R_tab) 362 if (police->tcfp_R_tab)
352 opt.rate = police->tcfp_R_tab->rate; 363 opt.rate = police->tcfp_R_tab->rate;
353 else
354 memset(&opt.rate, 0, sizeof(opt.rate));
355 if (police->tcfp_P_tab) 364 if (police->tcfp_P_tab)
356 opt.peakrate = police->tcfp_P_tab->rate; 365 opt.peakrate = police->tcfp_P_tab->rate;
357 else
358 memset(&opt.peakrate, 0, sizeof(opt.peakrate));
359 NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt); 366 NLA_PUT(skb, TCA_POLICE_TBF, sizeof(opt), &opt);
360 if (police->tcfp_result) 367 if (police->tcfp_result)
361 NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result); 368 NLA_PUT_U32(skb, TCA_POLICE_RESULT, police->tcfp_result);
@@ -396,6 +403,7 @@ static void __exit
396police_cleanup_module(void) 403police_cleanup_module(void)
397{ 404{
398 tcf_unregister_action(&act_police_ops); 405 tcf_unregister_action(&act_police_ops);
406 rcu_barrier(); /* Wait for completion of call_rcu()'s (tcf_police_free_rcu) */
399} 407}
400 408
401module_init(police_init_module); 409module_init(police_init_module);
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c
index 8daa1ebc7413..97e84f3ee775 100644
--- a/net/sched/act_simple.c
+++ b/net/sched/act_simple.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/slab.h>
14#include <linux/init.h> 15#include <linux/init.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/skbuff.h> 17#include <linux/skbuff.h>
@@ -48,7 +49,7 @@ static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result
48 * Example if this was the 3rd packet and the string was "hello" 49 * Example if this was the 3rd packet and the string was "hello"
49 * then it would look like "hello_3" (without quotes) 50 * then it would look like "hello_3" (without quotes)
50 **/ 51 **/
51 printk("simple: %s_%d\n", 52 pr_info("simple: %s_%d\n",
52 (char *)d->tcfd_defdata, d->tcf_bstats.packets); 53 (char *)d->tcfd_defdata, d->tcf_bstats.packets);
53 spin_unlock(&d->tcf_lock); 54 spin_unlock(&d->tcf_lock);
54 return d->tcf_action; 55 return d->tcf_action;
@@ -72,10 +73,10 @@ static int tcf_simp_release(struct tcf_defact *d, int bind)
72 73
73static int alloc_defdata(struct tcf_defact *d, char *defdata) 74static int alloc_defdata(struct tcf_defact *d, char *defdata)
74{ 75{
75 d->tcfd_defdata = kstrndup(defdata, SIMP_MAX_DATA, GFP_KERNEL); 76 d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
76 if (unlikely(!d->tcfd_defdata)) 77 if (unlikely(!d->tcfd_defdata))
77 return -ENOMEM; 78 return -ENOMEM;
78 79 strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
79 return 0; 80 return 0;
80} 81}
81 82
@@ -163,13 +164,14 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
163{ 164{
164 unsigned char *b = skb_tail_pointer(skb); 165 unsigned char *b = skb_tail_pointer(skb);
165 struct tcf_defact *d = a->priv; 166 struct tcf_defact *d = a->priv;
166 struct tc_defact opt; 167 struct tc_defact opt = {
168 .index = d->tcf_index,
169 .refcnt = d->tcf_refcnt - ref,
170 .bindcnt = d->tcf_bindcnt - bind,
171 .action = d->tcf_action,
172 };
167 struct tcf_t t; 173 struct tcf_t t;
168 174
169 opt.index = d->tcf_index;
170 opt.refcnt = d->tcf_refcnt - ref;
171 opt.bindcnt = d->tcf_bindcnt - bind;
172 opt.action = d->tcf_action;
173 NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt); 175 NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
174 NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata); 176 NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
175 t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install); 177 t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
@@ -204,7 +206,7 @@ static int __init simp_init_module(void)
204{ 206{
205 int ret = tcf_register_action(&act_simp_ops); 207 int ret = tcf_register_action(&act_simp_ops);
206 if (!ret) 208 if (!ret)
207 printk("Simple TC action Loaded\n"); 209 pr_info("Simple TC action Loaded\n");
208 return ret; 210 return ret;
209} 211}
210 212
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index e9607fe55b58..66cbf4eb8855 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -159,13 +159,14 @@ static inline int tcf_skbedit_dump(struct sk_buff *skb, struct tc_action *a,
159{ 159{
160 unsigned char *b = skb_tail_pointer(skb); 160 unsigned char *b = skb_tail_pointer(skb);
161 struct tcf_skbedit *d = a->priv; 161 struct tcf_skbedit *d = a->priv;
162 struct tc_skbedit opt; 162 struct tc_skbedit opt = {
163 .index = d->tcf_index,
164 .refcnt = d->tcf_refcnt - ref,
165 .bindcnt = d->tcf_bindcnt - bind,
166 .action = d->tcf_action,
167 };
163 struct tcf_t t; 168 struct tcf_t t;
164 169
165 opt.index = d->tcf_index;
166 opt.refcnt = d->tcf_refcnt - ref;
167 opt.bindcnt = d->tcf_bindcnt - bind;
168 opt.action = d->tcf_action;
169 NLA_PUT(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt); 170 NLA_PUT(skb, TCA_SKBEDIT_PARMS, sizeof(opt), &opt);
170 if (d->flags & SKBEDIT_F_PRIORITY) 171 if (d->flags & SKBEDIT_F_PRIORITY)
171 NLA_PUT(skb, TCA_SKBEDIT_PRIORITY, sizeof(d->priority), 172 NLA_PUT(skb, TCA_SKBEDIT_PRIORITY, sizeof(d->priority),
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 3725d8fa29db..5fd0c28ef79a 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -24,6 +24,7 @@
24#include <linux/kmod.h> 24#include <linux/kmod.h>
25#include <linux/netlink.h> 25#include <linux/netlink.h>
26#include <linux/err.h> 26#include <linux/err.h>
27#include <linux/slab.h>
27#include <net/net_namespace.h> 28#include <net/net_namespace.h>
28#include <net/sock.h> 29#include <net/sock.h>
29#include <net/netlink.h> 30#include <net/netlink.h>
@@ -98,8 +99,9 @@ out:
98} 99}
99EXPORT_SYMBOL(unregister_tcf_proto_ops); 100EXPORT_SYMBOL(unregister_tcf_proto_ops);
100 101
101static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n, 102static int tfilter_notify(struct net *net, struct sk_buff *oskb,
102 struct tcf_proto *tp, unsigned long fh, int event); 103 struct nlmsghdr *n, struct tcf_proto *tp,
104 unsigned long fh, int event);
103 105
104 106
105/* Select new prio value from the range, managed by kernel. */ 107/* Select new prio value from the range, managed by kernel. */
@@ -137,9 +139,6 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
137 int err; 139 int err;
138 int tp_created = 0; 140 int tp_created = 0;
139 141
140 if (!net_eq(net, &init_net))
141 return -EINVAL;
142
143replay: 142replay:
144 t = NLMSG_DATA(n); 143 t = NLMSG_DATA(n);
145 protocol = TC_H_MIN(t->tcm_info); 144 protocol = TC_H_MIN(t->tcm_info);
@@ -158,7 +157,7 @@ replay:
158 /* Find head of filter chain. */ 157 /* Find head of filter chain. */
159 158
160 /* Find link */ 159 /* Find link */
161 dev = __dev_get_by_index(&init_net, t->tcm_ifindex); 160 dev = __dev_get_by_index(net, t->tcm_ifindex);
162 if (dev == NULL) 161 if (dev == NULL)
163 return -ENODEV; 162 return -ENODEV;
164 163
@@ -282,7 +281,7 @@ replay:
282 *back = tp->next; 281 *back = tp->next;
283 spin_unlock_bh(root_lock); 282 spin_unlock_bh(root_lock);
284 283
285 tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); 284 tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
286 tcf_destroy(tp); 285 tcf_destroy(tp);
287 err = 0; 286 err = 0;
288 goto errout; 287 goto errout;
@@ -305,10 +304,10 @@ replay:
305 case RTM_DELTFILTER: 304 case RTM_DELTFILTER:
306 err = tp->ops->delete(tp, fh); 305 err = tp->ops->delete(tp, fh);
307 if (err == 0) 306 if (err == 0)
308 tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); 307 tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
309 goto errout; 308 goto errout;
310 case RTM_GETTFILTER: 309 case RTM_GETTFILTER:
311 err = tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); 310 err = tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER);
312 goto errout; 311 goto errout;
313 default: 312 default:
314 err = -EINVAL; 313 err = -EINVAL;
@@ -324,7 +323,7 @@ replay:
324 *back = tp; 323 *back = tp;
325 spin_unlock_bh(root_lock); 324 spin_unlock_bh(root_lock);
326 } 325 }
327 tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER); 326 tfilter_notify(net, skb, n, tp, fh, RTM_NEWTFILTER);
328 } else { 327 } else {
329 if (tp_created) 328 if (tp_created)
330 tcf_destroy(tp); 329 tcf_destroy(tp);
@@ -370,8 +369,9 @@ nla_put_failure:
370 return -1; 369 return -1;
371} 370}
372 371
373static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n, 372static int tfilter_notify(struct net *net, struct sk_buff *oskb,
374 struct tcf_proto *tp, unsigned long fh, int event) 373 struct nlmsghdr *n, struct tcf_proto *tp,
374 unsigned long fh, int event)
375{ 375{
376 struct sk_buff *skb; 376 struct sk_buff *skb;
377 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; 377 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
@@ -385,7 +385,7 @@ static int tfilter_notify(struct sk_buff *oskb, struct nlmsghdr *n,
385 return -EINVAL; 385 return -EINVAL;
386 } 386 }
387 387
388 return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, 388 return rtnetlink_send(skb, net, pid, RTNLGRP_TC,
389 n->nlmsg_flags & NLM_F_ECHO); 389 n->nlmsg_flags & NLM_F_ECHO);
390} 390}
391 391
@@ -418,12 +418,9 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb)
418 const struct Qdisc_class_ops *cops; 418 const struct Qdisc_class_ops *cops;
419 struct tcf_dump_args arg; 419 struct tcf_dump_args arg;
420 420
421 if (!net_eq(net, &init_net))
422 return 0;
423
424 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) 421 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
425 return skb->len; 422 return skb->len;
426 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 423 if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
427 return skb->len; 424 return skb->len;
428 425
429 if (!tcm->tcm_parent) 426 if (!tcm->tcm_parent)
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index 4e2bda854119..efd4f95fd050 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/string.h> 16#include <linux/string.h>
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index e4877ca6727c..78ef2c5e130b 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -10,20 +10,37 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/string.h> 15#include <linux/string.h>
15#include <linux/errno.h> 16#include <linux/errno.h>
16#include <linux/skbuff.h> 17#include <linux/skbuff.h>
17#include <linux/cgroup.h> 18#include <linux/cgroup.h>
19#include <linux/rcupdate.h>
18#include <net/rtnetlink.h> 20#include <net/rtnetlink.h>
19#include <net/pkt_cls.h> 21#include <net/pkt_cls.h>
22#include <net/sock.h>
23#include <net/cls_cgroup.h>
20 24
21struct cgroup_cls_state 25static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss,
22{ 26 struct cgroup *cgrp);
23 struct cgroup_subsys_state css; 27static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp);
24 u32 classid; 28static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp);
29
30struct cgroup_subsys net_cls_subsys = {
31 .name = "net_cls",
32 .create = cgrp_create,
33 .destroy = cgrp_destroy,
34 .populate = cgrp_populate,
35#ifdef CONFIG_NET_CLS_CGROUP
36 .subsys_id = net_cls_subsys_id,
37#else
38#define net_cls_subsys_id net_cls_subsys.subsys_id
39#endif
40 .module = THIS_MODULE,
25}; 41};
26 42
43
27static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp) 44static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp)
28{ 45{
29 return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id), 46 return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id),
@@ -79,14 +96,6 @@ static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
79 return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files)); 96 return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files));
80} 97}
81 98
82struct cgroup_subsys net_cls_subsys = {
83 .name = "net_cls",
84 .create = cgrp_create,
85 .destroy = cgrp_destroy,
86 .populate = cgrp_populate,
87 .subsys_id = net_cls_subsys_id,
88};
89
90struct cls_cgroup_head 99struct cls_cgroup_head
91{ 100{
92 u32 handle; 101 u32 handle;
@@ -100,6 +109,10 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp,
100 struct cls_cgroup_head *head = tp->root; 109 struct cls_cgroup_head *head = tp->root;
101 u32 classid; 110 u32 classid;
102 111
112 rcu_read_lock();
113 classid = task_cls_state(current)->classid;
114 rcu_read_unlock();
115
103 /* 116 /*
104 * Due to the nature of the classifier it is required to ignore all 117 * Due to the nature of the classifier it is required to ignore all
105 * packets originating from softirq context as accessing `current' 118 * packets originating from softirq context as accessing `current'
@@ -110,12 +123,12 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp,
110 * calls by looking at the number of nested bh disable calls because 123 * calls by looking at the number of nested bh disable calls because
111 * softirqs always disables bh. 124 * softirqs always disables bh.
112 */ 125 */
113 if (softirq_count() != SOFTIRQ_OFFSET) 126 if (softirq_count() != SOFTIRQ_OFFSET) {
114 return -1; 127 /* If there is an sk_classid we'll use that. */
115 128 if (!skb->sk)
116 rcu_read_lock(); 129 return -1;
117 classid = task_cls_state(current)->classid; 130 classid = skb->sk->sk_classid;
118 rcu_read_unlock(); 131 }
119 132
120 if (!classid) 133 if (!classid)
121 return -1; 134 return -1;
@@ -277,12 +290,36 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = {
277 290
278static int __init init_cgroup_cls(void) 291static int __init init_cgroup_cls(void)
279{ 292{
280 return register_tcf_proto_ops(&cls_cgroup_ops); 293 int ret;
294
295 ret = cgroup_load_subsys(&net_cls_subsys);
296 if (ret)
297 goto out;
298
299#ifndef CONFIG_NET_CLS_CGROUP
300 /* We can't use rcu_assign_pointer because this is an int. */
301 smp_wmb();
302 net_cls_subsys_id = net_cls_subsys.subsys_id;
303#endif
304
305 ret = register_tcf_proto_ops(&cls_cgroup_ops);
306 if (ret)
307 cgroup_unload_subsys(&net_cls_subsys);
308
309out:
310 return ret;
281} 311}
282 312
283static void __exit exit_cgroup_cls(void) 313static void __exit exit_cgroup_cls(void)
284{ 314{
285 unregister_tcf_proto_ops(&cls_cgroup_ops); 315 unregister_tcf_proto_ops(&cls_cgroup_ops);
316
317#ifndef CONFIG_NET_CLS_CGROUP
318 net_cls_subsys_id = -1;
319 synchronize_rcu();
320#endif
321
322 cgroup_unload_subsys(&net_cls_subsys);
286} 323}
287 324
288module_init(init_cgroup_cls); 325module_init(init_cgroup_cls);
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index e054c62857e1..e17096e3913c 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -20,6 +20,7 @@
20#include <linux/ip.h> 20#include <linux/ip.h>
21#include <linux/ipv6.h> 21#include <linux/ipv6.h>
22#include <linux/if_vlan.h> 22#include <linux/if_vlan.h>
23#include <linux/slab.h>
23 24
24#include <net/pkt_cls.h> 25#include <net/pkt_cls.h>
25#include <net/ip.h> 26#include <net/ip.h>
@@ -64,37 +65,47 @@ static inline u32 addr_fold(void *addr)
64 return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0); 65 return (a & 0xFFFFFFFF) ^ (BITS_PER_LONG > 32 ? a >> 32 : 0);
65} 66}
66 67
67static u32 flow_get_src(const struct sk_buff *skb) 68static u32 flow_get_src(struct sk_buff *skb)
68{ 69{
69 switch (skb->protocol) { 70 switch (skb->protocol) {
70 case htons(ETH_P_IP): 71 case htons(ETH_P_IP):
71 return ntohl(ip_hdr(skb)->saddr); 72 if (pskb_network_may_pull(skb, sizeof(struct iphdr)))
73 return ntohl(ip_hdr(skb)->saddr);
74 break;
72 case htons(ETH_P_IPV6): 75 case htons(ETH_P_IPV6):
73 return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]); 76 if (pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
74 default: 77 return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]);
75 return addr_fold(skb->sk); 78 break;
76 } 79 }
80
81 return addr_fold(skb->sk);
77} 82}
78 83
79static u32 flow_get_dst(const struct sk_buff *skb) 84static u32 flow_get_dst(struct sk_buff *skb)
80{ 85{
81 switch (skb->protocol) { 86 switch (skb->protocol) {
82 case htons(ETH_P_IP): 87 case htons(ETH_P_IP):
83 return ntohl(ip_hdr(skb)->daddr); 88 if (pskb_network_may_pull(skb, sizeof(struct iphdr)))
89 return ntohl(ip_hdr(skb)->daddr);
90 break;
84 case htons(ETH_P_IPV6): 91 case htons(ETH_P_IPV6):
85 return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]); 92 if (pskb_network_may_pull(skb, sizeof(struct ipv6hdr)))
86 default: 93 return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]);
87 return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol; 94 break;
88 } 95 }
96
97 return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
89} 98}
90 99
91static u32 flow_get_proto(const struct sk_buff *skb) 100static u32 flow_get_proto(struct sk_buff *skb)
92{ 101{
93 switch (skb->protocol) { 102 switch (skb->protocol) {
94 case htons(ETH_P_IP): 103 case htons(ETH_P_IP):
95 return ip_hdr(skb)->protocol; 104 return pskb_network_may_pull(skb, sizeof(struct iphdr)) ?
105 ip_hdr(skb)->protocol : 0;
96 case htons(ETH_P_IPV6): 106 case htons(ETH_P_IPV6):
97 return ipv6_hdr(skb)->nexthdr; 107 return pskb_network_may_pull(skb, sizeof(struct ipv6hdr)) ?
108 ipv6_hdr(skb)->nexthdr : 0;
98 default: 109 default:
99 return 0; 110 return 0;
100 } 111 }
@@ -115,58 +126,64 @@ static int has_ports(u8 protocol)
115 } 126 }
116} 127}
117 128
118static u32 flow_get_proto_src(const struct sk_buff *skb) 129static u32 flow_get_proto_src(struct sk_buff *skb)
119{ 130{
120 u32 res = 0;
121
122 switch (skb->protocol) { 131 switch (skb->protocol) {
123 case htons(ETH_P_IP): { 132 case htons(ETH_P_IP): {
124 struct iphdr *iph = ip_hdr(skb); 133 struct iphdr *iph;
125 134
135 if (!pskb_network_may_pull(skb, sizeof(*iph)))
136 break;
137 iph = ip_hdr(skb);
126 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && 138 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
127 has_ports(iph->protocol)) 139 has_ports(iph->protocol) &&
128 res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4)); 140 pskb_network_may_pull(skb, iph->ihl * 4 + 2))
141 return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4));
129 break; 142 break;
130 } 143 }
131 case htons(ETH_P_IPV6): { 144 case htons(ETH_P_IPV6): {
132 struct ipv6hdr *iph = ipv6_hdr(skb); 145 struct ipv6hdr *iph;
133 146
147 if (!pskb_network_may_pull(skb, sizeof(*iph) + 2))
148 break;
149 iph = ipv6_hdr(skb);
134 if (has_ports(iph->nexthdr)) 150 if (has_ports(iph->nexthdr))
135 res = ntohs(*(__be16 *)&iph[1]); 151 return ntohs(*(__be16 *)&iph[1]);
136 break; 152 break;
137 } 153 }
138 default:
139 res = addr_fold(skb->sk);
140 } 154 }
141 155
142 return res; 156 return addr_fold(skb->sk);
143} 157}
144 158
145static u32 flow_get_proto_dst(const struct sk_buff *skb) 159static u32 flow_get_proto_dst(struct sk_buff *skb)
146{ 160{
147 u32 res = 0;
148
149 switch (skb->protocol) { 161 switch (skb->protocol) {
150 case htons(ETH_P_IP): { 162 case htons(ETH_P_IP): {
151 struct iphdr *iph = ip_hdr(skb); 163 struct iphdr *iph;
152 164
165 if (!pskb_network_may_pull(skb, sizeof(*iph)))
166 break;
167 iph = ip_hdr(skb);
153 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && 168 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
154 has_ports(iph->protocol)) 169 has_ports(iph->protocol) &&
155 res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2)); 170 pskb_network_may_pull(skb, iph->ihl * 4 + 4))
171 return ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2));
156 break; 172 break;
157 } 173 }
158 case htons(ETH_P_IPV6): { 174 case htons(ETH_P_IPV6): {
159 struct ipv6hdr *iph = ipv6_hdr(skb); 175 struct ipv6hdr *iph;
160 176
177 if (!pskb_network_may_pull(skb, sizeof(*iph) + 4))
178 break;
179 iph = ipv6_hdr(skb);
161 if (has_ports(iph->nexthdr)) 180 if (has_ports(iph->nexthdr))
162 res = ntohs(*(__be16 *)((void *)&iph[1] + 2)); 181 return ntohs(*(__be16 *)((void *)&iph[1] + 2));
163 break; 182 break;
164 } 183 }
165 default:
166 res = addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
167 } 184 }
168 185
169 return res; 186 return addr_fold(skb_dst(skb)) ^ (__force u16)skb->protocol;
170} 187}
171 188
172static u32 flow_get_iif(const struct sk_buff *skb) 189static u32 flow_get_iif(const struct sk_buff *skb)
@@ -210,7 +227,7 @@ static u32 flow_get_nfct(const struct sk_buff *skb)
210}) 227})
211#endif 228#endif
212 229
213static u32 flow_get_nfct_src(const struct sk_buff *skb) 230static u32 flow_get_nfct_src(struct sk_buff *skb)
214{ 231{
215 switch (skb->protocol) { 232 switch (skb->protocol) {
216 case htons(ETH_P_IP): 233 case htons(ETH_P_IP):
@@ -222,7 +239,7 @@ fallback:
222 return flow_get_src(skb); 239 return flow_get_src(skb);
223} 240}
224 241
225static u32 flow_get_nfct_dst(const struct sk_buff *skb) 242static u32 flow_get_nfct_dst(struct sk_buff *skb)
226{ 243{
227 switch (skb->protocol) { 244 switch (skb->protocol) {
228 case htons(ETH_P_IP): 245 case htons(ETH_P_IP):
@@ -234,14 +251,14 @@ fallback:
234 return flow_get_dst(skb); 251 return flow_get_dst(skb);
235} 252}
236 253
237static u32 flow_get_nfct_proto_src(const struct sk_buff *skb) 254static u32 flow_get_nfct_proto_src(struct sk_buff *skb)
238{ 255{
239 return ntohs(CTTUPLE(skb, src.u.all)); 256 return ntohs(CTTUPLE(skb, src.u.all));
240fallback: 257fallback:
241 return flow_get_proto_src(skb); 258 return flow_get_proto_src(skb);
242} 259}
243 260
244static u32 flow_get_nfct_proto_dst(const struct sk_buff *skb) 261static u32 flow_get_nfct_proto_dst(struct sk_buff *skb)
245{ 262{
246 return ntohs(CTTUPLE(skb, dst.u.all)); 263 return ntohs(CTTUPLE(skb, dst.u.all));
247fallback: 264fallback:
@@ -280,7 +297,7 @@ static u32 flow_get_vlan_tag(const struct sk_buff *skb)
280 return tag & VLAN_VID_MASK; 297 return tag & VLAN_VID_MASK;
281} 298}
282 299
283static u32 flow_key_get(const struct sk_buff *skb, int key) 300static u32 flow_key_get(struct sk_buff *skb, int key)
284{ 301{
285 switch (key) { 302 switch (key) {
286 case FLOW_KEY_SRC: 303 case FLOW_KEY_SRC:
@@ -601,7 +618,6 @@ static unsigned long flow_get(struct tcf_proto *tp, u32 handle)
601 618
602static void flow_put(struct tcf_proto *tp, unsigned long f) 619static void flow_put(struct tcf_proto *tp, unsigned long f)
603{ 620{
604 return;
605} 621}
606 622
607static int flow_dump(struct tcf_proto *tp, unsigned long fh, 623static int flow_dump(struct tcf_proto *tp, unsigned long fh,
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 6d6e87585fb1..93b0a7b6f9b4 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -19,6 +19,7 @@
19 */ 19 */
20 20
21#include <linux/module.h> 21#include <linux/module.h>
22#include <linux/slab.h>
22#include <linux/types.h> 23#include <linux/types.h>
23#include <linux/kernel.h> 24#include <linux/kernel.h>
24#include <linux/string.h> 25#include <linux/string.h>
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index dd872d5383ef..694dcd85dec8 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/string.h> 16#include <linux/string.h>
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index dd9414e44200..425a1790b048 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -143,9 +143,17 @@ static int rsvp_classify(struct sk_buff *skb, struct tcf_proto *tp,
143 u8 tunnelid = 0; 143 u8 tunnelid = 0;
144 u8 *xprt; 144 u8 *xprt;
145#if RSVP_DST_LEN == 4 145#if RSVP_DST_LEN == 4
146 struct ipv6hdr *nhptr = ipv6_hdr(skb); 146 struct ipv6hdr *nhptr;
147
148 if (!pskb_network_may_pull(skb, sizeof(*nhptr)))
149 return -1;
150 nhptr = ipv6_hdr(skb);
147#else 151#else
148 struct iphdr *nhptr = ip_hdr(skb); 152 struct iphdr *nhptr;
153
154 if (!pskb_network_may_pull(skb, sizeof(*nhptr)))
155 return -1;
156 nhptr = ip_hdr(skb);
149#endif 157#endif
150 158
151restart: 159restart:
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index e806f2314b5e..20ef330bb918 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -9,6 +9,7 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/skbuff.h> 10#include <linux/skbuff.h>
11#include <linux/errno.h> 11#include <linux/errno.h>
12#include <linux/slab.h>
12#include <net/act_api.h> 13#include <net/act_api.h>
13#include <net/netlink.h> 14#include <net/netlink.h>
14#include <net/pkt_cls.h> 15#include <net/pkt_cls.h>
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 07372f60bee3..b0c2a82178af 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -31,6 +31,7 @@
31 */ 31 */
32 32
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/slab.h>
34#include <linux/types.h> 35#include <linux/types.h>
35#include <linux/kernel.h> 36#include <linux/kernel.h>
36#include <linux/string.h> 37#include <linux/string.h>
@@ -97,11 +98,11 @@ static int u32_classify(struct sk_buff *skb, struct tcf_proto *tp, struct tcf_re
97{ 98{
98 struct { 99 struct {
99 struct tc_u_knode *knode; 100 struct tc_u_knode *knode;
100 u8 *ptr; 101 unsigned int off;
101 } stack[TC_U32_MAXDEPTH]; 102 } stack[TC_U32_MAXDEPTH];
102 103
103 struct tc_u_hnode *ht = (struct tc_u_hnode*)tp->root; 104 struct tc_u_hnode *ht = (struct tc_u_hnode*)tp->root;
104 u8 *ptr = skb_network_header(skb); 105 unsigned int off = skb_network_offset(skb);
105 struct tc_u_knode *n; 106 struct tc_u_knode *n;
106 int sdepth = 0; 107 int sdepth = 0;
107 int off2 = 0; 108 int off2 = 0;
@@ -133,8 +134,16 @@ next_knode:
133#endif 134#endif
134 135
135 for (i = n->sel.nkeys; i>0; i--, key++) { 136 for (i = n->sel.nkeys; i>0; i--, key++) {
137 int toff = off + key->off + (off2 & key->offmask);
138 __be32 *data, _data;
136 139
137 if ((*(__be32*)(ptr+key->off+(off2&key->offmask))^key->val)&key->mask) { 140 if (skb_headroom(skb) + toff > INT_MAX)
141 goto out;
142
143 data = skb_header_pointer(skb, toff, 4, &_data);
144 if (!data)
145 goto out;
146 if ((*data ^ key->val) & key->mask) {
138 n = n->next; 147 n = n->next;
139 goto next_knode; 148 goto next_knode;
140 } 149 }
@@ -173,29 +182,45 @@ check_terminal:
173 if (sdepth >= TC_U32_MAXDEPTH) 182 if (sdepth >= TC_U32_MAXDEPTH)
174 goto deadloop; 183 goto deadloop;
175 stack[sdepth].knode = n; 184 stack[sdepth].knode = n;
176 stack[sdepth].ptr = ptr; 185 stack[sdepth].off = off;
177 sdepth++; 186 sdepth++;
178 187
179 ht = n->ht_down; 188 ht = n->ht_down;
180 sel = 0; 189 sel = 0;
181 if (ht->divisor) 190 if (ht->divisor) {
182 sel = ht->divisor&u32_hash_fold(*(__be32*)(ptr+n->sel.hoff), &n->sel,n->fshift); 191 __be32 *data, _data;
183 192
193 data = skb_header_pointer(skb, off + n->sel.hoff, 4,
194 &_data);
195 if (!data)
196 goto out;
197 sel = ht->divisor & u32_hash_fold(*data, &n->sel,
198 n->fshift);
199 }
184 if (!(n->sel.flags&(TC_U32_VAROFFSET|TC_U32_OFFSET|TC_U32_EAT))) 200 if (!(n->sel.flags&(TC_U32_VAROFFSET|TC_U32_OFFSET|TC_U32_EAT)))
185 goto next_ht; 201 goto next_ht;
186 202
187 if (n->sel.flags&(TC_U32_OFFSET|TC_U32_VAROFFSET)) { 203 if (n->sel.flags&(TC_U32_OFFSET|TC_U32_VAROFFSET)) {
188 off2 = n->sel.off + 3; 204 off2 = n->sel.off + 3;
189 if (n->sel.flags&TC_U32_VAROFFSET) 205 if (n->sel.flags & TC_U32_VAROFFSET) {
190 off2 += ntohs(n->sel.offmask & *(__be16*)(ptr+n->sel.offoff)) >>n->sel.offshift; 206 __be16 *data, _data;
207
208 data = skb_header_pointer(skb,
209 off + n->sel.offoff,
210 2, &_data);
211 if (!data)
212 goto out;
213 off2 += ntohs(n->sel.offmask & *data) >>
214 n->sel.offshift;
215 }
191 off2 &= ~3; 216 off2 &= ~3;
192 } 217 }
193 if (n->sel.flags&TC_U32_EAT) { 218 if (n->sel.flags&TC_U32_EAT) {
194 ptr += off2; 219 off += off2;
195 off2 = 0; 220 off2 = 0;
196 } 221 }
197 222
198 if (ptr < skb_tail_pointer(skb)) 223 if (off < skb->len)
199 goto next_ht; 224 goto next_ht;
200 } 225 }
201 226
@@ -203,14 +228,15 @@ check_terminal:
203 if (sdepth--) { 228 if (sdepth--) {
204 n = stack[sdepth].knode; 229 n = stack[sdepth].knode;
205 ht = n->ht_up; 230 ht = n->ht_up;
206 ptr = stack[sdepth].ptr; 231 off = stack[sdepth].off;
207 goto check_terminal; 232 goto check_terminal;
208 } 233 }
234out:
209 return -1; 235 return -1;
210 236
211deadloop: 237deadloop:
212 if (net_ratelimit()) 238 if (net_ratelimit())
213 printk("cls_u32: dead loop\n"); 239 printk(KERN_WARNING "cls_u32: dead loop\n");
214 return -1; 240 return -1;
215} 241}
216 242
@@ -767,15 +793,15 @@ static struct tcf_proto_ops cls_u32_ops __read_mostly = {
767 793
768static int __init init_u32(void) 794static int __init init_u32(void)
769{ 795{
770 printk("u32 classifier\n"); 796 pr_info("u32 classifier\n");
771#ifdef CONFIG_CLS_U32_PERF 797#ifdef CONFIG_CLS_U32_PERF
772 printk(" Performance counters on\n"); 798 pr_info(" Performance counters on\n");
773#endif 799#endif
774#ifdef CONFIG_NET_CLS_IND 800#ifdef CONFIG_NET_CLS_IND
775 printk(" input device check on \n"); 801 pr_info(" input device check on\n");
776#endif 802#endif
777#ifdef CONFIG_NET_CLS_ACT 803#ifdef CONFIG_NET_CLS_ACT
778 printk(" Actions configured \n"); 804 pr_info(" Actions configured\n");
779#endif 805#endif
780 return register_tcf_proto_ops(&cls_u32_ops); 806 return register_tcf_proto_ops(&cls_u32_ops);
781} 807}
diff --git a/net/sched/em_meta.c b/net/sched/em_meta.c
index 24dce8b648a4..3bcac8aa333c 100644
--- a/net/sched/em_meta.c
+++ b/net/sched/em_meta.c
@@ -58,6 +58,7 @@
58 * only available if that subsystem is enabled in the kernel. 58 * only available if that subsystem is enabled in the kernel.
59 */ 59 */
60 60
61#include <linux/slab.h>
61#include <linux/module.h> 62#include <linux/module.h>
62#include <linux/types.h> 63#include <linux/types.h>
63#include <linux/kernel.h> 64#include <linux/kernel.h>
diff --git a/net/sched/em_nbyte.c b/net/sched/em_nbyte.c
index 370a1b2ea317..1a4176aee6e5 100644
--- a/net/sched/em_nbyte.c
+++ b/net/sched/em_nbyte.c
@@ -9,6 +9,7 @@
9 * Authors: Thomas Graf <tgraf@suug.ch> 9 * Authors: Thomas Graf <tgraf@suug.ch>
10 */ 10 */
11 11
12#include <linux/gfp.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
diff --git a/net/sched/em_text.c b/net/sched/em_text.c
index 853c5ead87fd..763253257411 100644
--- a/net/sched/em_text.c
+++ b/net/sched/em_text.c
@@ -9,6 +9,7 @@
9 * Authors: Thomas Graf <tgraf@suug.ch> 9 * Authors: Thomas Graf <tgraf@suug.ch>
10 */ 10 */
11 11
12#include <linux/slab.h>
12#include <linux/module.h> 13#include <linux/module.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
diff --git a/net/sched/ematch.c b/net/sched/ematch.c
index aab59409728b..5e37da961f80 100644
--- a/net/sched/ematch.c
+++ b/net/sched/ematch.c
@@ -82,6 +82,7 @@
82 */ 82 */
83 83
84#include <linux/module.h> 84#include <linux/module.h>
85#include <linux/slab.h>
85#include <linux/types.h> 86#include <linux/types.h>
86#include <linux/kernel.h> 87#include <linux/kernel.h>
87#include <linux/errno.h> 88#include <linux/errno.h>
@@ -526,7 +527,8 @@ pop_stack:
526 527
527stack_overflow: 528stack_overflow:
528 if (net_ratelimit()) 529 if (net_ratelimit())
529 printk("Local stack overflow, increase NET_EMATCH_STACK\n"); 530 printk(KERN_WARNING "tc ematch: local stack overflow,"
531 " increase NET_EMATCH_STACK\n");
530 return -1; 532 return -1;
531} 533}
532EXPORT_SYMBOL(__tcf_em_tree_match); 534EXPORT_SYMBOL(__tcf_em_tree_match);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 75fd1c672c61..408eea7086aa 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -28,16 +28,19 @@
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/hrtimer.h> 29#include <linux/hrtimer.h>
30#include <linux/lockdep.h> 30#include <linux/lockdep.h>
31#include <linux/slab.h>
31 32
32#include <net/net_namespace.h> 33#include <net/net_namespace.h>
33#include <net/sock.h> 34#include <net/sock.h>
34#include <net/netlink.h> 35#include <net/netlink.h>
35#include <net/pkt_sched.h> 36#include <net/pkt_sched.h>
36 37
37static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, u32 clid, 38static int qdisc_notify(struct net *net, struct sk_buff *oskb,
39 struct nlmsghdr *n, u32 clid,
38 struct Qdisc *old, struct Qdisc *new); 40 struct Qdisc *old, struct Qdisc *new);
39static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, 41static int tclass_notify(struct net *net, struct sk_buff *oskb,
40 struct Qdisc *q, unsigned long cl, int event); 42 struct nlmsghdr *n, struct Qdisc *q,
43 unsigned long cl, int event);
41 44
42/* 45/*
43 46
@@ -147,22 +150,34 @@ int register_qdisc(struct Qdisc_ops *qops)
147 if (qops->enqueue == NULL) 150 if (qops->enqueue == NULL)
148 qops->enqueue = noop_qdisc_ops.enqueue; 151 qops->enqueue = noop_qdisc_ops.enqueue;
149 if (qops->peek == NULL) { 152 if (qops->peek == NULL) {
150 if (qops->dequeue == NULL) { 153 if (qops->dequeue == NULL)
151 qops->peek = noop_qdisc_ops.peek; 154 qops->peek = noop_qdisc_ops.peek;
152 } else { 155 else
153 rc = -EINVAL; 156 goto out_einval;
154 goto out;
155 }
156 } 157 }
157 if (qops->dequeue == NULL) 158 if (qops->dequeue == NULL)
158 qops->dequeue = noop_qdisc_ops.dequeue; 159 qops->dequeue = noop_qdisc_ops.dequeue;
159 160
161 if (qops->cl_ops) {
162 const struct Qdisc_class_ops *cops = qops->cl_ops;
163
164 if (!(cops->get && cops->put && cops->walk && cops->leaf))
165 goto out_einval;
166
167 if (cops->tcf_chain && !(cops->bind_tcf && cops->unbind_tcf))
168 goto out_einval;
169 }
170
160 qops->next = NULL; 171 qops->next = NULL;
161 *qp = qops; 172 *qp = qops;
162 rc = 0; 173 rc = 0;
163out: 174out:
164 write_unlock(&qdisc_mod_lock); 175 write_unlock(&qdisc_mod_lock);
165 return rc; 176 return rc;
177
178out_einval:
179 rc = -EINVAL;
180 goto out;
166} 181}
167EXPORT_SYMBOL(register_qdisc); 182EXPORT_SYMBOL(register_qdisc);
168 183
@@ -638,11 +653,12 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
638} 653}
639EXPORT_SYMBOL(qdisc_tree_decrease_qlen); 654EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
640 655
641static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid, 656static void notify_and_destroy(struct net *net, struct sk_buff *skb,
657 struct nlmsghdr *n, u32 clid,
642 struct Qdisc *old, struct Qdisc *new) 658 struct Qdisc *old, struct Qdisc *new)
643{ 659{
644 if (new || old) 660 if (new || old)
645 qdisc_notify(skb, n, clid, old, new); 661 qdisc_notify(net, skb, n, clid, old, new);
646 662
647 if (old) 663 if (old)
648 qdisc_destroy(old); 664 qdisc_destroy(old);
@@ -662,6 +678,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
662 struct Qdisc *new, struct Qdisc *old) 678 struct Qdisc *new, struct Qdisc *old)
663{ 679{
664 struct Qdisc *q = old; 680 struct Qdisc *q = old;
681 struct net *net = dev_net(dev);
665 int err = 0; 682 int err = 0;
666 683
667 if (parent == NULL) { 684 if (parent == NULL) {
@@ -698,12 +715,13 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
698 } 715 }
699 716
700 if (!ingress) { 717 if (!ingress) {
701 notify_and_destroy(skb, n, classid, dev->qdisc, new); 718 notify_and_destroy(net, skb, n, classid,
719 dev->qdisc, new);
702 if (new && !new->ops->attach) 720 if (new && !new->ops->attach)
703 atomic_inc(&new->refcnt); 721 atomic_inc(&new->refcnt);
704 dev->qdisc = new ? : &noop_qdisc; 722 dev->qdisc = new ? : &noop_qdisc;
705 } else { 723 } else {
706 notify_and_destroy(skb, n, classid, old, new); 724 notify_and_destroy(net, skb, n, classid, old, new);
707 } 725 }
708 726
709 if (dev->flags & IFF_UP) 727 if (dev->flags & IFF_UP)
@@ -721,7 +739,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
721 err = -ENOENT; 739 err = -ENOENT;
722 } 740 }
723 if (!err) 741 if (!err)
724 notify_and_destroy(skb, n, classid, old, new); 742 notify_and_destroy(net, skb, n, classid, old, new);
725 } 743 }
726 return err; 744 return err;
727} 745}
@@ -947,10 +965,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
947 struct Qdisc *p = NULL; 965 struct Qdisc *p = NULL;
948 int err; 966 int err;
949 967
950 if (!net_eq(net, &init_net)) 968 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; 969 return -ENODEV;
955 970
956 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 971 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
@@ -990,7 +1005,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) 1005 if ((err = qdisc_graft(dev, p, skb, n, clid, NULL, q)) != 0)
991 return err; 1006 return err;
992 } else { 1007 } else {
993 qdisc_notify(skb, n, clid, NULL, q); 1008 qdisc_notify(net, skb, n, clid, NULL, q);
994 } 1009 }
995 return 0; 1010 return 0;
996} 1011}
@@ -1009,16 +1024,13 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1009 struct Qdisc *q, *p; 1024 struct Qdisc *q, *p;
1010 int err; 1025 int err;
1011 1026
1012 if (!net_eq(net, &init_net))
1013 return -EINVAL;
1014
1015replay: 1027replay:
1016 /* Reinit, just in case something touches this. */ 1028 /* Reinit, just in case something touches this. */
1017 tcm = NLMSG_DATA(n); 1029 tcm = NLMSG_DATA(n);
1018 clid = tcm->tcm_parent; 1030 clid = tcm->tcm_parent;
1019 q = p = NULL; 1031 q = p = NULL;
1020 1032
1021 if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 1033 if ((dev = __dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
1022 return -ENODEV; 1034 return -ENODEV;
1023 1035
1024 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 1036 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
@@ -1105,7 +1117,7 @@ replay:
1105 return -EINVAL; 1117 return -EINVAL;
1106 err = qdisc_change(q, tca); 1118 err = qdisc_change(q, tca);
1107 if (err == 0) 1119 if (err == 0)
1108 qdisc_notify(skb, n, clid, NULL, q); 1120 qdisc_notify(net, skb, n, clid, NULL, q);
1109 return err; 1121 return err;
1110 1122
1111create_n_graft: 1123create_n_graft:
@@ -1195,8 +1207,14 @@ nla_put_failure:
1195 return -1; 1207 return -1;
1196} 1208}
1197 1209
1198static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, 1210static bool tc_qdisc_dump_ignore(struct Qdisc *q)
1199 u32 clid, struct Qdisc *old, struct Qdisc *new) 1211{
1212 return (q->flags & TCQ_F_BUILTIN) ? true : false;
1213}
1214
1215static int qdisc_notify(struct net *net, struct sk_buff *oskb,
1216 struct nlmsghdr *n, u32 clid,
1217 struct Qdisc *old, struct Qdisc *new)
1200{ 1218{
1201 struct sk_buff *skb; 1219 struct sk_buff *skb;
1202 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; 1220 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
@@ -1205,28 +1223,23 @@ static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n,
1205 if (!skb) 1223 if (!skb)
1206 return -ENOBUFS; 1224 return -ENOBUFS;
1207 1225
1208 if (old && old->handle) { 1226 if (old && !tc_qdisc_dump_ignore(old)) {
1209 if (tc_fill_qdisc(skb, old, clid, pid, n->nlmsg_seq, 0, RTM_DELQDISC) < 0) 1227 if (tc_fill_qdisc(skb, old, clid, pid, n->nlmsg_seq, 0, RTM_DELQDISC) < 0)
1210 goto err_out; 1228 goto err_out;
1211 } 1229 }
1212 if (new) { 1230 if (new && !tc_qdisc_dump_ignore(new)) {
1213 if (tc_fill_qdisc(skb, new, clid, pid, n->nlmsg_seq, old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0) 1231 if (tc_fill_qdisc(skb, new, clid, pid, n->nlmsg_seq, old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0)
1214 goto err_out; 1232 goto err_out;
1215 } 1233 }
1216 1234
1217 if (skb->len) 1235 if (skb->len)
1218 return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 1236 return rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
1219 1237
1220err_out: 1238err_out:
1221 kfree_skb(skb); 1239 kfree_skb(skb);
1222 return -EINVAL; 1240 return -EINVAL;
1223} 1241}
1224 1242
1225static bool tc_qdisc_dump_ignore(struct Qdisc *q)
1226{
1227 return (q->flags & TCQ_F_BUILTIN) ? true : false;
1228}
1229
1230static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb, 1243static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
1231 struct netlink_callback *cb, 1244 struct netlink_callback *cb,
1232 int *q_idx_p, int s_q_idx) 1245 int *q_idx_p, int s_q_idx)
@@ -1274,15 +1287,12 @@ static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
1274 int s_idx, s_q_idx; 1287 int s_idx, s_q_idx;
1275 struct net_device *dev; 1288 struct net_device *dev;
1276 1289
1277 if (!net_eq(net, &init_net))
1278 return 0;
1279
1280 s_idx = cb->args[0]; 1290 s_idx = cb->args[0];
1281 s_q_idx = q_idx = cb->args[1]; 1291 s_q_idx = q_idx = cb->args[1];
1282 1292
1283 rcu_read_lock(); 1293 rcu_read_lock();
1284 idx = 0; 1294 idx = 0;
1285 for_each_netdev_rcu(&init_net, dev) { 1295 for_each_netdev_rcu(net, dev) {
1286 struct netdev_queue *dev_queue; 1296 struct netdev_queue *dev_queue;
1287 1297
1288 if (idx < s_idx) 1298 if (idx < s_idx)
@@ -1334,10 +1344,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1334 u32 qid = TC_H_MAJ(clid); 1344 u32 qid = TC_H_MAJ(clid);
1335 int err; 1345 int err;
1336 1346
1337 if (!net_eq(net, &init_net)) 1347 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; 1348 return -ENODEV;
1342 1349
1343 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); 1350 err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
@@ -1418,10 +1425,10 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1418 if (cops->delete) 1425 if (cops->delete)
1419 err = cops->delete(q, cl); 1426 err = cops->delete(q, cl);
1420 if (err == 0) 1427 if (err == 0)
1421 tclass_notify(skb, n, q, cl, RTM_DELTCLASS); 1428 tclass_notify(net, skb, n, q, cl, RTM_DELTCLASS);
1422 goto out; 1429 goto out;
1423 case RTM_GETTCLASS: 1430 case RTM_GETTCLASS:
1424 err = tclass_notify(skb, n, q, cl, RTM_NEWTCLASS); 1431 err = tclass_notify(net, skb, n, q, cl, RTM_NEWTCLASS);
1425 goto out; 1432 goto out;
1426 default: 1433 default:
1427 err = -EINVAL; 1434 err = -EINVAL;
@@ -1434,7 +1441,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1434 if (cops->change) 1441 if (cops->change)
1435 err = cops->change(q, clid, pid, tca, &new_cl); 1442 err = cops->change(q, clid, pid, tca, &new_cl);
1436 if (err == 0) 1443 if (err == 0)
1437 tclass_notify(skb, n, q, new_cl, RTM_NEWTCLASS); 1444 tclass_notify(net, skb, n, q, new_cl, RTM_NEWTCLASS);
1438 1445
1439out: 1446out:
1440 if (cl) 1447 if (cl)
@@ -1486,8 +1493,9 @@ nla_put_failure:
1486 return -1; 1493 return -1;
1487} 1494}
1488 1495
1489static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n, 1496static int tclass_notify(struct net *net, struct sk_buff *oskb,
1490 struct Qdisc *q, unsigned long cl, int event) 1497 struct nlmsghdr *n, struct Qdisc *q,
1498 unsigned long cl, int event)
1491{ 1499{
1492 struct sk_buff *skb; 1500 struct sk_buff *skb;
1493 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0; 1501 u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
@@ -1501,7 +1509,7 @@ static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
1501 return -EINVAL; 1509 return -EINVAL;
1502 } 1510 }
1503 1511
1504 return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO); 1512 return rtnetlink_send(skb, net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
1505} 1513}
1506 1514
1507struct qdisc_dump_args 1515struct qdisc_dump_args
@@ -1576,12 +1584,9 @@ static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1576 struct net_device *dev; 1584 struct net_device *dev;
1577 int t, s_t; 1585 int t, s_t;
1578 1586
1579 if (!net_eq(net, &init_net))
1580 return 0;
1581
1582 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm))) 1587 if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
1583 return 0; 1588 return 0;
1584 if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL) 1589 if ((dev = dev_get_by_index(net, tcm->tcm_ifindex)) == NULL)
1585 return 0; 1590 return 0;
1586 1591
1587 s_t = cb->args[0]; 1592 s_t = cb->args[0];
@@ -1644,9 +1649,12 @@ reclassify:
1644 tp = otp; 1649 tp = otp;
1645 1650
1646 if (verd++ >= MAX_REC_LOOP) { 1651 if (verd++ >= MAX_REC_LOOP) {
1647 printk("rule prio %u protocol %02x reclassify loop, " 1652 if (net_ratelimit())
1648 "packet dropped\n", 1653 printk(KERN_NOTICE
1649 tp->prio&0xffff, ntohs(tp->protocol)); 1654 "%s: packet reclassify loop"
1655 " rule prio %u protocol %02x\n",
1656 tp->q->ops->id,
1657 tp->prio & 0xffff, ntohs(tp->protocol));
1650 return TC_ACT_SHOT; 1658 return TC_ACT_SHOT;
1651 } 1659 }
1652 skb->tc_verd = SET_TC_VERD(skb->tc_verd, verd); 1660 skb->tc_verd = SET_TC_VERD(skb->tc_verd, verd);
@@ -1691,7 +1699,7 @@ static int psched_show(struct seq_file *seq, void *v)
1691 1699
1692static int psched_open(struct inode *inode, struct file *file) 1700static int psched_open(struct inode *inode, struct file *file)
1693{ 1701{
1694 return single_open(file, psched_show, PDE(inode)->data); 1702 return single_open(file, psched_show, NULL);
1695} 1703}
1696 1704
1697static const struct file_operations psched_fops = { 1705static const struct file_operations psched_fops = {
@@ -1701,14 +1709,53 @@ static const struct file_operations psched_fops = {
1701 .llseek = seq_lseek, 1709 .llseek = seq_lseek,
1702 .release = single_release, 1710 .release = single_release,
1703}; 1711};
1712
1713static int __net_init psched_net_init(struct net *net)
1714{
1715 struct proc_dir_entry *e;
1716
1717 e = proc_net_fops_create(net, "psched", 0, &psched_fops);
1718 if (e == NULL)
1719 return -ENOMEM;
1720
1721 return 0;
1722}
1723
1724static void __net_exit psched_net_exit(struct net *net)
1725{
1726 proc_net_remove(net, "psched");
1727}
1728#else
1729static int __net_init psched_net_init(struct net *net)
1730{
1731 return 0;
1732}
1733
1734static void __net_exit psched_net_exit(struct net *net)
1735{
1736}
1704#endif 1737#endif
1705 1738
1739static struct pernet_operations psched_net_ops = {
1740 .init = psched_net_init,
1741 .exit = psched_net_exit,
1742};
1743
1706static int __init pktsched_init(void) 1744static int __init pktsched_init(void)
1707{ 1745{
1746 int err;
1747
1748 err = register_pernet_subsys(&psched_net_ops);
1749 if (err) {
1750 printk(KERN_ERR "pktsched_init: "
1751 "cannot initialize per netns operations\n");
1752 return err;
1753 }
1754
1708 register_qdisc(&pfifo_qdisc_ops); 1755 register_qdisc(&pfifo_qdisc_ops);
1709 register_qdisc(&bfifo_qdisc_ops); 1756 register_qdisc(&bfifo_qdisc_ops);
1757 register_qdisc(&pfifo_head_drop_qdisc_ops);
1710 register_qdisc(&mq_qdisc_ops); 1758 register_qdisc(&mq_qdisc_ops);
1711 proc_net_fops_create(&init_net, "psched", 0, &psched_fops);
1712 1759
1713 rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL); 1760 rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);
1714 rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL); 1761 rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL);
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index ab82f145f689..6318e1136b83 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -3,6 +3,7 @@
3/* Written 1998-2000 by Werner Almesberger, EPFL ICA */ 3/* Written 1998-2000 by Werner Almesberger, EPFL ICA */
4 4
5#include <linux/module.h> 5#include <linux/module.h>
6#include <linux/slab.h>
6#include <linux/init.h> 7#include <linux/init.h>
7#include <linux/string.h> 8#include <linux/string.h>
8#include <linux/errno.h> 9#include <linux/errno.h>
@@ -51,7 +52,7 @@ struct atm_flow_data {
51 int ref; /* reference count */ 52 int ref; /* reference count */
52 struct gnet_stats_basic_packed bstats; 53 struct gnet_stats_basic_packed bstats;
53 struct gnet_stats_queue qstats; 54 struct gnet_stats_queue qstats;
54 struct atm_flow_data *next; 55 struct list_head list;
55 struct atm_flow_data *excess; /* flow for excess traffic; 56 struct atm_flow_data *excess; /* flow for excess traffic;
56 NULL to set CLP instead */ 57 NULL to set CLP instead */
57 int hdr_len; 58 int hdr_len;
@@ -60,34 +61,23 @@ struct atm_flow_data {
60 61
61struct atm_qdisc_data { 62struct atm_qdisc_data {
62 struct atm_flow_data link; /* unclassified skbs go here */ 63 struct atm_flow_data link; /* unclassified skbs go here */
63 struct atm_flow_data *flows; /* NB: "link" is also on this 64 struct list_head flows; /* NB: "link" is also on this
64 list */ 65 list */
65 struct tasklet_struct task; /* dequeue tasklet */ 66 struct tasklet_struct task; /* dequeue tasklet */
66}; 67};
67 68
68/* ------------------------- Class/flow operations ------------------------- */ 69/* ------------------------- Class/flow operations ------------------------- */
69 70
70static int find_flow(struct atm_qdisc_data *qdisc, struct atm_flow_data *flow)
71{
72 struct atm_flow_data *walk;
73
74 pr_debug("find_flow(qdisc %p,flow %p)\n", qdisc, flow);
75 for (walk = qdisc->flows; walk; walk = walk->next)
76 if (walk == flow)
77 return 1;
78 pr_debug("find_flow: not found\n");
79 return 0;
80}
81
82static inline struct atm_flow_data *lookup_flow(struct Qdisc *sch, u32 classid) 71static inline struct atm_flow_data *lookup_flow(struct Qdisc *sch, u32 classid)
83{ 72{
84 struct atm_qdisc_data *p = qdisc_priv(sch); 73 struct atm_qdisc_data *p = qdisc_priv(sch);
85 struct atm_flow_data *flow; 74 struct atm_flow_data *flow;
86 75
87 for (flow = p->flows; flow; flow = flow->next) 76 list_for_each_entry(flow, &p->flows, list) {
88 if (flow->classid == classid) 77 if (flow->classid == classid)
89 break; 78 return flow;
90 return flow; 79 }
80 return NULL;
91} 81}
92 82
93static int atm_tc_graft(struct Qdisc *sch, unsigned long arg, 83static int atm_tc_graft(struct Qdisc *sch, unsigned long arg,
@@ -98,7 +88,7 @@ static int atm_tc_graft(struct Qdisc *sch, unsigned long arg,
98 88
99 pr_debug("atm_tc_graft(sch %p,[qdisc %p],flow %p,new %p,old %p)\n", 89 pr_debug("atm_tc_graft(sch %p,[qdisc %p],flow %p,new %p,old %p)\n",
100 sch, p, flow, new, old); 90 sch, p, flow, new, old);
101 if (!find_flow(p, flow)) 91 if (list_empty(&flow->list))
102 return -EINVAL; 92 return -EINVAL;
103 if (!new) 93 if (!new)
104 new = &noop_qdisc; 94 new = &noop_qdisc;
@@ -145,20 +135,12 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
145{ 135{
146 struct atm_qdisc_data *p = qdisc_priv(sch); 136 struct atm_qdisc_data *p = qdisc_priv(sch);
147 struct atm_flow_data *flow = (struct atm_flow_data *)cl; 137 struct atm_flow_data *flow = (struct atm_flow_data *)cl;
148 struct atm_flow_data **prev;
149 138
150 pr_debug("atm_tc_put(sch %p,[qdisc %p],flow %p)\n", sch, p, flow); 139 pr_debug("atm_tc_put(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
151 if (--flow->ref) 140 if (--flow->ref)
152 return; 141 return;
153 pr_debug("atm_tc_put: destroying\n"); 142 pr_debug("atm_tc_put: destroying\n");
154 for (prev = &p->flows; *prev; prev = &(*prev)->next) 143 list_del_init(&flow->list);
155 if (*prev == flow)
156 break;
157 if (!*prev) {
158 printk(KERN_CRIT "atm_tc_put: class %p not found\n", flow);
159 return;
160 }
161 *prev = flow->next;
162 pr_debug("atm_tc_put: qdisc %p\n", flow->q); 144 pr_debug("atm_tc_put: qdisc %p\n", flow->q);
163 qdisc_destroy(flow->q); 145 qdisc_destroy(flow->q);
164 tcf_destroy_chain(&flow->filter_list); 146 tcf_destroy_chain(&flow->filter_list);
@@ -273,10 +255,6 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
273 error = -EINVAL; 255 error = -EINVAL;
274 goto err_out; 256 goto err_out;
275 } 257 }
276 if (find_flow(p, flow)) {
277 error = -EEXIST;
278 goto err_out;
279 }
280 } else { 258 } else {
281 int i; 259 int i;
282 unsigned long cl; 260 unsigned long cl;
@@ -312,8 +290,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
312 flow->classid = classid; 290 flow->classid = classid;
313 flow->ref = 1; 291 flow->ref = 1;
314 flow->excess = excess; 292 flow->excess = excess;
315 flow->next = p->link.next; 293 list_add(&flow->list, &p->link.list);
316 p->link.next = flow;
317 flow->hdr_len = hdr_len; 294 flow->hdr_len = hdr_len;
318 if (hdr) 295 if (hdr)
319 memcpy(flow->hdr, hdr, hdr_len); 296 memcpy(flow->hdr, hdr, hdr_len);
@@ -334,7 +311,7 @@ static int atm_tc_delete(struct Qdisc *sch, unsigned long arg)
334 struct atm_flow_data *flow = (struct atm_flow_data *)arg; 311 struct atm_flow_data *flow = (struct atm_flow_data *)arg;
335 312
336 pr_debug("atm_tc_delete(sch %p,[qdisc %p],flow %p)\n", sch, p, flow); 313 pr_debug("atm_tc_delete(sch %p,[qdisc %p],flow %p)\n", sch, p, flow);
337 if (!find_flow(qdisc_priv(sch), flow)) 314 if (list_empty(&flow->list))
338 return -EINVAL; 315 return -EINVAL;
339 if (flow->filter_list || flow == &p->link) 316 if (flow->filter_list || flow == &p->link)
340 return -EBUSY; 317 return -EBUSY;
@@ -360,12 +337,12 @@ static void atm_tc_walk(struct Qdisc *sch, struct qdisc_walker *walker)
360 pr_debug("atm_tc_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker); 337 pr_debug("atm_tc_walk(sch %p,[qdisc %p],walker %p)\n", sch, p, walker);
361 if (walker->stop) 338 if (walker->stop)
362 return; 339 return;
363 for (flow = p->flows; flow; flow = flow->next) { 340 list_for_each_entry(flow, &p->flows, list) {
364 if (walker->count >= walker->skip) 341 if (walker->count >= walker->skip &&
365 if (walker->fn(sch, (unsigned long)flow, walker) < 0) { 342 walker->fn(sch, (unsigned long)flow, walker) < 0) {
366 walker->stop = 1; 343 walker->stop = 1;
367 break; 344 break;
368 } 345 }
369 walker->count++; 346 walker->count++;
370 } 347 }
371} 348}
@@ -384,16 +361,17 @@ static struct tcf_proto **atm_tc_find_tcf(struct Qdisc *sch, unsigned long cl)
384static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch) 361static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
385{ 362{
386 struct atm_qdisc_data *p = qdisc_priv(sch); 363 struct atm_qdisc_data *p = qdisc_priv(sch);
387 struct atm_flow_data *flow = NULL; /* @@@ */ 364 struct atm_flow_data *flow;
388 struct tcf_result res; 365 struct tcf_result res;
389 int result; 366 int result;
390 int ret = NET_XMIT_POLICED; 367 int ret = NET_XMIT_POLICED;
391 368
392 pr_debug("atm_tc_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p); 369 pr_debug("atm_tc_enqueue(skb %p,sch %p,[qdisc %p])\n", skb, sch, p);
393 result = TC_POLICE_OK; /* be nice to gcc */ 370 result = TC_POLICE_OK; /* be nice to gcc */
371 flow = NULL;
394 if (TC_H_MAJ(skb->priority) != sch->handle || 372 if (TC_H_MAJ(skb->priority) != sch->handle ||
395 !(flow = (struct atm_flow_data *)atm_tc_get(sch, skb->priority))) 373 !(flow = (struct atm_flow_data *)atm_tc_get(sch, skb->priority))) {
396 for (flow = p->flows; flow; flow = flow->next) 374 list_for_each_entry(flow, &p->flows, list) {
397 if (flow->filter_list) { 375 if (flow->filter_list) {
398 result = tc_classify_compat(skb, 376 result = tc_classify_compat(skb,
399 flow->filter_list, 377 flow->filter_list,
@@ -403,8 +381,13 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
403 flow = (struct atm_flow_data *)res.class; 381 flow = (struct atm_flow_data *)res.class;
404 if (!flow) 382 if (!flow)
405 flow = lookup_flow(sch, res.classid); 383 flow = lookup_flow(sch, res.classid);
406 break; 384 goto done;
407 } 385 }
386 }
387 flow = NULL;
388 done:
389 ;
390 }
408 if (!flow) 391 if (!flow)
409 flow = &p->link; 392 flow = &p->link;
410 else { 393 else {
@@ -431,7 +414,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch)
431 } 414 }
432 415
433 ret = qdisc_enqueue(skb, flow->q); 416 ret = qdisc_enqueue(skb, flow->q);
434 if (ret != 0) { 417 if (ret != NET_XMIT_SUCCESS) {
435drop: __maybe_unused 418drop: __maybe_unused
436 if (net_xmit_drop_count(ret)) { 419 if (net_xmit_drop_count(ret)) {
437 sch->qstats.drops++; 420 sch->qstats.drops++;
@@ -455,7 +438,7 @@ drop: __maybe_unused
455 */ 438 */
456 if (flow == &p->link) { 439 if (flow == &p->link) {
457 sch->q.qlen++; 440 sch->q.qlen++;
458 return 0; 441 return NET_XMIT_SUCCESS;
459 } 442 }
460 tasklet_schedule(&p->task); 443 tasklet_schedule(&p->task);
461 return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; 444 return NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
@@ -476,7 +459,9 @@ static void sch_atm_dequeue(unsigned long data)
476 struct sk_buff *skb; 459 struct sk_buff *skb;
477 460
478 pr_debug("sch_atm_dequeue(sch %p,[qdisc %p])\n", sch, p); 461 pr_debug("sch_atm_dequeue(sch %p,[qdisc %p])\n", sch, p);
479 for (flow = p->link.next; flow; flow = flow->next) 462 list_for_each_entry(flow, &p->flows, list) {
463 if (flow == &p->link)
464 continue;
480 /* 465 /*
481 * If traffic is properly shaped, this won't generate nasty 466 * If traffic is properly shaped, this won't generate nasty
482 * little bursts. Otherwise, it may ... (but that's okay) 467 * little bursts. Otherwise, it may ... (but that's okay)
@@ -511,6 +496,7 @@ static void sch_atm_dequeue(unsigned long data)
511 /* atm.atm_options are already set by atm_tc_enqueue */ 496 /* atm.atm_options are already set by atm_tc_enqueue */
512 flow->vcc->send(flow->vcc, skb); 497 flow->vcc->send(flow->vcc, skb);
513 } 498 }
499 }
514} 500}
515 501
516static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch) 502static struct sk_buff *atm_tc_dequeue(struct Qdisc *sch)
@@ -542,9 +528,10 @@ static unsigned int atm_tc_drop(struct Qdisc *sch)
542 unsigned int len; 528 unsigned int len;
543 529
544 pr_debug("atm_tc_drop(sch %p,[qdisc %p])\n", sch, p); 530 pr_debug("atm_tc_drop(sch %p,[qdisc %p])\n", sch, p);
545 for (flow = p->flows; flow; flow = flow->next) 531 list_for_each_entry(flow, &p->flows, list) {
546 if (flow->q->ops->drop && (len = flow->q->ops->drop(flow->q))) 532 if (flow->q->ops->drop && (len = flow->q->ops->drop(flow->q)))
547 return len; 533 return len;
534 }
548 return 0; 535 return 0;
549} 536}
550 537
@@ -553,7 +540,9 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt)
553 struct atm_qdisc_data *p = qdisc_priv(sch); 540 struct atm_qdisc_data *p = qdisc_priv(sch);
554 541
555 pr_debug("atm_tc_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt); 542 pr_debug("atm_tc_init(sch %p,[qdisc %p],opt %p)\n", sch, p, opt);
556 p->flows = &p->link; 543 INIT_LIST_HEAD(&p->flows);
544 INIT_LIST_HEAD(&p->link.list);
545 list_add(&p->link.list, &p->flows);
557 p->link.q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, 546 p->link.q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
558 &pfifo_qdisc_ops, sch->handle); 547 &pfifo_qdisc_ops, sch->handle);
559 if (!p->link.q) 548 if (!p->link.q)
@@ -564,7 +553,6 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt)
564 p->link.sock = NULL; 553 p->link.sock = NULL;
565 p->link.classid = sch->handle; 554 p->link.classid = sch->handle;
566 p->link.ref = 1; 555 p->link.ref = 1;
567 p->link.next = NULL;
568 tasklet_init(&p->task, sch_atm_dequeue, (unsigned long)sch); 556 tasklet_init(&p->task, sch_atm_dequeue, (unsigned long)sch);
569 return 0; 557 return 0;
570} 558}
@@ -575,7 +563,7 @@ static void atm_tc_reset(struct Qdisc *sch)
575 struct atm_flow_data *flow; 563 struct atm_flow_data *flow;
576 564
577 pr_debug("atm_tc_reset(sch %p,[qdisc %p])\n", sch, p); 565 pr_debug("atm_tc_reset(sch %p,[qdisc %p])\n", sch, p);
578 for (flow = p->flows; flow; flow = flow->next) 566 list_for_each_entry(flow, &p->flows, list)
579 qdisc_reset(flow->q); 567 qdisc_reset(flow->q);
580 sch->q.qlen = 0; 568 sch->q.qlen = 0;
581} 569}
@@ -583,24 +571,17 @@ static void atm_tc_reset(struct Qdisc *sch)
583static void atm_tc_destroy(struct Qdisc *sch) 571static void atm_tc_destroy(struct Qdisc *sch)
584{ 572{
585 struct atm_qdisc_data *p = qdisc_priv(sch); 573 struct atm_qdisc_data *p = qdisc_priv(sch);
586 struct atm_flow_data *flow; 574 struct atm_flow_data *flow, *tmp;
587 575
588 pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p); 576 pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p);
589 for (flow = p->flows; flow; flow = flow->next) 577 list_for_each_entry(flow, &p->flows, list)
590 tcf_destroy_chain(&flow->filter_list); 578 tcf_destroy_chain(&flow->filter_list);
591 579
592 /* races ? */ 580 list_for_each_entry_safe(flow, tmp, &p->flows, list) {
593 while ((flow = p->flows)) {
594 if (flow->ref > 1) 581 if (flow->ref > 1)
595 printk(KERN_ERR "atm_destroy: %p->ref = %d\n", flow, 582 printk(KERN_ERR "atm_destroy: %p->ref = %d\n", flow,
596 flow->ref); 583 flow->ref);
597 atm_tc_put(sch, (unsigned long)flow); 584 atm_tc_put(sch, (unsigned long)flow);
598 if (p->flows == flow) {
599 printk(KERN_ERR "atm_destroy: putting flow %p didn't "
600 "kill it\n", flow);
601 p->flows = flow->next; /* brute force */
602 break;
603 }
604 } 585 }
605 tasklet_kill(&p->task); 586 tasklet_kill(&p->task);
606} 587}
@@ -614,7 +595,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
614 595
615 pr_debug("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n", 596 pr_debug("atm_tc_dump_class(sch %p,[qdisc %p],flow %p,skb %p,tcm %p)\n",
616 sch, p, flow, skb, tcm); 597 sch, p, flow, skb, tcm);
617 if (!find_flow(p, flow)) 598 if (list_empty(&flow->list))
618 return -EINVAL; 599 return -EINVAL;
619 tcm->tcm_handle = flow->classid; 600 tcm->tcm_handle = flow->classid;
620 tcm->tcm_info = flow->q->handle; 601 tcm->tcm_info = flow->q->handle;
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 3846d65bc03e..28c01ef5abc8 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/slab.h>
14#include <linux/types.h> 15#include <linux/types.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/string.h> 17#include <linux/string.h>
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index a65604f8f2b8..b74046a95397 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/slab.h>
12#include <linux/init.h> 13#include <linux/init.h>
13#include <linux/errno.h> 14#include <linux/errno.h>
14#include <linux/netdevice.h> 15#include <linux/netdevice.h>
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index d303daa45d49..63d41f86679c 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -5,6 +5,7 @@
5 5
6#include <linux/module.h> 6#include <linux/module.h>
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/slab.h>
8#include <linux/types.h> 9#include <linux/types.h>
9#include <linux/string.h> 10#include <linux/string.h>
10#include <linux/errno.h> 11#include <linux/errno.h>
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index 69188e8358b4..5948bafa8ce2 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h>
13#include <linux/types.h> 14#include <linux/types.h>
14#include <linux/kernel.h> 15#include <linux/kernel.h>
15#include <linux/errno.h> 16#include <linux/errno.h>
@@ -43,6 +44,26 @@ static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
43 return qdisc_reshape_fail(skb, sch); 44 return qdisc_reshape_fail(skb, sch);
44} 45}
45 46
47static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch)
48{
49 struct sk_buff *skb_head;
50 struct fifo_sched_data *q = qdisc_priv(sch);
51
52 if (likely(skb_queue_len(&sch->q) < q->limit))
53 return qdisc_enqueue_tail(skb, sch);
54
55 /* queue full, remove one skb to fulfill the limit */
56 skb_head = qdisc_dequeue_head(sch);
57 sch->bstats.bytes -= qdisc_pkt_len(skb_head);
58 sch->bstats.packets--;
59 sch->qstats.drops++;
60 kfree_skb(skb_head);
61
62 qdisc_enqueue_tail(skb, sch);
63
64 return NET_XMIT_CN;
65}
66
46static int fifo_init(struct Qdisc *sch, struct nlattr *opt) 67static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
47{ 68{
48 struct fifo_sched_data *q = qdisc_priv(sch); 69 struct fifo_sched_data *q = qdisc_priv(sch);
@@ -108,6 +129,20 @@ struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
108}; 129};
109EXPORT_SYMBOL(bfifo_qdisc_ops); 130EXPORT_SYMBOL(bfifo_qdisc_ops);
110 131
132struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = {
133 .id = "pfifo_head_drop",
134 .priv_size = sizeof(struct fifo_sched_data),
135 .enqueue = pfifo_tail_enqueue,
136 .dequeue = qdisc_dequeue_head,
137 .peek = qdisc_peek_head,
138 .drop = qdisc_queue_drop_head,
139 .init = fifo_init,
140 .reset = qdisc_reset_queue,
141 .change = fifo_init,
142 .dump = fifo_dump,
143 .owner = THIS_MODULE,
144};
145
111/* Pass size change message down to embedded FIFO */ 146/* Pass size change message down to embedded FIFO */
112int fifo_set_limit(struct Qdisc *q, unsigned int limit) 147int fifo_set_limit(struct Qdisc *q, unsigned int limit)
113{ 148{
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 5173c1e1b19c..2aeb3a4386a1 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -24,7 +24,9 @@
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/rcupdate.h> 25#include <linux/rcupdate.h>
26#include <linux/list.h> 26#include <linux/list.h>
27#include <linux/slab.h>
27#include <net/pkt_sched.h> 28#include <net/pkt_sched.h>
29#include <net/dst.h>
28 30
29/* Main transmission queue. */ 31/* Main transmission queue. */
30 32
@@ -39,6 +41,7 @@
39 41
40static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q) 42static inline int dev_requeue_skb(struct sk_buff *skb, struct Qdisc *q)
41{ 43{
44 skb_dst_force(skb);
42 q->gso_skb = skb; 45 q->gso_skb = skb;
43 q->qstats.requeues++; 46 q->qstats.requeues++;
44 q->q.qlen++; /* it's still part of the queue */ 47 q->q.qlen++; /* it's still part of the queue */
@@ -93,7 +96,7 @@ static inline int handle_dev_cpu_collision(struct sk_buff *skb,
93 * Another cpu is holding lock, requeue & delay xmits for 96 * Another cpu is holding lock, requeue & delay xmits for
94 * some time. 97 * some time.
95 */ 98 */
96 __get_cpu_var(netdev_rx_stat).cpu_collision++; 99 __this_cpu_inc(softnet_data.cpu_collision);
97 ret = dev_requeue_skb(skb, q); 100 ret = dev_requeue_skb(skb, q);
98 } 101 }
99 102
@@ -178,7 +181,7 @@ static inline int qdisc_restart(struct Qdisc *q)
178 skb = dequeue_skb(q); 181 skb = dequeue_skb(q);
179 if (unlikely(!skb)) 182 if (unlikely(!skb))
180 return 0; 183 return 0;
181 184 WARN_ON_ONCE(skb_dst_is_noref(skb));
182 root_lock = qdisc_lock(q); 185 root_lock = qdisc_lock(q);
183 dev = qdisc_dev(q); 186 dev = qdisc_dev(q);
184 txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); 187 txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
@@ -202,7 +205,7 @@ void __qdisc_run(struct Qdisc *q)
202 } 205 }
203 } 206 }
204 207
205 clear_bit(__QDISC_STATE_RUNNING, &q->state); 208 qdisc_run_end(q);
206} 209}
207 210
208unsigned long dev_trans_start(struct net_device *dev) 211unsigned long dev_trans_start(struct net_device *dev)
@@ -324,6 +327,24 @@ void netif_carrier_off(struct net_device *dev)
324} 327}
325EXPORT_SYMBOL(netif_carrier_off); 328EXPORT_SYMBOL(netif_carrier_off);
326 329
330/**
331 * netif_notify_peers - notify network peers about existence of @dev
332 * @dev: network device
333 *
334 * Generate traffic such that interested network peers are aware of
335 * @dev, such as by generating a gratuitous ARP. This may be used when
336 * a device wants to inform the rest of the network about some sort of
337 * reconfiguration such as a failover event or virtual machine
338 * migration.
339 */
340void netif_notify_peers(struct net_device *dev)
341{
342 rtnl_lock();
343 call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, dev);
344 rtnl_unlock();
345}
346EXPORT_SYMBOL(netif_notify_peers);
347
327/* "NOOP" scheduler: the best scheduler, recommended for all interfaces 348/* "NOOP" scheduler: the best scheduler, recommended for all interfaces
328 under all circumstances. It is difficult to invent anything faster or 349 under all circumstances. It is difficult to invent anything faster or
329 cheaper. 350 cheaper.
@@ -528,7 +549,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
528 unsigned int size; 549 unsigned int size;
529 int err = -ENOBUFS; 550 int err = -ENOBUFS;
530 551
531 /* ensure that the Qdisc and the private data are 32-byte aligned */ 552 /* ensure that the Qdisc and the private data are 64-byte aligned */
532 size = QDISC_ALIGN(sizeof(*sch)); 553 size = QDISC_ALIGN(sizeof(*sch));
533 size += ops->priv_size + (QDISC_ALIGNTO - 1); 554 size += ops->priv_size + (QDISC_ALIGNTO - 1);
534 555
@@ -540,6 +561,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
540 561
541 INIT_LIST_HEAD(&sch->list); 562 INIT_LIST_HEAD(&sch->list);
542 skb_queue_head_init(&sch->q); 563 skb_queue_head_init(&sch->q);
564 spin_lock_init(&sch->busylock);
543 sch->ops = ops; 565 sch->ops = ops;
544 sch->enqueue = ops->enqueue; 566 sch->enqueue = ops->enqueue;
545 sch->dequeue = ops->dequeue; 567 sch->dequeue = ops->dequeue;
@@ -590,6 +612,13 @@ void qdisc_reset(struct Qdisc *qdisc)
590} 612}
591EXPORT_SYMBOL(qdisc_reset); 613EXPORT_SYMBOL(qdisc_reset);
592 614
615static void qdisc_rcu_free(struct rcu_head *head)
616{
617 struct Qdisc *qdisc = container_of(head, struct Qdisc, rcu_head);
618
619 kfree((char *) qdisc - qdisc->padded);
620}
621
593void qdisc_destroy(struct Qdisc *qdisc) 622void qdisc_destroy(struct Qdisc *qdisc)
594{ 623{
595 const struct Qdisc_ops *ops = qdisc->ops; 624 const struct Qdisc_ops *ops = qdisc->ops;
@@ -613,7 +642,11 @@ void qdisc_destroy(struct Qdisc *qdisc)
613 dev_put(qdisc_dev(qdisc)); 642 dev_put(qdisc_dev(qdisc));
614 643
615 kfree_skb(qdisc->gso_skb); 644 kfree_skb(qdisc->gso_skb);
616 kfree((char *) qdisc - qdisc->padded); 645 /*
646 * gen_estimator est_timer() might access qdisc->q.lock,
647 * wait a RCU grace period before freeing qdisc.
648 */
649 call_rcu(&qdisc->rcu_head, qdisc_rcu_free);
617} 650}
618EXPORT_SYMBOL(qdisc_destroy); 651EXPORT_SYMBOL(qdisc_destroy);
619 652
@@ -765,7 +798,7 @@ static bool some_qdisc_is_busy(struct net_device *dev)
765 798
766 spin_lock_bh(root_lock); 799 spin_lock_bh(root_lock);
767 800
768 val = (test_bit(__QDISC_STATE_RUNNING, &q->state) || 801 val = (qdisc_is_running(q) ||
769 test_bit(__QDISC_STATE_SCHED, &q->state)); 802 test_bit(__QDISC_STATE_SCHED, &q->state));
770 803
771 spin_unlock_bh(root_lock); 804 spin_unlock_bh(root_lock);
diff --git a/net/sched/sch_gred.c b/net/sched/sch_gred.c
index 40408d595c08..51dcc2aa5c92 100644
--- a/net/sched/sch_gred.c
+++ b/net/sched/sch_gred.c
@@ -18,6 +18,7 @@
18 * For all the glorious comments look at include/net/red.h 18 * For all the glorious comments look at include/net/red.h
19 */ 19 */
20 20
21#include <linux/slab.h>
21#include <linux/module.h> 22#include <linux/module.h>
22#include <linux/types.h> 23#include <linux/types.h>
23#include <linux/kernel.h> 24#include <linux/kernel.h>
diff --git a/net/sched/sch_hfsc.c b/net/sched/sch_hfsc.c
index b38b39c60752..47496098d35c 100644
--- a/net/sched/sch_hfsc.c
+++ b/net/sched/sch_hfsc.c
@@ -617,7 +617,6 @@ rtsc_min(struct runtime_sc *rtsc, struct internal_sc *isc, u64 x, u64 y)
617 rtsc->y = y; 617 rtsc->y = y;
618 rtsc->dx = dx; 618 rtsc->dx = dx;
619 rtsc->dy = dy; 619 rtsc->dy = dy;
620 return;
621} 620}
622 621
623static void 622static void
@@ -762,8 +761,8 @@ init_vf(struct hfsc_class *cl, unsigned int len)
762 if (f != cl->cl_f) { 761 if (f != cl->cl_f) {
763 cl->cl_f = f; 762 cl->cl_f = f;
764 cftree_update(cl); 763 cftree_update(cl);
765 update_cfmin(cl->cl_parent);
766 } 764 }
765 update_cfmin(cl->cl_parent);
767 } 766 }
768} 767}
769 768
@@ -1155,7 +1154,7 @@ static struct hfsc_class *
1155hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr) 1154hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
1156{ 1155{
1157 struct hfsc_sched *q = qdisc_priv(sch); 1156 struct hfsc_sched *q = qdisc_priv(sch);
1158 struct hfsc_class *cl; 1157 struct hfsc_class *head, *cl;
1159 struct tcf_result res; 1158 struct tcf_result res;
1160 struct tcf_proto *tcf; 1159 struct tcf_proto *tcf;
1161 int result; 1160 int result;
@@ -1166,6 +1165,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
1166 return cl; 1165 return cl;
1167 1166
1168 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS; 1167 *qerr = NET_XMIT_SUCCESS | __NET_XMIT_BYPASS;
1168 head = &q->root;
1169 tcf = q->root.filter_list; 1169 tcf = q->root.filter_list;
1170 while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) { 1170 while (tcf && (result = tc_classify(skb, tcf, &res)) >= 0) {
1171#ifdef CONFIG_NET_CLS_ACT 1171#ifdef CONFIG_NET_CLS_ACT
@@ -1180,6 +1180,8 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
1180 if ((cl = (struct hfsc_class *)res.class) == NULL) { 1180 if ((cl = (struct hfsc_class *)res.class) == NULL) {
1181 if ((cl = hfsc_find_class(res.classid, sch)) == NULL) 1181 if ((cl = hfsc_find_class(res.classid, sch)) == NULL)
1182 break; /* filter selected invalid classid */ 1182 break; /* filter selected invalid classid */
1183 if (cl->level >= head->level)
1184 break; /* filter may only point downwards */
1183 } 1185 }
1184 1186
1185 if (cl->level == 0) 1187 if (cl->level == 0)
@@ -1187,6 +1189,7 @@ hfsc_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
1187 1189
1188 /* apply inner filter chain */ 1190 /* apply inner filter chain */
1189 tcf = cl->filter_list; 1191 tcf = cl->filter_list;
1192 head = cl;
1190 } 1193 }
1191 1194
1192 /* classification failed, try default class */ 1195 /* classification failed, try default class */
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 508cf5f3a6d5..4be8d04b262d 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -36,6 +36,7 @@
36#include <linux/compiler.h> 36#include <linux/compiler.h>
37#include <linux/rbtree.h> 37#include <linux/rbtree.h>
38#include <linux/workqueue.h> 38#include <linux/workqueue.h>
39#include <linux/slab.h>
39#include <net/netlink.h> 40#include <net/netlink.h>
40#include <net/pkt_sched.h> 41#include <net/pkt_sched.h>
41 42
@@ -1549,7 +1550,6 @@ static const struct Qdisc_class_ops htb_class_ops = {
1549}; 1550};
1550 1551
1551static struct Qdisc_ops htb_qdisc_ops __read_mostly = { 1552static struct Qdisc_ops htb_qdisc_ops __read_mostly = {
1552 .next = NULL,
1553 .cl_ops = &htb_class_ops, 1553 .cl_ops = &htb_class_ops,
1554 .id = "htb", 1554 .id = "htb",
1555 .priv_size = sizeof(struct htb_sched), 1555 .priv_size = sizeof(struct htb_sched),
@@ -1560,7 +1560,6 @@ static struct Qdisc_ops htb_qdisc_ops __read_mostly = {
1560 .init = htb_init, 1560 .init = htb_init,
1561 .reset = htb_reset, 1561 .reset = htb_reset,
1562 .destroy = htb_destroy, 1562 .destroy = htb_destroy,
1563 .change = NULL /* htb_change */,
1564 .dump = htb_dump, 1563 .dump = htb_dump,
1565 .owner = THIS_MODULE, 1564 .owner = THIS_MODULE,
1566}; 1565};
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c
index a9e646bdb605..f10e34a68445 100644
--- a/net/sched/sch_ingress.c
+++ b/net/sched/sch_ingress.c
@@ -44,7 +44,6 @@ static void ingress_put(struct Qdisc *sch, unsigned long cl)
44 44
45static void ingress_walk(struct Qdisc *sch, struct qdisc_walker *walker) 45static void ingress_walk(struct Qdisc *sch, struct qdisc_walker *walker)
46{ 46{
47 return;
48} 47}
49 48
50static struct tcf_proto **ingress_find_tcf(struct Qdisc *sch, unsigned long cl) 49static struct tcf_proto **ingress_find_tcf(struct Qdisc *sch, unsigned long cl)
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index d1dea3d5dc92..fe91e50f9d98 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -9,6 +9,7 @@
9 */ 9 */
10 10
11#include <linux/types.h> 11#include <linux/types.h>
12#include <linux/slab.h>
12#include <linux/kernel.h> 13#include <linux/kernel.h>
13#include <linux/string.h> 14#include <linux/string.h>
14#include <linux/errno.h> 15#include <linux/errno.h>
@@ -173,7 +174,6 @@ static unsigned long mq_get(struct Qdisc *sch, u32 classid)
173 174
174static void mq_put(struct Qdisc *sch, unsigned long cl) 175static void mq_put(struct Qdisc *sch, unsigned long cl)
175{ 176{
176 return;
177} 177}
178 178
179static int mq_dump_class(struct Qdisc *sch, unsigned long cl, 179static int mq_dump_class(struct Qdisc *sch, unsigned long cl,
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index 7db2c88ce585..6ae251279fc2 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -18,6 +18,7 @@
18 */ 18 */
19 19
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/slab.h>
21#include <linux/types.h> 22#include <linux/types.h>
22#include <linux/kernel.h> 23#include <linux/kernel.h>
23#include <linux/string.h> 24#include <linux/string.h>
@@ -339,7 +340,6 @@ static unsigned long multiq_bind(struct Qdisc *sch, unsigned long parent,
339 340
340static void multiq_put(struct Qdisc *q, unsigned long cl) 341static void multiq_put(struct Qdisc *q, unsigned long cl)
341{ 342{
342 return;
343} 343}
344 344
345static int multiq_dump_class(struct Qdisc *sch, unsigned long cl, 345static int multiq_dump_class(struct Qdisc *sch, unsigned long cl,
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
index d8b10e054627..4714ff162bbd 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -14,6 +14,7 @@
14 */ 14 */
15 15
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/slab.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/kernel.h> 19#include <linux/kernel.h>
19#include <linux/errno.h> 20#include <linux/errno.h>
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index 93285cecb246..0748fb1e3a49 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/slab.h>
15#include <linux/types.h> 16#include <linux/types.h>
16#include <linux/kernel.h> 17#include <linux/kernel.h>
17#include <linux/string.h> 18#include <linux/string.h>
@@ -302,7 +303,6 @@ static unsigned long prio_bind(struct Qdisc *sch, unsigned long parent, u32 clas
302 303
303static void prio_put(struct Qdisc *q, unsigned long cl) 304static void prio_put(struct Qdisc *q, unsigned long cl)
304{ 305{
305 return;
306} 306}
307 307
308static int prio_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb, 308static int prio_dump_class(struct Qdisc *sch, unsigned long cl, struct sk_buff *skb,
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c
index 072cdf442f8e..8d42bb3ba540 100644
--- a/net/sched/sch_red.c
+++ b/net/sched/sch_red.c
@@ -303,7 +303,6 @@ static unsigned long red_get(struct Qdisc *sch, u32 classid)
303 303
304static void red_put(struct Qdisc *sch, unsigned long arg) 304static void red_put(struct Qdisc *sch, unsigned long arg)
305{ 305{
306 return;
307} 306}
308 307
309static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker) 308static void red_walk(struct Qdisc *sch, struct qdisc_walker *walker)
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index cb21380c0605..201cbac2b32c 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -20,6 +20,7 @@
20#include <linux/ipv6.h> 20#include <linux/ipv6.h>
21#include <linux/skbuff.h> 21#include <linux/skbuff.h>
22#include <linux/jhash.h> 22#include <linux/jhash.h>
23#include <linux/slab.h>
23#include <net/ip.h> 24#include <net/ip.h>
24#include <net/netlink.h> 25#include <net/netlink.h>
25#include <net/pkt_sched.h> 26#include <net/pkt_sched.h>
@@ -121,35 +122,46 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
121 switch (skb->protocol) { 122 switch (skb->protocol) {
122 case htons(ETH_P_IP): 123 case htons(ETH_P_IP):
123 { 124 {
124 const struct iphdr *iph = ip_hdr(skb); 125 const struct iphdr *iph;
125 h = iph->daddr; 126
126 h2 = iph->saddr ^ iph->protocol; 127 if (!pskb_network_may_pull(skb, sizeof(*iph)))
128 goto err;
129 iph = ip_hdr(skb);
130 h = (__force u32)iph->daddr;
131 h2 = (__force u32)iph->saddr ^ iph->protocol;
127 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) && 132 if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
128 (iph->protocol == IPPROTO_TCP || 133 (iph->protocol == IPPROTO_TCP ||
129 iph->protocol == IPPROTO_UDP || 134 iph->protocol == IPPROTO_UDP ||
130 iph->protocol == IPPROTO_UDPLITE || 135 iph->protocol == IPPROTO_UDPLITE ||
131 iph->protocol == IPPROTO_SCTP || 136 iph->protocol == IPPROTO_SCTP ||
132 iph->protocol == IPPROTO_DCCP || 137 iph->protocol == IPPROTO_DCCP ||
133 iph->protocol == IPPROTO_ESP)) 138 iph->protocol == IPPROTO_ESP) &&
139 pskb_network_may_pull(skb, iph->ihl * 4 + 4))
134 h2 ^= *(((u32*)iph) + iph->ihl); 140 h2 ^= *(((u32*)iph) + iph->ihl);
135 break; 141 break;
136 } 142 }
137 case htons(ETH_P_IPV6): 143 case htons(ETH_P_IPV6):
138 { 144 {
139 struct ipv6hdr *iph = ipv6_hdr(skb); 145 struct ipv6hdr *iph;
140 h = iph->daddr.s6_addr32[3]; 146
141 h2 = iph->saddr.s6_addr32[3] ^ iph->nexthdr; 147 if (!pskb_network_may_pull(skb, sizeof(*iph)))
142 if (iph->nexthdr == IPPROTO_TCP || 148 goto err;
143 iph->nexthdr == IPPROTO_UDP || 149 iph = ipv6_hdr(skb);
144 iph->nexthdr == IPPROTO_UDPLITE || 150 h = (__force u32)iph->daddr.s6_addr32[3];
145 iph->nexthdr == IPPROTO_SCTP || 151 h2 = (__force u32)iph->saddr.s6_addr32[3] ^ iph->nexthdr;
146 iph->nexthdr == IPPROTO_DCCP || 152 if ((iph->nexthdr == IPPROTO_TCP ||
147 iph->nexthdr == IPPROTO_ESP) 153 iph->nexthdr == IPPROTO_UDP ||
154 iph->nexthdr == IPPROTO_UDPLITE ||
155 iph->nexthdr == IPPROTO_SCTP ||
156 iph->nexthdr == IPPROTO_DCCP ||
157 iph->nexthdr == IPPROTO_ESP) &&
158 pskb_network_may_pull(skb, sizeof(*iph) + 4))
148 h2 ^= *(u32*)&iph[1]; 159 h2 ^= *(u32*)&iph[1];
149 break; 160 break;
150 } 161 }
151 default: 162 default:
152 h = (unsigned long)skb_dst(skb) ^ skb->protocol; 163err:
164 h = (unsigned long)skb_dst(skb) ^ (__force u32)skb->protocol;
153 h2 = (unsigned long)skb->sk; 165 h2 = (unsigned long)skb->sk;
154 } 166 }
155 167
@@ -322,7 +334,7 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
322 if (++sch->q.qlen <= q->limit) { 334 if (++sch->q.qlen <= q->limit) {
323 sch->bstats.bytes += qdisc_pkt_len(skb); 335 sch->bstats.bytes += qdisc_pkt_len(skb);
324 sch->bstats.packets++; 336 sch->bstats.packets++;
325 return 0; 337 return NET_XMIT_SUCCESS;
326 } 338 }
327 339
328 sfq_drop(sch); 340 sfq_drop(sch);
@@ -496,11 +508,26 @@ nla_put_failure:
496 return -1; 508 return -1;
497} 509}
498 510
511static struct Qdisc *sfq_leaf(struct Qdisc *sch, unsigned long arg)
512{
513 return NULL;
514}
515
499static unsigned long sfq_get(struct Qdisc *sch, u32 classid) 516static unsigned long sfq_get(struct Qdisc *sch, u32 classid)
500{ 517{
501 return 0; 518 return 0;
502} 519}
503 520
521static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent,
522 u32 classid)
523{
524 return 0;
525}
526
527static void sfq_put(struct Qdisc *q, unsigned long cl)
528{
529}
530
504static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl) 531static struct tcf_proto **sfq_find_tcf(struct Qdisc *sch, unsigned long cl)
505{ 532{
506 struct sfq_sched_data *q = qdisc_priv(sch); 533 struct sfq_sched_data *q = qdisc_priv(sch);
@@ -553,8 +580,12 @@ static void sfq_walk(struct Qdisc *sch, struct qdisc_walker *arg)
553} 580}
554 581
555static const struct Qdisc_class_ops sfq_class_ops = { 582static const struct Qdisc_class_ops sfq_class_ops = {
583 .leaf = sfq_leaf,
556 .get = sfq_get, 584 .get = sfq_get,
585 .put = sfq_put,
557 .tcf_chain = sfq_find_tcf, 586 .tcf_chain = sfq_find_tcf,
587 .bind_tcf = sfq_bind,
588 .unbind_tcf = sfq_put,
558 .dump = sfq_dump_class, 589 .dump = sfq_dump_class,
559 .dump_stats = sfq_dump_class_stats, 590 .dump_stats = sfq_dump_class_stats,
560 .walk = sfq_walk, 591 .walk = sfq_walk,
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 8fb8107ab188..641a30d64635 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -127,7 +127,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
127 return qdisc_reshape_fail(skb, sch); 127 return qdisc_reshape_fail(skb, sch);
128 128
129 ret = qdisc_enqueue(skb, q->qdisc); 129 ret = qdisc_enqueue(skb, q->qdisc);
130 if (ret != 0) { 130 if (ret != NET_XMIT_SUCCESS) {
131 if (net_xmit_drop_count(ret)) 131 if (net_xmit_drop_count(ret))
132 sch->qstats.drops++; 132 sch->qstats.drops++;
133 return ret; 133 return ret;
@@ -136,7 +136,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
136 sch->q.qlen++; 136 sch->q.qlen++;
137 sch->bstats.bytes += qdisc_pkt_len(skb); 137 sch->bstats.bytes += qdisc_pkt_len(skb);
138 sch->bstats.packets++; 138 sch->bstats.packets++;
139 return 0; 139 return NET_XMIT_SUCCESS;
140} 140}
141 141
142static unsigned int tbf_drop(struct Qdisc* sch) 142static unsigned int tbf_drop(struct Qdisc* sch)
@@ -273,7 +273,11 @@ static int tbf_change(struct Qdisc* sch, struct nlattr *opt)
273 if (max_size < 0) 273 if (max_size < 0)
274 goto done; 274 goto done;
275 275
276 if (qopt->limit > 0) { 276 if (q->qdisc != &noop_qdisc) {
277 err = fifo_set_limit(q->qdisc, qopt->limit);
278 if (err)
279 goto done;
280 } else if (qopt->limit > 0) {
277 child = fifo_create_dflt(sch, &bfifo_qdisc_ops, qopt->limit); 281 child = fifo_create_dflt(sch, &bfifo_qdisc_ops, qopt->limit);
278 if (IS_ERR(child)) { 282 if (IS_ERR(child)) {
279 err = PTR_ERR(child); 283 err = PTR_ERR(child);
diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
index db69637069c4..feaabc103ce6 100644
--- a/net/sched/sch_teql.c
+++ b/net/sched/sch_teql.c
@@ -11,6 +11,7 @@
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/slab.h>
14#include <linux/string.h> 15#include <linux/string.h>
15#include <linux/errno.h> 16#include <linux/errno.h>
16#include <linux/if_arp.h> 17#include <linux/if_arp.h>
@@ -84,7 +85,7 @@ teql_enqueue(struct sk_buff *skb, struct Qdisc* sch)
84 __skb_queue_tail(&q->q, skb); 85 __skb_queue_tail(&q->q, skb);
85 sch->bstats.bytes += qdisc_pkt_len(skb); 86 sch->bstats.bytes += qdisc_pkt_len(skb);
86 sch->bstats.packets++; 87 sch->bstats.packets++;
87 return 0; 88 return NET_XMIT_SUCCESS;
88 } 89 }
89 90
90 kfree_skb(skb); 91 kfree_skb(skb);
@@ -448,6 +449,7 @@ static __init void teql_master_setup(struct net_device *dev)
448 dev->tx_queue_len = 100; 449 dev->tx_queue_len = 100;
449 dev->flags = IFF_NOARP; 450 dev->flags = IFF_NOARP;
450 dev->hard_header_len = LL_MAX_HEADER; 451 dev->hard_header_len = LL_MAX_HEADER;
452 dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
451} 453}
452 454
453static LIST_HEAD(master_dev_list); 455static LIST_HEAD(master_dev_list);