Commit 2ca7b0ac authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller
Browse files

[NETFILTER]: Avoid skb_copy/pskb_copy/skb_realloc_headroom



This patch replaces unnecessary uses of skb_copy, pskb_copy and
skb_realloc_headroom by functions such as skb_make_writable and
pskb_expand_head.

This allows us to remove the double pointers later.

Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent af1e1cf0
Loading
Loading
Loading
Loading
+3 −10
Original line number Diff line number Diff line
@@ -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>
@@ -19,17 +20,9 @@ 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)
	if (skb_make_writable(*pskb, 0))
		return NF_DROP;
		if ((*pskb)->sk)
			skb_set_owner_w(nskb, (*pskb)->sk);
		kfree_skb(*pskb);
		*pskb = nskb;
	}

	memcpy(eth_hdr(*pskb)->h_dest, info->mac, ETH_ALEN);
	return info->target;
}
+3 −10
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@
 *
 */

#include <linux/netfilter.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <linux/netfilter_bridge/ebt_redirect.h>
#include <linux/module.h>
@@ -20,17 +21,9 @@ 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)
	if (skb_make_writable(*pskb, 0))
		return NF_DROP;
		if ((*pskb)->sk)
			skb_set_owner_w(nskb, (*pskb)->sk);
		kfree_skb(*pskb);
		*pskb = nskb;
	}

	if (hooknr != NF_BR_BROUTING)
		memcpy(eth_hdr(*pskb)->h_dest,
		       in->br_port->br->dev->dev_addr, ETH_ALEN);
+3 −10
Original line number Diff line number Diff line
@@ -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>
@@ -21,17 +22,9 @@ 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)
	if (skb_make_writable(*pskb, 0))
		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);
	if (!(info->target & NAT_ARP_BIT) &&
	    eth_hdr(*pskb)->h_proto == htons(ETH_P_ARP)) {
+9 −22
Original line number Diff line number Diff line
@@ -3,6 +3,7 @@
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/ip.h>
#include <linux/skbuff.h>
#include <net/route.h>
#include <net/xfrm.h>
#include <net/ip.h>
@@ -66,17 +67,10 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)

	/* Change in oif may mean change in hh_len. */
	hh_len = (*pskb)->dst->dev->hard_header_len;
	if (skb_headroom(*pskb) < hh_len) {
		struct sk_buff *nskb;

		nskb = skb_realloc_headroom(*pskb, hh_len);
		if (!nskb)
	if (skb_headroom(*pskb) < hh_len &&
	    pskb_expand_head(*pskb, hh_len - skb_headroom(*pskb), 0,
			     GFP_ATOMIC))
		return -1;
		if ((*pskb)->sk)
			skb_set_owner_w(nskb, (*pskb)->sk);
		kfree_skb(*pskb);
		*pskb = nskb;
	}

	return 0;
}
@@ -107,17 +101,10 @@ int ip_xfrm_me_harder(struct sk_buff **pskb)

	/* Change in oif may mean change in hh_len. */
	hh_len = (*pskb)->dst->dev->hard_header_len;
	if (skb_headroom(*pskb) < hh_len) {
		struct sk_buff *nskb;

		nskb = skb_realloc_headroom(*pskb, hh_len);
		if (!nskb)
	if (skb_headroom(*pskb) < hh_len &&
	    pskb_expand_head(*pskb, hh_len - skb_headroom(*pskb), 0,
			     GFP_ATOMIC))
		return -1;
		if ((*pskb)->sk)
			skb_set_owner_w(nskb, (*pskb)->sk);
		kfree_skb(*pskb);
		*pskb = nskb;
	}
	return 0;
}
EXPORT_SYMBOL(ip_xfrm_me_harder);
+3 −11
Original line number Diff line number Diff line
/* module that allows mangling of the arp payload */
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_arp/arpt_mangle.h>
#include <net/sock.h>

@@ -18,17 +19,8 @@ target(struct sk_buff **pskb,
	unsigned char *arpptr;
	int pln, hln;

	if (skb_shared(*pskb) || skb_cloned(*pskb)) {
		struct sk_buff *nskb;

		nskb = skb_copy(*pskb, GFP_ATOMIC);
		if (!nskb)
	if (skb_make_writable(*pskb, (*pskb)->len))
		return NF_DROP;
		if ((*pskb)->sk)
			skb_set_owner_w(nskb, (*pskb)->sk);
		kfree_skb(*pskb);
		*pskb = nskb;
	}

	arp = arp_hdr(*pskb);
	arpptr = skb_network_header(*pskb) + sizeof(*arp);
Loading