5 * Bart De Schuymer <bdschuym@pandora.be>
11 #include <linux/netfilter_bridge/ebtables.h>
12 #include <linux/netfilter_bridge/ebt_redirect.h>
13 #include <linux/module.h>
15 #include "../br_private.h"
17 static int ebt_target_redirect(struct sk_buff
**pskb
, unsigned int hooknr
,
18 const struct net_device
*in
, const struct net_device
*out
,
19 const void *data
, unsigned int datalen
)
21 struct ebt_redirect_info
*info
= (struct ebt_redirect_info
*)data
;
23 if (skb_shared(*pskb
) || skb_cloned(*pskb
)) {
26 nskb
= skb_copy(*pskb
, GFP_ATOMIC
);
30 skb_set_owner_w(nskb
, (*pskb
)->sk
);
34 if (hooknr
!= NF_BR_BROUTING
)
35 memcpy(eth_hdr(*pskb
)->h_dest
,
36 in
->br_port
->br
->dev
->dev_addr
, ETH_ALEN
);
38 memcpy(eth_hdr(*pskb
)->h_dest
, in
->dev_addr
, ETH_ALEN
);
39 (*pskb
)->pkt_type
= PACKET_HOST
;
43 static int ebt_target_redirect_check(const char *tablename
, unsigned int hookmask
,
44 const struct ebt_entry
*e
, void *data
, unsigned int datalen
)
46 struct ebt_redirect_info
*info
= (struct ebt_redirect_info
*)data
;
48 if (datalen
!= EBT_ALIGN(sizeof(struct ebt_redirect_info
)))
50 if (BASE_CHAIN
&& info
->target
== EBT_RETURN
)
53 if ( (strcmp(tablename
, "nat") || hookmask
& ~(1 << NF_BR_PRE_ROUTING
)) &&
54 (strcmp(tablename
, "broute") || hookmask
& ~(1 << NF_BR_BROUTING
)) )
61 static struct ebt_target redirect_target
=
63 .name
= EBT_REDIRECT_TARGET
,
64 .target
= ebt_target_redirect
,
65 .check
= ebt_target_redirect_check
,
69 static int __init
ebt_redirect_init(void)
71 return ebt_register_target(&redirect_target
);
74 static void __exit
ebt_redirect_fini(void)
76 ebt_unregister_target(&redirect_target
);
79 module_init(ebt_redirect_init
);
80 module_exit(ebt_redirect_fini
);
81 MODULE_LICENSE("GPL");