Commit 49001a2e authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso
Browse files

netfilter: conntrack: split inner loop of list dumping to own function



This allows code re-use in the followup patch.
No functional changes intended.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 9027ce0b
Loading
Loading
Loading
Loading
+43 −25
Original line number Diff line number Diff line
@@ -1708,6 +1708,47 @@ static int ctnetlink_done_list(struct netlink_callback *cb)
	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)
{
@@ -1715,12 +1756,9 @@ 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;
@@ -1739,30 +1777,10 @@ ctnetlink_dump_list(struct sk_buff *skb, struct netlink_callback *cb, bool dying
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;
			}