Commit a2dd0233 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

netfilter: nf_tables: remove busy mark and gc batch API



Ditch it, it has been replace it by the GC transaction API and it has no
clients anymore.

Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent c92db303
Loading
Loading
Loading
Loading
+3 −95
Original line number Diff line number Diff line
@@ -599,7 +599,6 @@ struct nft_set *nft_set_lookup_global(const struct net *net,

struct nft_set_ext *nft_set_catchall_lookup(const struct net *net,
					    const struct nft_set *set);
void *nft_set_catchall_gc(const struct nft_set *set);

static inline unsigned long nft_set_gc_interval(const struct nft_set *set)
{
@@ -816,62 +815,6 @@ void nft_set_elem_destroy(const struct nft_set *set, void *elem,
void nf_tables_set_elem_destroy(const struct nft_ctx *ctx,
				const struct nft_set *set, void *elem);

/**
 *	struct nft_set_gc_batch_head - nf_tables set garbage collection batch
 *
 *	@rcu: rcu head
 *	@set: set the elements belong to
 *	@cnt: count of elements
 */
struct nft_set_gc_batch_head {
	struct rcu_head			rcu;
	const struct nft_set		*set;
	unsigned int			cnt;
};

#define NFT_SET_GC_BATCH_SIZE	((PAGE_SIZE -				  \
				  sizeof(struct nft_set_gc_batch_head)) / \
				 sizeof(void *))

/**
 *	struct nft_set_gc_batch - nf_tables set garbage collection batch
 *
 * 	@head: GC batch head
 * 	@elems: garbage collection elements
 */
struct nft_set_gc_batch {
	struct nft_set_gc_batch_head	head;
	void				*elems[NFT_SET_GC_BATCH_SIZE];
};

struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
						gfp_t gfp);
void nft_set_gc_batch_release(struct rcu_head *rcu);

static inline void nft_set_gc_batch_complete(struct nft_set_gc_batch *gcb)
{
	if (gcb != NULL)
		call_rcu(&gcb->head.rcu, nft_set_gc_batch_release);
}

static inline struct nft_set_gc_batch *
nft_set_gc_batch_check(const struct nft_set *set, struct nft_set_gc_batch *gcb,
		       gfp_t gfp)
{
	if (gcb != NULL) {
		if (gcb->head.cnt + 1 < ARRAY_SIZE(gcb->elems))
			return gcb;
		nft_set_gc_batch_complete(gcb);
	}
	return nft_set_gc_batch_alloc(set, gfp);
}

static inline void nft_set_gc_batch_add(struct nft_set_gc_batch *gcb,
					void *elem)
{
	gcb->elems[gcb->head.cnt++] = elem;
}

struct nft_expr_ops;
/**
 *	struct nft_expr_type - nf_tables expression type
@@ -1560,47 +1503,12 @@ static inline void nft_set_elem_change_active(const struct net *net,

#endif /* IS_ENABLED(CONFIG_NF_TABLES) */

/*
 * We use a free bit in the genmask field to indicate the element
 * is busy, meaning it is currently being processed either by
 * the netlink API or GC.
 *
 * Even though the genmask is only a single byte wide, this works
 * because the extension structure if fully constant once initialized,
 * so there are no non-atomic write accesses unless it is already
 * marked busy.
 */
#define NFT_SET_ELEM_BUSY_MASK	(1 << 2)

#if defined(__LITTLE_ENDIAN_BITFIELD)
#define NFT_SET_ELEM_BUSY_BIT	2
#elif defined(__BIG_ENDIAN_BITFIELD)
#define NFT_SET_ELEM_BUSY_BIT	(BITS_PER_LONG - BITS_PER_BYTE + 2)
#else
#error
#endif

static inline int nft_set_elem_mark_busy(struct nft_set_ext *ext)
{
	unsigned long *word = (unsigned long *)ext;

	BUILD_BUG_ON(offsetof(struct nft_set_ext, genmask) != 0);
	return test_and_set_bit(NFT_SET_ELEM_BUSY_BIT, word);
}

static inline void nft_set_elem_clear_busy(struct nft_set_ext *ext)
{
	unsigned long *word = (unsigned long *)ext;

	clear_bit(NFT_SET_ELEM_BUSY_BIT, word);
}

#define NFT_SET_ELEM_DEAD_MASK	(1 << 3)
#define NFT_SET_ELEM_DEAD_MASK	(1 << 2)

#if defined(__LITTLE_ENDIAN_BITFIELD)
#define NFT_SET_ELEM_DEAD_BIT	3
#define NFT_SET_ELEM_DEAD_BIT	2
#elif defined(__BIG_ENDIAN_BITFIELD)
#define NFT_SET_ELEM_DEAD_BIT	(BITS_PER_LONG - BITS_PER_BYTE + 3)
#define NFT_SET_ELEM_DEAD_BIT	(BITS_PER_LONG - BITS_PER_BYTE + 2)
#else
#error
#endif
+1 −47
Original line number Diff line number Diff line
@@ -6296,29 +6296,6 @@ struct nft_set_ext *nft_set_catchall_lookup(const struct net *net,
}
EXPORT_SYMBOL_GPL(nft_set_catchall_lookup);

void *nft_set_catchall_gc(const struct nft_set *set)
{
	struct nft_set_elem_catchall *catchall, *next;
	struct nft_set_ext *ext;
	void *elem = NULL;

	list_for_each_entry_safe(catchall, next, &set->catchall_list, list) {
		ext = nft_set_elem_ext(set, catchall->elem);

		if (!nft_set_elem_expired(ext) ||
		    nft_set_elem_mark_busy(ext))
			continue;

		elem = catchall->elem;
		list_del_rcu(&catchall->list);
		kfree_rcu(catchall, rcu);
		break;
	}

	return elem;
}
EXPORT_SYMBOL_GPL(nft_set_catchall_gc);

static int nft_setelem_catchall_insert(const struct net *net,
				       struct nft_set *set,
				       const struct nft_set_elem *elem,
@@ -6789,7 +6766,7 @@ static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set,
		goto err_elem_free;
	}

	ext->genmask = nft_genmask_cur(ctx->net) | NFT_SET_ELEM_BUSY_MASK;
	ext->genmask = nft_genmask_cur(ctx->net);

	err = nft_setelem_insert(ctx->net, set, &elem, &ext2, flags);
	if (err) {
@@ -7181,29 +7158,6 @@ static int nf_tables_delsetelem(struct sk_buff *skb,
	return err;
}

void nft_set_gc_batch_release(struct rcu_head *rcu)
{
	struct nft_set_gc_batch *gcb;
	unsigned int i;

	gcb = container_of(rcu, struct nft_set_gc_batch, head.rcu);
	for (i = 0; i < gcb->head.cnt; i++)
		nft_set_elem_destroy(gcb->head.set, gcb->elems[i], true);
	kfree(gcb);
}

struct nft_set_gc_batch *nft_set_gc_batch_alloc(const struct nft_set *set,
						gfp_t gfp)
{
	struct nft_set_gc_batch *gcb;

	gcb = kzalloc(sizeof(*gcb), gfp);
	if (gcb == NULL)
		return gcb;
	gcb->head.set = set;
	return gcb;
}

/*
 * Stateful objects
 */