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,
346 /* swap all bytes in the data to network order */
347 bswap_test_data(test_data, dim, 1);
349 /* store pointers to test data */
350 for (i = 0; i < dim; i++)
351 data[i] = (uint8_t *)&test_data[i];
354 for (i = 0; i != RTE_DIM(alg); i++) {
355 ret = test_classify_alg(acx, test_data, data, dim, alg[i]);
357 printf("Line %i: %s() for alg=%d failed, errno=%d\n",
358 __LINE__, __func__, alg[i], -ret);
363 /* swap data back to cpu order so that next time tests don't fail */
364 bswap_test_data(test_data, dim, 0);
369 test_classify_buid(struct rte_acl_ctx *acx,
370 const struct rte_acl_ipv4vlan_rule *rules, uint32_t num)
374 /* add rules to the context */
375 ret = rte_acl_ipv4vlan_add_rules(acx, rules, num);
377 printf("Line %i: Adding rules to ACL context failed!\n",
382 /* try building the context */
383 ret = rte_acl_ipv4vlan_build(acx, ipv4_7tuple_layout,
384 RTE_ACL_MAX_CATEGORIES);
386 printf("Line %i: Building ACL context failed!\n", __LINE__);
393 #define TEST_CLASSIFY_ITER 4
396 * Test scalar and SSE ACL lookup.
401 struct rte_acl_ctx *acx;
404 acx = rte_acl_create(&acl_param);
406 printf("Line %i: Error creating ACL context!\n", __LINE__);
411 for (i = 0; i != TEST_CLASSIFY_ITER; i++) {
416 rte_acl_reset_rules(acx);
418 ret = test_classify_buid(acx, acl_test_rules,
419 RTE_DIM(acl_test_rules));
421 printf("Line %i, iter: %d: "
422 "Adding rules to ACL context failed!\n",
427 ret = test_classify_run(acx, acl_test_data,
428 RTE_DIM(acl_test_data));
430 printf("Line %i, iter: %d: %s failed!\n",
431 __LINE__, i, __func__);
435 /* reset rules and make sure that classify still works ok. */
436 rte_acl_reset_rules(acx);
437 ret = test_classify_run(acx, acl_test_data,
438 RTE_DIM(acl_test_data));
440 printf("Line %i, iter: %d: %s failed!\n",
441 __LINE__, i, __func__);
451 test_build_ports_range(void)
453 static const struct rte_acl_ipv4vlan_rule test_rules[] = {
455 /* match all packets. */
458 .category_mask = ACL_ALLOW_MASK,
462 .src_port_high = UINT16_MAX,
464 .dst_port_high = UINT16_MAX,
467 /* match all packets with dst ports [54-65280]. */
470 .category_mask = ACL_ALLOW_MASK,
474 .src_port_high = UINT16_MAX,
476 .dst_port_high = 65280,
479 /* match all packets with dst ports [0-52]. */
482 .category_mask = ACL_ALLOW_MASK,
486 .src_port_high = UINT16_MAX,
491 /* match all packets with dst ports [53]. */
494 .category_mask = ACL_ALLOW_MASK,
498 .src_port_high = UINT16_MAX,
503 /* match all packets with dst ports [65279-65535]. */
506 .category_mask = ACL_ALLOW_MASK,
510 .src_port_high = UINT16_MAX,
511 .dst_port_low = 65279,
512 .dst_port_high = UINT16_MAX,
516 static struct ipv4_7tuple test_data[] = {
519 .ip_src = RTE_IPV4(10, 1, 1, 1),
520 .ip_dst = RTE_IPV4(192, 168, 0, 33),
526 .ip_src = RTE_IPV4(127, 84, 33, 1),
527 .ip_dst = RTE_IPV4(1, 2, 3, 4),
533 struct rte_acl_ctx *acx;
535 uint32_t results[RTE_DIM(test_data)];
536 const uint8_t *data[RTE_DIM(test_data)];
538 acx = rte_acl_create(&acl_param);
540 printf("Line %i: Error creating ACL context!\n", __LINE__);
544 /* swap all bytes in the data to network order */
545 bswap_test_data(test_data, RTE_DIM(test_data), 1);
547 /* store pointers to test data */
548 for (i = 0; i != RTE_DIM(test_data); i++)
549 data[i] = (uint8_t *)&test_data[i];
551 for (i = 0; i != RTE_DIM(test_rules); i++) {
553 ret = test_classify_buid(acx, test_rules, i + 1);
555 printf("Line %i, iter: %d: "
556 "Adding rules to ACL context failed!\n",
560 ret = rte_acl_classify(acx, data, results,
563 printf("Line %i, iter: %d: classify failed!\n",
569 for (j = 0; j != RTE_DIM(results); j++) {
570 if (results[j] != test_data[j].allow) {
571 printf("Line %i: Error in allow results at %i "
572 "(expected %"PRIu32" got %"PRIu32")!\n",
573 __LINE__, j, test_data[j].allow,
580 bswap_test_data(test_data, RTE_DIM(test_data), 0);
587 convert_rule(const struct rte_acl_ipv4vlan_rule *ri,
588 struct acl_ipv4vlan_rule *ro)
592 ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto;
593 ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan;
594 ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain;
595 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr;
596 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr;
597 ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low;
598 ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low;
600 ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask;
601 ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask;
602 ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 =
604 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
606 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len;
607 ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 =
609 ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 =
614 * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
615 * RTE_ACL_FIELD_TYPE_BITMASK.
618 convert_rule_1(const struct rte_acl_ipv4vlan_rule *ri,
619 struct acl_ipv4vlan_rule *ro)
623 convert_rule(ri, ro);
624 v = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32;
625 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
626 RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v));
627 v = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32;
628 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 =
629 RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v));
633 * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
634 * RTE_ACL_FIELD_TYPE_RANGE.
637 convert_rule_2(const struct rte_acl_ipv4vlan_rule *ri,
638 struct acl_ipv4vlan_rule *ro)
640 uint32_t hi, lo, mask;
642 convert_rule(ri, ro);
644 mask = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32;
645 mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask));
646 lo = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 & mask;
648 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = lo;
649 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = hi;
651 mask = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32;
652 mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask));
653 lo = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 & mask;
655 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = lo;
656 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = hi;
660 * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule fields.
663 convert_rule_3(const struct rte_acl_ipv4vlan_rule *ri,
664 struct acl_ipv4vlan_rule *ro)
666 struct rte_acl_field t1, t2;
668 convert_rule(ri, ro);
670 t1 = ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD];
671 t2 = ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD];
673 ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD] =
674 ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD];
675 ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD] =
676 ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD];
678 ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD] = t1;
679 ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD] = t2;
683 * Convert rte_acl_ipv4vlan_rule: swap SRC and DST IPv4 address rules.
686 convert_rule_4(const struct rte_acl_ipv4vlan_rule *ri,
687 struct acl_ipv4vlan_rule *ro)
689 struct rte_acl_field t;
691 convert_rule(ri, ro);
693 t = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD];
694 ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD] =
695 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD];
697 ro->field[RTE_ACL_IPV4VLAN_DST_FIELD] = t;
701 ipv4vlan_config(struct rte_acl_config *cfg,
702 const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],
703 uint32_t num_categories)
705 static const struct rte_acl_field_def
706 ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = {
708 .type = RTE_ACL_FIELD_TYPE_BITMASK,
709 .size = sizeof(uint8_t),
710 .field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD,
711 .input_index = RTE_ACL_IPV4VLAN_PROTO,
714 .type = RTE_ACL_FIELD_TYPE_BITMASK,
715 .size = sizeof(uint16_t),
716 .field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD,
717 .input_index = RTE_ACL_IPV4VLAN_VLAN,
720 .type = RTE_ACL_FIELD_TYPE_BITMASK,
721 .size = sizeof(uint16_t),
722 .field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD,
723 .input_index = RTE_ACL_IPV4VLAN_VLAN,
726 .type = RTE_ACL_FIELD_TYPE_MASK,
727 .size = sizeof(uint32_t),
728 .field_index = RTE_ACL_IPV4VLAN_SRC_FIELD,
729 .input_index = RTE_ACL_IPV4VLAN_SRC,
732 .type = RTE_ACL_FIELD_TYPE_MASK,
733 .size = sizeof(uint32_t),
734 .field_index = RTE_ACL_IPV4VLAN_DST_FIELD,
735 .input_index = RTE_ACL_IPV4VLAN_DST,
738 .type = RTE_ACL_FIELD_TYPE_RANGE,
739 .size = sizeof(uint16_t),
740 .field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD,
741 .input_index = RTE_ACL_IPV4VLAN_PORTS,
744 .type = RTE_ACL_FIELD_TYPE_RANGE,
745 .size = sizeof(uint16_t),
746 .field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD,
747 .input_index = RTE_ACL_IPV4VLAN_PORTS,
751 memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs));
752 cfg->num_fields = RTE_DIM(ipv4_defs);
754 cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset =
755 layout[RTE_ACL_IPV4VLAN_PROTO];
756 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset =
757 layout[RTE_ACL_IPV4VLAN_VLAN];
758 cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset =
759 layout[RTE_ACL_IPV4VLAN_VLAN] +
760 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size;
761 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset =
762 layout[RTE_ACL_IPV4VLAN_SRC];
763 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset =
764 layout[RTE_ACL_IPV4VLAN_DST];
765 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset =
766 layout[RTE_ACL_IPV4VLAN_PORTS];
767 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset =
768 layout[RTE_ACL_IPV4VLAN_PORTS] +
769 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size;
771 cfg->num_categories = num_categories;
775 convert_rules(struct rte_acl_ctx *acx,
776 void (*convert)(const struct rte_acl_ipv4vlan_rule *,
777 struct acl_ipv4vlan_rule *),
778 const struct rte_acl_ipv4vlan_rule *rules, uint32_t num)
782 struct acl_ipv4vlan_rule r;
784 for (i = 0; i != num; i++) {
785 convert(rules + i, &r);
786 rc = rte_acl_add_rules(acx, (struct rte_acl_rule *)&r, 1);
788 printf("Line %i: Adding rule %u to ACL context "
789 "failed with error code: %d\n",
799 convert_config(struct rte_acl_config *cfg)
801 ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
805 * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_BITMASK.
808 convert_config_1(struct rte_acl_config *cfg)
810 ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
811 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK;
812 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK;
816 * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_RANGE.
819 convert_config_2(struct rte_acl_config *cfg)
821 ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
822 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE;
823 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE;
827 * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule definitions.
830 convert_config_3(struct rte_acl_config *cfg)
832 struct rte_acl_field_def t1, t2;
834 ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
836 t1 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD];
837 t2 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD];
839 /* swap VLAN1 and SRCP rule definition. */
840 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD] =
841 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD];
842 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].field_index = t1.field_index;
843 cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].input_index = t1.input_index;
845 /* swap VLAN2 and DSTP rule definition. */
846 cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD] =
847 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD];
848 cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].field_index = t2.field_index;
849 cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].input_index = t2.input_index;
851 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].type = t1.type;
852 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size = t1.size;
853 cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = t1.offset;
855 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].type = t2.type;
856 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].size = t2.size;
857 cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = t2.offset;
861 * Convert rte_acl_ipv4vlan_rule: swap SRC and DST ip address rule definitions.
864 convert_config_4(struct rte_acl_config *cfg)
866 struct rte_acl_field_def t;
868 ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
870 t = cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD];
872 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD] =
873 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD];
874 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].field_index = t.field_index;
875 cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].input_index = t.input_index;
877 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = t.type;
878 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].size = t.size;
879 cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = t.offset;
884 build_convert_rules(struct rte_acl_ctx *acx,
885 void (*config)(struct rte_acl_config *),
888 struct rte_acl_config cfg;
890 memset(&cfg, 0, sizeof(cfg));
892 cfg.max_size = max_size;
893 return rte_acl_build(acx, &cfg);
897 test_convert_rules(const char *desc,
898 void (*config)(struct rte_acl_config *),
899 void (*convert)(const struct rte_acl_ipv4vlan_rule *,
900 struct acl_ipv4vlan_rule *))
902 struct rte_acl_ctx *acx;
905 static const size_t mem_sizes[] = {0, -1};
907 printf("running %s(%s)\n", __func__, desc);
909 acx = rte_acl_create(&acl_param);
911 printf("Line %i: Error creating ACL context!\n", __LINE__);
915 rc = convert_rules(acx, convert, acl_test_rules,
916 RTE_DIM(acl_test_rules));
918 printf("Line %i: Error converting ACL rules!\n", __LINE__);
920 for (i = 0; rc == 0 && i != RTE_DIM(mem_sizes); i++) {
922 rc = build_convert_rules(acx, config, mem_sizes[i]);
924 printf("Line %i: Error @ build_convert_rules(%zu)!\n",
925 __LINE__, mem_sizes[i]);
929 rc = test_classify_run(acx, acl_test_data,
930 RTE_DIM(acl_test_data));
932 printf("%s failed at line %i, max_size=%zu\n",
933 __func__, __LINE__, mem_sizes[i]);
943 static const struct {
945 void (*config)(struct rte_acl_config *);
946 void (*convert)(const struct rte_acl_ipv4vlan_rule *,
947 struct acl_ipv4vlan_rule *);
948 } convert_param[] = {
950 "acl_ipv4vlan_tuple",
955 "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_BITMASK type "
961 "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_RANGE type "
967 "acl_ipv4vlan_tuple: swap VLAN and PORTs order",
972 "acl_ipv4vlan_tuple: swap SRC and DST IPv4 order",
981 for (i = 0; i != RTE_DIM(convert_param); i++) {
982 rc = test_convert_rules(convert_param[i].desc,
983 convert_param[i].config,
984 convert_param[i].convert);
986 printf("%s for test-case: %s failed, error code: %d;\n",
987 __func__, convert_param[i].desc, rc);
996 * Test wrong layout behavior
997 * This test supplies the ACL context with invalid layout, which results in
998 * ACL matching the wrong stuff. However, it should match the wrong stuff
999 * the right way. We switch around source and destination addresses,
1000 * source and destination ports, and protocol will point to first byte of
1004 test_invalid_layout(void)
1006 struct rte_acl_ctx *acx;
1009 uint32_t results[RTE_DIM(invalid_layout_data)];
1010 const uint8_t *data[RTE_DIM(invalid_layout_data)];
1012 const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {
1013 /* proto points to destination port's first byte */
1014 offsetof(struct ipv4_7tuple, port_dst),
1016 0, /* VLAN not used */
1018 /* src and dst addresses are swapped */
1019 offsetof(struct ipv4_7tuple, ip_dst),
1020 offsetof(struct ipv4_7tuple, ip_src),
1023 * we can't swap ports here, so we will swap
1026 offsetof(struct ipv4_7tuple, port_src),
1029 acx = rte_acl_create(&acl_param);
1031 printf("Line %i: Error creating ACL context!\n", __LINE__);
1035 /* putting a lot of rules into the context results in greater
1036 * coverage numbers. it doesn't matter if they are identical */
1037 for (i = 0; i < 1000; i++) {
1038 /* add rules to the context */
1039 ret = rte_acl_ipv4vlan_add_rules(acx, invalid_layout_rules,
1040 RTE_DIM(invalid_layout_rules));
1042 printf("Line %i: Adding rules to ACL context failed!\n",
1049 /* try building the context */
1050 ret = rte_acl_ipv4vlan_build(acx, layout, 1);
1052 printf("Line %i: Building ACL context failed!\n", __LINE__);
1057 /* swap all bytes in the data to network order */
1058 bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 1);
1061 for (i = 0; i < (int) RTE_DIM(invalid_layout_data); i++) {
1062 data[i] = (uint8_t *)&invalid_layout_data[i];
1065 /* classify tuples */
1066 ret = rte_acl_classify_alg(acx, data, results,
1067 RTE_DIM(results), 1, RTE_ACL_CLASSIFY_SCALAR);
1069 printf("Line %i: SSE classify failed!\n", __LINE__);
1074 for (i = 0; i < (int) RTE_DIM(results); i++) {
1075 if (results[i] != invalid_layout_data[i].allow) {
1076 printf("Line %i: Wrong results at %i "
1077 "(result=%u, should be %u)!\n",
1078 __LINE__, i, results[i],
1079 invalid_layout_data[i].allow);
1084 /* classify tuples (scalar) */
1085 ret = rte_acl_classify_alg(acx, data, results, RTE_DIM(results), 1,
1086 RTE_ACL_CLASSIFY_SCALAR);
1089 printf("Line %i: Scalar classify failed!\n", __LINE__);
1094 for (i = 0; i < (int) RTE_DIM(results); i++) {
1095 if (results[i] != invalid_layout_data[i].allow) {
1096 printf("Line %i: Wrong results at %i "
1097 "(result=%u, should be %u)!\n",
1098 __LINE__, i, results[i],
1099 invalid_layout_data[i].allow);
1106 /* swap data back to cpu order so that next time tests don't fail */
1107 bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0);
1112 /* swap data back to cpu order so that next time tests don't fail */
1113 bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0);
1121 * Test creating and finding ACL contexts, and adding rules
1124 test_create_find_add(void)
1126 struct rte_acl_param param;
1127 struct rte_acl_ctx *acx, *acx2, *tmp;
1128 struct rte_acl_ipv4vlan_rule rules[LEN];
1130 const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0};
1132 const char *acx_name = "acx";
1133 const char *acx2_name = "acx2";
1136 /* create two contexts */
1137 memcpy(¶m, &acl_param, sizeof(param));
1138 param.max_rule_num = 2;
1140 param.name = acx_name;
1141 acx = rte_acl_create(¶m);
1143 printf("Line %i: Error creating %s!\n", __LINE__, acx_name);
1147 param.name = acx2_name;
1148 acx2 = rte_acl_create(¶m);
1149 if (acx2 == NULL || acx2 == acx) {
1150 printf("Line %i: Error creating %s!\n", __LINE__, acx2_name);
1155 /* try to create third one, with an existing name */
1156 param.name = acx_name;
1157 tmp = rte_acl_create(¶m);
1159 printf("Line %i: Creating context with existing name "
1167 param.name = acx2_name;
1168 tmp = rte_acl_create(¶m);
1170 printf("Line %i: Creating context with existing "
1171 "name test 2 failed!\n",
1178 /* try to find existing ACL contexts */
1179 tmp = rte_acl_find_existing(acx_name);
1181 printf("Line %i: Finding %s failed!\n", __LINE__, acx_name);
1187 tmp = rte_acl_find_existing(acx2_name);
1189 printf("Line %i: Finding %s failed!\n", __LINE__, acx2_name);
1195 /* try to find non-existing context */
1196 tmp = rte_acl_find_existing("invalid");
1198 printf("Line %i: Non-existent ACL context found!\n", __LINE__);
1206 /* create valid (but severely limited) acx */
1207 memcpy(¶m, &acl_param, sizeof(param));
1208 param.max_rule_num = LEN;
1210 acx = rte_acl_create(¶m);
1212 printf("Line %i: Error creating %s!\n", __LINE__, param.name);
1216 /* create dummy acl */
1217 for (i = 0; i < LEN; i++) {
1218 memcpy(&rules[i], &acl_rule,
1219 sizeof(struct rte_acl_ipv4vlan_rule));
1221 rules[i].data.userdata = i + 1;
1222 /* one rule per category */
1223 rules[i].data.category_mask = 1 << i;
1226 /* try filling up the context */
1227 ret = rte_acl_ipv4vlan_add_rules(acx, rules, LEN);
1229 printf("Line %i: Adding %i rules to ACL context failed!\n",
1234 /* try adding to a (supposedly) full context */
1235 ret = rte_acl_ipv4vlan_add_rules(acx, rules, 1);
1237 printf("Line %i: Adding rules to full ACL context should"
1238 "have failed!\n", __LINE__);
1242 /* try building the context */
1243 ret = rte_acl_ipv4vlan_build(acx, layout, RTE_ACL_MAX_CATEGORIES);
1245 printf("Line %i: Building ACL context failed!\n", __LINE__);
1260 * test various invalid rules
1263 test_invalid_rules(void)
1265 struct rte_acl_ctx *acx;
1268 struct rte_acl_ipv4vlan_rule rule;
1270 acx = rte_acl_create(&acl_param);
1272 printf("Line %i: Error creating ACL context!\n", __LINE__);
1276 /* test inverted high/low source and destination ports.
1277 * originally, there was a problem with memory consumption when using
1280 /* create dummy acl */
1281 memcpy(&rule, &acl_rule, sizeof(struct rte_acl_ipv4vlan_rule));
1282 rule.data.userdata = 1;
1283 rule.dst_port_low = 0xfff0;
1284 rule.dst_port_high = 0x0010;
1286 /* add rules to context and try to build it */
1287 ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1289 printf("Line %i: Adding rules to ACL context "
1290 "should have failed!\n", __LINE__);
1294 rule.dst_port_low = 0x0;
1295 rule.dst_port_high = 0xffff;
1296 rule.src_port_low = 0xfff0;
1297 rule.src_port_high = 0x0010;
1299 /* add rules to context and try to build it */
1300 ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1302 printf("Line %i: Adding rules to ACL context "
1303 "should have failed!\n", __LINE__);
1307 rule.dst_port_low = 0x0;
1308 rule.dst_port_high = 0xffff;
1309 rule.src_port_low = 0x0;
1310 rule.src_port_high = 0xffff;
1312 rule.dst_mask_len = 33;
1314 /* add rules to context and try to build it */
1315 ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1317 printf("Line %i: Adding rules to ACL context "
1318 "should have failed!\n", __LINE__);
1322 rule.dst_mask_len = 0;
1323 rule.src_mask_len = 33;
1325 /* add rules to context and try to build it */
1326 ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1328 printf("Line %i: Adding rules to ACL context "
1329 "should have failed!\n", __LINE__);
1344 * test functions by passing invalid or
1345 * non-workable parameters.
1347 * we do very limited testing of classify functions here
1348 * because those are performance-critical and
1349 * thus don't do much parameter checking.
1352 test_invalid_parameters(void)
1354 struct rte_acl_param param;
1355 struct rte_acl_ctx *acx;
1356 struct rte_acl_ipv4vlan_rule rule;
1359 uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0};
1367 acx = rte_acl_create(NULL);
1369 printf("Line %i: ACL context creation with NULL param "
1370 "should have failed!\n", __LINE__);
1375 /* zero rule size */
1376 memcpy(¶m, &acl_param, sizeof(param));
1377 param.rule_size = 0;
1379 acx = rte_acl_create(¶m);
1381 printf("Line %i: ACL context creation with zero rule len "
1382 "failed!\n", __LINE__);
1387 /* zero max rule num */
1388 memcpy(¶m, &acl_param, sizeof(param));
1389 param.max_rule_num = 0;
1391 acx = rte_acl_create(¶m);
1393 printf("Line %i: ACL context creation with zero rule num "
1394 "failed!\n", __LINE__);
1399 if (rte_eal_has_hugepages()) {
1400 /* invalid NUMA node */
1401 memcpy(¶m, &acl_param, sizeof(param));
1402 param.socket_id = RTE_MAX_NUMA_NODES + 1;
1404 acx = rte_acl_create(¶m);
1406 printf("Line %i: ACL context creation with invalid "
1407 "NUMA should have failed!\n", __LINE__);
1414 memcpy(¶m, &acl_param, sizeof(param));
1417 acx = rte_acl_create(¶m);
1419 printf("Line %i: ACL context creation with NULL name "
1420 "should have failed!\n", __LINE__);
1426 * rte_acl_find_existing
1429 acx = rte_acl_find_existing(NULL);
1431 printf("Line %i: NULL ACL context found!\n", __LINE__);
1437 * rte_acl_ipv4vlan_add_rules
1440 /* initialize everything */
1441 memcpy(¶m, &acl_param, sizeof(param));
1442 acx = rte_acl_create(¶m);
1444 printf("Line %i: ACL context creation failed!\n", __LINE__);
1448 memcpy(&rule, &acl_rule, sizeof(rule));
1451 result = rte_acl_ipv4vlan_add_rules(NULL, &rule, 1);
1453 printf("Line %i: Adding rules with NULL ACL context "
1454 "should have failed!\n", __LINE__);
1460 result = rte_acl_ipv4vlan_add_rules(acx, NULL, 1);
1462 printf("Line %i: Adding NULL rule to ACL context "
1463 "should have failed!\n", __LINE__);
1468 /* zero count (should succeed) */
1469 result = rte_acl_ipv4vlan_add_rules(acx, &rule, 0);
1471 printf("Line %i: Adding 0 rules to ACL context failed!\n",
1477 /* free ACL context */
1482 * rte_acl_ipv4vlan_build
1485 /* reinitialize context */
1486 memcpy(¶m, &acl_param, sizeof(param));
1487 acx = rte_acl_create(¶m);
1489 printf("Line %i: ACL context creation failed!\n", __LINE__);
1494 result = rte_acl_ipv4vlan_build(NULL, layout, 1);
1496 printf("Line %i: Building with NULL context "
1497 "should have failed!\n", __LINE__);
1503 result = rte_acl_ipv4vlan_build(acx, NULL, 1);
1505 printf("Line %i: Building with NULL layout "
1506 "should have failed!\n", __LINE__);
1511 /* zero categories (should not fail) */
1512 result = rte_acl_ipv4vlan_build(acx, layout, 0);
1514 printf("Line %i: Building with 0 categories should fail!\n",
1520 /* SSE classify test */
1522 /* cover zero categories in classify (should not fail) */
1523 result = rte_acl_classify(acx, NULL, NULL, 0, 0);
1525 printf("Line %i: SSE classify with zero categories "
1526 "failed!\n", __LINE__);
1531 /* cover invalid but positive categories in classify */
1532 result = rte_acl_classify(acx, NULL, NULL, 0, 3);
1534 printf("Line %i: SSE classify with 3 categories "
1535 "should have failed!\n", __LINE__);
1540 /* scalar classify test */
1542 /* cover zero categories in classify (should not fail) */
1543 result = rte_acl_classify_alg(acx, NULL, NULL, 0, 0,
1544 RTE_ACL_CLASSIFY_SCALAR);
1546 printf("Line %i: Scalar classify with zero categories "
1547 "failed!\n", __LINE__);
1552 /* cover invalid but positive categories in classify */
1553 result = rte_acl_classify(acx, NULL, NULL, 0, 3);
1555 printf("Line %i: Scalar classify with 3 categories "
1556 "should have failed!\n", __LINE__);
1561 /* free ACL context */
1566 * make sure void functions don't crash with NULL parameters
1577 * Various tests that don't test much but improve coverage
1582 struct rte_acl_param param;
1583 struct rte_acl_ctx *acx;
1585 /* create context */
1586 memcpy(¶m, &acl_param, sizeof(param));
1588 acx = rte_acl_create(¶m);
1590 printf("Line %i: Error creating ACL context!\n", __LINE__);
1594 /* dump context with rules - useful for coverage */
1595 rte_acl_list_dump();
1605 get_u32_range_max(void)
1610 for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++)
1611 max = RTE_MAX(max, acl_u32_range_test_rules[i].src_mask_len);
1616 get_u32_range_min(void)
1621 for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++)
1622 min = RTE_MIN(min, acl_u32_range_test_rules[i].src_addr);
1626 static const struct rte_acl_ipv4vlan_rule *
1627 find_u32_range_rule(uint32_t val)
1631 for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++) {
1632 if (val >= acl_u32_range_test_rules[i].src_addr &&
1633 val <= acl_u32_range_test_rules[i].src_mask_len)
1634 return acl_u32_range_test_rules + i;
1640 fill_u32_range_data(struct ipv4_7tuple tdata[], uint32_t start, uint32_t num)
1643 const struct rte_acl_ipv4vlan_rule *r;
1645 for (i = 0; i != num; i++) {
1646 tdata[i].ip_src = start + i;
1647 r = find_u32_range_rule(start + i);
1649 tdata[i].allow = r->data.userdata;
1654 test_u32_range(void)
1657 uint32_t i, k, max, min;
1658 struct rte_acl_ctx *acx;
1659 struct acl_ipv4vlan_rule r;
1660 struct ipv4_7tuple test_data[64];
1662 acx = rte_acl_create(&acl_param);
1664 printf("%s#%i: Error creating ACL context!\n",
1665 __func__, __LINE__);
1669 for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++) {
1670 convert_rule(&acl_u32_range_test_rules[i], &r);
1671 rc = rte_acl_add_rules(acx, (struct rte_acl_rule *)&r, 1);
1673 printf("%s#%i: Adding rule to ACL context "
1674 "failed with error code: %d\n",
1675 __func__, __LINE__, rc);
1681 rc = build_convert_rules(acx, convert_config_2, 0);
1683 printf("%s#%i Error @ build_convert_rules!\n",
1684 __func__, __LINE__);
1689 max = get_u32_range_max();
1690 min = get_u32_range_min();
1692 max = RTE_MAX(max, max + 1);
1693 min = RTE_MIN(min, min - 1);
1695 printf("%s#%d starting range test from %u to %u\n",
1696 __func__, __LINE__, min, max);
1698 for (i = min; i <= max; i += k) {
1700 k = RTE_MIN(max - i + 1, RTE_DIM(test_data));
1702 memset(test_data, 0, sizeof(test_data));
1703 fill_u32_range_data(test_data, i, k);
1705 rc = test_classify_run(acx, test_data, k);
1707 printf("%s#%d failed at [%u, %u) interval\n",
1708 __func__, __LINE__, i, i + k);
1720 if (test_invalid_parameters() < 0)
1722 if (test_invalid_rules() < 0)
1724 if (test_create_find_add() < 0)
1726 if (test_invalid_layout() < 0)
1728 if (test_misc() < 0)
1730 if (test_classify() < 0)
1732 if (test_build_ports_range() < 0)
1734 if (test_convert() < 0)
1736 if (test_u32_range() < 0)
1742 REGISTER_TEST_COMMAND(acl_autotest, test_acl);