Linux Audio

Check our new training course

Loading...
v3.5.6
  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#include <net/netlink.h>
 16#include <net/pkt_sched.h>
 17
 18
 19struct ingress_qdisc_data {
 20	struct tcf_proto	*filter_list;
 21};
 22
 23/* ------------------------- Class/flow operations ------------------------- */
 24
 25static struct Qdisc *ingress_leaf(struct Qdisc *sch, unsigned long arg)
 26{
 27	return NULL;
 28}
 29
 30static unsigned long ingress_get(struct Qdisc *sch, u32 classid)
 31{
 32	return TC_H_MIN(classid) + 1;
 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 **ingress_find_tcf(struct Qdisc *sch, unsigned long cl)
 
 50{
 51	struct ingress_qdisc_data *p = qdisc_priv(sch);
 52
 53	return &p->filter_list;
 54}
 55
 56/* --------------------------- Qdisc operations ---------------------------- */
 57
 58static int ingress_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 59{
 60	struct ingress_qdisc_data *p = qdisc_priv(sch);
 61	struct tcf_result res;
 62	int result;
 63
 64	result = tc_classify(skb, p->filter_list, &res);
 65
 66	qdisc_bstats_update(sch, skb);
 67	switch (result) {
 68	case TC_ACT_SHOT:
 69		result = TC_ACT_SHOT;
 70		sch->qstats.drops++;
 71		break;
 72	case TC_ACT_STOLEN:
 73	case TC_ACT_QUEUED:
 74		result = TC_ACT_STOLEN;
 75		break;
 76	case TC_ACT_RECLASSIFY:
 77	case TC_ACT_OK:
 78		skb->tc_index = TC_H_MIN(res.classid);
 79	default:
 80		result = TC_ACT_OK;
 81		break;
 82	}
 83
 84	return result;
 85}
 86
 87/* ------------------------------------------------------------- */
 88
 89static void ingress_destroy(struct Qdisc *sch)
 90{
 91	struct ingress_qdisc_data *p = qdisc_priv(sch);
 92
 93	tcf_destroy_chain(&p->filter_list);
 
 94}
 95
 96static int ingress_dump(struct Qdisc *sch, struct sk_buff *skb)
 97{
 98	struct nlattr *nest;
 99
100	nest = nla_nest_start(skb, TCA_OPTIONS);
101	if (nest == NULL)
102		goto nla_put_failure;
103	nla_nest_end(skb, nest);
104	return skb->len;
105
106nla_put_failure:
107	nla_nest_cancel(skb, nest);
108	return -1;
109}
110
111static const struct Qdisc_class_ops ingress_class_ops = {
112	.leaf		=	ingress_leaf,
113	.get		=	ingress_get,
114	.put		=	ingress_put,
115	.walk		=	ingress_walk,
116	.tcf_chain	=	ingress_find_tcf,
 
117	.bind_tcf	=	ingress_bind_filter,
118	.unbind_tcf	=	ingress_put,
119};
120
121static struct Qdisc_ops ingress_qdisc_ops __read_mostly = {
122	.cl_ops		=	&ingress_class_ops,
123	.id		=	"ingress",
124	.priv_size	=	sizeof(struct ingress_qdisc_data),
125	.enqueue	=	ingress_enqueue,
126	.destroy	=	ingress_destroy,
127	.dump		=	ingress_dump,
128	.owner		=	THIS_MODULE,
129};
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131static int __init ingress_module_init(void)
132{
133	return register_qdisc(&ingress_qdisc_ops);
 
 
 
 
 
 
 
 
 
134}
135
136static void __exit ingress_module_exit(void)
137{
138	unregister_qdisc(&ingress_qdisc_ops);
 
139}
140
141module_init(ingress_module_init)
142module_exit(ingress_module_exit)
 
 
143MODULE_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");