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_ */ 388