X-Git-Url: http://pilppa.org/gitweb/?a=blobdiff_plain;f=net%2Fnetfilter%2Fcore.c;h=bed9ba01e8eced0641d9f293b45ab2e68e32c26b;hb=921314811be704252ad2caa8dde507d4c421ddc4;hp=381a77cf0c9eb83c5900fb775f6e38a5fcd4b7ad;hpb=dc690d8ef842b464f1c429a376ca16cb8dbee6ae;p=linux-2.6-omap-h63xx.git diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 381a77cf0c9..bed9ba01e8e 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "nf_internals.h" @@ -116,7 +117,7 @@ void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n) EXPORT_SYMBOL(nf_unregister_hooks); unsigned int nf_iterate(struct list_head *head, - struct sk_buff **skb, + struct sk_buff *skb, int hook, const struct net_device *indev, const struct net_device *outdev, @@ -159,7 +160,7 @@ unsigned int nf_iterate(struct list_head *head, /* Returns 1 if okfn() needs to be executed by the caller, * -EPERM for NF_DROP, 0 otherwise. */ -int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb, +int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, struct net_device *indev, struct net_device *outdev, int (*okfn)(struct sk_buff *), @@ -174,17 +175,17 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff **pskb, elem = &nf_hooks[pf][hook]; next_hook: - verdict = nf_iterate(&nf_hooks[pf][hook], pskb, hook, indev, + verdict = nf_iterate(&nf_hooks[pf][hook], skb, hook, indev, outdev, &elem, okfn, hook_thresh); if (verdict == NF_ACCEPT || verdict == NF_STOP) { ret = 1; goto unlock; } else if (verdict == NF_DROP) { - kfree_skb(*pskb); + kfree_skb(skb); ret = -EPERM; } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { NFDEBUG("nf_hook: Verdict = QUEUE.\n"); - if (!nf_queue(*pskb, elem, pf, hook, indev, outdev, okfn, + if (!nf_queue(skb, elem, pf, hook, indev, outdev, okfn, verdict >> NF_VERDICT_BITS)) goto next_hook; } @@ -195,34 +196,24 @@ unlock: EXPORT_SYMBOL(nf_hook_slow); -int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len) +int skb_make_writable(struct sk_buff *skb, unsigned int writable_len) { - struct sk_buff *nskb; - - if (writable_len > (*pskb)->len) + if (writable_len > skb->len) return 0; /* Not exclusive use of packet? Must copy. */ - if (skb_cloned(*pskb) && !skb_clone_writable(*pskb, writable_len)) - goto copy_skb; - if (skb_shared(*pskb)) - goto copy_skb; - - return pskb_may_pull(*pskb, writable_len); - -copy_skb: - nskb = skb_copy(*pskb, GFP_ATOMIC); - if (!nskb) - return 0; - BUG_ON(skb_is_nonlinear(nskb)); - - /* Rest of kernel will get very unhappy if we pass it a - suddenly-orphaned skbuff */ - if ((*pskb)->sk) - skb_set_owner_w(nskb, (*pskb)->sk); - kfree_skb(*pskb); - *pskb = nskb; - return 1; + if (!skb_cloned(skb)) { + if (writable_len <= skb_headlen(skb)) + return 1; + } else if (skb_clone_writable(skb, writable_len)) + return 1; + + if (writable_len <= skb_headlen(skb)) + writable_len = 0; + else + writable_len -= skb_headlen(skb); + + return !!__pskb_pull_tail(skb, writable_len); } EXPORT_SYMBOL(skb_make_writable); @@ -293,7 +284,7 @@ void __init netfilter_init(void) } #ifdef CONFIG_PROC_FS - proc_net_netfilter = proc_mkdir("netfilter", proc_net); + proc_net_netfilter = proc_mkdir("netfilter", init_net.proc_net); if (!proc_net_netfilter) panic("cannot create netfilter proc entry"); #endif