1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2010-2014 Intel Corporation
10 #include <rte_string_fns.h>
12 #include <rte_byteorder.h>
15 #include <rte_common.h>
19 #define BIT_SIZEOF(x) (sizeof(x) * CHAR_BIT)
21 #define LEN RTE_ACL_MAX_CATEGORIES
23 RTE_ACL_RULE_DEF(acl_ipv4vlan_rule, RTE_ACL_IPV4VLAN_NUM_FIELDS);
25 struct rte_acl_param acl_param = {
27 .socket_id = SOCKET_ID_ANY,
28 .rule_size = RTE_ACL_IPV4VLAN_RULE_SZ,
29 .max_rule_num = 0x30000,
32 struct rte_acl_ipv4vlan_rule acl_rule = {
33 .data = { .priority = 1, .category_mask = 0xff },
35 .src_port_high = UINT16_MAX,
37 .dst_port_high = UINT16_MAX,
40 const uint32_t ipv4_7tuple_layout[RTE_ACL_IPV4VLAN_NUM] = {
41 offsetof(struct ipv4_7tuple, proto),
42 offsetof(struct ipv4_7tuple, vlan),
43 offsetof(struct ipv4_7tuple, ip_src),
44 offsetof(struct ipv4_7tuple, ip_dst),
45 offsetof(struct ipv4_7tuple, port_src),
49 /* byteswap to cpu or network order */
51 bswap_test_data(struct ipv4_7tuple *data, int len, int to_be)
55 for (i = 0; i < len; i++) {
58 /* swap all bytes so that they are in network order */
59 data[i].ip_dst = rte_cpu_to_be_32(data[i].ip_dst);
60 data[i].ip_src = rte_cpu_to_be_32(data[i].ip_src);
61 data[i].port_dst = rte_cpu_to_be_16(data[i].port_dst);
62 data[i].port_src = rte_cpu_to_be_16(data[i].port_src);
63 data[i].vlan = rte_cpu_to_be_16(data[i].vlan);
64 data[i].domain = rte_cpu_to_be_16(data[i].domain);
66 data[i].ip_dst = rte_be_to_cpu_32(data[i].ip_dst);
67 data[i].ip_src = rte_be_to_cpu_32(data[i].ip_src);
68 data[i].port_dst = rte_be_to_cpu_16(data[i].port_dst);
69 data[i].port_src = rte_be_to_cpu_16(data[i].port_src);
70 data[i].vlan = rte_be_to_cpu_16(data[i].vlan);
71 data[i].domain = rte_be_to_cpu_16(data[i].domain);
77 acl_ipv4vlan_check_rule(const struct rte_acl_ipv4vlan_rule *rule)
79 if (rule->src_port_low > rule->src_port_high ||
80 rule->dst_port_low > rule->dst_port_high ||
81 rule->src_mask_len > BIT_SIZEOF(rule->src_addr) ||
82 rule->dst_mask_len > BIT_SIZEOF(rule->dst_addr))
88 acl_ipv4vlan_convert_rule(const struct rte_acl_ipv4vlan_rule *ri,
89 struct acl_ipv4vlan_rule *ro)
93 ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto;
94 ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan;
95 ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain;
96 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr;
97 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr;
98 ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low;
99 ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low;
101 ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask;
102 ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask;
103 ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 =
105 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
107 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len;
108 ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 =
110 ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 =
115 * Add ipv4vlan rules to an existing ACL context.
116 * This function is not multi-thread safe.
119 * ACL context to add patterns to.
121 * Array of rules to add to the ACL context.
122 * Note that all fields in rte_acl_ipv4vlan_rule structures are expected
123 * to be in host byte order.
125 * Number of elements in the input array of rules.
127 * - -ENOMEM if there is no space in the ACL context for these rules.
128 * - -EINVAL if the parameters are invalid.
129 * - Zero if operation completed successfully.
132 rte_acl_ipv4vlan_add_rules(struct rte_acl_ctx *ctx,
133 const struct rte_acl_ipv4vlan_rule *rules,
138 struct acl_ipv4vlan_rule rv;
140 if (ctx == NULL || rules == NULL)
143 /* check input rules. */
144 for (i = 0; i != num; i++) {
145 rc = acl_ipv4vlan_check_rule(rules + i);
147 RTE_LOG(ERR, ACL, "%s: rule #%u is invalid\n",
153 /* perform conversion to the internal format and add to the context. */
154 for (i = 0, rc = 0; i != num && rc == 0; i++) {
155 acl_ipv4vlan_convert_rule(rules + i, &rv);
156 rc = rte_acl_add_rules(ctx, (struct rte_acl_rule *)&rv, 1);
163 acl_ipv4vlan_config(struct rte_acl_config *cfg,
164 const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],
165 uint32_t num_categories)
167 static const struct rte_acl_field_def
168 ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = {
170 .type = RTE_ACL_FIELD_TYPE_BITMASK,
171 .size = sizeof(uint8_t),
172 .field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD,
173 .input_index = RTE_ACL_IPV4VLAN_PROTO,
176 .type = RTE_ACL_FIELD_TYPE_BITMASK,
177 .size = sizeof(uint16_t),
178 .field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD,
179 .input_index = RTE_ACL_IPV4VLAN_VLAN,
182 .type = RTE_ACL_FIELD_TYPE_BITMASK,
183 .size = sizeof(uint16_t),
184 .field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD,
185 .input_index = RTE_ACL_IPV4VLAN_VLAN,
188 .type = RTE_ACL_FIELD_TYPE_MASK,
189 .size = sizeof(uint32_t),
190 .field_index = RTE_ACL_IPV4VLAN_SRC_FIELD,
191 .input_index = RTE_ACL_IPV4VLAN_SRC,
194 .type = RTE_ACL_FIELD_TYPE_MASK,
195 .size = sizeof(uint32_t),
196 .field_index = RTE_ACL_IPV4VLAN_DST_FIELD,
197 .input_index = RTE_ACL_IPV4VLAN_DST,
200 .type = RTE_ACL_FIELD_TYPE_RANGE,
201 .size = sizeof(uint16_t),
202 .field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD,
203 .input_index = RTE_ACL_IPV4VLAN_PORTS,
206 .type = RTE_ACL_FIELD_TYPE_RANGE,
207 .size = sizeof(uint16_t),
208 .field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD,
209 .input_index = RTE_ACL_IPV4VLAN_PORTS,
213 memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs));
214 cfg->num_fields = RTE_DIM(ipv4_defs);
216 cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset =
217 layout[RTE_ACL_IPV4VLAN_PROTO];
218 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset =
219 layout[RTE_ACL_IPV4VLAN_VLAN];
220 cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset =
221 layout[RTE_ACL_IPV4VLAN_VLAN] +
222 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size;
223 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset =
224 layout[RTE_ACL_IPV4VLAN_SRC];
225 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset =
226 layout[RTE_ACL_IPV4VLAN_DST];
227 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset =
228 layout[RTE_ACL_IPV4VLAN_PORTS];
229 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset =
230 layout[RTE_ACL_IPV4VLAN_PORTS] +
231 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size;
233 cfg->num_categories = num_categories;
237 * Analyze set of ipv4vlan rules and build required internal
238 * run-time structures.
239 * This function is not multi-thread safe.
242 * ACL context to build.
244 * Layout of input data to search through.
245 * @param num_categories
246 * Maximum number of categories to use in that build.
248 * - -ENOMEM if couldn't allocate enough memory.
249 * - -EINVAL if the parameters are invalid.
250 * - Negative error code if operation failed.
251 * - Zero if operation completed successfully.
254 rte_acl_ipv4vlan_build(struct rte_acl_ctx *ctx,
255 const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],
256 uint32_t num_categories)
258 struct rte_acl_config cfg;
260 if (ctx == NULL || layout == NULL)
263 memset(&cfg, 0, sizeof(cfg));
264 acl_ipv4vlan_config(&cfg, layout, num_categories);
265 return rte_acl_build(ctx, &cfg);
269 * Test ACL lookup (selected alg).
272 test_classify_alg(struct rte_acl_ctx *acx, struct ipv4_7tuple test_data[],
273 const uint8_t *data[], size_t dim, enum rte_acl_classify_alg alg)
276 uint32_t i, result, count;
277 uint32_t results[dim * RTE_ACL_MAX_CATEGORIES];
279 /* set given classify alg, skip test if alg is not supported */
280 ret = rte_acl_set_ctx_classify(acx, alg);
282 return (ret == -ENOTSUP) ? 0 : ret;
285 * these will run quite a few times, it's necessary to test code paths
286 * from num=0 to num>8
288 for (count = 0; count <= dim; count++) {
289 ret = rte_acl_classify(acx, data, results,
290 count, RTE_ACL_MAX_CATEGORIES);
292 printf("Line %i: classify(alg=%d) failed!\n",
297 /* check if we allow everything we should allow */
298 for (i = 0; i < count; i++) {
300 results[i * RTE_ACL_MAX_CATEGORIES + ACL_ALLOW];
301 if (result != test_data[i].allow) {
302 printf("Line %i: Error in allow results at %i "
303 "(expected %"PRIu32" got %"PRIu32")!\n",
304 __LINE__, i, test_data[i].allow,
310 /* check if we deny everything we should deny */
311 for (i = 0; i < count; i++) {
312 result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_DENY];
313 if (result != test_data[i].deny) {
314 printf("Line %i: Error in deny results at %i "
315 "(expected %"PRIu32" got %"PRIu32")!\n",
316 __LINE__, i, test_data[i].deny,
323 /* restore default classify alg */
324 return rte_acl_set_ctx_classify(acx, RTE_ACL_CLASSIFY_DEFAULT);
328 * Test ACL lookup (all possible methods).
331 test_classify_run(struct rte_acl_ctx *acx, struct ipv4_7tuple test_data[],
336 const uint8_t *data[dim];
338 static const enum rte_acl_classify_alg alg[] = {
339 RTE_ACL_CLASSIFY_SCALAR,
340 RTE_ACL_CLASSIFY_SSE,
341 RTE_ACL_CLASSIFY_AVX2,
342 RTE_ACL_CLASSIFY_NEON,
343 RTE_ACL_CLASSIFY_ALTIVEC,
344 RTE_ACL_CLASSIFY_AVX512X16,
345 RTE_ACL_CLASSIFY_AVX512X32,
348 /* swap all bytes in the data to network order */
349 bswap_test_data(test_data, dim, 1);
351 /* store pointers to test data */
352 for (i = 0; i < dim; i++)
353 data[i] = (uint8_t *)&test_data[i];
356 for (i = 0; i != RTE_DIM(alg); i++) {
357 ret = test_classify_alg(acx, test_data, data, dim, alg[i]);
359 printf("Line %i: %s() for alg=%d failed, errno=%d\n",
360 __LINE__, __func__, alg[i], -ret);
365 /* swap data back to cpu order so that next time tests don't fail */
366 bswap_test_data(test_data, dim, 0);
371 test_classify_buid(struct rte_acl_ctx *acx,
372 const struct rte_acl_ipv4vlan_rule *rules, uint32_t num)
376 /* add rules to the context */
377 ret = rte_acl_ipv4vlan_add_rules(acx, rules, num);
379 printf("Line %i: Adding rules to ACL context failed!\n",
384 /* try building the context */
385 ret = rte_acl_ipv4vlan_build(acx, ipv4_7tuple_layout,
386 RTE_ACL_MAX_CATEGORIES);
388 printf("Line %i: Building ACL context failed!\n", __LINE__);
395 #define TEST_CLASSIFY_ITER 4
398 * Test scalar and SSE ACL lookup.
403 struct rte_acl_ctx *acx;
406 acx = rte_acl_create(&acl_param);
408 printf("Line %i: Error creating ACL context!\n", __LINE__);
413 for (i = 0; i != TEST_CLASSIFY_ITER; i++) {
418 rte_acl_reset_rules(acx);
420 ret = test_classify_buid(acx, acl_test_rules,
421 RTE_DIM(acl_test_rules));
423 printf("Line %i, iter: %d: "
424 "Adding rules to ACL context failed!\n",
429 ret = test_classify_run(acx, acl_test_data,
430 RTE_DIM(acl_test_data));
432 printf("Line %i, iter: %d: %s failed!\n",
433 __LINE__, i, __func__);
437 /* reset rules and make sure that classify still works ok. */
438 rte_acl_reset_rules(acx);
439 ret = test_classify_run(acx, acl_test_data,
440 RTE_DIM(acl_test_data));
442 printf("Line %i, iter: %d: %s failed!\n",
443 __LINE__, i, __func__);
453 test_build_ports_range(void)
455 static const struct rte_acl_ipv4vlan_rule test_rules[] = {
457 /* match all packets. */
460 .category_mask = ACL_ALLOW_MASK,
464 .src_port_high = UINT16_MAX,
466 .dst_port_high = UINT16_MAX,
469 /* match all packets with dst ports [54-65280]. */
472 .category_mask = ACL_ALLOW_MASK,
476 .src_port_high = UINT16_MAX,
478 .dst_port_high = 65280,
481 /* match all packets with dst ports [0-52]. */
484 .category_mask = ACL_ALLOW_MASK,
488 .src_port_high = UINT16_MAX,
493 /* match all packets with dst ports [53]. */
496 .category_mask = ACL_ALLOW_MASK,
500 .src_port_high = UINT16_MAX,
505 /* match all packets with dst ports [65279-65535]. */
508 .category_mask = ACL_ALLOW_MASK,
512 .src_port_high = UINT16_MAX,
513 .dst_port_low = 65279,
514 .dst_port_high = UINT16_MAX,
518 static struct ipv4_7tuple test_data[] = {
521 .ip_src = RTE_IPV4(10, 1, 1, 1),
522 .ip_dst = RTE_IPV4(192, 168, 0, 33),
528 .ip_src = RTE_IPV4(127, 84, 33, 1),
529 .ip_dst = RTE_IPV4(1, 2, 3, 4),
535 struct rte_acl_ctx *acx;
537 uint32_t results[RTE_DIM(test_data)];
538 const uint8_t *data[RTE_DIM(test_data)];
540 acx = rte_acl_create(&acl_param);
542 printf("Line %i: Error creating ACL context!\n", __LINE__);
546 /* swap all bytes in the data to network order */
547 bswap_test_data(test_data, RTE_DIM(test_data), 1);
549 /* store pointers to test data */
550 for (i = 0; i != RTE_DIM(test_data); i++)
551 data[i] = (uint8_t *)&test_data[i];
553 for (i = 0; i != RTE_DIM(test_rules); i++) {
555 ret = test_classify_buid(acx, test_rules, i + 1);
557 printf("Line %i, iter: %d: "
558 "Adding rules to ACL context failed!\n",
562 ret = rte_acl_classify(acx, data, results,
565 printf("Line %i, iter: %d: classify failed!\n",
571 for (j = 0; j != RTE_DIM(results); j++) {
572 if (results[j] != test_data[j].allow) {
573 printf("Line %i: Error in allow results at %i "
574 "(expected %"PRIu32" got %"PRIu32")!\n",
575 __LINE__, j, test_data[j].allow,
582 bswap_test_data(test_data, RTE_DIM(test_data), 0);
589 convert_rule(const struct rte_acl_ipv4vlan_rule *ri,
590 struct acl_ipv4vlan_rule *ro)
594 ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto;
595 ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan;
596 ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain;
597 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr;
598 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr;
599 ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low;
600 ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low;
602 ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask;
603 ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask;
604 ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 =
606 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
608 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len;
609 ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 =
611 ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 =
616 * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
617 * RTE_ACL_FIELD_TYPE_BITMASK.
620 convert_rule_1(const struct rte_acl_ipv4vlan_rule *ri,
621 struct acl_ipv4vlan_rule *ro)
625 convert_rule(ri, ro);
626 v = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32;
627 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
628 RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v));
629 v = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32;
630 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 =
631 RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v));
635 * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
636 * RTE_ACL_FIELD_TYPE_RANGE.
639 convert_rule_2(const struct rte_acl_ipv4vlan_rule *ri,
640 struct acl_ipv4vlan_rule *ro)
642 uint32_t hi, lo, mask;
644 convert_rule(ri, ro);
646 mask = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32;
647 mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask));
648 lo = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 & mask;
650 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = lo;
651 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = hi;
653 mask = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32;
654 mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask));
655 lo = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 & mask;
657 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = lo;
658 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = hi;
662 * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule fields.
665 convert_rule_3(const struct rte_acl_ipv4vlan_rule *ri,
666 struct acl_ipv4vlan_rule *ro)
668 struct rte_acl_field t1, t2;
670 convert_rule(ri, ro);
672 t1 = ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD];
673 t2 = ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD];
675 ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD] =
676 ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD];
677 ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD] =
678 ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD];
680 ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD] = t1;
681 ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD] = t2;
685 * Convert rte_acl_ipv4vlan_rule: swap SRC and DST IPv4 address rules.
688 convert_rule_4(const struct rte_acl_ipv4vlan_rule *ri,
689 struct acl_ipv4vlan_rule *ro)
691 struct rte_acl_field t;
693 convert_rule(ri, ro);
695 t = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD];
696 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD] =
697 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD];
699 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD] = t;
703 ipv4vlan_config(struct rte_acl_config *cfg,
704 const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],
705 uint32_t num_categories)
707 static const struct rte_acl_field_def
708 ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = {
710 .type = RTE_ACL_FIELD_TYPE_BITMASK,
711 .size = sizeof(uint8_t),
712 .field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD,
713 .input_index = RTE_ACL_IPV4VLAN_PROTO,
716 .type = RTE_ACL_FIELD_TYPE_BITMASK,
717 .size = sizeof(uint16_t),
718 .field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD,
719 .input_index = RTE_ACL_IPV4VLAN_VLAN,
722 .type = RTE_ACL_FIELD_TYPE_BITMASK,
723 .size = sizeof(uint16_t),
724 .field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD,
725 .input_index = RTE_ACL_IPV4VLAN_VLAN,
728 .type = RTE_ACL_FIELD_TYPE_MASK,
729 .size = sizeof(uint32_t),
730 .field_index = RTE_ACL_IPV4VLAN_SRC_FIELD,
731 .input_index = RTE_ACL_IPV4VLAN_SRC,
734 .type = RTE_ACL_FIELD_TYPE_MASK,
735 .size = sizeof(uint32_t),
736 .field_index = RTE_ACL_IPV4VLAN_DST_FIELD,
737 .input_index = RTE_ACL_IPV4VLAN_DST,
740 .type = RTE_ACL_FIELD_TYPE_RANGE,
741 .size = sizeof(uint16_t),
742 .field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD,
743 .input_index = RTE_ACL_IPV4VLAN_PORTS,
746 .type = RTE_ACL_FIELD_TYPE_RANGE,
747 .size = sizeof(uint16_t),
748 .field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD,
749 .input_index = RTE_ACL_IPV4VLAN_PORTS,
753 memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs));
754 cfg->num_fields = RTE_DIM(ipv4_defs);
756 cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset =
757 layout[RTE_ACL_IPV4VLAN_PROTO];
758 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset =
759 layout[RTE_ACL_IPV4VLAN_VLAN];
760 cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset =
761 layout[RTE_ACL_IPV4VLAN_VLAN] +
762 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size;
763 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset =
764 layout[RTE_ACL_IPV4VLAN_SRC];
765 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset =
766 layout[RTE_ACL_IPV4VLAN_DST];
767 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset =
768 layout[RTE_ACL_IPV4VLAN_PORTS];
769 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset =
770 layout[RTE_ACL_IPV4VLAN_PORTS] +
771 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size;
773 cfg->num_categories = num_categories;
777 convert_rules(struct rte_acl_ctx *acx,
778 void (*convert)(const struct rte_acl_ipv4vlan_rule *,
779 struct acl_ipv4vlan_rule *),
780 const struct rte_acl_ipv4vlan_rule *rules, uint32_t num)
784 struct acl_ipv4vlan_rule r;
786 for (i = 0; i != num; i++) {
787 convert(rules + i, &r);
788 rc = rte_acl_add_rules(acx, (struct rte_acl_rule *)&r, 1);
790 printf("Line %i: Adding rule %u to ACL context "
791 "failed with error code: %d\n",
801 convert_config(struct rte_acl_config *cfg)
803 ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
807 * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_BITMASK.
810 convert_config_1(struct rte_acl_config *cfg)
812 ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
813 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK;
814 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK;
818 * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_RANGE.
821 convert_config_2(struct rte_acl_config *cfg)
823 ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
824 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE;
825 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE;
829 * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule definitions.
832 convert_config_3(struct rte_acl_config *cfg)
834 struct rte_acl_field_def t1, t2;
836 ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
838 t1 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD];
839 t2 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD];
841 /* swap VLAN1 and SRCP rule definition. */
842 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD] =
843 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD];
844 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].field_index = t1.field_index;
845 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].input_index = t1.input_index;
847 /* swap VLAN2 and DSTP rule definition. */
848 cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD] =
849 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD];
850 cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].field_index = t2.field_index;
851 cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].input_index = t2.input_index;
853 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].type = t1.type;
854 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size = t1.size;
855 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = t1.offset;
857 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].type = t2.type;
858 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].size = t2.size;
859 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = t2.offset;
863 * Convert rte_acl_ipv4vlan_rule: swap SRC and DST ip address rule definitions.
866 convert_config_4(struct rte_acl_config *cfg)
868 struct rte_acl_field_def t;
870 ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
872 t = cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD];
874 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD] =
875 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD];
876 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].field_index = t.field_index;
877 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].input_index = t.input_index;
879 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = t.type;
880 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].size = t.size;
881 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = t.offset;
886 build_convert_rules(struct rte_acl_ctx *acx,
887 void (*config)(struct rte_acl_config *),
890 struct rte_acl_config cfg;
892 memset(&cfg, 0, sizeof(cfg));
894 cfg.max_size = max_size;
895 return rte_acl_build(acx, &cfg);
899 test_convert_rules(const char *desc,
900 void (*config)(struct rte_acl_config *),
901 void (*convert)(const struct rte_acl_ipv4vlan_rule *,
902 struct acl_ipv4vlan_rule *))
904 struct rte_acl_ctx *acx;
907 static const size_t mem_sizes[] = {0, -1};
909 printf("running %s(%s)\n", __func__, desc);
911 acx = rte_acl_create(&acl_param);
913 printf("Line %i: Error creating ACL context!\n", __LINE__);
917 rc = convert_rules(acx, convert, acl_test_rules,
918 RTE_DIM(acl_test_rules));
920 printf("Line %i: Error converting ACL rules!\n", __LINE__);
922 for (i = 0; rc == 0 && i != RTE_DIM(mem_sizes); i++) {
924 rc = build_convert_rules(acx, config, mem_sizes[i]);
926 printf("Line %i: Error @ build_convert_rules(%zu)!\n",
927 __LINE__, mem_sizes[i]);
931 rc = test_classify_run(acx, acl_test_data,
932 RTE_DIM(acl_test_data));
934 printf("%s failed at line %i, max_size=%zu\n",
935 __func__, __LINE__, mem_sizes[i]);
945 static const struct {
947 void (*config)(struct rte_acl_config *);
948 void (*convert)(const struct rte_acl_ipv4vlan_rule *,
949 struct acl_ipv4vlan_rule *);
950 } convert_param[] = {
952 "acl_ipv4vlan_tuple",
957 "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_BITMASK type "
963 "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_RANGE type "
969 "acl_ipv4vlan_tuple: swap VLAN and PORTs order",
974 "acl_ipv4vlan_tuple: swap SRC and DST IPv4 order",
983 for (i = 0; i != RTE_DIM(convert_param); i++) {
984 rc = test_convert_rules(convert_param[i].desc,
985 convert_param[i].config,
986 convert_param[i].convert);
988 printf("%s for test-case: %s failed, error code: %d;\n",
989 __func__, convert_param[i].desc, rc);
998 * Test wrong layout behavior
999 * This test supplies the ACL context with invalid layout, which results in
1000 * ACL matching the wrong stuff. However, it should match the wrong stuff
1001 * the right way. We switch around source and destination addresses,
1002 * source and destination ports, and protocol will point to first byte of
1006 test_invalid_layout(void)
1008 struct rte_acl_ctx *acx;
1011 uint32_t results[RTE_DIM(invalid_layout_data)];
1012 const uint8_t *data[RTE_DIM(invalid_layout_data)];
1014 const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {
1015 /* proto points to destination port's first byte */
1016 offsetof(struct ipv4_7tuple, port_dst),
1018 0, /* VLAN not used */
1020 /* src and dst addresses are swapped */
1021 offsetof(struct ipv4_7tuple, ip_dst),
1022 offsetof(struct ipv4_7tuple, ip_src),
1025 * we can't swap ports here, so we will swap
1028 offsetof(struct ipv4_7tuple, port_src),
1031 acx = rte_acl_create(&acl_param);
1033 printf("Line %i: Error creating ACL context!\n", __LINE__);
1037 /* putting a lot of rules into the context results in greater
1038 * coverage numbers. it doesn't matter if they are identical */
1039 for (i = 0; i < 1000; i++) {
1040 /* add rules to the context */
1041 ret = rte_acl_ipv4vlan_add_rules(acx, invalid_layout_rules,
1042 RTE_DIM(invalid_layout_rules));
1044 printf("Line %i: Adding rules to ACL context failed!\n",
1051 /* try building the context */
1052 ret = rte_acl_ipv4vlan_build(acx, layout, 1);
1054 printf("Line %i: Building ACL context failed!\n", __LINE__);
1059 /* swap all bytes in the data to network order */
1060 bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 1);
1063 for (i = 0; i < (int) RTE_DIM(invalid_layout_data); i++) {
1064 data[i] = (uint8_t *)&invalid_layout_data[i];
1067 /* classify tuples */
1068 ret = rte_acl_classify_alg(acx, data, results,
1069 RTE_DIM(results), 1, RTE_ACL_CLASSIFY_SCALAR);
1071 printf("Line %i: SSE classify failed!\n", __LINE__);
1076 for (i = 0; i < (int) RTE_DIM(results); i++) {
1077 if (results[i] != invalid_layout_data[i].allow) {
1078 printf("Line %i: Wrong results at %i "
1079 "(result=%u, should be %u)!\n",
1080 __LINE__, i, results[i],
1081 invalid_layout_data[i].allow);
1086 /* classify tuples (scalar) */
1087 ret = rte_acl_classify_alg(acx, data, results, RTE_DIM(results), 1,
1088 RTE_ACL_CLASSIFY_SCALAR);
1091 printf("Line %i: Scalar classify failed!\n", __LINE__);
1096 for (i = 0; i < (int) RTE_DIM(results); i++) {
1097 if (results[i] != invalid_layout_data[i].allow) {
1098 printf("Line %i: Wrong results at %i "
1099 "(result=%u, should be %u)!\n",
1100 __LINE__, i, results[i],
1101 invalid_layout_data[i].allow);
1108 /* swap data back to cpu order so that next time tests don't fail */
1109 bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0);
1114 /* swap data back to cpu order so that next time tests don't fail */
1115 bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0);
1123 * Test creating and finding ACL contexts, and adding rules
1126 test_create_find_add(void)
1128 struct rte_acl_param param;
1129 struct rte_acl_ctx *acx, *acx2, *tmp;
1130 struct rte_acl_ipv4vlan_rule rules[LEN];
1132 const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0};
1134 const char *acx_name = "acx";
1135 const char *acx2_name = "acx2";
1138 /* create two contexts */
1139 memcpy(¶m, &acl_param, sizeof(param));
1140 param.max_rule_num = 2;
1142 param.name = acx_name;
1143 acx = rte_acl_create(¶m);
1145 printf("Line %i: Error creating %s!\n", __LINE__, acx_name);
1149 param.name = acx2_name;
1150 acx2 = rte_acl_create(¶m);
1151 if (acx2 == NULL || acx2 == acx) {
1152 printf("Line %i: Error creating %s!\n", __LINE__, acx2_name);
1157 /* try to create third one, with an existing name */
1158 param.name = acx_name;
1159 tmp = rte_acl_create(¶m);
1161 printf("Line %i: Creating context with existing name "
1169 param.name = acx2_name;
1170 tmp = rte_acl_create(¶m);
1172 printf("Line %i: Creating context with existing "
1173 "name test 2 failed!\n",
1180 /* try to find existing ACL contexts */
1181 tmp = rte_acl_find_existing(acx_name);
1183 printf("Line %i: Finding %s failed!\n", __LINE__, acx_name);
1189 tmp = rte_acl_find_existing(acx2_name);
1191 printf("Line %i: Finding %s failed!\n", __LINE__, acx2_name);
1197 /* try to find non-existing context */
1198 tmp = rte_acl_find_existing("invalid");
1200 printf("Line %i: Non-existent ACL context found!\n", __LINE__);
1208 /* create valid (but severely limited) acx */
1209 memcpy(¶m, &acl_param, sizeof(param));
1210 param.max_rule_num = LEN;
1212 acx = rte_acl_create(¶m);
1214 printf("Line %i: Error creating %s!\n", __LINE__, param.name);
1218 /* create dummy acl */
1219 for (i = 0; i < LEN; i++) {
1220 memcpy(&rules[i], &acl_rule,
1221 sizeof(struct rte_acl_ipv4vlan_rule));
1223 rules[i].data.userdata = i + 1;
1224 /* one rule per category */
1225 rules[i].data.category_mask = 1 << i;
1228 /* try filling up the context */
1229 ret = rte_acl_ipv4vlan_add_rules(acx, rules, LEN);
1231 printf("Line %i: Adding %i rules to ACL context failed!\n",
1236 /* try adding to a (supposedly) full context */
1237 ret = rte_acl_ipv4vlan_add_rules(acx, rules, 1);
1239 printf("Line %i: Adding rules to full ACL context should"
1240 "have failed!\n", __LINE__);
1244 /* try building the context */
1245 ret = rte_acl_ipv4vlan_build(acx, layout, RTE_ACL_MAX_CATEGORIES);
1247 printf("Line %i: Building ACL context failed!\n", __LINE__);
1262 * test various invalid rules
1265 test_invalid_rules(void)
1267 struct rte_acl_ctx *acx;
1270 struct rte_acl_ipv4vlan_rule rule;
1272 acx = rte_acl_create(&acl_param);
1274 printf("Line %i: Error creating ACL context!\n", __LINE__);
1278 /* test inverted high/low source and destination ports.
1279 * originally, there was a problem with memory consumption when using
1282 /* create dummy acl */
1283 memcpy(&rule, &acl_rule, sizeof(struct rte_acl_ipv4vlan_rule));
1284 rule.data.userdata = 1;
1285 rule.dst_port_low = 0xfff0;
1286 rule.dst_port_high = 0x0010;
1288 /* add rules to context and try to build it */
1289 ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1291 printf("Line %i: Adding rules to ACL context "
1292 "should have failed!\n", __LINE__);
1296 rule.dst_port_low = 0x0;
1297 rule.dst_port_high = 0xffff;
1298 rule.src_port_low = 0xfff0;
1299 rule.src_port_high = 0x0010;
1301 /* add rules to context and try to build it */
1302 ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1304 printf("Line %i: Adding rules to ACL context "
1305 "should have failed!\n", __LINE__);
1309 rule.dst_port_low = 0x0;
1310 rule.dst_port_high = 0xffff;
1311 rule.src_port_low = 0x0;
1312 rule.src_port_high = 0xffff;
1314 rule.dst_mask_len = 33;
1316 /* add rules to context and try to build it */
1317 ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1319 printf("Line %i: Adding rules to ACL context "
1320 "should have failed!\n", __LINE__);
1324 rule.dst_mask_len = 0;
1325 rule.src_mask_len = 33;
1327 /* add rules to context and try to build it */
1328 ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1330 printf("Line %i: Adding rules to ACL context "
1331 "should have failed!\n", __LINE__);
1346 * test functions by passing invalid or
1347 * non-workable parameters.
1349 * we do very limited testing of classify functions here
1350 * because those are performance-critical and
1351 * thus don't do much parameter checking.
1354 test_invalid_parameters(void)
1356 struct rte_acl_param param;
1357 struct rte_acl_ctx *acx;
1358 struct rte_acl_ipv4vlan_rule rule;
1361 uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0};
1369 acx = rte_acl_create(NULL);
1371 printf("Line %i: ACL context creation with NULL param "
1372 "should have failed!\n", __LINE__);
1377 /* zero rule size */
1378 memcpy(¶m, &acl_param, sizeof(param));
1379 param.rule_size = 0;
1381 acx = rte_acl_create(¶m);
1383 printf("Line %i: ACL context creation with zero rule len "
1384 "failed!\n", __LINE__);
1389 /* zero max rule num */
1390 memcpy(¶m, &acl_param, sizeof(param));
1391 param.max_rule_num = 0;
1393 acx = rte_acl_create(¶m);
1395 printf("Line %i: ACL context creation with zero rule num "
1396 "failed!\n", __LINE__);
1401 if (rte_eal_has_hugepages()) {
1402 /* invalid NUMA node */
1403 memcpy(¶m, &acl_param, sizeof(param));
1404 param.socket_id = RTE_MAX_NUMA_NODES + 1;
1406 acx = rte_acl_create(¶m);
1408 printf("Line %i: ACL context creation with invalid "
1409 "NUMA should have failed!\n", __LINE__);
1416 memcpy(¶m, &acl_param, sizeof(param));
1419 acx = rte_acl_create(¶m);
1421 printf("Line %i: ACL context creation with NULL name "
1422 "should have failed!\n", __LINE__);
1428 * rte_acl_find_existing
1431 acx = rte_acl_find_existing(NULL);
1433 printf("Line %i: NULL ACL context found!\n", __LINE__);
1439 * rte_acl_ipv4vlan_add_rules
1442 /* initialize everything */
1443 memcpy(¶m, &acl_param, sizeof(param));
1444 acx = rte_acl_create(¶m);
1446 printf("Line %i: ACL context creation failed!\n", __LINE__);
1450 memcpy(&rule, &acl_rule, sizeof(rule));
1453 result = rte_acl_ipv4vlan_add_rules(NULL, &rule, 1);
1455 printf("Line %i: Adding rules with NULL ACL context "
1456 "should have failed!\n", __LINE__);
1462 result = rte_acl_ipv4vlan_add_rules(acx, NULL, 1);
1464 printf("Line %i: Adding NULL rule to ACL context "
1465 "should have failed!\n", __LINE__);
1470 /* zero count (should succeed) */
1471 result = rte_acl_ipv4vlan_add_rules(acx, &rule, 0);
1473 printf("Line %i: Adding 0 rules to ACL context failed!\n",
1479 /* free ACL context */
1484 * rte_acl_ipv4vlan_build
1487 /* reinitialize context */
1488 memcpy(¶m, &acl_param, sizeof(param));
1489 acx = rte_acl_create(¶m);
1491 printf("Line %i: ACL context creation failed!\n", __LINE__);
1496 result = rte_acl_ipv4vlan_build(NULL, layout, 1);
1498 printf("Line %i: Building with NULL context "
1499 "should have failed!\n", __LINE__);
1505 result = rte_acl_ipv4vlan_build(acx, NULL, 1);
1507 printf("Line %i: Building with NULL layout "
1508 "should have failed!\n", __LINE__);
1513 /* zero categories (should not fail) */
1514 result = rte_acl_ipv4vlan_build(acx, layout, 0);
1516 printf("Line %i: Building with 0 categories should fail!\n",
1522 /* SSE classify test */
1524 /* cover zero categories in classify (should not fail) */
1525 result = rte_acl_classify(acx, NULL, NULL, 0, 0);
1527 printf("Line %i: SSE classify with zero categories "
1528 "failed!\n", __LINE__);
1533 /* cover invalid but positive categories in classify */
1534 result = rte_acl_classify(acx, NULL, NULL, 0, 3);
1536 printf("Line %i: SSE classify with 3 categories "
1537 "should have failed!\n", __LINE__);
1542 /* scalar classify test */
1544 /* cover zero categories in classify (should not fail) */
1545 result = rte_acl_classify_alg(acx, NULL, NULL, 0, 0,
1546 RTE_ACL_CLASSIFY_SCALAR);
1548 printf("Line %i: Scalar classify with zero categories "
1549 "failed!\n", __LINE__);
1554 /* cover invalid but positive categories in classify */
1555 result = rte_acl_classify(acx, NULL, NULL, 0, 3);
1557 printf("Line %i: Scalar classify with 3 categories "
1558 "should have failed!\n", __LINE__);
1563 /* free ACL context */
1568 * make sure void functions don't crash with NULL parameters
1579 * Various tests that don't test much but improve coverage
1584 struct rte_acl_param param;
1585 struct rte_acl_ctx *acx;
1587 /* create context */
1588 memcpy(¶m, &acl_param, sizeof(param));
1590 acx = rte_acl_create(¶m);
1592 printf("Line %i: Error creating ACL context!\n", __LINE__);
1596 /* dump context with rules - useful for coverage */
1597 rte_acl_list_dump();
1607 get_u32_range_max(void)
1612 for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++)
1613 max = RTE_MAX(max, acl_u32_range_test_rules[i].src_mask_len);
1618 get_u32_range_min(void)
1623 for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++)
1624 min = RTE_MIN(min, acl_u32_range_test_rules[i].src_addr);
1628 static const struct rte_acl_ipv4vlan_rule *
1629 find_u32_range_rule(uint32_t val)
1633 for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++) {
1634 if (val >= acl_u32_range_test_rules[i].src_addr &&
1635 val <= acl_u32_range_test_rules[i].src_mask_len)
1636 return acl_u32_range_test_rules + i;
1642 fill_u32_range_data(struct ipv4_7tuple tdata[], uint32_t start, uint32_t num)
1645 const struct rte_acl_ipv4vlan_rule *r;
1647 for (i = 0; i != num; i++) {
1648 tdata[i].ip_src = start + i;
1649 r = find_u32_range_rule(start + i);
1651 tdata[i].allow = r->data.userdata;
1656 test_u32_range(void)
1659 uint32_t i, k, max, min;
1660 struct rte_acl_ctx *acx;
1661 struct acl_ipv4vlan_rule r;
1662 struct ipv4_7tuple test_data[64];
1664 acx = rte_acl_create(&acl_param);
1666 printf("%s#%i: Error creating ACL context!\n",
1667 __func__, __LINE__);
1671 for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++) {
1672 convert_rule(&acl_u32_range_test_rules[i], &r);
1673 rc = rte_acl_add_rules(acx, (struct rte_acl_rule *)&r, 1);
1675 printf("%s#%i: Adding rule to ACL context "
1676 "failed with error code: %d\n",
1677 __func__, __LINE__, rc);
1683 rc = build_convert_rules(acx, convert_config_2, 0);
1685 printf("%s#%i Error @ build_convert_rules!\n",
1686 __func__, __LINE__);
1691 max = get_u32_range_max();
1692 min = get_u32_range_min();
1694 max = RTE_MAX(max, max + 1);
1695 min = RTE_MIN(min, min - 1);
1697 printf("%s#%d starting range test from %u to %u\n",
1698 __func__, __LINE__, min, max);
1700 for (i = min; i <= max; i += k) {
1702 k = RTE_MIN(max - i + 1, RTE_DIM(test_data));
1704 memset(test_data, 0, sizeof(test_data));
1705 fill_u32_range_data(test_data, i, k);
1707 rc = test_classify_run(acx, test_data, k);
1709 printf("%s#%d failed at [%u, %u) interval\n",
1710 __func__, __LINE__, i, i + k);
1722 if (test_invalid_parameters() < 0)
1724 if (test_invalid_rules() < 0)
1726 if (test_create_find_add() < 0)
1728 if (test_invalid_layout() < 0)
1730 if (test_misc() < 0)
1732 if (test_classify() < 0)
1734 if (test_build_ports_range() < 0)
1736 if (test_convert() < 0)
1738 if (test_u32_range() < 0)
1744 REGISTER_TEST_COMMAND(acl_autotest, test_acl);