Commit 08d07f25 authored by Florian Westphal's avatar Florian Westphal
Browse files

netfilter: ctnetlink: remove refcounting in dying list dumping



There is no need to keep the object alive via refcount, use a cookie and
then use that as the skip hint for dump resumption.

Unlike the two earlier, similar patches in this file, this is a cleanup
without intended side effects.

Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
parent 5c69e0b3
Loading
Loading
Loading
Loading
+10 −29
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("List and change connection tracking table");

struct ctnetlink_list_dump_ctx {
	struct nf_conn *last;
	unsigned long last_id;
	unsigned int cpu;
	bool done;
};
@@ -1733,16 +1733,6 @@ static int ctnetlink_get_conntrack(struct sk_buff *skb,
	return nfnetlink_unicast(skb2, info->net, NETLINK_CB(skb).portid);
}

static int ctnetlink_done_list(struct netlink_callback *cb)
{
	struct ctnetlink_list_dump_ctx *ctx = (void *)cb->ctx;

	if (ctx->last)
		nf_ct_put(ctx->last);

	return 0;
}

#ifdef CONFIG_NF_CONNTRACK_EVENTS
static int ctnetlink_dump_one_entry(struct sk_buff *skb,
				    struct netlink_callback *cb,
@@ -1757,11 +1747,11 @@ static int ctnetlink_dump_one_entry(struct sk_buff *skb,
	if (l3proto && nf_ct_l3num(ct) != l3proto)
		return 0;

	if (ctx->last) {
		if (ct != ctx->last)
	if (ctx->last_id) {
		if (ctnetlink_get_id(ct) != ctx->last_id)
			return 0;

		ctx->last = NULL;
		ctx->last_id = 0;
	}

	/* We can't dump extension info for the unconfirmed
@@ -1775,12 +1765,8 @@ static int ctnetlink_dump_one_entry(struct sk_buff *skb,
				  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;
	}
	if (res < 0)
		ctx->last_id = ctnetlink_get_id(ct);

	return res;
}
@@ -1796,10 +1782,10 @@ static int
ctnetlink_dump_dying(struct sk_buff *skb, struct netlink_callback *cb)
{
	struct ctnetlink_list_dump_ctx *ctx = (void *)cb->ctx;
	struct nf_conn *last = ctx->last;
#ifdef CONFIG_NF_CONNTRACK_EVENTS
	const struct net *net = sock_net(skb->sk);
	struct nf_conntrack_net_ecache *ecache_net;
	unsigned long last_id = ctx->last_id;
	struct nf_conntrack_tuple_hash *h;
	struct hlist_nulls_node *n;
#endif
@@ -1807,7 +1793,7 @@ ctnetlink_dump_dying(struct sk_buff *skb, struct netlink_callback *cb)
	if (ctx->done)
		return 0;

	ctx->last = NULL;
	ctx->last_id = 0;

#ifdef CONFIG_NF_CONNTRACK_EVENTS
	ecache_net = nf_conn_pernet_ecache(net);
@@ -1818,24 +1804,21 @@ ctnetlink_dump_dying(struct sk_buff *skb, struct netlink_callback *cb)
		int res;

		ct = nf_ct_tuplehash_to_ctrack(h);
		if (last && last != ct)
		if (last_id && last_id != ctnetlink_get_id(ct))
			continue;

		res = ctnetlink_dump_one_entry(skb, cb, ct, true);
		if (res < 0) {
			spin_unlock_bh(&ecache_net->dying_lock);
			nf_ct_put(last);
			return skb->len;
		}

		nf_ct_put(last);
		last = NULL;
		last_id = 0;
	}

	spin_unlock_bh(&ecache_net->dying_lock);
#endif
	ctx->done = true;
	nf_ct_put(last);

	return skb->len;
}
@@ -1847,7 +1830,6 @@ static int ctnetlink_get_ct_dying(struct sk_buff *skb,
	if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
		struct netlink_dump_control c = {
			.dump = ctnetlink_dump_dying,
			.done = ctnetlink_done_list,
		};
		return netlink_dump_start(info->sk, skb, info->nlh, &c);
	}
@@ -1862,7 +1844,6 @@ static int ctnetlink_get_ct_unconfirmed(struct sk_buff *skb,
	if (info->nlh->nlmsg_flags & NLM_F_DUMP) {
		struct netlink_dump_control c = {
			.dump = ctnetlink_dump_unconfirmed,
			.done = ctnetlink_done_list,
		};
		return netlink_dump_start(info->sk, skb, info->nlh, &c);
	}