20 #include <linux/module.h>
21 #include <linux/slab.h>
22 #include <linux/types.h>
23 #include <linux/kernel.h>
24 #include <linux/string.h>
25 #include <linux/errno.h>
50 #ifdef CONFIG_NET_CLS_ACT
59 band = skb_get_queue_mapping(skb);
73 qdisc = multiq_classify(skb, sch, &ret);
74 #ifdef CONFIG_NET_CLS_ACT
84 ret = qdisc_enqueue(skb, qdisc);
101 for (band = 0; band < q->
bands; band++) {
110 if (!netif_xmit_stopped(
111 netdev_get_tx_queue(qdisc_dev(sch), q->
curband))) {
115 qdisc_bstats_update(sch, skb);
133 for (band = 0; band < q->
bands; band++) {
136 if (curband >= q->
bands)
142 if (!netif_xmit_stopped(
143 netdev_get_tx_queue(qdisc_dev(sch), curband))) {
144 qdisc = q->
queues[curband];
145 skb = qdisc->
ops->peek(qdisc);
154 static unsigned int multiq_drop(
struct Qdisc *sch)
161 for (band = q->
bands - 1; band >= 0; band--) {
163 if (qdisc->
ops->drop) {
164 len = qdisc->
ops->drop(qdisc);
176 multiq_reset(
struct Qdisc *sch)
181 for (band = 0; band < q->
bands; band++)
188 multiq_destroy(
struct Qdisc *sch)
194 for (band = 0; band < q->
bands; band++)
206 if (!netif_is_multiqueue(qdisc_dev(sch)))
208 if (nla_len(opt) <
sizeof(*qopt))
211 qopt = nla_data(opt);
213 qopt->
bands = qdisc_dev(sch)->real_num_tx_queues;
226 sch_tree_unlock(sch);
228 for (i = 0; i < q->
bands; i++) {
245 sch_tree_unlock(sch);
252 static int multiq_init(
struct Qdisc *sch,
struct nlattr *opt)
262 q->
max_bands = qdisc_dev(sch)->num_tx_queues;
270 err = multiq_tune(sch, opt);
278 static int multiq_dump(
struct Qdisc *sch,
struct sk_buff *skb)
281 unsigned char *
b = skb_tail_pointer(skb);
284 opt.bands = q->
bands;
288 goto nla_put_failure;
297 static int multiq_graft(
struct Qdisc *sch,
unsigned long arg,
struct Qdisc *
new,
301 unsigned long band = arg - 1;
311 sch_tree_unlock(sch);
316 static struct Qdisc *
317 multiq_leaf(
struct Qdisc *sch,
unsigned long arg)
320 unsigned long band = arg - 1;
325 static unsigned long multiq_get(
struct Qdisc *sch,
u32 classid)
328 unsigned long band =
TC_H_MIN(classid);
330 if (band - 1 >= q->
bands)
335 static unsigned long multiq_bind(
struct Qdisc *sch,
unsigned long parent,
338 return multiq_get(sch, classid);
342 static void multiq_put(
struct Qdisc *q,
unsigned long cl)
346 static int multiq_dump_class(
struct Qdisc *sch,
unsigned long cl,
356 static int multiq_dump_class_stats(
struct Qdisc *sch,
unsigned long cl,
363 cl_q->
qstats.qlen = cl_q->
q.qlen;
379 for (band = 0; band < q->
bands; band++) {
384 if (arg->
fn(sch, band + 1, arg) < 0) {
392 static struct tcf_proto **multiq_find_tcf(
struct Qdisc *sch,
unsigned long cl)
402 .graft = multiq_graft,
407 .tcf_chain = multiq_find_tcf,
408 .bind_tcf = multiq_bind,
409 .unbind_tcf = multiq_put,
410 .dump = multiq_dump_class,
411 .dump_stats = multiq_dump_class_stats,
416 .cl_ops = &multiq_class_ops,
419 .enqueue = multiq_enqueue,
420 .dequeue = multiq_dequeue,
424 .reset = multiq_reset,
425 .destroy = multiq_destroy,
426 .change = multiq_tune,
431 static int __init multiq_module_init(
void)
436 static void __exit multiq_module_exit(
void)