Linux Audio

Check our new training course

Loading...
v4.6
  1/* net/sched/sch_ingress.c - Ingress and clsact qdisc
  2 *
  3 *              This program is free software; you can redistribute it and/or
  4 *              modify it under the terms of the GNU General Public License
  5 *              as published by the Free Software Foundation; either version
  6 *              2 of the License, or (at your option) any later version.
  7 *
  8 * Authors:     Jamal Hadi Salim 1999
  9 */
 10
 11#include <linux/module.h>
 12#include <linux/types.h>
 13#include <linux/list.h>
 14#include <linux/skbuff.h>
 15#include <linux/rtnetlink.h>
 16
 17#include <net/netlink.h>
 18#include <net/pkt_sched.h>
 19
 20static struct Qdisc *ingress_leaf(struct Qdisc *sch, unsigned long arg)
 21{
 22	return NULL;
 23}
 24
 25static unsigned long ingress_get(struct Qdisc *sch, u32 classid)
 26{
 27	return TC_H_MIN(classid) + 1;
 28}
 29
 
 
 
 
 
 30static unsigned long ingress_bind_filter(struct Qdisc *sch,
 31					 unsigned long parent, u32 classid)
 32{
 33	return ingress_get(sch, classid);
 34}
 35
 36static void ingress_put(struct Qdisc *sch, unsigned long cl)
 37{
 38}
 39
 40static void ingress_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 41{
 42}
 43
 44static struct tcf_proto __rcu **ingress_find_tcf(struct Qdisc *sch,
 45						 unsigned long cl)
 46{
 47	struct net_device *dev = qdisc_dev(sch);
 48
 49	return &dev->ingress_cl_list;
 50}
 51
 52static int ingress_init(struct Qdisc *sch, struct nlattr *opt)
 53{
 54	net_inc_ingress_queue();
 55	sch->flags |= TCQ_F_CPUSTATS;
 56
 57	return 0;
 58}
 59
 60static void ingress_destroy(struct Qdisc *sch)
 61{
 62	struct net_device *dev = qdisc_dev(sch);
 63
 64	tcf_destroy_chain(&dev->ingress_cl_list);
 65	net_dec_ingress_queue();
 66}
 67
 68static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
 69{
 70	struct nlattr *nest;
 71
 72	nest = nla_nest_start(skb, TCA_OPTIONS);
 73	if (nest == NULL)
 74		goto nla_put_failure;
 75
 76	return nla_nest_end(skb, nest);
 77
 78nla_put_failure:
 79	nla_nest_cancel(skb, nest);
 80	return -1;
 81}
 82
 83static const struct Qdisc_class_ops ingress_class_ops = {
 84	.leaf		=	ingress_leaf,
 85	.get		=	ingress_get,
 86	.put		=	ingress_put,
 87	.walk		=	ingress_walk,
 88	.tcf_chain	=	ingress_find_tcf,
 
 89	.bind_tcf	=	ingress_bind_filter,
 90	.unbind_tcf	=	ingress_put,
 91};
 92
 93static struct Qdisc_ops ingress_qdisc_ops __read_mostly = {
 94	.cl_ops		=	&ingress_class_ops,
 95	.id		=	"ingress",
 96	.init		=	ingress_init,
 97	.destroy	=	ingress_destroy,
 98	.dump		=	ingress_dump,
 99	.owner		=	THIS_MODULE,
100};
101
102static unsigned long clsact_get(struct Qdisc *sch, u32 classid)
103{
104	switch (TC_H_MIN(classid)) {
105	case TC_H_MIN(TC_H_MIN_INGRESS):
106	case TC_H_MIN(TC_H_MIN_EGRESS):
107		return TC_H_MIN(classid);
108	default:
109		return 0;
110	}
111}
112
 
 
 
 
 
