15 #include <linux/types.h>
16 #include <linux/kernel.h>
17 #include <linux/string.h>
18 #include <linux/errno.h>
20 #include <linux/rtnetlink.h>
21 #include <linux/module.h>
30 #include <linux/if_arp.h>
32 #define MIRRED_TAB_MASK 7
34 static u32 mirred_idx_gen;
39 .htab = tcf_mirred_ht,
44 static int tcf_mirred_release(
struct tcf_mirred *
m,
int bind)
50 if (!m->tcf_bindcnt && m->tcf_refcnt <= 0) {
66 struct tc_action *
a,
int ovr,
int bind)
116 &mirred_idx_gen, &mirred_hash_info);
128 spin_lock_bh(&m->tcf_lock);
129 m->tcf_action = parm->action;
133 if (ret != ACT_P_CREATED)
139 spin_unlock_bh(&m->tcf_lock);
140 if (ret == ACT_P_CREATED) {
148 static int tcf_mirred_cleanup(
struct tc_action *a,
int bind)
153 return tcf_mirred_release(m, bind);
166 spin_lock(&m->tcf_lock);
168 bstats_update(&m->tcf_bstats, skb);
183 skb2 = skb_act_clone(skb,
GFP_ATOMIC, m->tcf_action);
202 m->tcf_qstats.overlimits++;
206 retval = m->tcf_action;
208 retval = m->tcf_action;
209 spin_unlock(&m->tcf_lock);
214 static int tcf_mirred_dump(
struct sk_buff *skb,
struct tc_action *a,
int bind,
int ref)
216 unsigned char *
b = skb_tail_pointer(skb);
219 .index = m->tcf_index,
220 .action = m->tcf_action,
221 .refcnt = m->tcf_refcnt - ref,
222 .bindcnt = m->tcf_bindcnt - bind,
229 goto nla_put_failure;
234 goto nla_put_failure;
260 .notifier_call = mirred_device_event,
264 static struct tc_action_ops act_mirred_ops = {
266 .hinfo = &mirred_hash_info,
268 .capab = TCA_CAP_NONE,
271 .dump = tcf_mirred_dump,
272 .cleanup = tcf_mirred_cleanup,
274 .init = tcf_mirred_init,
282 static int __init mirred_init_module(
void)
288 pr_info(
"Mirror/redirect action on\n");
292 static void __exit mirred_cleanup_module(
void)