diff options
Diffstat (limited to 'net/sched')
| -rw-r--r-- | net/sched/Kconfig | 5 | ||||
| -rw-r--r-- | net/sched/cls_cgroup.c | 36 | ||||
| -rw-r--r-- | net/sched/sch_api.c | 1 | ||||
| -rw-r--r-- | net/sched/sch_fifo.c | 34 |
4 files changed, 66 insertions, 10 deletions
diff --git a/net/sched/Kconfig b/net/sched/Kconfig index 21f9c7678aa3..2f691fb180d1 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig | |||
| @@ -328,13 +328,16 @@ config NET_CLS_FLOW | |||
| 328 | module will be called cls_flow. | 328 | module will be called cls_flow. |
| 329 | 329 | ||
| 330 | config NET_CLS_CGROUP | 330 | config 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 | |||
| 338 | config NET_EMATCH | 341 | config NET_EMATCH |
| 339 | bool "Extended Matches" | 342 | bool "Extended Matches" |
| 340 | select NET_CLS | 343 | select NET_CLS |
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c index e4877ca6727c..7f27d2c15e08 100644 --- a/net/sched/cls_cgroup.c +++ b/net/sched/cls_cgroup.c | |||
| @@ -24,6 +24,25 @@ struct cgroup_cls_state | |||
| 24 | u32 classid; | 24 | u32 classid; |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | static struct cgroup_subsys_state *cgrp_create(struct cgroup_subsys *ss, | ||
| 28 | struct cgroup *cgrp); | ||
| 29 | static void cgrp_destroy(struct cgroup_subsys *ss, struct cgroup *cgrp); | ||
| 30 | static int cgrp_populate(struct cgroup_subsys *ss, struct cgroup *cgrp); | ||
| 31 | |||
| 32 | struct cgroup_subsys net_cls_subsys = { | ||
| 33 | .name = "net_cls", | ||
| 34 | .create = cgrp_create, | ||
| 35 | .destroy = cgrp_destroy, | ||
| 36 | .populate = cgrp_populate, | ||
| 37 | #ifdef CONFIG_NET_CLS_CGROUP | ||
| 38 | .subsys_id = net_cls_subsys_id, | ||
| 39 | #else | ||
| 40 | #define net_cls_subsys_id net_cls_subsys.subsys_id | ||
| 41 | #endif | ||
| 42 | .module = THIS_MODULE, | ||
| 43 | }; | ||
| 44 | |||
| 45 | |||
| 27 | static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp) | 46 | static inline struct cgroup_cls_state *cgrp_cls_state(struct cgroup *cgrp) |
| 28 | { | 47 | { |
| 29 | return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id), | 48 | return container_of(cgroup_subsys_state(cgrp, net_cls_subsys_id), |
| @@ -79,14 +98,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)); | 98 | return cgroup_add_files(cgrp, ss, ss_files, ARRAY_SIZE(ss_files)); |
| 80 | } | 99 | } |
| 81 | 100 | ||
| 82 | struct 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 | |||
| 90 | struct cls_cgroup_head | 101 | struct cls_cgroup_head |
| 91 | { | 102 | { |
| 92 | u32 handle; | 103 | u32 handle; |
| @@ -277,12 +288,19 @@ static struct tcf_proto_ops cls_cgroup_ops __read_mostly = { | |||
| 277 | 288 | ||
| 278 | static int __init init_cgroup_cls(void) | 289 | static int __init init_cgroup_cls(void) |
| 279 | { | 290 | { |
| 280 | return register_tcf_proto_ops(&cls_cgroup_ops); | 291 | int ret = register_tcf_proto_ops(&cls_cgroup_ops); |
| 292 | if (ret) | ||
| 293 | return ret; | ||
| 294 | ret = cgroup_load_subsys(&net_cls_subsys); | ||
| 295 | if (ret) | ||
| 296 | unregister_tcf_proto_ops(&cls_cgroup_ops); | ||
| 297 | return ret; | ||
| 281 | } | 298 | } |
| 282 | 299 | ||
| 283 | static void __exit exit_cgroup_cls(void) | 300 | static void __exit exit_cgroup_cls(void) |
| 284 | { | 301 | { |
| 285 | unregister_tcf_proto_ops(&cls_cgroup_ops); | 302 | unregister_tcf_proto_ops(&cls_cgroup_ops); |
| 303 | cgroup_unload_subsys(&net_cls_subsys); | ||
| 286 | } | 304 | } |
| 287 | 305 | ||
| 288 | module_init(init_cgroup_cls); | 306 | module_init(init_cgroup_cls); |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 75fd1c672c61..6cd491013b50 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
| @@ -1707,6 +1707,7 @@ static int __init pktsched_init(void) | |||
| 1707 | { | 1707 | { |
| 1708 | register_qdisc(&pfifo_qdisc_ops); | 1708 | register_qdisc(&pfifo_qdisc_ops); |
| 1709 | register_qdisc(&bfifo_qdisc_ops); | 1709 | register_qdisc(&bfifo_qdisc_ops); |
| 1710 | register_qdisc(&pfifo_head_drop_qdisc_ops); | ||
| 1710 | register_qdisc(&mq_qdisc_ops); | 1711 | register_qdisc(&mq_qdisc_ops); |
| 1711 | proc_net_fops_create(&init_net, "psched", 0, &psched_fops); | 1712 | proc_net_fops_create(&init_net, "psched", 0, &psched_fops); |
| 1712 | 1713 | ||
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index 69188e8358b4..4b0a6cc44c77 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c | |||
| @@ -43,6 +43,26 @@ static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
| 43 | return qdisc_reshape_fail(skb, sch); | 43 | return qdisc_reshape_fail(skb, sch); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc* sch) | ||
| 47 | { | ||
| 48 | struct sk_buff *skb_head; | ||
| 49 | struct fifo_sched_data *q = qdisc_priv(sch); | ||
| 50 | |||
| 51 | if (likely(skb_queue_len(&sch->q) < q->limit)) | ||
| 52 | return qdisc_enqueue_tail(skb, sch); | ||
| 53 | |||
| 54 | /* queue full, remove one skb to fulfill the limit */ | ||
| 55 | skb_head = qdisc_dequeue_head(sch); | ||
| 56 | sch->bstats.bytes -= qdisc_pkt_len(skb_head); | ||
| 57 | sch->bstats.packets--; | ||
| 58 | sch->qstats.drops++; | ||
| 59 | kfree_skb(skb_head); | ||
| 60 | |||
| 61 | qdisc_enqueue_tail(skb, sch); | ||
| 62 | |||
| 63 | return NET_XMIT_CN; | ||
| 64 | } | ||
| 65 | |||
| 46 | static int fifo_init(struct Qdisc *sch, struct nlattr *opt) | 66 | static int fifo_init(struct Qdisc *sch, struct nlattr *opt) |
| 47 | { | 67 | { |
| 48 | struct fifo_sched_data *q = qdisc_priv(sch); | 68 | struct fifo_sched_data *q = qdisc_priv(sch); |
| @@ -108,6 +128,20 @@ struct Qdisc_ops bfifo_qdisc_ops __read_mostly = { | |||
| 108 | }; | 128 | }; |
| 109 | EXPORT_SYMBOL(bfifo_qdisc_ops); | 129 | EXPORT_SYMBOL(bfifo_qdisc_ops); |
| 110 | 130 | ||
| 131 | struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = { | ||
| 132 | .id = "pfifo_head_drop", | ||
| 133 | .priv_size = sizeof(struct fifo_sched_data), | ||
| 134 | .enqueue = pfifo_tail_enqueue, | ||
| 135 | .dequeue = qdisc_dequeue_head, | ||
| 136 | .peek = qdisc_peek_head, | ||
| 137 | .drop = qdisc_queue_drop_head, | ||
| 138 | .init = fifo_init, | ||
| 139 | .reset = qdisc_reset_queue, | ||
| 140 | .change = fifo_init, | ||
| 141 | .dump = fifo_dump, | ||
| 142 | .owner = THIS_MODULE, | ||
| 143 | }; | ||
| 144 | |||
| 111 | /* Pass size change message down to embedded FIFO */ | 145 | /* Pass size change message down to embedded FIFO */ |
| 112 | int fifo_set_limit(struct Qdisc *q, unsigned int limit) | 146 | int fifo_set_limit(struct Qdisc *q, unsigned int limit) |
| 113 | { | 147 | { |
