199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 399a2dd95SBruce Richardson */ 499a2dd95SBruce Richardson 599a2dd95SBruce Richardson #ifndef _ACL_H_ 699a2dd95SBruce Richardson #define _ACL_H_ 799a2dd95SBruce Richardson 899a2dd95SBruce Richardson #ifdef __cplusplus 999a2dd95SBruce Richardson extern "C" { 1099a2dd95SBruce Richardson #endif /* __cplusplus */ 1199a2dd95SBruce Richardson 1299a2dd95SBruce Richardson #define RTE_ACL_QUAD_MAX 5 1399a2dd95SBruce Richardson #define RTE_ACL_QUAD_SIZE 4 1499a2dd95SBruce Richardson #define RTE_ACL_QUAD_SINGLE UINT64_C(0x7f7f7f7f00000000) 1599a2dd95SBruce Richardson 1699a2dd95SBruce Richardson #define RTE_ACL_SINGLE_TRIE_SIZE 2000 1799a2dd95SBruce Richardson 1899a2dd95SBruce Richardson #define RTE_ACL_DFA_MAX UINT8_MAX 1999a2dd95SBruce Richardson #define RTE_ACL_DFA_SIZE (UINT8_MAX + 1) 2099a2dd95SBruce Richardson 2199a2dd95SBruce Richardson #define RTE_ACL_DFA_GR64_SIZE 64 2299a2dd95SBruce Richardson #define RTE_ACL_DFA_GR64_NUM (RTE_ACL_DFA_SIZE / RTE_ACL_DFA_GR64_SIZE) 2399a2dd95SBruce Richardson #define RTE_ACL_DFA_GR64_BIT \ 2499a2dd95SBruce Richardson (CHAR_BIT * sizeof(uint32_t) / RTE_ACL_DFA_GR64_NUM) 2599a2dd95SBruce Richardson 2699a2dd95SBruce Richardson typedef int bits_t; 2799a2dd95SBruce Richardson 2899a2dd95SBruce Richardson #define RTE_ACL_BIT_SET_SIZE ((UINT8_MAX + 1) / (sizeof(bits_t) * CHAR_BIT)) 2999a2dd95SBruce Richardson 3099a2dd95SBruce Richardson struct rte_acl_bitset { 3199a2dd95SBruce Richardson bits_t bits[RTE_ACL_BIT_SET_SIZE]; 3299a2dd95SBruce Richardson }; 3399a2dd95SBruce Richardson 3499a2dd95SBruce Richardson #define RTE_ACL_NODE_DFA (0 << RTE_ACL_TYPE_SHIFT) 3599a2dd95SBruce Richardson #define RTE_ACL_NODE_SINGLE (1U << RTE_ACL_TYPE_SHIFT) 3699a2dd95SBruce Richardson #define RTE_ACL_NODE_QRANGE (3U << RTE_ACL_TYPE_SHIFT) 3799a2dd95SBruce Richardson #define RTE_ACL_NODE_MATCH (4U << RTE_ACL_TYPE_SHIFT) 3899a2dd95SBruce Richardson #define RTE_ACL_NODE_TYPE (7U << RTE_ACL_TYPE_SHIFT) 3999a2dd95SBruce Richardson #define RTE_ACL_NODE_UNDEFINED UINT32_MAX 4099a2dd95SBruce Richardson 4199a2dd95SBruce Richardson /* 4299a2dd95SBruce Richardson * ACL RT structure is a set of multibit tries (with stride == 8) 4399a2dd95SBruce Richardson * represented by an array of transitions. The next position is calculated 4499a2dd95SBruce Richardson * based on the current position and the input byte. 4599a2dd95SBruce Richardson * Each transition is 64 bit value with the following format: 4699a2dd95SBruce Richardson * | node_type_specific : 32 | node_type : 3 | node_addr : 29 | 4799a2dd95SBruce Richardson * For all node types except RTE_ACL_NODE_MATCH, node_addr is an index 48*4a6672c2SStephen Hemminger * to the start of the node in the transitions array. 4999a2dd95SBruce Richardson * Few different node types are used: 5099a2dd95SBruce Richardson * RTE_ACL_NODE_MATCH: 5199a2dd95SBruce Richardson * node_addr value is and index into an array that contains the return value 5299a2dd95SBruce Richardson * and its priority for each category. 5399a2dd95SBruce Richardson * Upper 32 bits of the transition value are not used for that node type. 5499a2dd95SBruce Richardson * RTE_ACL_NODE_QRANGE: 5599a2dd95SBruce Richardson * that node consist of up to 5 transitions. 5699a2dd95SBruce Richardson * Upper 32 bits are interpreted as 4 signed character values which 5799a2dd95SBruce Richardson * are ordered from smallest(INT8_MIN) to largest (INT8_MAX). 5899a2dd95SBruce Richardson * These values define 5 ranges: 5999a2dd95SBruce Richardson * INT8_MIN <= range[0] <= ((int8_t *)&transition)[4] 6099a2dd95SBruce Richardson * ((int8_t *)&transition)[4] < range[1] <= ((int8_t *)&transition)[5] 6199a2dd95SBruce Richardson * ((int8_t *)&transition)[5] < range[2] <= ((int8_t *)&transition)[6] 6299a2dd95SBruce Richardson * ((int8_t *)&transition)[6] < range[3] <= ((int8_t *)&transition)[7] 6399a2dd95SBruce Richardson * ((int8_t *)&transition)[7] < range[4] <= INT8_MAX 6499a2dd95SBruce Richardson * So for input byte value within range[i] i-th transition within that node 6599a2dd95SBruce Richardson * will be used. 6699a2dd95SBruce Richardson * RTE_ACL_NODE_SINGLE: 6799a2dd95SBruce Richardson * always transitions to the same node regardless of the input value. 6899a2dd95SBruce Richardson * RTE_ACL_NODE_DFA: 69*4a6672c2SStephen Hemminger * that node consists of up to 256 transitions. 7099a2dd95SBruce Richardson * In attempt to conserve space all transitions are divided into 4 consecutive 7199a2dd95SBruce Richardson * groups, by 64 transitions per group: 7299a2dd95SBruce Richardson * group64[i] contains transitions[i * 64, .. i * 64 + 63]. 7399a2dd95SBruce Richardson * Upper 32 bits are interpreted as 4 unsigned character values one per group, 7499a2dd95SBruce Richardson * which contain index to the start of the given group within the node. 7599a2dd95SBruce Richardson * So to calculate transition index within the node for given input byte value: 7699a2dd95SBruce Richardson * input_byte - ((uint8_t *)&transition)[4 + input_byte / 64]. 7799a2dd95SBruce Richardson */ 7899a2dd95SBruce Richardson 7999a2dd95SBruce Richardson /* 8099a2dd95SBruce Richardson * Each ACL RT contains an idle nomatch node: 8199a2dd95SBruce Richardson * a SINGLE node at predefined position (RTE_ACL_DFA_SIZE) 8299a2dd95SBruce Richardson * that points to itself. 8399a2dd95SBruce Richardson */ 8499a2dd95SBruce Richardson #define RTE_ACL_IDLE_NODE (RTE_ACL_DFA_SIZE | RTE_ACL_NODE_SINGLE) 8599a2dd95SBruce Richardson 8699a2dd95SBruce Richardson /* 8799a2dd95SBruce Richardson * Structure of a node is a set of ptrs and each ptr has a bit map 8899a2dd95SBruce Richardson * of values associated with this transition. 8999a2dd95SBruce Richardson */ 9099a2dd95SBruce Richardson struct rte_acl_ptr_set { 9199a2dd95SBruce Richardson struct rte_acl_bitset values; /* input values associated with ptr */ 9299a2dd95SBruce Richardson struct rte_acl_node *ptr; /* transition to next node */ 9399a2dd95SBruce Richardson }; 9499a2dd95SBruce Richardson 9599a2dd95SBruce Richardson struct rte_acl_classifier_results { 9699a2dd95SBruce Richardson int results[RTE_ACL_MAX_CATEGORIES]; 9799a2dd95SBruce Richardson }; 9899a2dd95SBruce Richardson 9999a2dd95SBruce Richardson struct rte_acl_match_results { 10099a2dd95SBruce Richardson uint32_t results[RTE_ACL_MAX_CATEGORIES]; 10199a2dd95SBruce Richardson int32_t priority[RTE_ACL_MAX_CATEGORIES]; 10299a2dd95SBruce Richardson }; 10399a2dd95SBruce Richardson 10499a2dd95SBruce Richardson struct rte_acl_node { 10599a2dd95SBruce Richardson uint64_t node_index; /* index for this node */ 10699a2dd95SBruce Richardson uint32_t level; /* level 0-n in the trie */ 10799a2dd95SBruce Richardson uint32_t ref_count; /* ref count for this node */ 10899a2dd95SBruce Richardson struct rte_acl_bitset values; 10999a2dd95SBruce Richardson /* set of all values that map to another node 11099a2dd95SBruce Richardson * (union of bits in each transition. 11199a2dd95SBruce Richardson */ 11299a2dd95SBruce Richardson uint32_t num_ptrs; /* number of ptr_set in use */ 11399a2dd95SBruce Richardson uint32_t max_ptrs; /* number of allocated ptr_set */ 11499a2dd95SBruce Richardson uint32_t min_add; /* number of ptr_set per allocation */ 11599a2dd95SBruce Richardson struct rte_acl_ptr_set *ptrs; /* transitions array for this node */ 11699a2dd95SBruce Richardson int32_t match_flag; 11799a2dd95SBruce Richardson int32_t match_index; /* index to match data */ 11899a2dd95SBruce Richardson uint32_t node_type; 11999a2dd95SBruce Richardson int32_t fanout; 12099a2dd95SBruce Richardson /* number of ranges (transitions w/ consecutive bits) */ 12199a2dd95SBruce Richardson int32_t id; 12299a2dd95SBruce Richardson struct rte_acl_match_results *mrt; /* only valid when match_flag != 0 */ 12399a2dd95SBruce Richardson union { 12499a2dd95SBruce Richardson char transitions[RTE_ACL_QUAD_SIZE]; 12599a2dd95SBruce Richardson /* boundaries for ranged node */ 12699a2dd95SBruce Richardson uint8_t dfa_gr64[RTE_ACL_DFA_GR64_NUM]; 12799a2dd95SBruce Richardson }; 12899a2dd95SBruce Richardson struct rte_acl_node *next; 12999a2dd95SBruce Richardson /* free list link or pointer to duplicate node during merge */ 13099a2dd95SBruce Richardson struct rte_acl_node *prev; 13199a2dd95SBruce Richardson /* points to node from which this node was duplicated */ 13299a2dd95SBruce Richardson }; 13399a2dd95SBruce Richardson 13499a2dd95SBruce Richardson /* 13599a2dd95SBruce Richardson * Types of tries used to generate runtime structure(s) 13699a2dd95SBruce Richardson */ 13799a2dd95SBruce Richardson enum { 13899a2dd95SBruce Richardson RTE_ACL_FULL_TRIE = 0, 13999a2dd95SBruce Richardson RTE_ACL_NOSRC_TRIE = 1, 14099a2dd95SBruce Richardson RTE_ACL_NODST_TRIE = 2, 14199a2dd95SBruce Richardson RTE_ACL_NOPORTS_TRIE = 4, 14299a2dd95SBruce Richardson RTE_ACL_NOVLAN_TRIE = 8, 14399a2dd95SBruce Richardson RTE_ACL_UNUSED_TRIE = 0x80000000 14499a2dd95SBruce Richardson }; 14599a2dd95SBruce Richardson 14699a2dd95SBruce Richardson 14799a2dd95SBruce Richardson /** MAX number of tries per one ACL context.*/ 14899a2dd95SBruce Richardson #define RTE_ACL_MAX_TRIES 8 14999a2dd95SBruce Richardson 15099a2dd95SBruce Richardson /** Max number of characters in PM name.*/ 15199a2dd95SBruce Richardson #define RTE_ACL_NAMESIZE 32 15299a2dd95SBruce Richardson 15399a2dd95SBruce Richardson 15499a2dd95SBruce Richardson struct rte_acl_trie { 15599a2dd95SBruce Richardson uint32_t type; 15699a2dd95SBruce Richardson uint32_t count; 15799a2dd95SBruce Richardson uint32_t root_index; 15899a2dd95SBruce Richardson const uint32_t *data_index; 15999a2dd95SBruce Richardson uint32_t num_data_indexes; 16099a2dd95SBruce Richardson }; 16199a2dd95SBruce Richardson 16299a2dd95SBruce Richardson struct rte_acl_bld_trie { 16399a2dd95SBruce Richardson struct rte_acl_node *trie; 16499a2dd95SBruce Richardson }; 16599a2dd95SBruce Richardson 16699a2dd95SBruce Richardson struct rte_acl_ctx { 16799a2dd95SBruce Richardson char name[RTE_ACL_NAMESIZE]; 16899a2dd95SBruce Richardson /** Name of the ACL context. */ 16999a2dd95SBruce Richardson int32_t socket_id; 17099a2dd95SBruce Richardson /** Socket ID to allocate memory from. */ 17199a2dd95SBruce Richardson enum rte_acl_classify_alg alg; 17299a2dd95SBruce Richardson uint32_t first_load_sz; 17399a2dd95SBruce Richardson void *rules; 17499a2dd95SBruce Richardson uint32_t max_rules; 17599a2dd95SBruce Richardson uint32_t rule_sz; 17699a2dd95SBruce Richardson uint32_t num_rules; 17799a2dd95SBruce Richardson uint32_t num_categories; 17899a2dd95SBruce Richardson uint32_t num_tries; 17999a2dd95SBruce Richardson uint32_t match_index; 18099a2dd95SBruce Richardson uint64_t no_match; 18199a2dd95SBruce Richardson uint64_t idle; 18299a2dd95SBruce Richardson uint64_t *trans_table; 18399a2dd95SBruce Richardson uint32_t *data_indexes; 18499a2dd95SBruce Richardson struct rte_acl_trie trie[RTE_ACL_MAX_TRIES]; 18599a2dd95SBruce Richardson void *mem; 18699a2dd95SBruce Richardson size_t mem_sz; 18799a2dd95SBruce Richardson struct rte_acl_config config; /* copy of build config. */ 18899a2dd95SBruce Richardson }; 18999a2dd95SBruce Richardson 19099a2dd95SBruce Richardson int rte_acl_gen(struct rte_acl_ctx *ctx, struct rte_acl_trie *trie, 19199a2dd95SBruce Richardson struct rte_acl_bld_trie *node_bld_trie, uint32_t num_tries, 19299a2dd95SBruce Richardson uint32_t num_categories, uint32_t data_index_sz, size_t max_size); 19399a2dd95SBruce Richardson 19499a2dd95SBruce Richardson typedef int (*rte_acl_classify_t) 19599a2dd95SBruce Richardson (const struct rte_acl_ctx *, const uint8_t **, uint32_t *, uint32_t, uint32_t); 19699a2dd95SBruce Richardson 19799a2dd95SBruce Richardson /* 19899a2dd95SBruce Richardson * Different implementations of ACL classify. 19999a2dd95SBruce Richardson */ 20099a2dd95SBruce Richardson int 20199a2dd95SBruce Richardson rte_acl_classify_scalar(const struct rte_acl_ctx *ctx, const uint8_t **data, 20299a2dd95SBruce Richardson uint32_t *results, uint32_t num, uint32_t categories); 20399a2dd95SBruce Richardson 20499a2dd95SBruce Richardson int 20599a2dd95SBruce Richardson rte_acl_classify_sse(const struct rte_acl_ctx *ctx, const uint8_t **data, 20699a2dd95SBruce Richardson uint32_t *results, uint32_t num, uint32_t categories); 20799a2dd95SBruce Richardson 20899a2dd95SBruce Richardson int 20999a2dd95SBruce Richardson rte_acl_classify_avx2(const struct rte_acl_ctx *ctx, const uint8_t **data, 21099a2dd95SBruce Richardson uint32_t *results, uint32_t num, uint32_t categories); 21199a2dd95SBruce Richardson 21299a2dd95SBruce Richardson int 21399a2dd95SBruce Richardson rte_acl_classify_avx512x16(const struct rte_acl_ctx *ctx, const uint8_t **data, 21499a2dd95SBruce Richardson uint32_t *results, uint32_t num, uint32_t categories); 21599a2dd95SBruce Richardson 21699a2dd95SBruce Richardson int 21799a2dd95SBruce Richardson rte_acl_classify_avx512x32(const struct rte_acl_ctx *ctx, const uint8_t **data, 21899a2dd95SBruce Richardson uint32_t *results, uint32_t num, uint32_t categories); 21999a2dd95SBruce Richardson 22099a2dd95SBruce Richardson int 22199a2dd95SBruce Richardson rte_acl_classify_neon(const struct rte_acl_ctx *ctx, const uint8_t **data, 22299a2dd95SBruce Richardson uint32_t *results, uint32_t num, uint32_t categories); 22399a2dd95SBruce Richardson 22499a2dd95SBruce Richardson int 22599a2dd95SBruce Richardson rte_acl_classify_altivec(const struct rte_acl_ctx *ctx, const uint8_t **data, 22699a2dd95SBruce Richardson uint32_t *results, uint32_t num, uint32_t categories); 22799a2dd95SBruce Richardson 22899a2dd95SBruce Richardson #ifdef __cplusplus 22999a2dd95SBruce Richardson } 23099a2dd95SBruce Richardson #endif /* __cplusplus */ 23199a2dd95SBruce Richardson 23299a2dd95SBruce Richardson #endif /* _ACL_H_ */ 233