xref: /dpdk/lib/acl/rte_acl.h (revision 448e01f1b5848b20cb0300d339100dd82f4459e9)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4 
5 #ifndef _RTE_ACL_H_
6 #define _RTE_ACL_H_
7 
8 /**
9  * @file
10  *
11  * RTE Classifier.
12  */
13 
14 #include <rte_acl_osdep.h>
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 #define	RTE_ACL_MAX_CATEGORIES	16
21 
22 #define	RTE_ACL_RESULTS_MULTIPLIER	(XMM_SIZE / sizeof(uint32_t))
23 
24 #define RTE_ACL_MAX_LEVELS 64
25 #define RTE_ACL_MAX_FIELDS 64
26 
27 union rte_acl_field_types {
28 	uint8_t  u8;
29 	uint16_t u16;
30 	uint32_t u32;
31 	uint64_t u64;
32 };
33 
34 enum {
35 	RTE_ACL_FIELD_TYPE_MASK = 0,
36 	RTE_ACL_FIELD_TYPE_RANGE,
37 	RTE_ACL_FIELD_TYPE_BITMASK
38 };
39 
40 /**
41  * ACL Field definition.
42  * Each field in the ACL rule has an associate definition.
43  * It defines the type of field, its size, its offset in the input buffer,
44  * the field index, and the input index.
45  * For performance reasons, the inner loop of the search function is unrolled
46  * to process four input bytes at a time. This requires the input to be grouped
47  * into sets of 4 consecutive bytes. The loop processes the first input byte as
48  * part of the setup and then subsequent bytes must be in groups of 4
49  * consecutive bytes.
50  */
51 struct rte_acl_field_def {
52 	uint8_t  type;        /**< type - RTE_ACL_FIELD_TYPE_*. */
53 	uint8_t	 size;        /**< size of field 1,2,4, or 8. */
54 	uint8_t	 field_index; /**< index of field inside the rule. */
55 	uint8_t  input_index; /**< 0-N input index. */
56 	uint32_t offset;      /**< offset to start of field. */
57 };
58 
59 /**
60  * ACL build configuration.
61  * Defines the fields of an ACL trie and number of categories to build with.
62  */
63 struct rte_acl_config {
64 	uint32_t num_categories; /**< Number of categories to build with. */
65 	uint32_t num_fields;     /**< Number of field definitions. */
66 	struct rte_acl_field_def defs[RTE_ACL_MAX_FIELDS];
67 	/**< array of field definitions. */
68 	size_t max_size;
69 	/**< max memory limit for internal run-time structures. */
70 };
71 
72 /**
73  * Defines the value of a field for a rule.
74  */
75 struct rte_acl_field {
76 	union rte_acl_field_types value;
77 	/**< a 1,2,4, or 8 byte value of the field. */
78 	union rte_acl_field_types mask_range;
79 	/**<
80 	 * depending on field type:
81 	 * mask -> 1.2.3.4/32 value=0x1020304, mask_range=32,
82 	 * range -> 0 : 65535 value=0, mask_range=65535,
83 	 * bitmask -> 0x06/0xff value=6, mask_range=0xff.
84 	 */
85 };
86 
87 enum {
88 	RTE_ACL_TYPE_SHIFT = 29,
89 	RTE_ACL_MAX_INDEX = RTE_LEN2MASK(RTE_ACL_TYPE_SHIFT, uint32_t),
90 	RTE_ACL_MAX_PRIORITY = RTE_ACL_MAX_INDEX,
91 	RTE_ACL_MIN_PRIORITY = 1,
92 };
93 
94 #define	RTE_ACL_MASKLEN_TO_BITMASK(v, s)	\
95 ((v) == 0 ? (v) : (typeof(v))((uint64_t)-1 << ((s) * CHAR_BIT - (v))))
96 
97 /**
98  * Miscellaneous data for ACL rule.
99  */
100 struct rte_acl_rule_data {
101 	uint32_t category_mask; /**< Mask of categories for that rule. */
102 	int32_t  priority;      /**< Priority for that rule. */
103 	uint32_t userdata;      /**< Associated with the rule user data. */
104 };
105 
106 /**
107  * Defines single ACL rule.
108  * data - miscellaneous data for the rule.
109  * field[] - value and mask or range for each field.
110  */
111 #define	RTE_ACL_RULE_DEF(name, fld_num)	struct name {\
112 	struct rte_acl_rule_data data;               \
113 	struct rte_acl_field field[fld_num];         \
114 }
115 
116 RTE_ACL_RULE_DEF(rte_acl_rule,);
117 
118 #define	RTE_ACL_RULE_SZ(fld_num)	\
119 	(sizeof(struct rte_acl_rule) + sizeof(struct rte_acl_field) * (fld_num))
120 
121 
122 /** Max number of characters in name.*/
123 #define	RTE_ACL_NAMESIZE		32
124 
125 /**
126  * Parameters used when creating the ACL context.
127  */
128 struct rte_acl_param {
129 	const char *name;         /**< Name of the ACL context. */
130 	int         socket_id;    /**< Socket ID to allocate memory for. */
131 	uint32_t    rule_size;    /**< Size of each rule. */
132 	uint32_t    max_rule_num; /**< Maximum number of rules. */
133 };
134 
135 
136 /**
137  * Create a new ACL context.
138  *
139  * @param param
140  *   Parameters used to create and initialise the ACL context.
141  * @return
142  *   Pointer to ACL context structure that is used in future ACL
143  *   operations, or NULL on error, with error code set in rte_errno.
144  *   Possible rte_errno errors include:
145  *   - EINVAL - invalid parameter passed to function
146  */
147 struct rte_acl_ctx *
148 rte_acl_create(const struct rte_acl_param *param);
149 
150 /**
151  * Find an existing ACL context object and return a pointer to it.
152  *
153  * @param name
154  *   Name of the ACL context as passed to rte_acl_create()
155  * @return
156  *   Pointer to ACL context or NULL if object not found
157  *   with rte_errno set appropriately. Possible rte_errno values include:
158  *    - ENOENT - value not available for return
159  */
160 struct rte_acl_ctx *
161 rte_acl_find_existing(const char *name);
162 
163 /**
164  * De-allocate all memory used by ACL context.
165  *
166  * @param ctx
167  *   ACL context to free
168  *   If ctx is NULL, no operation is performed.
169  */
170 void
171 rte_acl_free(struct rte_acl_ctx *ctx);
172 
173 /**
174  * Add rules to an existing ACL context.
175  * This function is not multi-thread safe.
176  *
177  * @param ctx
178  *   ACL context to add patterns to.
179  * @param rules
180  *   Array of rules to add to the ACL context.
181  *   Note that all fields in rte_acl_rule structures are expected
182  *   to be in host byte order.
183  *   Each rule expected to be in the same format and not exceed size
184  *   specified at ACL context creation time.
185  * @param num
186  *   Number of elements in the input array of rules.
187  * @return
188  *   - -ENOMEM if there is no space in the ACL context for these rules.
189  *   - -EINVAL if the parameters are invalid.
190  *   - Zero if operation completed successfully.
191  */
192 int
193 rte_acl_add_rules(struct rte_acl_ctx *ctx, const struct rte_acl_rule *rules,
194 	uint32_t num);
195 
196 /**
197  * Delete all rules from the ACL context.
198  * This function is not multi-thread safe.
199  * Note that internal run-time structures are not affected.
200  *
201  * @param ctx
202  *   ACL context to delete rules from.
203  */
204 void
205 rte_acl_reset_rules(struct rte_acl_ctx *ctx);
206 
207 /**
208  * Analyze set of rules and build required internal run-time structures.
209  * This function is not multi-thread safe.
210  *
211  * @param ctx
212  *   ACL context to build.
213  * @param cfg
214  *   Pointer to struct rte_acl_config - defines build parameters.
215  * @return
216  *   - -ENOMEM if couldn't allocate enough memory.
217  *   - -EINVAL if the parameters are invalid.
218  *   - Negative error code if operation failed.
219  *   - Zero if operation completed successfully.
220  */
221 int
222 rte_acl_build(struct rte_acl_ctx *ctx, const struct rte_acl_config *cfg);
223 
224 /**
225  * Delete all rules from the ACL context and
226  * destroy all internal run-time structures.
227  * This function is not multi-thread safe.
228  *
229  * @param ctx
230  *   ACL context to reset.
231  */
232 void
233 rte_acl_reset(struct rte_acl_ctx *ctx);
234 
235 /**
236  *  Available implementations of ACL classify.
237  */
238 enum rte_acl_classify_alg {
239 	RTE_ACL_CLASSIFY_DEFAULT = 0,
240 	RTE_ACL_CLASSIFY_SCALAR = 1,  /**< generic implementation. */
241 	RTE_ACL_CLASSIFY_SSE = 2,     /**< requires SSE4.1 support. */
242 	RTE_ACL_CLASSIFY_AVX2 = 3,    /**< requires AVX2 support. */
243 	RTE_ACL_CLASSIFY_NEON = 4,    /**< requires NEON support. */
244 	RTE_ACL_CLASSIFY_ALTIVEC = 5,    /**< requires ALTIVEC support. */
245 	RTE_ACL_CLASSIFY_AVX512X16 = 6,  /**< requires AVX512 support. */
246 	RTE_ACL_CLASSIFY_AVX512X32 = 7,  /**< requires AVX512 support. */
247 };
248 
249 /**
250  * Perform search for a matching ACL rule for each input data buffer.
251  * Each input data buffer can have up to *categories* matches.
252  * That implies that results array should be big enough to hold
253  * (categories * num) elements.
254  * Also categories parameter should be either one or multiple of
255  * RTE_ACL_RESULTS_MULTIPLIER and can't be bigger than RTE_ACL_MAX_CATEGORIES.
256  * If more than one rule is applicable for given input buffer and
257  * given category, then rule with highest priority will be returned as a match.
258  * Note, that it is a caller's responsibility to ensure that input parameters
259  * are valid and point to correct memory locations.
260  *
261  * @param ctx
262  *   ACL context to search with.
263  * @param data
264  *   Array of pointers to input data buffers to perform search.
265  *   Note that all fields in input data buffers supposed to be in network
266  *   byte order (MSB).
267  * @param results
268  *   Array of search results, *categories* results per each input data buffer.
269  * @param num
270  *   Number of elements in the input data buffers array.
271  * @param categories
272  *   Number of maximum possible matches for each input buffer, one possible
273  *   match per category.
274  * @return
275  *   zero on successful completion.
276  *   -EINVAL for incorrect arguments.
277  */
278 extern int
279 rte_acl_classify(const struct rte_acl_ctx *ctx,
280 		 const uint8_t **data,
281 		 uint32_t *results, uint32_t num,
282 		 uint32_t categories);
283 
284 /**
285  * Perform search using specified algorithm for a matching ACL rule for
286  * each input data buffer.
287  * Each input data buffer can have up to *categories* matches.
288  * That implies that results array should be big enough to hold
289  * (categories * num) elements.
290  * Also categories parameter should be either one or multiple of
291  * RTE_ACL_RESULTS_MULTIPLIER and can't be bigger than RTE_ACL_MAX_CATEGORIES.
292  * If more than one rule is applicable for given input buffer and
293  * given category, then rule with highest priority will be returned as a match.
294  * Note, that it is a caller's responsibility to ensure that input parameters
295  * are valid and point to correct memory locations.
296  *
297  * @param ctx
298  *   ACL context to search with.
299  * @param data
300  *   Array of pointers to input data buffers to perform search.
301  *   Note that all fields in input data buffers supposed to be in network
302  *   byte order (MSB).
303  * @param results
304  *   Array of search results, *categories* results per each input data buffer.
305  * @param num
306  *   Number of elements in the input data buffers array.
307  * @param categories
308  *   Number of maximum possible matches for each input buffer, one possible
309  *   match per category.
310  * @param alg
311  *   Algorithm to be used for the search.
312  *   It is the caller responsibility to ensure that the value refers to the
313  *   existing algorithm, and that it could be run on the given CPU.
314  * @return
315  *   zero on successful completion.
316  *   -EINVAL for incorrect arguments.
317  */
318 extern int
319 rte_acl_classify_alg(const struct rte_acl_ctx *ctx,
320 		 const uint8_t **data,
321 		 uint32_t *results, uint32_t num,
322 		 uint32_t categories,
323 		 enum rte_acl_classify_alg alg);
324 
325 /*
326  * Override the default classifier function for a given ACL context.
327  * @param ctx
328  *   ACL context to change classify function for.
329  * @param alg
330  *   New default classify algorithm for given ACL context.
331  *   It is the caller responsibility to ensure that the value refers to the
332  *   existing algorithm, and that it could be run on the given CPU.
333  *   The max SIMD bitwidth value in EAL must also allow for the chosen algorithm.
334  * @return
335  *   - -EINVAL if the parameters are invalid.
336  *   - -ENOTSUP requested algorithm is not supported by given platform.
337  *   - Zero if operation completed successfully.
338  */
339 extern int
340 rte_acl_set_ctx_classify(struct rte_acl_ctx *ctx,
341 	enum rte_acl_classify_alg alg);
342 
343 /**
344  * Dump an ACL context structure to the console.
345  *
346  * @param ctx
347  *   ACL context to dump.
348  */
349 void
350 rte_acl_dump(const struct rte_acl_ctx *ctx);
351 
352 /**
353  * Dump all ACL context structures to the console.
354  */
355 void
356 rte_acl_list_dump(void);
357 
358 #ifdef __cplusplus
359 }
360 #endif
361 
362 #endif /* _RTE_ACL_H_ */
363