2 * net/sched/gact.c Generic actions
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * copyright Jamal Hadi Salim (2002-4)
13 #include <asm/uaccess.h>
14 #include <asm/system.h>
15 #include <linux/bitops.h>
16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <linux/sched.h>
19 #include <linux/string.h>
21 #include <linux/socket.h>
22 #include <linux/sockios.h>
24 #include <linux/errno.h>
25 #include <linux/interrupt.h>
26 #include <linux/netdevice.h>
27 #include <linux/skbuff.h>
28 #include <linux/rtnetlink.h>
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/proc_fs.h>
33 #include <net/pkt_sched.h>
34 #include <linux/tc_act/tc_gact.h>
35 #include <net/tc_act/tc_gact.h>
37 /* use generic hash table */
38 #define MY_TAB_SIZE 16
39 #define MY_TAB_MASK 15
42 static struct tcf_gact
*tcf_gact_ht
[MY_TAB_SIZE
];
43 static DEFINE_RWLOCK(gact_lock
);
45 /* ovewrride the defaults */
46 #define tcf_st tcf_gact
48 #define tcf_t_lock gact_lock
49 #define tcf_ht tcf_gact_ht
51 #define CONFIG_NET_ACT_INIT 1
52 #include <net/pkt_act.h>
54 #ifdef CONFIG_GACT_PROB
55 static int gact_net_rand(struct tcf_gact
*p
)
57 if (net_random()%p
->pval
)
62 static int gact_determ(struct tcf_gact
*p
)
64 if (p
->bstats
.packets
%p
->pval
)
69 typedef int (*g_rand
)(struct tcf_gact
*p
);
70 static g_rand gact_rand
[MAX_RAND
]= { NULL
, gact_net_rand
, gact_determ
};
73 static int tcf_gact_init(struct rtattr
*rta
, struct rtattr
*est
,
74 struct tc_action
*a
, int ovr
, int bind
)
76 struct rtattr
*tb
[TCA_GACT_MAX
];
81 if (rta
== NULL
|| rtattr_parse_nested(tb
, TCA_GACT_MAX
, rta
) < 0)
84 if (tb
[TCA_GACT_PARMS
- 1] == NULL
||
85 RTA_PAYLOAD(tb
[TCA_GACT_PARMS
- 1]) < sizeof(*parm
))
87 parm
= RTA_DATA(tb
[TCA_GACT_PARMS
- 1]);
89 if (tb
[TCA_GACT_PROB
-1] != NULL
)
90 #ifdef CONFIG_GACT_PROB
91 if (RTA_PAYLOAD(tb
[TCA_GACT_PROB
-1]) < sizeof(struct tc_gact_p
))
97 p
= tcf_hash_check(parm
->index
, a
, ovr
, bind
);
99 p
= tcf_hash_create(parm
->index
, est
, a
, sizeof(*p
), ovr
, bind
);
105 tcf_hash_release(p
, bind
);
110 spin_lock_bh(&p
->lock
);
111 p
->action
= parm
->action
;
112 #ifdef CONFIG_GACT_PROB
113 if (tb
[TCA_GACT_PROB
-1] != NULL
) {
114 struct tc_gact_p
*p_parm
= RTA_DATA(tb
[TCA_GACT_PROB
-1]);
115 p
->paction
= p_parm
->paction
;
116 p
->pval
= p_parm
->pval
;
117 p
->ptype
= p_parm
->ptype
;
120 spin_unlock_bh(&p
->lock
);
121 if (ret
== ACT_P_CREATED
)
127 tcf_gact_cleanup(struct tc_action
*a
, int bind
)
129 struct tcf_gact
*p
= PRIV(a
, gact
);
132 return tcf_hash_release(p
, bind
);
137 tcf_gact(struct sk_buff
*skb
, struct tc_action
*a
, struct tcf_result
*res
)
139 struct tcf_gact
*p
= PRIV(a
, gact
);
140 int action
= TC_ACT_SHOT
;
143 #ifdef CONFIG_GACT_PROB
144 if (p
->ptype
&& gact_rand
[p
->ptype
] != NULL
)
145 action
= gact_rand
[p
->ptype
](p
);
151 p
->bstats
.bytes
+= skb
->len
;
153 if (action
== TC_ACT_SHOT
)
155 p
->tm
.lastuse
= jiffies
;
156 spin_unlock(&p
->lock
);
162 tcf_gact_dump(struct sk_buff
*skb
, struct tc_action
*a
, int bind
, int ref
)
164 unsigned char *b
= skb
->tail
;
166 struct tcf_gact
*p
= PRIV(a
, gact
);
169 opt
.index
= p
->index
;
170 opt
.refcnt
= p
->refcnt
- ref
;
171 opt
.bindcnt
= p
->bindcnt
- bind
;
172 opt
.action
= p
->action
;
173 RTA_PUT(skb
, TCA_GACT_PARMS
, sizeof(opt
), &opt
);
174 #ifdef CONFIG_GACT_PROB
176 struct tc_gact_p p_opt
;
177 p_opt
.paction
= p
->paction
;
178 p_opt
.pval
= p
->pval
;
179 p_opt
.ptype
= p
->ptype
;
180 RTA_PUT(skb
, TCA_GACT_PROB
, sizeof(p_opt
), &p_opt
);
183 t
.install
= jiffies_to_clock_t(jiffies
- p
->tm
.install
);
184 t
.lastuse
= jiffies_to_clock_t(jiffies
- p
->tm
.lastuse
);
185 t
.expires
= jiffies_to_clock_t(p
->tm
.expires
);
186 RTA_PUT(skb
, TCA_GACT_TM
, sizeof(t
), &t
);
190 skb_trim(skb
, b
- skb
->data
);
194 static struct tc_action_ops act_gact_ops
= {
196 .type
= TCA_ACT_GACT
,
197 .capab
= TCA_CAP_NONE
,
198 .owner
= THIS_MODULE
,
200 .dump
= tcf_gact_dump
,
201 .cleanup
= tcf_gact_cleanup
,
202 .lookup
= tcf_hash_search
,
203 .init
= tcf_gact_init
,
204 .walk
= tcf_generic_walker
207 MODULE_AUTHOR("Jamal Hadi Salim(2002-4)");
208 MODULE_DESCRIPTION("Generic Classifier actions");
209 MODULE_LICENSE("GPL");
212 gact_init_module(void)
214 #ifdef CONFIG_GACT_PROB
215 printk("GACT probability on\n");
217 printk("GACT probability NOT on\n");
219 return tcf_register_action(&act_gact_ops
);
223 gact_cleanup_module(void)
225 tcf_unregister_action(&act_gact_ops
);
228 module_init(gact_init_module
);
229 module_exit(gact_cleanup_module
);