summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorBart De Schuymer <bdschuym@pandora.be>2003-07-20 15:06:00 -0700
committerDavid S. Miller <davem@nuts.ninka.net>2003-07-20 15:06:00 -0700
commit3348a8943522066d16a8653b6de3df0587cf8d15 (patch)
treecfde6a24ec07ff844e674c7e435d5ed5db8ccd72 /net
parent900eb6a5f7b969ea91f7ba765bf9442c50f1a619 (diff)
[EBTABLES]: Copy skb when shared.
Diffstat (limited to 'net')
-rw-r--r--net/bridge/netfilter/ebt_dnat.c11
-rw-r--r--net/bridge/netfilter/ebt_redirect.c11
-rw-r--r--net/bridge/netfilter/ebt_snat.c12
3 files changed, 34 insertions, 0 deletions
diff --git a/net/bridge/netfilter/ebt_dnat.c b/net/bridge/netfilter/ebt_dnat.c
index fd9a6245ccb3..c8b3357cc090 100644
--- a/net/bridge/netfilter/ebt_dnat.c
+++ b/net/bridge/netfilter/ebt_dnat.c
@@ -19,6 +19,17 @@ static int ebt_target_dnat(struct sk_buff **pskb, unsigned int hooknr,
{
struct ebt_nat_info *info = (struct ebt_nat_info *)data;
+ if (skb_shared(*pskb) || skb_cloned(*pskb)) {
+ struct sk_buff *nskb;
+
+ 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(((**pskb).mac.ethernet)->h_dest, info->mac,
ETH_ALEN * sizeof(unsigned char));
return info->target;
diff --git a/net/bridge/netfilter/ebt_redirect.c b/net/bridge/netfilter/ebt_redirect.c
index be4346095c67..d97d05fdd14f 100644
--- a/net/bridge/netfilter/ebt_redirect.c
+++ b/net/bridge/netfilter/ebt_redirect.c
@@ -20,6 +20,17 @@ static int ebt_target_redirect(struct sk_buff **pskb, unsigned int hooknr,
{
struct ebt_redirect_info *info = (struct ebt_redirect_info *)data;
+ if (skb_shared(*pskb) || skb_cloned(*pskb)) {
+ struct sk_buff *nskb;
+
+ 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;
+ }
if (hooknr != NF_BR_BROUTING)
memcpy((**pskb).mac.ethernet->h_dest,
in->br_port->br->dev->dev_addr, ETH_ALEN);
diff --git a/net/bridge/netfilter/ebt_snat.c b/net/bridge/netfilter/ebt_snat.c
index 3c0a6506d846..c457ac90c5c6 100644
--- a/net/bridge/netfilter/ebt_snat.c
+++ b/net/bridge/netfilter/ebt_snat.c
@@ -11,6 +11,7 @@
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h>
#include <linux/module.h>
+#include <net/sock.h>
static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out,
@@ -18,6 +19,17 @@ static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr,
{
struct ebt_nat_info *info = (struct ebt_nat_info *) data;
+ if (skb_shared(*pskb) || skb_cloned(*pskb)) {
+ struct sk_buff *nskb;
+
+ 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(((**pskb).mac.ethernet)->h_source, info->mac,
ETH_ALEN * sizeof(unsigned char));
return info->target;