5 * Bart De Schuymer <bdschuym@pandora.be>
10 #include <linux/module.h>
12 #include "../br_private.h"
13 #include <linux/netfilter.h>
14 #include <linux/netfilter/x_tables.h>
15 #include <linux/netfilter_bridge/ebtables.h>
16 #include <linux/netfilter_bridge/ebt_redirect.h>
19 ebt_redirect_tg(struct sk_buff
*skb
, const struct xt_action_param
*par
)
21 const struct ebt_redirect_info
*info
= par
->targinfo
;
23 if (!skb_make_writable(skb
, 0))
26 if (par
->hooknum
!= NF_BR_BROUTING
)
27 /* rcu_read_lock()ed by nf_hook_slow */
28 memcpy(eth_hdr(skb
)->h_dest
,
29 br_port_get_rcu(par
->in
)->br
->dev
->dev_addr
, ETH_ALEN
);
31 memcpy(eth_hdr(skb
)->h_dest
, par
->in
->dev_addr
, ETH_ALEN
);
32 skb
->pkt_type
= PACKET_HOST
;
36 static int ebt_redirect_tg_check(const struct xt_tgchk_param
*par
)
38 const struct ebt_redirect_info
*info
= par
->targinfo
;
39 unsigned int hook_mask
;
41 if (BASE_CHAIN
&& info
->target
== EBT_RETURN
)
44 hook_mask
= par
->hook_mask
& ~(1 << NF_BR_NUMHOOKS
);
45 if ((strcmp(par
->table
, "nat") != 0 ||
46 hook_mask
& ~(1 << NF_BR_PRE_ROUTING
)) &&
47 (strcmp(par
->table
, "broute") != 0 ||
48 hook_mask
& ~(1 << NF_BR_BROUTING
)))
55 static struct xt_target ebt_redirect_tg_reg __read_mostly
= {
58 .family
= NFPROTO_BRIDGE
,
59 .hooks
= (1 << NF_BR_NUMHOOKS
) | (1 << NF_BR_PRE_ROUTING
) |
60 (1 << NF_BR_BROUTING
),
61 .target
= ebt_redirect_tg
,
62 .checkentry
= ebt_redirect_tg_check
,
63 .targetsize
= sizeof(struct ebt_redirect_info
),
67 static int __init
ebt_redirect_init(void)
69 return xt_register_target(&ebt_redirect_tg_reg
);
72 static void __exit
ebt_redirect_fini(void)
74 xt_unregister_target(&ebt_redirect_tg_reg
);
77 module_init(ebt_redirect_init
);
78 module_exit(ebt_redirect_fini
);
79 MODULE_DESCRIPTION("Ebtables: Packet redirection to localhost");
80 MODULE_LICENSE("GPL");