Blame view

net/sched/act_simple.c 4.53 KB
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
1
2
3
4
5
6
7
8
  /*
   * net/sched/simp.c	Simple example of an action
   *
   *		This program is free software; you can redistribute it and/or
   *		modify it under the terms of the GNU General Public License
   *		as published by the Free Software Foundation; either version
   *		2 of the License, or (at your option) any later version.
   *
fa1b1cff3   Jamal Hadi Salim   net_cls_act: Make...
9
   * Authors:	Jamal Hadi Salim (2005-8)
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
10
11
   *
   */
cbdbf00aa   David S. Miller   [PKT_SCHED]: Elim...
12
  #include <linux/module.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
13
  #include <linux/slab.h>
cbdbf00aa   David S. Miller   [PKT_SCHED]: Elim...
14
  #include <linux/init.h>
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
15
  #include <linux/kernel.h>
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
16
17
  #include <linux/skbuff.h>
  #include <linux/rtnetlink.h>
dc5fc579b   Arnaldo Carvalho de Melo   [NETLINK]: Use nl...
18
  #include <net/netlink.h>
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
19
20
21
  #include <net/pkt_sched.h>
  
  #define TCA_ACT_SIMP 22
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
22
23
  #include <linux/tc_act/tc_defact.h>
  #include <net/tc_act/tc_defact.h>
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
24
  #define SIMP_TAB_MASK     7
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
25

fa1b1cff3   Jamal Hadi Salim   net_cls_act: Make...
26
  #define SIMP_MAX_DATA	32
dc7f9f6e8   Eric Dumazet   net: sched: const...
27
28
  static int tcf_simp(struct sk_buff *skb, const struct tc_action *a,
  		    struct tcf_result *res)
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
29
  {
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
30
  	struct tcf_defact *d = a->priv;
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
31

e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
32
33
  	spin_lock(&d->tcf_lock);
  	d->tcf_tm.lastuse = jiffies;
bfe0d0298   Eric Dumazet   net_sched: factor...
34
  	bstats_update(&d->tcf_bstats, skb);
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
35

10297b993   YOSHIFUJI Hideaki   [NET] SCHED: Fix ...
36
37
38
  	/* print policy string followed by _ then packet count
  	 * Example if this was the 3rd packet and the string was "hello"
  	 * then it would look like "hello_3" (without quotes)
cc7ec456f   Eric Dumazet   net_sched: cleanups
39
  	 */
6ff9c3644   stephen hemminger   net sched: printk...
40
41
  	pr_info("simple: %s_%d
  ",
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
42
43
44
45
  	       (char *)d->tcfd_defdata, d->tcf_bstats.packets);
  	spin_unlock(&d->tcf_lock);
  	return d->tcf_action;
  }
a5b5c958f   WANG Cong   net_sched: act: r...
46
  static void tcf_simp_release(struct tc_action *a, int bind)
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
47
  {
86062033f   WANG Cong   net_sched: act: h...
48
  	struct tcf_defact *d = to_defact(a);
a5b5c958f   WANG Cong   net_sched: act: r...
49
  	kfree(d->tcfd_defdata);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
50
  }
fa1b1cff3   Jamal Hadi Salim   net_cls_act: Make...
51
  static int alloc_defdata(struct tcf_defact *d, char *defdata)
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
52
  {
0eff683f7   Dan Carpenter   net/sched: potent...
53
  	d->tcfd_defdata = kzalloc(SIMP_MAX_DATA, GFP_KERNEL);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
54
55
  	if (unlikely(!d->tcfd_defdata))
  		return -ENOMEM;
0eff683f7   Dan Carpenter   net/sched: potent...
56
  	strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
57
58
  	return 0;
  }
9d1045ad6   Jamal Hadi Salim   net_cls_act: act_...
59
60
  static void reset_policy(struct tcf_defact *d, char *defdata,
  			 struct tc_defact *p)
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
61
  {
9d1045ad6   Jamal Hadi Salim   net_cls_act: act_...
62
63
64
65
66
  	spin_lock_bh(&d->tcf_lock);
  	d->tcf_action = p->action;
  	memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
  	strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
  	spin_unlock_bh(&d->tcf_lock);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
67
  }
53b2bf3f8   Patrick McHardy   [NET_SCHED]: Use ...
68
69
  static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
  	[TCA_DEF_PARMS]	= { .len = sizeof(struct tc_defact) },
fa1b1cff3   Jamal Hadi Salim   net_cls_act: Make...
70
  	[TCA_DEF_DATA]	= { .type = NLA_STRING, .len = SIMP_MAX_DATA },
53b2bf3f8   Patrick McHardy   [NET_SCHED]: Use ...
71
  };
c1b52739e   Benjamin LaHaise   pkt_sched: namesp...
72
73
74
  static int tcf_simp_init(struct net *net, struct nlattr *nla,
  			 struct nlattr *est, struct tc_action *a,
  			 int ovr, int bind)
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
75
  {
7ba699c60   Patrick McHardy   [NET_SCHED]: Conv...
76
  	struct nlattr *tb[TCA_DEF_MAX + 1];
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
77
78
  	struct tc_defact *parm;
  	struct tcf_defact *d;
fa1b1cff3   Jamal Hadi Salim   net_cls_act: Make...
79
  	char *defdata;
cee63723b   Patrick McHardy   [NET_SCHED]: Prop...
80
  	int ret = 0, err;
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
81

cee63723b   Patrick McHardy   [NET_SCHED]: Prop...
82
  	if (nla == NULL)
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
83
  		return -EINVAL;
fa1b1cff3   Jamal Hadi Salim   net_cls_act: Make...
84
  	err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy);
