16 #define MAX_SEARCHES_AVX16 16
17 #define MAX_SEARCHES_SSE8 8
18 #define MAX_SEARCHES_ALTIVEC8 8
19 #define MAX_SEARCHES_SSE4 4
20 #define MAX_SEARCHES_ALTIVEC4 4
21 #define MAX_SEARCHES_SCALAR 2
23 #define GET_NEXT_4BYTES(prm, idx) \
24 (*((const int32_t *)((prm)[(idx)].data + *(prm)[idx].data_index++)))
26 #define CNE_ACL_NODE_INDEX ((uint32_t)~CNE_ACL_NODE_TYPE)
28 #define SCALAR_QRANGE_MULT 0x01010101
29 #define SCALAR_QRANGE_MASK 0x7f7f7f7f
30 #define SCALAR_QRANGE_MIN 0x80808080
39 struct acl_flow_data {
48 uint32_t total_packets;
51 const uint64_t *trans;
54 struct completion *last_cmplt;
55 struct completion *cmplt_array;
64 int32_t priority[CNE_ACL_MAX_CATEGORIES];
75 const uint32_t *data_index;
77 struct completion *cmplt;
84 static const uint32_t idle[UINT8_MAX + 1];
89 static inline struct completion *
90 alloc_completion(
struct completion *p, uint32_t size, uint32_t tries, uint32_t *results)
94 for (n = 0; n < size; n++) {
96 if (p[n].count == 0) {
100 p[n].results = results;
113 resolve_single_priority(uint64_t transition,
int n,
const struct cne_acl_ctx *ctx,
114 struct parms *parms,
const struct cne_acl_match_results *p)
116 if (parms[n].cmplt->count == ctx->num_tries ||
117 parms[n].cmplt->priority[0] <= p[transition].priority[0]) {
119 parms[n].cmplt->priority[0] = p[transition].priority[0];
120 parms[n].cmplt->results[0] = p[transition].results[0];
128 static inline uint64_t
129 acl_start_next_trie(
struct acl_flow_data *flows,
struct parms *parms,
int n,
130 const struct cne_acl_ctx *ctx)
135 if (flows->num_packets < flows->total_packets) {
136 parms[n].data = flows->data[flows->num_packets];
137 parms[n].data_index = ctx->trie[flows->trie].data_index;
140 if (flows->trie == 0) {
142 alloc_completion(flows->cmplt_array, flows->cmplt_size, ctx->num_tries,
143 flows->results + flows->num_packets * flows->categories);
147 parms[n].cmplt = flows->last_cmplt;
149 flows->trans[parms[n].data[*parms[n].data_index++] + ctx->trie[flows->trie].root_index];
156 if (flows->trie >= ctx->num_tries) {
158 flows->num_packets++;
166 transition = ctx->idle;
167 parms[n].data = (
const uint8_t *)idle;
168 parms[n].data_index = idle;
174 acl_set_flow(
struct acl_flow_data *flows,
struct completion *cmplt, uint32_t cmplt_size,
175 const uint8_t **data, uint32_t *results, uint32_t data_num, uint32_t categories,
176 const uint64_t *trans)
178 flows->num_packets = 0;
181 flows->last_cmplt = NULL;
182 flows->cmplt_array = cmplt;
183 flows->total_packets = data_num;
184 flows->categories = categories;
185 flows->cmplt_size = cmplt_size;
187 flows->results = results;
188 flows->trans = trans;
191 typedef void (*resolve_priority_t)(uint64_t transition,
int n,
const struct cne_acl_ctx *ctx,
192 struct parms *parms,
const struct cne_acl_match_results *p,
193 uint32_t categories);
200 static inline uint64_t
201 acl_match_check(uint64_t transition,
int slot,
const struct cne_acl_ctx *ctx,
struct parms *parms,
202 struct acl_flow_data *flows, resolve_priority_t resolve_priority)
204 const struct cne_acl_match_results *p;
206 p = (
const struct cne_acl_match_results *)(flows->trans + ctx->match_index);
208 if (transition & CNE_ACL_NODE_MATCH) {
211 transition &= (uint64_t)CNE_ACL_NODE_INDEX;
215 if (flows->categories == 1)
216 resolve_single_priority(transition, slot, ctx, parms, p);
218 resolve_priority(transition, slot, ctx, parms, p, flows->categories);
221 parms[slot].cmplt->count--;
224 transition = acl_start_next_trie(flows, parms, slot, ctx);