return 0;
 }
 
+static int ctnetlink_dump_one_entry(struct sk_buff *skb,
+                                   struct netlink_callback *cb,
+                                   struct nf_conn *ct,
+                                   bool dying)
+{
+       struct ctnetlink_list_dump_ctx *ctx = (void *)cb->ctx;
+       struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
+       u8 l3proto = nfmsg->nfgen_family;
+       int res;
+
+       if (l3proto && nf_ct_l3num(ct) != l3proto)
+               return 0;
+
+       if (ctx->last) {
+               if (ct != ctx->last)
+                       return 0;
+
+               ctx->last = NULL;
+       }
+
+       /* We can't dump extension info for the unconfirmed
+        * list because unconfirmed conntracks can have
+        * ct->ext reallocated (and thus freed).
+        *
+        * In the dying list case ct->ext can't be free'd
+        * until after we drop pcpu->lock.
+        */
+       res = ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).portid,
+                                 cb->nlh->nlmsg_seq,
+                                 NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
+                                 ct, dying, 0);
+       if (res < 0) {
+               if (!refcount_inc_not_zero(&ct->ct_general.use))
+                       return 0;
+
+               ctx->last = ct;
+       }
+
+       return res;
+}
+
 static int
 ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying)
 {
        struct nf_conn *ct, *last;
        struct nf_conntrack_tuple_hash *h;
        struct hlist_nulls_node *n;
-       struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
-       u_int8_t l3proto = nfmsg->nfgen_family;
-       int res;
-       int cpu;
        struct hlist_nulls_head *list;
        struct net *net = sock_net(skb->sk);
+       int res, cpu;
 
        if (ctx->done)
                return 0;
 restart:
                hlist_nulls_for_each_entry(h, n, list, hnnode) {
                        ct = nf_ct_tuplehash_to_ctrack(h);
-                       if (l3proto && nf_ct_l3num(ct) != l3proto)
-                               continue;
-                       if (ctx->last) {
-                               if (ct != last)
-                                       continue;
-                               ctx->last = NULL;
-                       }
 
-                       /* We can't dump extension info for the unconfirmed
-                        * list because unconfirmed conntracks can have
-                        * ct->ext reallocated (and thus freed).
-                        *
-                        * In the dying list case ct->ext can't be free'd
-                        * until after we drop pcpu->lock.
-                        */
-                       res = ctnetlink_fill_info(skb, NETLINK_CB(cb->skb).portid,
-                                                 cb->nlh->nlmsg_seq,
-                                                 NFNL_MSG_TYPE(cb->nlh->nlmsg_type),
-                                                 ct, dying, 0);
+                       res = ctnetlink_dump_one_entry(skb, cb, ct, dying);
                        if (res < 0) {
-                               if (!refcount_inc_not_zero(&ct->ct_general.use))
-                                       continue;
                                ctx->cpu = cpu;
-                               ctx->last = ct;
                                spin_unlock_bh(&pcpu->lock);
                                goto out;
                        }