diff options
| author | Bart De Schuymer <bdschuym@pandora.be> | 2003-07-20 15:06:00 -0700 |
|---|---|---|
| committer | David S. Miller <davem@nuts.ninka.net> | 2003-07-20 15:06:00 -0700 |
| commit | 3348a8943522066d16a8653b6de3df0587cf8d15 (patch) | |
| tree | cfde6a24ec07ff844e674c7e435d5ed5db8ccd72 /net | |
| parent | 900eb6a5f7b969ea91f7ba765bf9442c50f1a619 (diff) | |
[EBTABLES]: Copy skb when shared.
Diffstat (limited to 'net')
| -rw-r--r-- | net/bridge/netfilter/ebt_dnat.c | 11 | ||||
| -rw-r--r-- | net/bridge/netfilter/ebt_redirect.c | 11 | ||||
| -rw-r--r-- | net/bridge/netfilter/ebt_snat.c | 12 |
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; |
