aboutsummaryrefslogtreecommitdiff
path: root/net/bridge/netfilter/ebt_snat.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/netfilter/ebt_snat.c')
-rw-r--r--net/bridge/netfilter/ebt_snat.c23
1 files changed, 8 insertions, 15 deletions
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c
index a50722182bf..425ac920904 100644
--- a/net/bridge/netfilter/ebt_snat.c
+++ b/net/bridge/netfilter/ebt_snat.c
@@ -8,6 +8,7 @@
*
*/
+#include <linux/netfilter.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
#include <linux/module.h>
@@ -15,34 +16,26 @@
#include <linux/if_arp.h>
#include <net/arp.h>
-static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr,
+static int ebt_target_snat(struct sk_buff *skb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
const void *data, unsigned int datalen)
{
struct ebt_nat_info *info = (struct ebt_nat_info *) data;
- if (skb_shared(*pskb) || skb_cloned(*pskb)) {
- struct sk_buff *nskb;
+ if (skb_make_writable(skb, 0))
+ return NF_DROP;
- nskb = skb_copy(*pskb, GFP_ATOMIC);
- if (!nskb)
- return NF_DROP;
- if ((*pskb)->sk)
- skb_set_owner_w(nskb, (*pskb)->sk);
- kfree_skb(*pskb);
- *pskb = nskb;
- }
- memcpy(eth_hdr(*pskb)->h_source, info->mac, ETH_ALEN);
+ memcpy(eth_hdr(skb)->h_source, info->mac, ETH_ALEN);
if (!(info->target & NAT_ARP_BIT) &&
- eth_hdr(*pskb)->h_proto == htons(ETH_P_ARP)) {
+ eth_hdr(skb)->h_proto == htons(ETH_P_ARP)) {
struct arphdr _ah, *ap;
- ap = skb_header_pointer(*pskb, 0, sizeof(_ah), &_ah);
+ ap = skb_header_pointer(skb, 0, sizeof(_ah), &_ah);
if (ap == NULL)
return EBT_DROP;
if (ap->ar_hln != ETH_ALEN)
goto out;
- if (skb_store_bits(*pskb, sizeof(_ah), info->mac,ETH_ALEN))
+ if (skb_store_bits(skb, sizeof(_ah), info->mac,ETH_ALEN))
return EBT_DROP;
}
out: