netfilter: nf_queue: move device refcount bump to extra function
authorFlorian Westphal <fw@strlen.de>
Fri, 19 Apr 2013 04:58:23 +0000 (04:58 +0000)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 29 Apr 2013 18:09:04 +0000 (20:09 +0200)
required by future patch that will need to duplicate the
nf_queue_entry, bumping refcounts of the copy.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
net/netfilter/nf_queue.c

index 5ccf01e..1d91e77 100644 (file)
@@ -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().
@@ -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;
 
@@ -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);