linux/net/netfilter/nft_set_pipapo.h

// SPDX-License-Identifier: GPL-2.0-only

#ifndef _NFT_SET_PIPAPO_H

#include <linux/log2.h>
#include <net/ipv6.h>			/* For the maximum length of a field */

/* Count of concatenated fields depends on count of 32-bit nftables registers */
#define NFT_PIPAPO_MAX_FIELDS

/* Restrict usage to multiple fields, make sure rbtree is used otherwise */
#define NFT_PIPAPO_MIN_FIELDS

/* Largest supported field size */
#define NFT_PIPAPO_MAX_BYTES
#define NFT_PIPAPO_MAX_BITS

/* Bits to be grouped together in table buckets depending on set size */
#define NFT_PIPAPO_GROUP_BITS_INIT
#define NFT_PIPAPO_GROUP_BITS_SMALL_SET
#define NFT_PIPAPO_GROUP_BITS_LARGE_SET
#define NFT_PIPAPO_GROUP_BITS_ARE_8_OR_4
#define NFT_PIPAPO_GROUPS_PER_BYTE(f)

/* If a lookup table gets bigger than NFT_PIPAPO_LT_SIZE_HIGH, switch to the
 * small group width, and switch to the big group width if the table gets
 * smaller than NFT_PIPAPO_LT_SIZE_LOW.
 *
 * Picking 2MiB as threshold (for a single table) avoids as much as possible
 * crossing page boundaries on most architectures (x86-64 and MIPS huge pages,
 * ARMv7 supersections, POWER "large" pages, SPARC Level 1 regions, etc.), which
 * keeps performance nice in case kvmalloc() gives us non-contiguous areas.
 */
#define NFT_PIPAPO_LT_SIZE_THRESHOLD
#define NFT_PIPAPO_LT_SIZE_HYSTERESIS
#define NFT_PIPAPO_LT_SIZE_HIGH
#define NFT_PIPAPO_LT_SIZE_LOW

/* Fields are padded to 32 bits in input registers */
#define NFT_PIPAPO_GROUPS_PADDED_SIZE(f)
#define NFT_PIPAPO_GROUPS_PADDING(f)

/* Number of buckets given by 2 ^ n, with n bucket bits */
#define NFT_PIPAPO_BUCKETS(bb)

/* Each n-bit range maps to up to n * 2 rules */
#define NFT_PIPAPO_MAP_NBITS

/* Use the rest of mapping table buckets for rule indices, but it makes no sense
 * to exceed 32 bits
 */
#if BITS_PER_LONG == 64
#define NFT_PIPAPO_MAP_TOBITS
#else
#define NFT_PIPAPO_MAP_TOBITS
#endif

/* ...which gives us the highest allowed index for a rule */
#define NFT_PIPAPO_RULE0_MAX

/* Definitions for vectorised implementations */
#ifdef NFT_PIPAPO_ALIGN
#define NFT_PIPAPO_ALIGN_HEADROOM
#define NFT_PIPAPO_LT_ALIGN(lt)
#else
#define NFT_PIPAPO_ALIGN_HEADROOM
#define NFT_PIPAPO_LT_ALIGN
#endif /* NFT_PIPAPO_ALIGN */

#define nft_pipapo_for_each_field(field, index, match)

/**
 * union nft_pipapo_map_bucket - Bucket of mapping table
 * @to:		First rule number (in next field) this rule maps to
 * @n:		Number of rules (in next field) this rule maps to
 * @e:		If there's no next field, pointer to element this rule maps to
 */
nft_pipapo_map_bucket;

/**
 * struct nft_pipapo_field - Lookup, mapping tables and related data for a field
 * @rules:	Number of inserted rules
 * @bsize:	Size of each bucket in lookup table, in longs
 * @rules_alloc: Number of allocated rules, always >= rules
 * @groups:	Amount of bit groups
 * @bb:		Number of bits grouped together in lookup table buckets
 * @lt:		Lookup table: 'groups' rows of buckets
 * @mt:		Mapping table: one bucket per rule
 */
struct nft_pipapo_field {};

/**
 * struct nft_pipapo_scratch - percpu data used for lookup and matching
 * @map_index:	Current working bitmap index, toggled between field matches
 * @align_off:	Offset to get the originally allocated address
 * @map:	store partial matching results during lookup
 */
struct nft_pipapo_scratch {};

/**
 * struct nft_pipapo_match - Data used for lookup and matching
 * @field_count:	Amount of fields in set
 * @bsize_max:		Maximum lookup table bucket size of all fields, in longs
 * @scratch:		Preallocated per-CPU maps for partial matching results
 * @rcu:		Matching data is swapped on commits
 * @f:			Fields, with lookup and mapping tables
 */
struct nft_pipapo_match {};

/**
 * struct nft_pipapo - Representation of a set
 * @match:	Currently in-use matching data
 * @clone:	Copy where pending insertions and deletions are kept
 * @width:	Total bytes to be matched for one packet, including padding
 * @last_gc:	Timestamp of last garbage collection run, jiffies
 */
struct nft_pipapo {};

struct nft_pipapo_elem;

/**
 * struct nft_pipapo_elem - API-facing representation of single set element
 * @priv:	element placeholder
 * @ext:	nftables API extensions
 */
struct nft_pipapo_elem {};

int pipapo_refill(unsigned long *map, unsigned int len, unsigned int rules,
		  unsigned long *dst,
		  const union nft_pipapo_map_bucket *mt, bool match_only);

/**
 * pipapo_and_field_buckets_4bit() - Intersect 4-bit buckets
 * @f:		Field including lookup table
 * @dst:	Area to store result
 * @data:	Input data selecting table buckets
 */
static inline void pipapo_and_field_buckets_4bit(const struct nft_pipapo_field *f,
						 unsigned long *dst,
						 const u8 *data)
{}

/**
 * pipapo_and_field_buckets_8bit() - Intersect 8-bit buckets
 * @f:		Field including lookup table
 * @dst:	Area to store result
 * @data:	Input data selecting table buckets
 */
static inline void pipapo_and_field_buckets_8bit(const struct nft_pipapo_field *f,
						 unsigned long *dst,
						 const u8 *data)
{}

/**
 * pipapo_estimate_size() - Estimate worst-case for set size
 * @desc:	Set description, element count and field description used here
 *
 * The size for this set type can vary dramatically, as it depends on the number
 * of rules (composing netmasks) the entries expand to. We compute the worst
 * case here.
 *
 * In general, for a non-ranged entry or a single composing netmask, we need
 * one bit in each of the sixteen NFT_PIPAPO_BUCKETS, for each 4-bit group (that
 * is, each input bit needs four bits of matching data), plus a bucket in the
 * mapping table for each field.
 *
 * Return: worst-case set size in bytes, 0 on any overflow
 */
static u64 pipapo_estimate_size(const struct nft_set_desc *desc)
{}

/**
 * pipapo_resmap_init() - Initialise result map before first use
 * @m:		Matching data, including mapping table
 * @res_map:	Result map
 *
 * Initialize all bits covered by the first field to one, so that after
 * the first step, only the matching bits of the first bit group remain.
 *
 * If other fields have a large bitmap, set remainder of res_map to 0.
 */
static inline void pipapo_resmap_init(const struct nft_pipapo_match *m, unsigned long *res_map)
{}
#endif /* _NFT_SET_PIPAPO_H */