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");
v3.15
  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	return nla_nest_end(skb, nest);
104
105nla_put_failure:
106	nla_nest_cancel(skb, nest);
107	return -1;
108}
109
110static const struct Qdisc_class_ops ingress_class_ops = {
111	.leaf		=	ingress_leaf,
112	.get		=	ingress_get,
113	.put		=	ingress_put,
114	.walk		=	ingress_walk,
115	.tcf_chain	=	ingress_find_tcf,
116	.bind_tcf	=	ingress_bind_filter,
117	.unbind_tcf	=	ingress_put,
118};
119
120static struct Qdisc_ops ingress_qdisc_ops __read_mostly = {
121	.cl_ops		=	&ingress_class_ops,
122	.id		=	"ingress",
123	.priv_size	=	sizeof(struct ingress_qdisc_data),
124	.enqueue	=	ingress_enqueue,
125	.destroy	=	ingress_destroy,
126	.dump		=	ingress_dump,
127	.owner		=	THIS_MODULE,
128};
129
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
130static int __init ingress_module_init(void)
131{
132	return register_qdisc(&ingress_qdisc_ops);
 
 
 
 
 
 
 
 
 
133}
134
135static void __exit ingress_module_exit(void)
136{
137	unregister_qdisc(&ingress_qdisc_ops);
 
138}
139
140module_init(ingress_module_init)
141module_exit(ingress_module_exit)
 
 
142MODULE_LICENSE("GPL");