[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: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Herbert Xu
2007-10-14 00:39:55 -07:00
committed by David S. Miller
parent af1e1cf073
commit 2ca7b0ac02
10 changed files with 45 additions and 117 deletions

View File

@@ -1,5 +1,6 @@
/* 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)
return NF_DROP;
if ((*pskb)->sk)
skb_set_owner_w(nskb, (*pskb)->sk);
kfree_skb(*pskb);
*pskb = nskb;
}
if (skb_make_writable(*pskb, (*pskb)->len))
return NF_DROP;
arp = arp_hdr(*pskb);
arpptr = skb_network_header(*pskb) + sizeof(*arp);

View File

@@ -335,6 +335,7 @@ static int
ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
{
int diff;
int err;
struct iphdr *user_iph = (struct iphdr *)v->payload;
if (v->data_len < sizeof(*user_iph))
@@ -347,21 +348,14 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
if (v->data_len > 0xFFFF)
return -EINVAL;
if (diff > skb_tailroom(e->skb)) {
struct sk_buff *newskb;
newskb = skb_copy_expand(e->skb,
skb_headroom(e->skb),
diff,
GFP_ATOMIC);
if (newskb == NULL) {
printk(KERN_WARNING "ip_queue: OOM "
"in mangle, dropping packet\n");
return -ENOMEM;
err = pskb_expand_head(e->skb, 0,
diff - skb_tailroom(e->skb),
GFP_ATOMIC);
if (err) {
printk(KERN_WARNING "ip_queue: error "
"in mangle, dropping packet: %d\n", -err);
return err;
}
if (e->skb->sk)
skb_set_owner_w(newskb, e->skb->sk);
kfree_skb(e->skb);
e->skb = newskb;
}
skb_put(e->skb, diff);
}

View File

@@ -113,20 +113,12 @@ static void mangle_contents(struct sk_buff *skb,
/* Unusual, but possible case. */
static int enlarge_skb(struct sk_buff **pskb, unsigned int extra)
{
struct sk_buff *nskb;
if ((*pskb)->len + extra > 65535)
return 0;
nskb = skb_copy_expand(*pskb, skb_headroom(*pskb), extra, GFP_ATOMIC);
if (!nskb)
if (pskb_expand_head(*pskb, 0, extra - skb_tailroom(*pskb), GFP_ATOMIC))
return 0;
/* Transfer socket to new skb. */
if ((*pskb)->sk)
skb_set_owner_w(nskb, (*pskb)->sk);
kfree_skb(*pskb);
*pskb = nskb;
return 1;
}