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