Commit 4bd60443 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

netfilter: nf_queue: move device refcount bump to extra function

required by future patch that will need to duplicate the
nf_queue_entry, bumping refcounts of the copy.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 6e01781d
...@@ -66,6 +66,33 @@ static void nf_queue_entry_release_refs(struct nf_queue_entry *entry) ...@@ -66,6 +66,33 @@ static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
module_put(entry->elem->owner); module_put(entry->elem->owner);
} }
/* Bump dev refs so they don't vanish while packet is out */
static bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
{
if (!try_module_get(entry->elem->owner))
return false;
if (entry->indev)
dev_hold(entry->indev);
if (entry->outdev)
dev_hold(entry->outdev);
#ifdef CONFIG_BRIDGE_NETFILTER
if (entry->skb->nf_bridge) {
struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
struct net_device *physdev;
physdev = nf_bridge->physindev;
if (physdev)
dev_hold(physdev);
physdev = nf_bridge->physoutdev;
if (physdev)
dev_hold(physdev);
}
#endif
return true;
}
/* /*
* Any packet that leaves via this function must come back * Any packet that leaves via this function must come back
* through nf_reinject(). * through nf_reinject().
...@@ -80,10 +107,6 @@ static int __nf_queue(struct sk_buff *skb, ...@@ -80,10 +107,6 @@ static int __nf_queue(struct sk_buff *skb,
{ {
int status = -ENOENT; int status = -ENOENT;
struct nf_queue_entry *entry = NULL; struct nf_queue_entry *entry = NULL;
#ifdef CONFIG_BRIDGE_NETFILTER
struct net_device *physindev;
struct net_device *physoutdev;
#endif
const struct nf_afinfo *afinfo; const struct nf_afinfo *afinfo;
const struct nf_queue_handler *qh; const struct nf_queue_handler *qh;
...@@ -116,26 +139,10 @@ static int __nf_queue(struct sk_buff *skb, ...@@ -116,26 +139,10 @@ static int __nf_queue(struct sk_buff *skb,
.okfn = okfn, .okfn = okfn,
}; };
/* If it's going away, ignore hook. */ if (!nf_queue_entry_get_refs(entry)) {
if (!try_module_get(entry->elem->owner)) {
status = -ECANCELED; status = -ECANCELED;
goto err_unlock; goto err_unlock;
} }
/* Bump dev refs so they don't vanish while packet is out */
if (indev)
dev_hold(indev);
if (outdev)
dev_hold(outdev);
#ifdef CONFIG_BRIDGE_NETFILTER
if (skb->nf_bridge) {
physindev = skb->nf_bridge->physindev;
if (physindev)
dev_hold(physindev);
physoutdev = skb->nf_bridge->physoutdev;
if (physoutdev)
dev_hold(physoutdev);
}
#endif
skb_dst_force(skb); skb_dst_force(skb);
afinfo->saveroute(skb, entry); afinfo->saveroute(skb, entry);
status = qh->outfn(entry, queuenum); status = qh->outfn(entry, queuenum);
......
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