diff options
author | Patrick McHardy <kaber@trash.net> | 2007-12-05 01:26:33 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 14:56:14 -0800 |
commit | 02f014d88831f73b895c1fe09badb66c88e932d3 (patch) | |
tree | 09aa75b8edeb240e62c4269f20630f8206c0e6d4 /net/netfilter/nf_queue.c | |
parent | 7a6c6653b3a977087ec64d76817c7ee6e1df5b60 (diff) | |
download | linux-stable-02f014d88831f73b895c1fe09badb66c88e932d3.tar.gz linux-stable-02f014d88831f73b895c1fe09badb66c88e932d3.tar.bz2 linux-stable-02f014d88831f73b895c1fe09badb66c88e932d3.zip |
[NETFILTER]: nf_queue: move list_head/skb/id to struct nf_info
Move common fields for queue management to struct nf_info and rename it
to struct nf_queue_entry. The avoids one allocation/free per packet and
simplifies the code a bit.
Alternatively we could add some private room at the tail, but since
all current users use identical structs this seems easier.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter/nf_queue.c')
-rw-r--r-- | net/netfilter/nf_queue.c | 65 |
1 files changed, 36 insertions, 29 deletions
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index bd71f433b85e..d9d3dc4ce1a3 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c @@ -93,7 +93,7 @@ static int __nf_queue(struct sk_buff *skb, unsigned int queuenum) { int status; - struct nf_info *info; + struct nf_queue_entry *entry; #ifdef CONFIG_BRIDGE_NETFILTER struct net_device *physindev = NULL; struct net_device *physoutdev = NULL; @@ -118,8 +118,8 @@ static int __nf_queue(struct sk_buff *skb, return 1; } - info = kmalloc(sizeof(*info) + afinfo->route_key_size, GFP_ATOMIC); - if (!info) { + entry = kmalloc(sizeof(*entry) + afinfo->route_key_size, GFP_ATOMIC); + if (!entry) { if (net_ratelimit()) printk(KERN_ERR "OOM queueing packet %p\n", skb); @@ -128,13 +128,20 @@ static int __nf_queue(struct sk_buff *skb, return 1; } - *info = (struct nf_info) { - (struct nf_hook_ops *)elem, pf, hook, indev, outdev, okfn }; + *entry = (struct nf_queue_entry) { + .skb = skb, + .elem = list_entry(elem, struct nf_hook_ops, list), + .pf = pf, + .hook = hook, + .indev = indev, + .outdev = outdev, + .okfn = okfn, + }; /* If it's going away, ignore hook. */ - if (!try_module_get(info->elem->owner)) { + if (!try_module_get(entry->elem->owner)) { rcu_read_unlock(); - kfree(info); + kfree(entry); return 0; } @@ -153,8 +160,8 @@ static int __nf_queue(struct sk_buff *skb, dev_hold(physoutdev); } #endif - afinfo->saveroute(skb, info); - status = qh->outfn(skb, info, queuenum); + afinfo->saveroute(skb, entry); + status = qh->outfn(entry, queuenum); rcu_read_unlock(); @@ -170,8 +177,8 @@ static int __nf_queue(struct sk_buff *skb, if (physoutdev) dev_put(physoutdev); #endif - module_put(info->elem->owner); - kfree(info); + module_put(entry->elem->owner); + kfree(entry); kfree_skb(skb); return 1; @@ -220,19 +227,19 @@ int nf_queue(struct sk_buff *skb, return 1; } -void nf_reinject(struct sk_buff *skb, struct nf_info *info, - unsigned int verdict) +void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) { - struct list_head *elem = &info->elem->list; + struct sk_buff *skb = entry->skb; + struct list_head *elem = &entry->elem->list; struct nf_afinfo *afinfo; rcu_read_lock(); /* Release those devices we held, or Alexey will kill me. */ - if (info->indev) - dev_put(info->indev); - if (info->outdev) - dev_put(info->outdev); + if (entry->indev) + dev_put(entry->indev); + if (entry->outdev) + dev_put(entry->outdev); #ifdef CONFIG_BRIDGE_NETFILTER if (skb->nf_bridge) { if (skb->nf_bridge->physindev) @@ -243,7 +250,7 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, #endif /* Drop reference to owner of hook which queued us. */ - module_put(info->elem->owner); + module_put(entry->elem->owner); /* Continue traversal iff userspace said ok... */ if (verdict == NF_REPEAT) { @@ -252,28 +259,28 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, } if (verdict == NF_ACCEPT) { - afinfo = nf_get_afinfo(info->pf); - if (!afinfo || afinfo->reroute(skb, info) < 0) + afinfo = nf_get_afinfo(entry->pf); + if (!afinfo || afinfo->reroute(skb, entry) < 0) verdict = NF_DROP; } if (verdict == NF_ACCEPT) { next_hook: - verdict = nf_iterate(&nf_hooks[info->pf][info->hook], - skb, info->hook, - info->indev, info->outdev, &elem, - info->okfn, INT_MIN); + verdict = nf_iterate(&nf_hooks[entry->pf][entry->hook], + skb, entry->hook, + entry->indev, entry->outdev, &elem, + entry->okfn, INT_MIN); } switch (verdict & NF_VERDICT_MASK) { case NF_ACCEPT: case NF_STOP: - info->okfn(skb); + entry->okfn(skb); case NF_STOLEN: break; case NF_QUEUE: - if (!__nf_queue(skb, elem, info->pf, info->hook, - info->indev, info->outdev, info->okfn, + if (!__nf_queue(skb, elem, entry->pf, entry->hook, + entry->indev, entry->outdev, entry->okfn, verdict >> NF_VERDICT_BITS)) goto next_hook; break; @@ -281,7 +288,7 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info, kfree_skb(skb); } rcu_read_unlock(); - kfree(info); + kfree(entry); return; } EXPORT_SYMBOL(nf_reinject); |