113static unsigned long clsact_bind_filter(struct Qdisc *sch,
114					unsigned long parent, u32 classid)
115{
116	return clsact_get(sch, classid);
117}
118
119static struct tcf_proto __rcu **clsact_find_tcf(struct Qdisc *sch,
120						unsigned long cl)
121{
122	struct net_device *dev = qdisc_dev(sch);
123
124	switch (cl) {
125	case TC_H_MIN(TC_H_MIN_INGRESS):
126		return &dev->ingress_cl_list;
127	case TC_H_MIN(TC_H_MIN_EGRESS):
128		return &dev->egress_cl_list;
129	default:
130		return NULL;
131	}
132}
133
134static int clsact_init(struct Qdisc *sch, struct nlattr *opt)
135{
136	net_inc_ingress_queue();
137	net_inc_egress_queue();
138
139	sch->flags |= TCQ_F_CPUSTATS;
140
141	return 0;
142}
143
144static void clsact_destroy(struct Qdisc *sch)
145{
146	struct net_device *dev = qdisc_dev(sch);
147
148	tcf_destroy_chain(&dev->ingress_cl_list);
149	tcf_destroy_chain(&dev->egress_cl_list);
150
151	net_dec_ingress_queue();
152	net_dec_egress_queue();
153}
154
155static const struct Qdisc_class_ops clsact_class_ops = {
156	.leaf		=	ingress_leaf,
157	.get		=	clsact_get,
158	.put		=	ingress_put,
159	.walk		=	ingress_walk,
160	.tcf_chain	=	clsact_find_tcf,
 
161	.bind_tcf	=	clsact_bind_filter,
162	.unbind_tcf	=	ingress_put,
163};
164
165static struct Qdisc_ops clsact_qdisc_ops __read_mostly = {
166	.cl_ops		=	&clsact_class_ops,
167	.id		=	"clsact",
168	.init		=	clsact_init,
169	.destroy	=	clsact_destroy,
170	.dump		=	ingress_dump,
171	.owner		=	THIS_MODULE,
172};
173
174static int __init ingress_module_init(void)
175{
176	int ret;
177
178	ret = register_qdisc(&ingress_qdisc_ops);
179	if (!ret) {
180		ret = register_qdisc(&clsact_qdisc_ops);
181		if (ret)
182			unregister_qdisc(&ingress_qdisc_ops);
183	}
184
185	return ret;
186}
187
188static void __exit ingress_module_exit(void)
189{
190	unregister_qdisc(&ingress_qdisc_ops);
191	unregister_qdisc(&clsact_qdisc_ops);
192}
193
194module_init(ingress_module_init);
195module_exit(ingress_module_exit);
196
197MODULE_ALIAS("sch_clsact");
198MODULE_LICENSE("GPL");
v4.10.11
  1/* net/sched/sch_ingress.c - Ingress and clsact qdisc
  2 *
  3 *              This program is free software; you can redistribute it and/or
  4 *              modify it under the terms of the GNU General Public License
  5 *              as published by the Free Software Foundation; either version
  6 *              2 of the License, or (at your option) any later version.
  7 *
  8 * Authors:     Jamal Hadi Salim 1999
  9 */
 10
 11#include <linux/module.h>
 12#include <linux/types.h>
 13#include <linux/list.h>
 14#include <linux/skbuff.h>
 15#include <linux/rtnetlink.h>
 16
 17#include <net/netlink.h>
 18#include <net/pkt_sched.h>
 19
 20static struct Qdisc *ingress_leaf(struct Qdisc *sch, unsigned long arg)
 21{
 22	return NULL;
 23}
 24
 25static unsigned long ingress_get(struct Qdisc *sch, u32 classid)
 26{
 27	return TC_H_MIN(classid) + 1;
 28}
 29
 30static bool ingress_cl_offload(u32 classid)
 31{
 32	return true;
 33}
 34
 35static unsigned long ingress_bind_filter(struct Qdisc *sch,
 36					 unsigned long parent, u32 classid)
 37{
 38	return ingress_get(sch, classid);
 39}
 40
 41static void ingress_put(struct Qdisc *sch, unsigned long cl)
 42{
 43}
 44
 45static void ingress_walk(struct Qdisc *sch, struct qdisc_walker *walker)
 46{
 47}
 48
 49static struct tcf_proto __rcu **ingress_find_tcf(struct Qdisc *sch,
 50						 unsigned long cl)
 51{
 52	struct net_device *dev = qdisc_dev(sch);
 53
 54	return &dev->ingress_cl_list;
 55}
 56
 57static int ingress_init(struct Qdisc *sch, struct nlattr *opt)
 58{
 59	net_inc_ingress_queue();
 60	sch->flags |= TCQ_F_CPUSTATS;
 61
 62	return 0;
 63}
 64
 65static void ingress_destroy(struct Qdisc *sch)
 66{
 67	struct net_device *dev = qdisc_dev(sch);
 68
 69	tcf_destroy_chain(&dev->ingress_cl_list);
 70	net_dec_ingress_queue();
 71}
 72
 73static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
 74{
 75	struct nlattr *nest;
 76
 77	nest = nla_nest_start(skb, TCA_OPTIONS);
 78	if (nest == NULL)
 79		goto nla_put_failure;
 80
 81	return nla_nest_end(skb, nest);
 82
 83nla_put_failure:
 84	nla_nest_cancel(skb, nest);
 85	return -1;
 86}
 87
 88static const struct Qdisc_class_ops ingress_class_ops = {
 89	.leaf		=	ingress_leaf,
 90	.get		=	ingress_get,
 91	.put		=	ingress_put,
 92	.walk		=	ingress_walk,
 93	.tcf_chain	=	ingress_find_tcf,
 94	.tcf_cl_offload	=	ingress_cl_offload,
 95	.bind_tcf	=	ingress_bind_filter,
 96	.unbind_tcf	=	ingress_put,
 97};
 98
 99static struct Qdisc_ops ingress_qdisc_ops __read_mostly = {
100	.cl_ops		=	&ingress_class_ops,
101	.id		=	"ingress",
102	.init		=	ingress_init,
103	.destroy	=	ingress_destroy,
104	.dump		=	ingress_dump,
105	.owner		=	THIS_MODULE,
106};
107
108static unsigned long clsact_get(struct Qdisc *sch, u32 classid)
109{
110	switch (TC_H_MIN(classid)) {
111	case TC_H_MIN(TC_H_MIN_INGRESS):
112	case TC_H_MIN(TC_H_MIN_EGRESS):
113		return TC_H_MIN(classid);
114	default:
115		return 0;
116	}
117}
118
119static bool clsact_cl_offload(u32 classid)
120{
121	return TC_H_MIN(classid) == TC_H_MIN(TC_H_MIN_INGRESS);
122}
123
124static unsigned long clsact_bind_filter(struct Qdisc *sch,
125					unsigned long parent, u32 classid)
126{
127	return clsact_get(sch, classid);
128}
129
130static struct tcf_proto __rcu **clsact_find_tcf(struct Qdisc *sch,
131						unsigned long cl)
132{
133	struct net_device *dev = qdisc_dev(sch);
134
135	switch (cl) {
136	case TC_H_MIN(TC_H_MIN_INGRESS):
137		return &dev->ingress_cl_list;
138	case TC_H_MIN(TC_H_MIN_EGRESS):
139		return &dev->egress_cl_list;
140	default:
141		return NULL;
142	}
143}
144
145static int clsact_init(struct Qdisc *sch, struct nlattr *opt)
146{
147	net_inc_ingress_queue();
148	net_inc_egress_queue();
149
150	sch->flags |= TCQ_F_CPUSTATS;
151
152	return 0;
153}
154
155static void clsact_destroy(struct Qdisc *sch)
156{
157	struct net_device *dev = qdisc_dev(sch);
158
159	tcf_destroy_chain(&dev->ingress_cl_list);
160	tcf_destroy_chain(&dev->egress_cl_list);
161
162	net_dec_ingress_queue();
163	net_dec_egress_queue();
164}
165
166static const struct Qdisc_class_ops clsact_class_ops = {
167	.leaf		=	ingress_leaf,
168	.get		=	clsact_get,
169	.put		=	ingress_put,
170	.walk		=	ingress_walk,
171	.tcf_chain	=	clsact_find_tcf,
172	.tcf_cl_offload	=	clsact_cl_offload,
173	.bind_tcf	=	clsact_bind_filter,
174	.unbind_tcf	=	ingress_put,
175};
176
177static struct Qdisc_ops clsact_qdisc_ops __read_mostly = {
178	.cl_ops		=	&clsact_class_ops,
179	.id		=	"clsact",
180	.init		=	clsact_init,
181	.destroy	=	clsact_destroy,
182	.dump		=	ingress_dump,
183	.owner		=	THIS_MODULE,
184};
185
186static int __init ingress_module_init(void)
187{
188	int ret;
189
190	ret = register_qdisc(&ingress_qdisc_ops);
191	if (!ret) {
192		ret = register_qdisc(&clsact_qdisc_ops);
193		if (ret)
194			unregister_qdisc(&ingress_qdisc_ops);
195	}
196
197	return ret;
198}
199
200static void __exit ingress_module_exit(void)
201{
202	unregister_qdisc(&ingress_qdisc_ops);
203	unregister_qdisc(&clsact_qdisc_ops);
204}
205
206module_init(ingress_module_init);
207module_exit(ingress_module_exit);
208
209MODULE_ALIAS("sch_clsact");
210MODULE_LICENSE("GPL");