1 /* net/sched/sch_ingress.c - Ingress qdisc 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License 4 * as published by the Free Software Foundation; either version 5 * 2 of the License, or (at your option) any later version. 6 * 7 * Authors: Jamal Hadi Salim 1999 8 */ 9 10 #include <linux/module.h> 11 #include <linux/types.h> 12 #include <linux/list.h> 13 #include <linux/skbuff.h> 14 #include <linux/rtnetlink.h> 15 16 #include <net/netlink.h> 17 #include <net/pkt_sched.h> 18 19 static struct Qdisc *ingress_leaf(struct Qdisc *sch, unsigned long arg) 20 { 21 return NULL; 22 } 23 24 static unsigned long ingress_get(struct Qdisc *sch, u32 classid) 25 { 26 return TC_H_MIN(classid) + 1; 27 } 28 29 static unsigned long ingress_bind_filter(struct Qdisc *sch, 30 unsigned long parent, u32 classid) 31 { 32 return ingress_get(sch, classid); 33 } 34 35 static void ingress_put(struct Qdisc *sch, unsigned long cl) 36 { 37 } 38 39 static void ingress_walk(struct Qdisc *sch, struct qdisc_walker *walker) 40 { 41 } 42 43 static struct tcf_proto __rcu **ingress_find_tcf(struct Qdisc *sch, 44 unsigned long cl) 45 { 46 struct net_device *dev = qdisc_dev(sch); 47 48 return &dev->ingress_cl_list; 49 } 50 51 static int ingress_init(struct Qdisc *sch, struct nlattr *opt) 52 { 53 net_inc_ingress_queue(); 54 sch->flags |= TCQ_F_CPUSTATS; 55 56 return 0; 57 } 58 59 static void ingress_destroy(struct Qdisc *sch) 60 { 61 struct net_device *dev = qdisc_dev(sch); 62 63 tcf_destroy_chain(&dev->ingress_cl_list); 64 net_dec_ingress_queue(); 65 } 66 67 static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb) 68 { 69 struct nlattr *nest; 70 71 nest = nla_nest_start(skb, TCA_OPTIONS); 72 if (nest == NULL) 73 goto nla_put_failure; 74 75 return nla_nest_end(skb, nest); 76 77 nla_put_failure: 78 nla_nest_cancel(skb, nest); 79 return -1; 80 } 81 82 static const struct Qdisc_class_ops ingress_class_ops = { 83 .leaf = ingress_leaf, 84 .get = ingress_get, 85 .put = ingress_put, 86 .walk = ingress_walk, 87 .tcf_chain = ingress_find_tcf, 88 .bind_tcf = ingress_bind_filter, 89 .unbind_tcf = ingress_put, 90 }; 91 92 static struct Qdisc_ops ingress_qdisc_ops __read_mostly = { 93 .cl_ops = &ingress_class_ops, 94 .id = "ingress", 95 .init = ingress_init, 96 .destroy = ingress_destroy, 97 .dump = ingress_dump, 98 .owner = THIS_MODULE, 99 }; 100 101 static int __init ingress_module_init(void) 102 { 103 return register_qdisc(&ingress_qdisc_ops); 104 } 105 106 static void __exit ingress_module_exit(void) 107 { 108 unregister_qdisc(&ingress_qdisc_ops); 109 } 110 111 module_init(ingress_module_init); 112 module_exit(ingress_module_exit); 113 114 MODULE_LICENSE("GPL"); 115