cee63723b   Patrick McHardy   [NET_SCHED]: Prop...
85
86
  	if (err < 0)
  		return err;
53b2bf3f8   Patrick McHardy   [NET_SCHED]: Use ...
87
  	if (tb[TCA_DEF_PARMS] == NULL)
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
88
  		return -EINVAL;
fa1b1cff3   Jamal Hadi Salim   net_cls_act: Make...
89
  	if (tb[TCA_DEF_DATA] == NULL)
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
90
  		return -EINVAL;
fa1b1cff3   Jamal Hadi Salim   net_cls_act: Make...
91
92
  	parm = nla_data(tb[TCA_DEF_PARMS]);
  	defdata = nla_data(tb[TCA_DEF_DATA]);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
93

86062033f   WANG Cong   net_sched: act: h...
94
95
96
97
  	if (!tcf_hash_check(parm->index, a, bind)) {
  		ret = tcf_hash_create(parm->index, est, a, sizeof(*d), bind);
  		if (ret)
  			return ret;
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
98

86062033f   WANG Cong   net_sched: act: h...
99
  		d = to_defact(a);
fa1b1cff3   Jamal Hadi Salim   net_cls_act: Make...
100
  		ret = alloc_defdata(d, defdata);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
101
  		if (ret < 0) {
86062033f   WANG Cong   net_sched: act: h...
102
  			tcf_hash_cleanup(a, est);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
103
104
  			return ret;
  		}
9d1045ad6   Jamal Hadi Salim   net_cls_act: act_...
105
  		d->tcf_action = parm->action;
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
106
107
  		ret = ACT_P_CREATED;
  	} else {
86062033f   WANG Cong   net_sched: act: h...
108
  		d = to_defact(a);
1a29321ed   Jamal Hadi Salim   net_sched: act: D...
109
110
111
  
  		if (bind)
  			return 0;
a5b5c958f   WANG Cong   net_sched: act: r...
112
  		tcf_hash_release(a, bind);
1a29321ed   Jamal Hadi Salim   net_sched: act: D...
113
  		if (!ovr)
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
114
  			return -EEXIST;
1a29321ed   Jamal Hadi Salim   net_sched: act: D...
115

9d1045ad6   Jamal Hadi Salim   net_cls_act: act_...
116
  		reset_policy(d, defdata, parm);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
117
  	}
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
118
  	if (ret == ACT_P_CREATED)
86062033f   WANG Cong   net_sched: act: h...
119
  		tcf_hash_insert(a);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
120
121
  	return ret;
  }
cc7ec456f   Eric Dumazet   net_sched: cleanups
122
123
  static int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
  			 int bind, int ref)
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
124
  {
27a884dc3   Arnaldo Carvalho de Melo   [SK_BUFF]: Conver...
125
  	unsigned char *b = skb_tail_pointer(skb);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
126
  	struct tcf_defact *d = a->priv;
1c40be12f   Eric Dumazet   net sched: fix so...
127
128
129
130
131
132
  	struct tc_defact opt = {
  		.index   = d->tcf_index,
  		.refcnt  = d->tcf_refcnt - ref,
  		.bindcnt = d->tcf_bindcnt - bind,
  		.action  = d->tcf_action,
  	};
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
133
  	struct tcf_t t;
1b34ec43c   David S. Miller   pkt_sched: Stop u...
134
135
136
  	if (nla_put(skb, TCA_DEF_PARMS, sizeof(opt), &opt) ||
  	    nla_put_string(skb, TCA_DEF_DATA, d->tcfd_defdata))
  		goto nla_put_failure;
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
137
138
139
  	t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
  	t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
  	t.expires = jiffies_to_clock_t(d->tcf_tm.expires);
1b34ec43c   David S. Miller   pkt_sched: Stop u...
140
141
  	if (nla_put(skb, TCA_DEF_TM, sizeof(t), &t))
  		goto nla_put_failure;
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
142
  	return skb->len;
7ba699c60   Patrick McHardy   [NET_SCHED]: Conv...
143
  nla_put_failure:
dc5fc579b   Arnaldo Carvalho de Melo   [NETLINK]: Use nl...
144
  	nlmsg_trim(skb, b);
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
145
  	return -1;
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
146
147
148
  }
  
  static struct tc_action_ops act_simp_ops = {
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
149
  	.kind		=	"simple",
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
150
  	.type		=	TCA_ACT_SIMP,
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
151
152
153
  	.owner		=	THIS_MODULE,
  	.act		=	tcf_simp,
  	.dump		=	tcf_simp_dump,
86062033f   WANG Cong   net_sched: act: h...
154
  	.cleanup	=	tcf_simp_release,
e9ce1cd3c   David S. Miller   [PKT_SCHED]: Kill...
155
  	.init		=	tcf_simp_init,
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
156
157
158
159
160
161
162
163
  };
  
  MODULE_AUTHOR("Jamal Hadi Salim(2005)");
  MODULE_DESCRIPTION("Simple example action");
  MODULE_LICENSE("GPL");
  
  static int __init simp_init_module(void)
  {
4f1e9d894   WANG Cong   net_sched: act: m...
164
165
  	int ret;
  	ret = tcf_register_action(&act_simp_ops, SIMP_TAB_MASK);
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
166
  	if (!ret)
6ff9c3644   stephen hemminger   net sched: printk...
167
168
  		pr_info("Simple TC action Loaded
  ");
db7530797   Jamal Hadi Salim   [PKT_SCHED]: Intr...
169
170
171
172
173
174
175
176
177
178
  	return ret;
  }
  
  static void __exit simp_cleanup_module(void)
  {
  	tcf_unregister_action(&act_simp_ops);
  }
  
  module_init(simp_init_module);
  module_exit(simp_cleanup_module);