netdev: Kill qdisc_ingress, use netdev->rx_queue.qdisc instead.
[safe/jmp/linux-2.6] / net / sched / sch_api.c
1 /*
2  * net/sched/sch_api.c  Packet scheduler API.
3  *
4  *              This program is free software; you can redistribute it and/or
5  *              modify it under the terms of the GNU General Public License
6  *              as published by the Free Software Foundation; either version
7  *              2 of the License, or (at your option) any later version.
8  *
9  * Authors:     Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
10  *
11  * Fixes:
12  *
13  * Rani Assaf <rani@magic.metawire.com> :980802: JIFFIES and CPU clock sources are repaired.
14  * Eduardo J. Blanco <ejbs@netlabs.com.uy> :990222: kmod support
15  * Jamal Hadi Salim <hadi@nortelnetworks.com>: 990601: ingress support
16  */
17
18 #include <linux/module.h>
19 #include <linux/types.h>
20 #include <linux/kernel.h>
21 #include <linux/string.h>
22 #include <linux/errno.h>
23 #include <linux/skbuff.h>
24 #include <linux/init.h>
25 #include <linux/proc_fs.h>
26 #include <linux/seq_file.h>
27 #include <linux/kmod.h>
28 #include <linux/list.h>
29 #include <linux/hrtimer.h>
30
31 #include <net/net_namespace.h>
32 #include <net/sock.h>
33 #include <net/netlink.h>
34 #include <net/pkt_sched.h>
35
36 static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n, u32 clid,
37                         struct Qdisc *old, struct Qdisc *new);
38 static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
39                          struct Qdisc *q, unsigned long cl, int event);
40
41 /*
42
43    Short review.
44    -------------
45
46    This file consists of two interrelated parts:
47
48    1. queueing disciplines manager frontend.
49    2. traffic classes manager frontend.
50
51    Generally, queueing discipline ("qdisc") is a black box,
52    which is able to enqueue packets and to dequeue them (when
53    device is ready to send something) in order and at times
54    determined by algorithm hidden in it.
55
56    qdisc's are divided to two categories:
57    - "queues", which have no internal structure visible from outside.
58    - "schedulers", which split all the packets to "traffic classes",
59      using "packet classifiers" (look at cls_api.c)
60
61    In turn, classes may have child qdiscs (as rule, queues)
62    attached to them etc. etc. etc.
63
64    The goal of the routines in this file is to translate
65    information supplied by user in the form of handles
66    to more intelligible for kernel form, to make some sanity
67    checks and part of work, which is common to all qdiscs
68    and to provide rtnetlink notifications.
69
70    All real intelligent work is done inside qdisc modules.
71
72
73
74    Every discipline has two major routines: enqueue and dequeue.
75
76    ---dequeue
77
78    dequeue usually returns a skb to send. It is allowed to return NULL,
79    but it does not mean that queue is empty, it just means that
80    discipline does not want to send anything this time.
81    Queue is really empty if q->q.qlen == 0.
82    For complicated disciplines with multiple queues q->q is not
83    real packet queue, but however q->q.qlen must be valid.
84
85    ---enqueue
86
87    enqueue returns 0, if packet was enqueued successfully.
88    If packet (this one or another one) was dropped, it returns
89    not zero error code.
90    NET_XMIT_DROP        - this packet dropped
91      Expected action: do not backoff, but wait until queue will clear.
92    NET_XMIT_CN          - probably this packet enqueued, but another one dropped.
93      Expected action: backoff or ignore
94    NET_XMIT_POLICED     - dropped by police.
95      Expected action: backoff or error to real-time apps.
96
97    Auxiliary routines:
98
99    ---requeue
100
101    requeues once dequeued packet. It is used for non-standard or
102    just buggy devices, which can defer output even if netif_queue_stopped()=0.
103
104    ---reset
105
106    returns qdisc to initial state: purge all buffers, clear all
107    timers, counters (except for statistics) etc.
108
109    ---init
110
111    initializes newly created qdisc.
112
113    ---destroy
114
115    destroys resources allocated by init and during lifetime of qdisc.
116
117    ---change
118
119    changes qdisc parameters.
120  */
121
122 /* Protects list of registered TC modules. It is pure SMP lock. */
123 static DEFINE_RWLOCK(qdisc_mod_lock);
124
125
126 /************************************************
127  *      Queueing disciplines manipulation.      *
128  ************************************************/
129
130
131 /* The list of all installed queueing disciplines. */
132
133 static struct Qdisc_ops *qdisc_base;
134
135 /* Register/uregister queueing discipline */
136
137 int register_qdisc(struct Qdisc_ops *qops)
138 {
139         struct Qdisc_ops *q, **qp;
140         int rc = -EEXIST;
141
142         write_lock(&qdisc_mod_lock);
143         for (qp = &qdisc_base; (q = *qp) != NULL; qp = &q->next)
144                 if (!strcmp(qops->id, q->id))
145                         goto out;
146
147         if (qops->enqueue == NULL)
148                 qops->enqueue = noop_qdisc_ops.enqueue;
149         if (qops->requeue == NULL)
150                 qops->requeue = noop_qdisc_ops.requeue;
151         if (qops->dequeue == NULL)
152                 qops->dequeue = noop_qdisc_ops.dequeue;
153
154         qops->next = NULL;
155         *qp = qops;
156         rc = 0;
157 out:
158         write_unlock(&qdisc_mod_lock);
159         return rc;
160 }
161 EXPORT_SYMBOL(register_qdisc);
162
163 int unregister_qdisc(struct Qdisc_ops *qops)
164 {
165         struct Qdisc_ops *q, **qp;
166         int err = -ENOENT;
167
168         write_lock(&qdisc_mod_lock);
169         for (qp = &qdisc_base; (q=*qp)!=NULL; qp = &q->next)
170                 if (q == qops)
171                         break;
172         if (q) {
173                 *qp = q->next;
174                 q->next = NULL;
175                 err = 0;
176         }
177         write_unlock(&qdisc_mod_lock);
178         return err;
179 }
180 EXPORT_SYMBOL(unregister_qdisc);
181
182 /* We know handle. Find qdisc among all qdisc's attached to device
183    (root qdisc, all its children, children of children etc.)
184  */
185
186 struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
187 {
188         struct netdev_queue *dev_queue = &dev->tx_queue;
189         struct Qdisc *q;
190
191         list_for_each_entry(q, &dev_queue->qdisc_list, list) {
192                 if (q->handle == handle)
193                         return q;
194         }
195         return NULL;
196 }
197
198 static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
199 {
200         unsigned long cl;
201         struct Qdisc *leaf;
202         const struct Qdisc_class_ops *cops = p->ops->cl_ops;
203
204         if (cops == NULL)
205                 return NULL;
206         cl = cops->get(p, classid);
207
208         if (cl == 0)
209                 return NULL;
210         leaf = cops->leaf(p, cl);
211         cops->put(p, cl);
212         return leaf;
213 }
214
215 /* Find queueing discipline by name */
216
217 static struct Qdisc_ops *qdisc_lookup_ops(struct nlattr *kind)
218 {
219         struct Qdisc_ops *q = NULL;
220
221         if (kind) {
222                 read_lock(&qdisc_mod_lock);
223                 for (q = qdisc_base; q; q = q->next) {
224                         if (nla_strcmp(kind, q->id) == 0) {
225                                 if (!try_module_get(q->owner))
226                                         q = NULL;
227                                 break;
228                         }
229                 }
230                 read_unlock(&qdisc_mod_lock);
231         }
232         return q;
233 }
234
235 static struct qdisc_rate_table *qdisc_rtab_list;
236
237 struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *tab)
238 {
239         struct qdisc_rate_table *rtab;
240
241         for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) {
242                 if (memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) == 0) {
243                         rtab->refcnt++;
244                         return rtab;
245                 }
246         }
247
248         if (tab == NULL || r->rate == 0 || r->cell_log == 0 ||
249             nla_len(tab) != TC_RTAB_SIZE)
250                 return NULL;
251
252         rtab = kmalloc(sizeof(*rtab), GFP_KERNEL);
253         if (rtab) {
254                 rtab->rate = *r;
255                 rtab->refcnt = 1;
256                 memcpy(rtab->data, nla_data(tab), 1024);
257                 rtab->next = qdisc_rtab_list;
258                 qdisc_rtab_list = rtab;
259         }
260         return rtab;
261 }
262 EXPORT_SYMBOL(qdisc_get_rtab);
263
264 void qdisc_put_rtab(struct qdisc_rate_table *tab)
265 {
266         struct qdisc_rate_table *rtab, **rtabp;
267
268         if (!tab || --tab->refcnt)
269                 return;
270
271         for (rtabp = &qdisc_rtab_list; (rtab=*rtabp) != NULL; rtabp = &rtab->next) {
272                 if (rtab == tab) {
273                         *rtabp = rtab->next;
274                         kfree(rtab);
275                         return;
276                 }
277         }
278 }
279 EXPORT_SYMBOL(qdisc_put_rtab);
280
281 static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
282 {
283         struct qdisc_watchdog *wd = container_of(timer, struct qdisc_watchdog,
284                                                  timer);
285         struct net_device *dev = qdisc_dev(wd->qdisc);
286
287         wd->qdisc->flags &= ~TCQ_F_THROTTLED;
288         smp_wmb();
289         netif_schedule(dev);
290
291         return HRTIMER_NORESTART;
292 }
293
294 void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc)
295 {
296         hrtimer_init(&wd->timer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
297         wd->timer.function = qdisc_watchdog;
298         wd->qdisc = qdisc;
299 }
300 EXPORT_SYMBOL(qdisc_watchdog_init);
301
302 void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires)
303 {
304         ktime_t time;
305
306         wd->qdisc->flags |= TCQ_F_THROTTLED;
307         time = ktime_set(0, 0);
308         time = ktime_add_ns(time, PSCHED_US2NS(expires));
309         hrtimer_start(&wd->timer, time, HRTIMER_MODE_ABS);
310 }
311 EXPORT_SYMBOL(qdisc_watchdog_schedule);
312
313 void qdisc_watchdog_cancel(struct qdisc_watchdog *wd)
314 {
315         hrtimer_cancel(&wd->timer);
316         wd->qdisc->flags &= ~TCQ_F_THROTTLED;
317 }
318 EXPORT_SYMBOL(qdisc_watchdog_cancel);
319
320 struct hlist_head *qdisc_class_hash_alloc(unsigned int n)
321 {
322         unsigned int size = n * sizeof(struct hlist_head), i;
323         struct hlist_head *h;
324
325         if (size <= PAGE_SIZE)
326                 h = kmalloc(size, GFP_KERNEL);
327         else
328                 h = (struct hlist_head *)
329                         __get_free_pages(GFP_KERNEL, get_order(size));
330
331         if (h != NULL) {
332                 for (i = 0; i < n; i++)
333                         INIT_HLIST_HEAD(&h[i]);
334         }
335         return h;
336 }
337
338 static void qdisc_class_hash_free(struct hlist_head *h, unsigned int n)
339 {
340         unsigned int size = n * sizeof(struct hlist_head);
341
342         if (size <= PAGE_SIZE)
343                 kfree(h);
344         else
345                 free_pages((unsigned long)h, get_order(size));
346 }
347
348 void qdisc_class_hash_grow(struct Qdisc *sch, struct Qdisc_class_hash *clhash)
349 {
350         struct Qdisc_class_common *cl;
351         struct hlist_node *n, *next;
352         struct hlist_head *nhash, *ohash;
353         unsigned int nsize, nmask, osize;
354         unsigned int i, h;
355
356         /* Rehash when load factor exceeds 0.75 */
357         if (clhash->hashelems * 4 <= clhash->hashsize * 3)
358                 return;
359         nsize = clhash->hashsize * 2;
360         nmask = nsize - 1;
361         nhash = qdisc_class_hash_alloc(nsize);
362         if (nhash == NULL)
363                 return;
364
365         ohash = clhash->hash;
366         osize = clhash->hashsize;
367
368         sch_tree_lock(sch);
369         for (i = 0; i < osize; i++) {
370                 hlist_for_each_entry_safe(cl, n, next, &ohash[i], hnode) {
371                         h = qdisc_class_hash(cl->classid, nmask);
372                         hlist_add_head(&cl->hnode, &nhash[h]);
373                 }
374         }
375         clhash->hash     = nhash;
376         clhash->hashsize = nsize;
377         clhash->hashmask = nmask;
378         sch_tree_unlock(sch);
379
380         qdisc_class_hash_free(ohash, osize);
381 }
382 EXPORT_SYMBOL(qdisc_class_hash_grow);
383
384 int qdisc_class_hash_init(struct Qdisc_class_hash *clhash)
385 {
386         unsigned int size = 4;
387
388         clhash->hash = qdisc_class_hash_alloc(size);
389         if (clhash->hash == NULL)
390                 return -ENOMEM;
391         clhash->hashsize  = size;
392         clhash->hashmask  = size - 1;
393         clhash->hashelems = 0;
394         return 0;
395 }
396 EXPORT_SYMBOL(qdisc_class_hash_init);
397
398 void qdisc_class_hash_destroy(struct Qdisc_class_hash *clhash)
399 {
400         qdisc_class_hash_free(clhash->hash, clhash->hashsize);
401 }
402 EXPORT_SYMBOL(qdisc_class_hash_destroy);
403
404 void qdisc_class_hash_insert(struct Qdisc_class_hash *clhash,
405                              struct Qdisc_class_common *cl)
406 {
407         unsigned int h;
408
409         INIT_HLIST_NODE(&cl->hnode);
410         h = qdisc_class_hash(cl->classid, clhash->hashmask);
411         hlist_add_head(&cl->hnode, &clhash->hash[h]);
412         clhash->hashelems++;
413 }
414 EXPORT_SYMBOL(qdisc_class_hash_insert);
415
416 void qdisc_class_hash_remove(struct Qdisc_class_hash *clhash,
417                              struct Qdisc_class_common *cl)
418 {
419         hlist_del(&cl->hnode);
420         clhash->hashelems--;
421 }
422 EXPORT_SYMBOL(qdisc_class_hash_remove);
423
424 /* Allocate an unique handle from space managed by kernel */
425
426 static u32 qdisc_alloc_handle(struct net_device *dev)
427 {
428         int i = 0x10000;
429         static u32 autohandle = TC_H_MAKE(0x80000000U, 0);
430
431         do {
432                 autohandle += TC_H_MAKE(0x10000U, 0);
433                 if (autohandle == TC_H_MAKE(TC_H_ROOT, 0))
434                         autohandle = TC_H_MAKE(0x80000000U, 0);
435         } while (qdisc_lookup(dev, autohandle) && --i > 0);
436
437         return i>0 ? autohandle : 0;
438 }
439
440 /* Attach toplevel qdisc to device dev */
441
442 static struct Qdisc *
443 dev_graft_qdisc(struct net_device *dev, struct Qdisc *qdisc)
444 {
445         struct netdev_queue *dev_queue;
446         struct Qdisc *oqdisc;
447
448         if (dev->flags & IFF_UP)
449                 dev_deactivate(dev);
450
451         qdisc_lock_tree(dev);
452         if (qdisc && qdisc->flags&TCQ_F_INGRESS) {
453                 dev_queue = &dev->rx_queue;
454                 oqdisc = dev_queue->qdisc;
455                 /* Prune old scheduler */
456                 if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) {
457                         /* delete */
458                         qdisc_reset(oqdisc);
459                         dev_queue->qdisc = NULL;
460                 } else {  /* new */
461                         dev_queue->qdisc = qdisc;
462                 }
463
464         } else {
465                 dev_queue = &dev->tx_queue;
466                 oqdisc = dev_queue->qdisc_sleeping;
467
468                 /* Prune old scheduler */
469                 if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1)
470                         qdisc_reset(oqdisc);
471
472                 /* ... and graft new one */
473                 if (qdisc == NULL)
474                         qdisc = &noop_qdisc;
475                 dev_queue->qdisc_sleeping = qdisc;
476                 dev_queue->qdisc = &noop_qdisc;
477         }
478
479         qdisc_unlock_tree(dev);
480
481         if (dev->flags & IFF_UP)
482                 dev_activate(dev);
483
484         return oqdisc;
485 }
486
487 void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
488 {
489         const struct Qdisc_class_ops *cops;
490         unsigned long cl;
491         u32 parentid;
492
493         if (n == 0)
494                 return;
495         while ((parentid = sch->parent)) {
496                 if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS))
497                         return;
498
499                 sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid));
500                 if (sch == NULL) {
501                         WARN_ON(parentid != TC_H_ROOT);
502                         return;
503                 }
504                 cops = sch->ops->cl_ops;
505                 if (cops->qlen_notify) {
506                         cl = cops->get(sch, parentid);
507                         cops->qlen_notify(sch, cl);
508                         cops->put(sch, cl);
509                 }
510                 sch->q.qlen -= n;
511         }
512 }
513 EXPORT_SYMBOL(qdisc_tree_decrease_qlen);
514
515 /* Graft qdisc "new" to class "classid" of qdisc "parent" or
516    to device "dev".
517
518    Old qdisc is not destroyed but returned in *old.
519  */
520
521 static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
522                        u32 classid,
523                        struct Qdisc *new, struct Qdisc **old)
524 {
525         int err = 0;
526         struct Qdisc *q = *old;
527
528
529         if (parent == NULL) {
530                 if (q && q->flags&TCQ_F_INGRESS) {
531                         *old = dev_graft_qdisc(dev, q);
532                 } else {
533                         *old = dev_graft_qdisc(dev, new);
534                 }
535         } else {
536                 const struct Qdisc_class_ops *cops = parent->ops->cl_ops;
537
538                 err = -EINVAL;
539
540                 if (cops) {
541                         unsigned long cl = cops->get(parent, classid);
542                         if (cl) {
543                                 err = cops->graft(parent, cl, new, old);
544                                 cops->put(parent, cl);
545                         }
546                 }
547         }
548         return err;
549 }
550
551 /*
552    Allocate and initialize new qdisc.
553
554    Parameters are passed via opt.
555  */
556
557 static struct Qdisc *
558 qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
559              u32 parent, u32 handle, struct nlattr **tca, int *errp)
560 {
561         int err;
562         struct nlattr *kind = tca[TCA_KIND];
563         struct Qdisc *sch;
564         struct Qdisc_ops *ops;
565
566         ops = qdisc_lookup_ops(kind);
567 #ifdef CONFIG_KMOD
568         if (ops == NULL && kind != NULL) {
569                 char name[IFNAMSIZ];
570                 if (nla_strlcpy(name, kind, IFNAMSIZ) < IFNAMSIZ) {
571                         /* We dropped the RTNL semaphore in order to
572                          * perform the module load.  So, even if we
573                          * succeeded in loading the module we have to
574                          * tell the caller to replay the request.  We
575                          * indicate this using -EAGAIN.
576                          * We replay the request because the device may
577                          * go away in the mean time.
578                          */
579                         rtnl_unlock();
580                         request_module("sch_%s", name);
581                         rtnl_lock();
582                         ops = qdisc_lookup_ops(kind);
583                         if (ops != NULL) {
584                                 /* We will try again qdisc_lookup_ops,
585                                  * so don't keep a reference.
586                                  */
587                                 module_put(ops->owner);
588                                 err = -EAGAIN;
589                                 goto err_out;
590                         }
591                 }
592         }
593 #endif
594
595         err = -ENOENT;
596         if (ops == NULL)
597                 goto err_out;
598
599         sch = qdisc_alloc(dev_queue, ops);
600         if (IS_ERR(sch)) {
601                 err = PTR_ERR(sch);
602                 goto err_out2;
603         }
604
605         sch->parent = parent;
606
607         sch->stats_lock = &dev_queue->lock;
608         if (handle == TC_H_INGRESS) {
609                 sch->flags |= TCQ_F_INGRESS;
610                 handle = TC_H_MAKE(TC_H_INGRESS, 0);
611         } else {
612                 if (handle == 0) {
613                         handle = qdisc_alloc_handle(dev);
614                         err = -ENOMEM;
615                         if (handle == 0)
616                                 goto err_out3;
617                 }
618         }
619
620         sch->handle = handle;
621
622         if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS])) == 0) {
623                 if (tca[TCA_RATE]) {
624                         err = gen_new_estimator(&sch->bstats, &sch->rate_est,
625                                                 sch->stats_lock,
626                                                 tca[TCA_RATE]);
627                         if (err) {
628                                 /*
629                                  * Any broken qdiscs that would require
630                                  * a ops->reset() here? The qdisc was never
631                                  * in action so it shouldn't be necessary.
632                                  */
633                                 if (ops->destroy)
634                                         ops->destroy(sch);
635                                 goto err_out3;
636                         }
637                 }
638                 qdisc_lock_tree(dev);
639                 list_add_tail(&sch->list, &dev_queue->qdisc_list);
640                 qdisc_unlock_tree(dev);
641
642                 return sch;
643         }
644 err_out3:
645         dev_put(dev);
646         kfree((char *) sch - sch->padded);
647 err_out2:
648         module_put(ops->owner);
649 err_out:
650         *errp = err;
651         return NULL;
652 }
653
654 static int qdisc_change(struct Qdisc *sch, struct nlattr **tca)
655 {
656         if (tca[TCA_OPTIONS]) {
657                 int err;
658
659                 if (sch->ops->change == NULL)
660                         return -EINVAL;
661                 err = sch->ops->change(sch, tca[TCA_OPTIONS]);
662                 if (err)
663                         return err;
664         }
665         if (tca[TCA_RATE])
666                 gen_replace_estimator(&sch->bstats, &sch->rate_est,
667                         sch->stats_lock, tca[TCA_RATE]);
668         return 0;
669 }
670
671 struct check_loop_arg
672 {
673         struct qdisc_walker     w;
674         struct Qdisc            *p;
675         int                     depth;
676 };
677
678 static int check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w);
679
680 static int check_loop(struct Qdisc *q, struct Qdisc *p, int depth)
681 {
682         struct check_loop_arg   arg;
683
684         if (q->ops->cl_ops == NULL)
685                 return 0;
686
687         arg.w.stop = arg.w.skip = arg.w.count = 0;
688         arg.w.fn = check_loop_fn;
689         arg.depth = depth;
690         arg.p = p;
691         q->ops->cl_ops->walk(q, &arg.w);
692         return arg.w.stop ? -ELOOP : 0;
693 }
694
695 static int
696 check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w)
697 {
698         struct Qdisc *leaf;
699         const struct Qdisc_class_ops *cops = q->ops->cl_ops;
700         struct check_loop_arg *arg = (struct check_loop_arg *)w;
701
702         leaf = cops->leaf(q, cl);
703         if (leaf) {
704                 if (leaf == arg->p || arg->depth > 7)
705                         return -ELOOP;
706                 return check_loop(leaf, arg->p, arg->depth + 1);
707         }
708         return 0;
709 }
710
711 /*
712  * Delete/get qdisc.
713  */
714
715 static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
716 {
717         struct net *net = sock_net(skb->sk);
718         struct tcmsg *tcm = NLMSG_DATA(n);
719         struct nlattr *tca[TCA_MAX + 1];
720         struct net_device *dev;
721         u32 clid = tcm->tcm_parent;
722         struct Qdisc *q = NULL;
723         struct Qdisc *p = NULL;
724         int err;
725
726         if (net != &init_net)
727                 return -EINVAL;
728
729         if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
730                 return -ENODEV;
731
732         err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
733         if (err < 0)
734                 return err;
735
736         if (clid) {
737                 if (clid != TC_H_ROOT) {
738                         if (TC_H_MAJ(clid) != TC_H_MAJ(TC_H_INGRESS)) {
739                                 if ((p = qdisc_lookup(dev, TC_H_MAJ(clid))) == NULL)
740                                         return -ENOENT;
741                                 q = qdisc_leaf(p, clid);
742                         } else { /* ingress */
743                                 q = dev->rx_queue.qdisc;
744                         }
745                 } else {
746                         struct netdev_queue *dev_queue = &dev->tx_queue;
747                         q = dev_queue->qdisc_sleeping;
748                 }
749                 if (!q)
750                         return -ENOENT;
751
752                 if (tcm->tcm_handle && q->handle != tcm->tcm_handle)
753                         return -EINVAL;
754         } else {
755                 if ((q = qdisc_lookup(dev, tcm->tcm_handle)) == NULL)
756                         return -ENOENT;
757         }
758
759         if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id))
760                 return -EINVAL;
761
762         if (n->nlmsg_type == RTM_DELQDISC) {
763                 if (!clid)
764                         return -EINVAL;
765                 if (q->handle == 0)
766                         return -ENOENT;
767                 if ((err = qdisc_graft(dev, p, clid, NULL, &q)) != 0)
768                         return err;
769                 if (q) {
770                         qdisc_notify(skb, n, clid, q, NULL);
771                         qdisc_lock_tree(dev);
772                         qdisc_destroy(q);
773                         qdisc_unlock_tree(dev);
774                 }
775         } else {
776                 qdisc_notify(skb, n, clid, NULL, q);
777         }
778         return 0;
779 }
780
781 /*
782    Create/change qdisc.
783  */
784
785 static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
786 {
787         struct net *net = sock_net(skb->sk);
788         struct tcmsg *tcm;
789         struct nlattr *tca[TCA_MAX + 1];
790         struct net_device *dev;
791         u32 clid;
792         struct Qdisc *q, *p;
793         int err;
794
795         if (net != &init_net)
796                 return -EINVAL;
797
798 replay:
799         /* Reinit, just in case something touches this. */
800         tcm = NLMSG_DATA(n);
801         clid = tcm->tcm_parent;
802         q = p = NULL;
803
804         if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
805                 return -ENODEV;
806
807         err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
808         if (err < 0)
809                 return err;
810
811         if (clid) {
812                 if (clid != TC_H_ROOT) {
813                         if (clid != TC_H_INGRESS) {
814                                 if ((p = qdisc_lookup(dev, TC_H_MAJ(clid))) == NULL)
815                                         return -ENOENT;
816                                 q = qdisc_leaf(p, clid);
817                         } else { /*ingress */
818                                 q = dev->rx_queue.qdisc;
819                         }
820                 } else {
821                         struct netdev_queue *dev_queue = &dev->tx_queue;
822                         q = dev_queue->qdisc_sleeping;
823                 }
824
825                 /* It may be default qdisc, ignore it */
826                 if (q && q->handle == 0)
827                         q = NULL;
828
829                 if (!q || !tcm->tcm_handle || q->handle != tcm->tcm_handle) {
830                         if (tcm->tcm_handle) {
831                                 if (q && !(n->nlmsg_flags&NLM_F_REPLACE))
832                                         return -EEXIST;
833                                 if (TC_H_MIN(tcm->tcm_handle))
834                                         return -EINVAL;
835                                 if ((q = qdisc_lookup(dev, tcm->tcm_handle)) == NULL)
836                                         goto create_n_graft;
837                                 if (n->nlmsg_flags&NLM_F_EXCL)
838                                         return -EEXIST;
839                                 if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id))
840                                         return -EINVAL;
841                                 if (q == p ||
842                                     (p && check_loop(q, p, 0)))
843                                         return -ELOOP;
844                                 atomic_inc(&q->refcnt);
845                                 goto graft;
846                         } else {
847                                 if (q == NULL)
848                                         goto create_n_graft;
849
850                                 /* This magic test requires explanation.
851                                  *
852                                  *   We know, that some child q is already
853                                  *   attached to this parent and have choice:
854                                  *   either to change it or to create/graft new one.
855                                  *
856                                  *   1. We are allowed to create/graft only
857                                  *   if CREATE and REPLACE flags are set.
858                                  *
859                                  *   2. If EXCL is set, requestor wanted to say,
860                                  *   that qdisc tcm_handle is not expected
861                                  *   to exist, so that we choose create/graft too.
862                                  *
863                                  *   3. The last case is when no flags are set.
864                                  *   Alas, it is sort of hole in API, we
865                                  *   cannot decide what to do unambiguously.
866                                  *   For now we select create/graft, if
867                                  *   user gave KIND, which does not match existing.
868                                  */
869                                 if ((n->nlmsg_flags&NLM_F_CREATE) &&
870                                     (n->nlmsg_flags&NLM_F_REPLACE) &&
871                                     ((n->nlmsg_flags&NLM_F_EXCL) ||
872                                      (tca[TCA_KIND] &&
873                                       nla_strcmp(tca[TCA_KIND], q->ops->id))))
874                                         goto create_n_graft;
875                         }
876                 }
877         } else {
878                 if (!tcm->tcm_handle)
879                         return -EINVAL;
880                 q = qdisc_lookup(dev, tcm->tcm_handle);
881         }
882
883         /* Change qdisc parameters */
884         if (q == NULL)
885                 return -ENOENT;
886         if (n->nlmsg_flags&NLM_F_EXCL)
887                 return -EEXIST;
888         if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], q->ops->id))
889                 return -EINVAL;
890         err = qdisc_change(q, tca);
891         if (err == 0)
892                 qdisc_notify(skb, n, clid, NULL, q);
893         return err;
894
895 create_n_graft:
896         if (!(n->nlmsg_flags&NLM_F_CREATE))
897                 return -ENOENT;
898         if (clid == TC_H_INGRESS)
899                 q = qdisc_create(dev, &dev->rx_queue,
900                                  tcm->tcm_parent, tcm->tcm_parent,
901                                  tca, &err);
902         else
903                 q = qdisc_create(dev, &dev->tx_queue,
904                                  tcm->tcm_parent, tcm->tcm_handle,
905                                  tca, &err);
906         if (q == NULL) {
907                 if (err == -EAGAIN)
908                         goto replay;
909                 return err;
910         }
911
912 graft:
913         if (1) {
914                 struct Qdisc *old_q = NULL;
915                 err = qdisc_graft(dev, p, clid, q, &old_q);
916                 if (err) {
917                         if (q) {
918                                 qdisc_lock_tree(dev);
919                                 qdisc_destroy(q);
920                                 qdisc_unlock_tree(dev);
921                         }
922                         return err;
923                 }
924                 qdisc_notify(skb, n, clid, old_q, q);
925                 if (old_q) {
926                         qdisc_lock_tree(dev);
927                         qdisc_destroy(old_q);
928                         qdisc_unlock_tree(dev);
929                 }
930         }
931         return 0;
932 }
933
934 static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
935                          u32 pid, u32 seq, u16 flags, int event)
936 {
937         struct tcmsg *tcm;
938         struct nlmsghdr  *nlh;
939         unsigned char *b = skb_tail_pointer(skb);
940         struct gnet_dump d;
941
942         nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
943         tcm = NLMSG_DATA(nlh);
944         tcm->tcm_family = AF_UNSPEC;
945         tcm->tcm__pad1 = 0;
946         tcm->tcm__pad2 = 0;
947         tcm->tcm_ifindex = qdisc_dev(q)->ifindex;
948         tcm->tcm_parent = clid;
949         tcm->tcm_handle = q->handle;
950         tcm->tcm_info = atomic_read(&q->refcnt);
951         NLA_PUT_STRING(skb, TCA_KIND, q->ops->id);
952         if (q->ops->dump && q->ops->dump(q, skb) < 0)
953                 goto nla_put_failure;
954         q->qstats.qlen = q->q.qlen;
955
956         if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
957                         TCA_XSTATS, q->stats_lock, &d) < 0)
958                 goto nla_put_failure;
959
960         if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0)
961                 goto nla_put_failure;
962
963         if (gnet_stats_copy_basic(&d, &q->bstats) < 0 ||
964             gnet_stats_copy_rate_est(&d, &q->rate_est) < 0 ||
965             gnet_stats_copy_queue(&d, &q->qstats) < 0)
966                 goto nla_put_failure;
967
968         if (gnet_stats_finish_copy(&d) < 0)
969                 goto nla_put_failure;
970
971         nlh->nlmsg_len = skb_tail_pointer(skb) - b;
972         return skb->len;
973
974 nlmsg_failure:
975 nla_put_failure:
976         nlmsg_trim(skb, b);
977         return -1;
978 }
979
980 static int qdisc_notify(struct sk_buff *oskb, struct nlmsghdr *n,
981                         u32 clid, struct Qdisc *old, struct Qdisc *new)
982 {
983         struct sk_buff *skb;
984         u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
985
986         skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
987         if (!skb)
988                 return -ENOBUFS;
989
990         if (old && old->handle) {
991                 if (tc_fill_qdisc(skb, old, clid, pid, n->nlmsg_seq, 0, RTM_DELQDISC) < 0)
992                         goto err_out;
993         }
994         if (new) {
995                 if (tc_fill_qdisc(skb, new, clid, pid, n->nlmsg_seq, old ? NLM_F_REPLACE : 0, RTM_NEWQDISC) < 0)
996                         goto err_out;
997         }
998
999         if (skb->len)
1000                 return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
1001
1002 err_out:
1003         kfree_skb(skb);
1004         return -EINVAL;
1005 }
1006
1007 static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
1008 {
1009         struct net *net = sock_net(skb->sk);
1010         int idx, q_idx;
1011         int s_idx, s_q_idx;
1012         struct net_device *dev;
1013         struct Qdisc *q;
1014
1015         if (net != &init_net)
1016                 return 0;
1017
1018         s_idx = cb->args[0];
1019         s_q_idx = q_idx = cb->args[1];
1020         read_lock(&dev_base_lock);
1021         idx = 0;
1022         for_each_netdev(&init_net, dev) {
1023                 struct netdev_queue *dev_queue;
1024                 if (idx < s_idx)
1025                         goto cont;
1026                 if (idx > s_idx)
1027                         s_q_idx = 0;
1028                 q_idx = 0;
1029                 dev_queue = &dev->tx_queue;
1030                 list_for_each_entry(q, &dev_queue->qdisc_list, list) {
1031                         if (q_idx < s_q_idx) {
1032                                 q_idx++;
1033                                 continue;
1034                         }
1035                         if (tc_fill_qdisc(skb, q, q->parent, NETLINK_CB(cb->skb).pid,
1036                                           cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWQDISC) <= 0)
1037                                 goto done;
1038                         q_idx++;
1039                 }
1040 cont:
1041                 idx++;
1042         }
1043
1044 done:
1045         read_unlock(&dev_base_lock);
1046
1047         cb->args[0] = idx;
1048         cb->args[1] = q_idx;
1049
1050         return skb->len;
1051 }
1052
1053
1054
1055 /************************************************
1056  *      Traffic classes manipulation.           *
1057  ************************************************/
1058
1059
1060
1061 static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
1062 {
1063         struct net *net = sock_net(skb->sk);
1064         struct netdev_queue *dev_queue;
1065         struct tcmsg *tcm = NLMSG_DATA(n);
1066         struct nlattr *tca[TCA_MAX + 1];
1067         struct net_device *dev;
1068         struct Qdisc *q = NULL;
1069         const struct Qdisc_class_ops *cops;
1070         unsigned long cl = 0;
1071         unsigned long new_cl;
1072         u32 pid = tcm->tcm_parent;
1073         u32 clid = tcm->tcm_handle;
1074         u32 qid = TC_H_MAJ(clid);
1075         int err;
1076
1077         if (net != &init_net)
1078                 return -EINVAL;
1079
1080         if ((dev = __dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
1081                 return -ENODEV;
1082
1083         err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL);
1084         if (err < 0)
1085                 return err;
1086
1087         /*
1088            parent == TC_H_UNSPEC - unspecified parent.
1089            parent == TC_H_ROOT   - class is root, which has no parent.
1090            parent == X:0         - parent is root class.
1091            parent == X:Y         - parent is a node in hierarchy.
1092            parent == 0:Y         - parent is X:Y, where X:0 is qdisc.
1093
1094            handle == 0:0         - generate handle from kernel pool.
1095            handle == 0:Y         - class is X:Y, where X:0 is qdisc.
1096            handle == X:Y         - clear.
1097            handle == X:0         - root class.
1098          */
1099
1100         /* Step 1. Determine qdisc handle X:0 */
1101
1102         dev_queue = &dev->tx_queue;
1103         if (pid != TC_H_ROOT) {
1104                 u32 qid1 = TC_H_MAJ(pid);
1105
1106                 if (qid && qid1) {
1107                         /* If both majors are known, they must be identical. */
1108                         if (qid != qid1)
1109                                 return -EINVAL;
1110                 } else if (qid1) {
1111                         qid = qid1;
1112                 } else if (qid == 0)
1113                         qid = dev_queue->qdisc_sleeping->handle;
1114
1115                 /* Now qid is genuine qdisc handle consistent
1116                    both with parent and child.
1117
1118                    TC_H_MAJ(pid) still may be unspecified, complete it now.
1119                  */
1120                 if (pid)
1121                         pid = TC_H_MAKE(qid, pid);
1122         } else {
1123                 if (qid == 0)
1124                         qid = dev_queue->qdisc_sleeping->handle;
1125         }
1126
1127         /* OK. Locate qdisc */
1128         if ((q = qdisc_lookup(dev, qid)) == NULL)
1129                 return -ENOENT;
1130
1131         /* An check that it supports classes */
1132         cops = q->ops->cl_ops;
1133         if (cops == NULL)
1134                 return -EINVAL;
1135
1136         /* Now try to get class */
1137         if (clid == 0) {
1138                 if (pid == TC_H_ROOT)
1139                         clid = qid;
1140         } else
1141                 clid = TC_H_MAKE(qid, clid);
1142
1143         if (clid)
1144                 cl = cops->get(q, clid);
1145
1146         if (cl == 0) {
1147                 err = -ENOENT;
1148                 if (n->nlmsg_type != RTM_NEWTCLASS || !(n->nlmsg_flags&NLM_F_CREATE))
1149                         goto out;
1150         } else {
1151                 switch (n->nlmsg_type) {
1152                 case RTM_NEWTCLASS:
1153                         err = -EEXIST;
1154                         if (n->nlmsg_flags&NLM_F_EXCL)
1155                                 goto out;
1156                         break;
1157                 case RTM_DELTCLASS:
1158                         err = cops->delete(q, cl);
1159                         if (err == 0)
1160                                 tclass_notify(skb, n, q, cl, RTM_DELTCLASS);
1161                         goto out;
1162                 case RTM_GETTCLASS:
1163                         err = tclass_notify(skb, n, q, cl, RTM_NEWTCLASS);
1164                         goto out;
1165                 default:
1166                         err = -EINVAL;
1167                         goto out;
1168                 }
1169         }
1170
1171         new_cl = cl;
1172         err = cops->change(q, clid, pid, tca, &new_cl);
1173         if (err == 0)
1174                 tclass_notify(skb, n, q, new_cl, RTM_NEWTCLASS);
1175
1176 out:
1177         if (cl)
1178                 cops->put(q, cl);
1179
1180         return err;
1181 }
1182
1183
1184 static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
1185                           unsigned long cl,
1186                           u32 pid, u32 seq, u16 flags, int event)
1187 {
1188         struct tcmsg *tcm;
1189         struct nlmsghdr  *nlh;
1190         unsigned char *b = skb_tail_pointer(skb);
1191         struct gnet_dump d;
1192         const struct Qdisc_class_ops *cl_ops = q->ops->cl_ops;
1193
1194         nlh = NLMSG_NEW(skb, pid, seq, event, sizeof(*tcm), flags);
1195         tcm = NLMSG_DATA(nlh);
1196         tcm->tcm_family = AF_UNSPEC;
1197         tcm->tcm_ifindex = qdisc_dev(q)->ifindex;
1198         tcm->tcm_parent = q->handle;
1199         tcm->tcm_handle = q->handle;
1200         tcm->tcm_info = 0;
1201         NLA_PUT_STRING(skb, TCA_KIND, q->ops->id);
1202         if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0)
1203                 goto nla_put_failure;
1204
1205         if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
1206                         TCA_XSTATS, q->stats_lock, &d) < 0)
1207                 goto nla_put_failure;
1208
1209         if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0)
1210                 goto nla_put_failure;
1211
1212         if (gnet_stats_finish_copy(&d) < 0)
1213                 goto nla_put_failure;
1214
1215         nlh->nlmsg_len = skb_tail_pointer(skb) - b;
1216         return skb->len;
1217
1218 nlmsg_failure:
1219 nla_put_failure:
1220         nlmsg_trim(skb, b);
1221         return -1;
1222 }
1223
1224 static int tclass_notify(struct sk_buff *oskb, struct nlmsghdr *n,
1225                           struct Qdisc *q, unsigned long cl, int event)
1226 {
1227         struct sk_buff *skb;
1228         u32 pid = oskb ? NETLINK_CB(oskb).pid : 0;
1229
1230         skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1231         if (!skb)
1232                 return -ENOBUFS;
1233
1234         if (tc_fill_tclass(skb, q, cl, pid, n->nlmsg_seq, 0, event) < 0) {
1235                 kfree_skb(skb);
1236                 return -EINVAL;
1237         }
1238
1239         return rtnetlink_send(skb, &init_net, pid, RTNLGRP_TC, n->nlmsg_flags&NLM_F_ECHO);
1240 }
1241
1242 struct qdisc_dump_args
1243 {
1244         struct qdisc_walker w;
1245         struct sk_buff *skb;
1246         struct netlink_callback *cb;
1247 };
1248
1249 static int qdisc_class_dump(struct Qdisc *q, unsigned long cl, struct qdisc_walker *arg)
1250 {
1251         struct qdisc_dump_args *a = (struct qdisc_dump_args *)arg;
1252
1253         return tc_fill_tclass(a->skb, q, cl, NETLINK_CB(a->cb->skb).pid,
1254                               a->cb->nlh->nlmsg_seq, NLM_F_MULTI, RTM_NEWTCLASS);
1255 }
1256
1257 static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
1258 {
1259         struct net *net = sock_net(skb->sk);
1260         struct netdev_queue *dev_queue;
1261         int t;
1262         int s_t;
1263         struct net_device *dev;
1264         struct Qdisc *q;
1265         struct tcmsg *tcm = (struct tcmsg*)NLMSG_DATA(cb->nlh);
1266         struct qdisc_dump_args arg;
1267
1268         if (net != &init_net)
1269                 return 0;
1270
1271         if (cb->nlh->nlmsg_len < NLMSG_LENGTH(sizeof(*tcm)))
1272                 return 0;
1273         if ((dev = dev_get_by_index(&init_net, tcm->tcm_ifindex)) == NULL)
1274                 return 0;
1275
1276         s_t = cb->args[0];
1277         t = 0;
1278
1279         dev_queue = &dev->tx_queue;
1280         list_for_each_entry(q, &dev_queue->qdisc_list, list) {
1281                 if (t < s_t || !q->ops->cl_ops ||
1282                     (tcm->tcm_parent &&
1283                      TC_H_MAJ(tcm->tcm_parent) != q->handle)) {
1284                         t++;
1285                         continue;
1286                 }
1287                 if (t > s_t)
1288                         memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(cb->args[0]));
1289                 arg.w.fn = qdisc_class_dump;
1290                 arg.skb = skb;
1291                 arg.cb = cb;
1292                 arg.w.stop  = 0;
1293                 arg.w.skip = cb->args[1];
1294                 arg.w.count = 0;
1295                 q->ops->cl_ops->walk(q, &arg.w);
1296                 cb->args[1] = arg.w.count;
1297                 if (arg.w.stop)
1298                         break;
1299                 t++;
1300         }
1301
1302         cb->args[0] = t;
1303
1304         dev_put(dev);
1305         return skb->len;
1306 }
1307
1308 /* Main classifier routine: scans classifier chain attached
1309    to this qdisc, (optionally) tests for protocol and asks
1310    specific classifiers.
1311  */
1312 int tc_classify_compat(struct sk_buff *skb, struct tcf_proto *tp,
1313                        struct tcf_result *res)
1314 {
1315         __be16 protocol = skb->protocol;
1316         int err = 0;
1317
1318         for (; tp; tp = tp->next) {
1319                 if ((tp->protocol == protocol ||
1320                      tp->protocol == htons(ETH_P_ALL)) &&
1321                     (err = tp->classify(skb, tp, res)) >= 0) {
1322 #ifdef CONFIG_NET_CLS_ACT
1323                         if (err != TC_ACT_RECLASSIFY && skb->tc_verd)
1324                                 skb->tc_verd = SET_TC_VERD(skb->tc_verd, 0);
1325 #endif
1326                         return err;
1327                 }
1328         }
1329         return -1;
1330 }
1331 EXPORT_SYMBOL(tc_classify_compat);
1332
1333 int tc_classify(struct sk_buff *skb, struct tcf_proto *tp,
1334                 struct tcf_result *res)
1335 {
1336         int err = 0;
1337         __be16 protocol;
1338 #ifdef CONFIG_NET_CLS_ACT
1339         struct tcf_proto *otp = tp;
1340 reclassify:
1341 #endif
1342         protocol = skb->protocol;
1343
1344         err = tc_classify_compat(skb, tp, res);
1345 #ifdef CONFIG_NET_CLS_ACT
1346         if (err == TC_ACT_RECLASSIFY) {
1347                 u32 verd = G_TC_VERD(skb->tc_verd);
1348                 tp = otp;
1349
1350                 if (verd++ >= MAX_REC_LOOP) {
1351                         printk("rule prio %u protocol %02x reclassify loop, "
1352                                "packet dropped\n",
1353                                tp->prio&0xffff, ntohs(tp->protocol));
1354                         return TC_ACT_SHOT;
1355                 }
1356                 skb->tc_verd = SET_TC_VERD(skb->tc_verd, verd);
1357                 goto reclassify;
1358         }
1359 #endif
1360         return err;
1361 }
1362 EXPORT_SYMBOL(tc_classify);
1363
1364 void tcf_destroy(struct tcf_proto *tp)
1365 {
1366         tp->ops->destroy(tp);
1367         module_put(tp->ops->owner);
1368         kfree(tp);
1369 }
1370
1371 void tcf_destroy_chain(struct tcf_proto **fl)
1372 {
1373         struct tcf_proto *tp;
1374
1375         while ((tp = *fl) != NULL) {
1376                 *fl = tp->next;
1377                 tcf_destroy(tp);
1378         }
1379 }
1380 EXPORT_SYMBOL(tcf_destroy_chain);
1381
1382 #ifdef CONFIG_PROC_FS
1383 static int psched_show(struct seq_file *seq, void *v)
1384 {
1385         struct timespec ts;
1386
1387         hrtimer_get_res(CLOCK_MONOTONIC, &ts);
1388         seq_printf(seq, "%08x %08x %08x %08x\n",
1389                    (u32)NSEC_PER_USEC, (u32)PSCHED_US2NS(1),
1390                    1000000,
1391                    (u32)NSEC_PER_SEC/(u32)ktime_to_ns(timespec_to_ktime(ts)));
1392
1393         return 0;
1394 }
1395
1396 static int psched_open(struct inode *inode, struct file *file)
1397 {
1398         return single_open(file, psched_show, PDE(inode)->data);
1399 }
1400
1401 static const struct file_operations psched_fops = {
1402         .owner = THIS_MODULE,
1403         .open = psched_open,
1404         .read  = seq_read,
1405         .llseek = seq_lseek,
1406         .release = single_release,
1407 };
1408 #endif
1409
1410 static int __init pktsched_init(void)
1411 {
1412         register_qdisc(&pfifo_qdisc_ops);
1413         register_qdisc(&bfifo_qdisc_ops);
1414         proc_net_fops_create(&init_net, "psched", 0, &psched_fops);
1415
1416         rtnl_register(PF_UNSPEC, RTM_NEWQDISC, tc_modify_qdisc, NULL);
1417         rtnl_register(PF_UNSPEC, RTM_DELQDISC, tc_get_qdisc, NULL);
1418         rtnl_register(PF_UNSPEC, RTM_GETQDISC, tc_get_qdisc, tc_dump_qdisc);
1419         rtnl_register(PF_UNSPEC, RTM_NEWTCLASS, tc_ctl_tclass, NULL);
1420         rtnl_register(PF_UNSPEC, RTM_DELTCLASS, tc_ctl_tclass, NULL);
1421         rtnl_register(PF_UNSPEC, RTM_GETTCLASS, tc_ctl_tclass, tc_dump_tclass);
1422
1423         return 0;
1424 }
1425
1426 subsys_initcall(pktsched_init);