net/netfilter/nft_set_pipapo.c

Source file repositories/reference/linux-study-clean/net/netfilter/nft_set_pipapo.c

File Facts

System
Linux kernel
Corpus path
net/netfilter/nft_set_pipapo.c
Extension
.c
Size
70842 bytes
Lines
2443
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

while (bitset) {
			unsigned long t = bitset & -bitset;
			int r = __builtin_ctzl(bitset);
			int i = k * BITS_PER_LONG + r;

			if (unlikely(i >= rules)) {
				map[k] = 0;
				return -1;
			}

			if (match_only) {
				bitmap_clear(map, i, 1);
				return i;
			}

			ret = 0;

			bitmap_set(dst, mt[i].to, mt[i].n);

			bitset ^= t;
		}
		map[k] = 0;
	}

	return ret;
}

/**
 * pipapo_get_slow() - Get matching element reference given key data
 * @m:		storage containing the set elements
 * @data:	Key data to be matched against existing elements
 * @genmask:	If set, check that element is active in given genmask
 * @tstamp:	timestamp to check for expired elements
 *
 * For more details, see DOC: Theory of Operation.
 *
 * This is the main lookup function.  It matches key data against either
 * the working match set or the uncommitted copy, depending on what the
 * caller passed to us.
 * nft_pipapo_get (lookup from userspace/control plane) and nft_pipapo_lookup
 * (datapath lookup) pass the active copy.
 * The insertion path will pass the uncommitted working copy.
 *
 * Return: pointer to &struct nft_pipapo_elem on match, NULL otherwise.
 */
static struct nft_pipapo_elem *pipapo_get_slow(const struct nft_pipapo_match *m,
					       const u8 *data, u8 genmask,
					       u64 tstamp)
{
	unsigned long *res_map, *fill_map, *map;
	struct nft_pipapo_scratch *scratch;
	const struct nft_pipapo_field *f;
	bool map_index;
	int i;

	local_bh_disable();

	scratch = *raw_cpu_ptr(m->scratch);
	if (unlikely(!scratch))
		goto out;
	__local_lock_nested_bh(&scratch->bh_lock);

	map_index = scratch->map_index;

	map = NFT_PIPAPO_LT_ALIGN(&scratch->__map[0]);
	res_map  = map + (map_index ? m->bsize_max : 0);
	fill_map = map + (map_index ? 0 : m->bsize_max);

	pipapo_resmap_init(m, res_map);

	nft_pipapo_for_each_field(f, i, m) {
		bool last = i == m->field_count - 1;
		int b;

		/* For each bit group: select lookup table bucket depending on
		 * packet bytes value, then AND bucket value
		 */
		if (likely(f->bb == 8))
			pipapo_and_field_buckets_8bit(f, res_map, data);
		else
			pipapo_and_field_buckets_4bit(f, res_map, data);
		NFT_PIPAPO_GROUP_BITS_ARE_8_OR_4;

		/* Now populate the bitmap for the next field, unless this is
		 * the last field, in which case return the matched 'ext'
		 * pointer if any.
		 *
		 * Now res_map contains the matching bitmap, and fill_map is the
		 * bitmap for the next field.
		 */

Annotation

Implementation Notes