Commit 3348a894 authored by Bart De Schuymer's avatar Bart De Schuymer Committed by David S. Miller

[EBTABLES]: Copy skb when shared.

parent 900eb6a5
...@@ -19,6 +19,17 @@ static int ebt_target_dnat(struct sk_buff **pskb, unsigned int hooknr, ...@@ -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; 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, memcpy(((**pskb).mac.ethernet)->h_dest, info->mac,
ETH_ALEN * sizeof(unsigned char)); ETH_ALEN * sizeof(unsigned char));
return info->target; return info->target;
......
...@@ -20,6 +20,17 @@ static int ebt_target_redirect(struct sk_buff **pskb, unsigned int hooknr, ...@@ -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; 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) if (hooknr != NF_BR_BROUTING)
memcpy((**pskb).mac.ethernet->h_dest, memcpy((**pskb).mac.ethernet->h_dest,
in->br_port->br->dev->dev_addr, ETH_ALEN); in->br_port->br->dev->dev_addr, ETH_ALEN);
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/netfilter_bridge/ebtables.h> #include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_nat.h> #include <linux/netfilter_bridge/ebt_nat.h>
#include <linux/module.h> #include <linux/module.h>
#include <net/sock.h>
static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr, static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr,
const struct net_device *in, const struct net_device *out, 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, ...@@ -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; 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, memcpy(((**pskb).mac.ethernet)->h_source, info->mac,
ETH_ALEN * sizeof(unsigned char)); ETH_ALEN * sizeof(unsigned char));
return info->target; return info->target;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment