Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 369818
b: refs/heads/master
c: 4bd6044
h: refs/heads/master
v: v3
  • Loading branch information
Florian Westphal authored and Pablo Neira Ayuso committed Apr 29, 2013
1 parent d9ff5f6 commit ddaf72f
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 22 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6e01781d1c80e2e8263471252a631e86165b15c5
refs/heads/master: 4bd60443cc44c93ff37d483d69674647a0c48e4e
49 changes: 28 additions & 21 deletions trunk/net/netfilter/nf_queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,33 @@ static void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
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
* through nf_reinject().
Expand All @@ -80,10 +107,6 @@ static int __nf_queue(struct sk_buff *skb,
{
int status = -ENOENT;
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_queue_handler *qh;

Expand Down Expand Up @@ -116,26 +139,10 @@ static int __nf_queue(struct sk_buff *skb,
.okfn = okfn,
};

/* If it's going away, ignore hook. */
if (!try_module_get(entry->elem->owner)) {
if (!nf_queue_entry_get_refs(entry)) {
status = -ECANCELED;
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);
afinfo->saveroute(skb, entry);
status = qh->outfn(entry, queuenum);
Expand Down

0 comments on commit ddaf72f

Please sign in to comment.