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 scalar and SSE ACL lookup.
272 test_classify_run(struct rte_acl_ctx
*acx
)
275 uint32_t result
, count
;
276 uint32_t results
[RTE_DIM(acl_test_data
) * RTE_ACL_MAX_CATEGORIES
];
277 const uint8_t *data
[RTE_DIM(acl_test_data
)];
279 /* swap all bytes in the data to network order */
280 bswap_test_data(acl_test_data
, RTE_DIM(acl_test_data
), 1);
282 /* store pointers to test data */
283 for (i
= 0; i
< (int) RTE_DIM(acl_test_data
); i
++)
284 data
[i
] = (uint8_t *)&acl_test_data
[i
];
287 * these will run quite a few times, it's necessary to test code paths
288 * from num=0 to num>8
290 for (count
= 0; count
<= RTE_DIM(acl_test_data
); count
++) {
291 ret
= rte_acl_classify(acx
, data
, results
,
292 count
, RTE_ACL_MAX_CATEGORIES
);
294 printf("Line %i: SSE classify failed!\n", __LINE__
);
298 /* check if we allow everything we should allow */
299 for (i
= 0; i
< (int) count
; i
++) {
301 results
[i
* RTE_ACL_MAX_CATEGORIES
+ ACL_ALLOW
];
302 if (result
!= acl_test_data
[i
].allow
) {
303 printf("Line %i: Error in allow results at %i "
304 "(expected %"PRIu32
" got %"PRIu32
")!\n",
305 __LINE__
, i
, acl_test_data
[i
].allow
,
312 /* check if we deny everything we should deny */
313 for (i
= 0; i
< (int) count
; i
++) {
314 result
= results
[i
* RTE_ACL_MAX_CATEGORIES
+ ACL_DENY
];
315 if (result
!= acl_test_data
[i
].deny
) {
316 printf("Line %i: Error in deny results at %i "
317 "(expected %"PRIu32
" got %"PRIu32
")!\n",
318 __LINE__
, i
, acl_test_data
[i
].deny
,
326 /* make a quick check for scalar */
327 ret
= rte_acl_classify_alg(acx
, data
, results
,
328 RTE_DIM(acl_test_data
), RTE_ACL_MAX_CATEGORIES
,
329 RTE_ACL_CLASSIFY_SCALAR
);
331 printf("Line %i: scalar classify failed!\n", __LINE__
);
335 /* check if we allow everything we should allow */
336 for (i
= 0; i
< (int) RTE_DIM(acl_test_data
); i
++) {
337 result
= results
[i
* RTE_ACL_MAX_CATEGORIES
+ ACL_ALLOW
];
338 if (result
!= acl_test_data
[i
].allow
) {
339 printf("Line %i: Error in allow results at %i "
340 "(expected %"PRIu32
" got %"PRIu32
")!\n",
341 __LINE__
, i
, acl_test_data
[i
].allow
,
348 /* check if we deny everything we should deny */
349 for (i
= 0; i
< (int) RTE_DIM(acl_test_data
); i
++) {
350 result
= results
[i
* RTE_ACL_MAX_CATEGORIES
+ ACL_DENY
];
351 if (result
!= acl_test_data
[i
].deny
) {
352 printf("Line %i: Error in deny results at %i "
353 "(expected %"PRIu32
" got %"PRIu32
")!\n",
354 __LINE__
, i
, acl_test_data
[i
].deny
,
364 /* swap data back to cpu order so that next time tests don't fail */
365 bswap_test_data(acl_test_data
, RTE_DIM(acl_test_data
), 0);
370 test_classify_buid(struct rte_acl_ctx
*acx
,
371 const struct rte_acl_ipv4vlan_rule
*rules
, uint32_t num
)
375 /* add rules to the context */
376 ret
= rte_acl_ipv4vlan_add_rules(acx
, rules
, num
);
378 printf("Line %i: Adding rules to ACL context failed!\n",
383 /* try building the context */
384 ret
= rte_acl_ipv4vlan_build(acx
, ipv4_7tuple_layout
,
385 RTE_ACL_MAX_CATEGORIES
);
387 printf("Line %i: Building ACL context failed!\n", __LINE__
);
394 #define TEST_CLASSIFY_ITER 4
397 * Test scalar and SSE ACL lookup.
402 struct rte_acl_ctx
*acx
;
405 acx
= rte_acl_create(&acl_param
);
407 printf("Line %i: Error creating ACL context!\n", __LINE__
);
412 for (i
= 0; i
!= TEST_CLASSIFY_ITER
; i
++) {
417 rte_acl_reset_rules(acx
);
419 ret
= test_classify_buid(acx
, acl_test_rules
,
420 RTE_DIM(acl_test_rules
));
422 printf("Line %i, iter: %d: "
423 "Adding rules to ACL context failed!\n",
428 ret
= test_classify_run(acx
);
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
);
439 printf("Line %i, iter: %d: %s failed!\n",
440 __LINE__
, i
, __func__
);
450 test_build_ports_range(void)
452 static const struct rte_acl_ipv4vlan_rule test_rules
[] = {
454 /* match all packets. */
457 .category_mask
= ACL_ALLOW_MASK
,
461 .src_port_high
= UINT16_MAX
,
463 .dst_port_high
= UINT16_MAX
,
466 /* match all packets with dst ports [54-65280]. */
469 .category_mask
= ACL_ALLOW_MASK
,
473 .src_port_high
= UINT16_MAX
,
475 .dst_port_high
= 65280,
478 /* match all packets with dst ports [0-52]. */
481 .category_mask
= ACL_ALLOW_MASK
,
485 .src_port_high
= UINT16_MAX
,
490 /* match all packets with dst ports [53]. */
493 .category_mask
= ACL_ALLOW_MASK
,
497 .src_port_high
= UINT16_MAX
,
502 /* match all packets with dst ports [65279-65535]. */
505 .category_mask
= ACL_ALLOW_MASK
,
509 .src_port_high
= UINT16_MAX
,
510 .dst_port_low
= 65279,
511 .dst_port_high
= UINT16_MAX
,
515 static struct ipv4_7tuple test_data
[] = {
518 .ip_src
= IPv4(10, 1, 1, 1),
519 .ip_dst
= IPv4(192, 168, 0, 33),
525 .ip_src
= IPv4(127, 84, 33, 1),
526 .ip_dst
= IPv4(1, 2, 3, 4),
532 struct rte_acl_ctx
*acx
;
534 uint32_t results
[RTE_DIM(test_data
)];
535 const uint8_t *data
[RTE_DIM(test_data
)];
537 acx
= rte_acl_create(&acl_param
);
539 printf("Line %i: Error creating ACL context!\n", __LINE__
);
543 /* swap all bytes in the data to network order */
544 bswap_test_data(test_data
, RTE_DIM(test_data
), 1);
546 /* store pointers to test data */
547 for (i
= 0; i
!= RTE_DIM(test_data
); i
++)
548 data
[i
] = (uint8_t *)&test_data
[i
];
550 for (i
= 0; i
!= RTE_DIM(test_rules
); i
++) {
552 ret
= test_classify_buid(acx
, test_rules
, i
+ 1);
554 printf("Line %i, iter: %d: "
555 "Adding rules to ACL context failed!\n",
559 ret
= rte_acl_classify(acx
, data
, results
,
562 printf("Line %i, iter: %d: classify failed!\n",
568 for (j
= 0; j
!= RTE_DIM(results
); j
++) {
569 if (results
[j
] != test_data
[j
].allow
) {
570 printf("Line %i: Error in allow results at %i "
571 "(expected %"PRIu32
" got %"PRIu32
")!\n",
572 __LINE__
, j
, test_data
[j
].allow
,
579 bswap_test_data(test_data
, RTE_DIM(test_data
), 0);
586 convert_rule(const struct rte_acl_ipv4vlan_rule
*ri
,
587 struct acl_ipv4vlan_rule
*ro
)
591 ro
->field
[RTE_ACL_IPV4VLAN_PROTO_FIELD
].value
.u8
= ri
->proto
;
592 ro
->field
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].value
.u16
= ri
->vlan
;
593 ro
->field
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].value
.u16
= ri
->domain
;
594 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].value
.u32
= ri
->src_addr
;
595 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].value
.u32
= ri
->dst_addr
;
596 ro
->field
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].value
.u16
= ri
->src_port_low
;
597 ro
->field
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].value
.u16
= ri
->dst_port_low
;
599 ro
->field
[RTE_ACL_IPV4VLAN_PROTO_FIELD
].mask_range
.u8
= ri
->proto_mask
;
600 ro
->field
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].mask_range
.u16
= ri
->vlan_mask
;
601 ro
->field
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].mask_range
.u16
=
603 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
=
605 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
= ri
->dst_mask_len
;
606 ro
->field
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].mask_range
.u16
=
608 ro
->field
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].mask_range
.u16
=
613 * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
614 * RTE_ACL_FIELD_TYPE_BITMASK.
617 convert_rule_1(const struct rte_acl_ipv4vlan_rule
*ri
,
618 struct acl_ipv4vlan_rule
*ro
)
622 convert_rule(ri
, ro
);
623 v
= ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
;
624 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
=
625 RTE_ACL_MASKLEN_TO_BITMASK(v
, sizeof(v
));
626 v
= ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
;
627 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
=
628 RTE_ACL_MASKLEN_TO_BITMASK(v
, sizeof(v
));
632 * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
633 * RTE_ACL_FIELD_TYPE_RANGE.
636 convert_rule_2(const struct rte_acl_ipv4vlan_rule
*ri
,
637 struct acl_ipv4vlan_rule
*ro
)
639 uint32_t hi
, lo
, mask
;
641 convert_rule(ri
, ro
);
643 mask
= ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
;
644 mask
= RTE_ACL_MASKLEN_TO_BITMASK(mask
, sizeof(mask
));
645 lo
= ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].value
.u32
& mask
;
647 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].value
.u32
= lo
;
648 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
= hi
;
650 mask
= ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
;
651 mask
= RTE_ACL_MASKLEN_TO_BITMASK(mask
, sizeof(mask
));
652 lo
= ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].value
.u32
& mask
;
654 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].value
.u32
= lo
;
655 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
= hi
;
659 * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule fields.
662 convert_rule_3(const struct rte_acl_ipv4vlan_rule
*ri
,
663 struct acl_ipv4vlan_rule
*ro
)
665 struct rte_acl_field t1
, t2
;
667 convert_rule(ri
, ro
);
669 t1
= ro
->field
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
];
670 t2
= ro
->field
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
];
672 ro
->field
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
] =
673 ro
->field
[RTE_ACL_IPV4VLAN_SRCP_FIELD
];
674 ro
->field
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
] =
675 ro
->field
[RTE_ACL_IPV4VLAN_DSTP_FIELD
];
677 ro
->field
[RTE_ACL_IPV4VLAN_SRCP_FIELD
] = t1
;
678 ro
->field
[RTE_ACL_IPV4VLAN_DSTP_FIELD
] = t2
;
682 * Convert rte_acl_ipv4vlan_rule: swap SRC and DST IPv4 address rules.
685 convert_rule_4(const struct rte_acl_ipv4vlan_rule
*ri
,
686 struct acl_ipv4vlan_rule
*ro
)
688 struct rte_acl_field t
;
690 convert_rule(ri
, ro
);
692 t
= ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
];
693 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
] =
694 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
];
696 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
] = t
;
700 ipv4vlan_config(struct rte_acl_config
*cfg
,
701 const uint32_t layout
[RTE_ACL_IPV4VLAN_NUM
],
702 uint32_t num_categories
)
704 static const struct rte_acl_field_def
705 ipv4_defs
[RTE_ACL_IPV4VLAN_NUM_FIELDS
] = {
707 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
708 .size
= sizeof(uint8_t),
709 .field_index
= RTE_ACL_IPV4VLAN_PROTO_FIELD
,
710 .input_index
= RTE_ACL_IPV4VLAN_PROTO
,
713 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
714 .size
= sizeof(uint16_t),
715 .field_index
= RTE_ACL_IPV4VLAN_VLAN1_FIELD
,
716 .input_index
= RTE_ACL_IPV4VLAN_VLAN
,
719 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
720 .size
= sizeof(uint16_t),
721 .field_index
= RTE_ACL_IPV4VLAN_VLAN2_FIELD
,
722 .input_index
= RTE_ACL_IPV4VLAN_VLAN
,
725 .type
= RTE_ACL_FIELD_TYPE_MASK
,
726 .size
= sizeof(uint32_t),
727 .field_index
= RTE_ACL_IPV4VLAN_SRC_FIELD
,
728 .input_index
= RTE_ACL_IPV4VLAN_SRC
,
731 .type
= RTE_ACL_FIELD_TYPE_MASK
,
732 .size
= sizeof(uint32_t),
733 .field_index
= RTE_ACL_IPV4VLAN_DST_FIELD
,
734 .input_index
= RTE_ACL_IPV4VLAN_DST
,
737 .type
= RTE_ACL_FIELD_TYPE_RANGE
,
738 .size
= sizeof(uint16_t),
739 .field_index
= RTE_ACL_IPV4VLAN_SRCP_FIELD
,
740 .input_index
= RTE_ACL_IPV4VLAN_PORTS
,
743 .type
= RTE_ACL_FIELD_TYPE_RANGE
,
744 .size
= sizeof(uint16_t),
745 .field_index
= RTE_ACL_IPV4VLAN_DSTP_FIELD
,
746 .input_index
= RTE_ACL_IPV4VLAN_PORTS
,
750 memcpy(&cfg
->defs
, ipv4_defs
, sizeof(ipv4_defs
));
751 cfg
->num_fields
= RTE_DIM(ipv4_defs
);
753 cfg
->defs
[RTE_ACL_IPV4VLAN_PROTO_FIELD
].offset
=
754 layout
[RTE_ACL_IPV4VLAN_PROTO
];
755 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].offset
=
756 layout
[RTE_ACL_IPV4VLAN_VLAN
];
757 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].offset
=
758 layout
[RTE_ACL_IPV4VLAN_VLAN
] +
759 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].size
;
760 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].offset
=
761 layout
[RTE_ACL_IPV4VLAN_SRC
];
762 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].offset
=
763 layout
[RTE_ACL_IPV4VLAN_DST
];
764 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].offset
=
765 layout
[RTE_ACL_IPV4VLAN_PORTS
];
766 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].offset
=
767 layout
[RTE_ACL_IPV4VLAN_PORTS
] +
768 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].size
;
770 cfg
->num_categories
= num_categories
;
774 convert_rules(struct rte_acl_ctx
*acx
,
775 void (*convert
)(const struct rte_acl_ipv4vlan_rule
*,
776 struct acl_ipv4vlan_rule
*),
777 const struct rte_acl_ipv4vlan_rule
*rules
, uint32_t num
)
781 struct acl_ipv4vlan_rule r
;
783 for (i
= 0; i
!= num
; i
++) {
784 convert(rules
+ i
, &r
);
785 rc
= rte_acl_add_rules(acx
, (struct rte_acl_rule
*)&r
, 1);
787 printf("Line %i: Adding rule %u to ACL context "
788 "failed with error code: %d\n",
798 convert_config(struct rte_acl_config
*cfg
)
800 ipv4vlan_config(cfg
, ipv4_7tuple_layout
, RTE_ACL_MAX_CATEGORIES
);
804 * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_BITMASK.
807 convert_config_1(struct rte_acl_config
*cfg
)
809 ipv4vlan_config(cfg
, ipv4_7tuple_layout
, RTE_ACL_MAX_CATEGORIES
);
810 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].type
= RTE_ACL_FIELD_TYPE_BITMASK
;
811 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].type
= RTE_ACL_FIELD_TYPE_BITMASK
;
815 * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_RANGE.
818 convert_config_2(struct rte_acl_config
*cfg
)
820 ipv4vlan_config(cfg
, ipv4_7tuple_layout
, RTE_ACL_MAX_CATEGORIES
);
821 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].type
= RTE_ACL_FIELD_TYPE_RANGE
;
822 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].type
= RTE_ACL_FIELD_TYPE_RANGE
;
826 * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule definitions.
829 convert_config_3(struct rte_acl_config
*cfg
)
831 struct rte_acl_field_def t1
, t2
;
833 ipv4vlan_config(cfg
, ipv4_7tuple_layout
, RTE_ACL_MAX_CATEGORIES
);
835 t1
= cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
];
836 t2
= cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
];
838 /* swap VLAN1 and SRCP rule definition. */
839 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
] =
840 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
];
841 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].field_index
= t1
.field_index
;
842 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].input_index
= t1
.input_index
;
844 /* swap VLAN2 and DSTP rule definition. */
845 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
] =
846 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
];
847 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].field_index
= t2
.field_index
;
848 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].input_index
= t2
.input_index
;
850 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].type
= t1
.type
;
851 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].size
= t1
.size
;
852 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].offset
= t1
.offset
;
854 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].type
= t2
.type
;
855 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].size
= t2
.size
;
856 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].offset
= t2
.offset
;
860 * Convert rte_acl_ipv4vlan_rule: swap SRC and DST ip address rule definitions.
863 convert_config_4(struct rte_acl_config
*cfg
)
865 struct rte_acl_field_def t
;
867 ipv4vlan_config(cfg
, ipv4_7tuple_layout
, RTE_ACL_MAX_CATEGORIES
);
869 t
= cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
];
871 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
] =
872 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
];
873 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].field_index
= t
.field_index
;
874 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].input_index
= t
.input_index
;
876 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].type
= t
.type
;
877 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].size
= t
.size
;
878 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].offset
= t
.offset
;
883 build_convert_rules(struct rte_acl_ctx
*acx
,
884 void (*config
)(struct rte_acl_config
*),
887 struct rte_acl_config cfg
;
889 memset(&cfg
, 0, sizeof(cfg
));
891 cfg
.max_size
= max_size
;
892 return rte_acl_build(acx
, &cfg
);
896 test_convert_rules(const char *desc
,
897 void (*config
)(struct rte_acl_config
*),
898 void (*convert
)(const struct rte_acl_ipv4vlan_rule
*,
899 struct acl_ipv4vlan_rule
*))
901 struct rte_acl_ctx
*acx
;
904 static const size_t mem_sizes
[] = {0, -1};
906 printf("running %s(%s)\n", __func__
, desc
);
908 acx
= rte_acl_create(&acl_param
);
910 printf("Line %i: Error creating ACL context!\n", __LINE__
);
914 rc
= convert_rules(acx
, convert
, acl_test_rules
,
915 RTE_DIM(acl_test_rules
));
917 printf("Line %i: Error converting ACL rules!\n", __LINE__
);
919 for (i
= 0; rc
== 0 && i
!= RTE_DIM(mem_sizes
); i
++) {
921 rc
= build_convert_rules(acx
, config
, mem_sizes
[i
]);
923 printf("Line %i: Error @ build_convert_rules(%zu)!\n",
924 __LINE__
, mem_sizes
[i
]);
928 rc
= test_classify_run(acx
);
930 printf("%s failed at line %i, max_size=%zu\n",
931 __func__
, __LINE__
, mem_sizes
[i
]);
941 static const struct {
943 void (*config
)(struct rte_acl_config
*);
944 void (*convert
)(const struct rte_acl_ipv4vlan_rule
*,
945 struct acl_ipv4vlan_rule
*);
946 } convert_param
[] = {
948 "acl_ipv4vlan_tuple",
953 "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_BITMASK type "
959 "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_RANGE type "
965 "acl_ipv4vlan_tuple: swap VLAN and PORTs order",
970 "acl_ipv4vlan_tuple: swap SRC and DST IPv4 order",
979 for (i
= 0; i
!= RTE_DIM(convert_param
); i
++) {
980 rc
= test_convert_rules(convert_param
[i
].desc
,
981 convert_param
[i
].config
,
982 convert_param
[i
].convert
);
984 printf("%s for test-case: %s failed, error code: %d;\n",
985 __func__
, convert_param
[i
].desc
, rc
);
994 * Test wrong layout behavior
995 * This test supplies the ACL context with invalid layout, which results in
996 * ACL matching the wrong stuff. However, it should match the wrong stuff
997 * the right way. We switch around source and destination addresses,
998 * source and destination ports, and protocol will point to first byte of
1002 test_invalid_layout(void)
1004 struct rte_acl_ctx
*acx
;
1007 uint32_t results
[RTE_DIM(invalid_layout_data
)];
1008 const uint8_t *data
[RTE_DIM(invalid_layout_data
)];
1010 const uint32_t layout
[RTE_ACL_IPV4VLAN_NUM
] = {
1011 /* proto points to destination port's first byte */
1012 offsetof(struct ipv4_7tuple
, port_dst
),
1014 0, /* VLAN not used */
1016 /* src and dst addresses are swapped */
1017 offsetof(struct ipv4_7tuple
, ip_dst
),
1018 offsetof(struct ipv4_7tuple
, ip_src
),
1021 * we can't swap ports here, so we will swap
1024 offsetof(struct ipv4_7tuple
, port_src
),
1027 acx
= rte_acl_create(&acl_param
);
1029 printf("Line %i: Error creating ACL context!\n", __LINE__
);
1033 /* putting a lot of rules into the context results in greater
1034 * coverage numbers. it doesn't matter if they are identical */
1035 for (i
= 0; i
< 1000; i
++) {
1036 /* add rules to the context */
1037 ret
= rte_acl_ipv4vlan_add_rules(acx
, invalid_layout_rules
,
1038 RTE_DIM(invalid_layout_rules
));
1040 printf("Line %i: Adding rules to ACL context failed!\n",
1047 /* try building the context */
1048 ret
= rte_acl_ipv4vlan_build(acx
, layout
, 1);
1050 printf("Line %i: Building ACL context failed!\n", __LINE__
);
1055 /* swap all bytes in the data to network order */
1056 bswap_test_data(invalid_layout_data
, RTE_DIM(invalid_layout_data
), 1);
1059 for (i
= 0; i
< (int) RTE_DIM(invalid_layout_data
); i
++) {
1060 data
[i
] = (uint8_t *)&invalid_layout_data
[i
];
1063 /* classify tuples */
1064 ret
= rte_acl_classify_alg(acx
, data
, results
,
1065 RTE_DIM(results
), 1, RTE_ACL_CLASSIFY_SCALAR
);
1067 printf("Line %i: SSE classify failed!\n", __LINE__
);
1072 for (i
= 0; i
< (int) RTE_DIM(results
); i
++) {
1073 if (results
[i
] != invalid_layout_data
[i
].allow
) {
1074 printf("Line %i: Wrong results at %i "
1075 "(result=%u, should be %u)!\n",
1076 __LINE__
, i
, results
[i
],
1077 invalid_layout_data
[i
].allow
);
1082 /* classify tuples (scalar) */
1083 ret
= rte_acl_classify_alg(acx
, data
, results
, RTE_DIM(results
), 1,
1084 RTE_ACL_CLASSIFY_SCALAR
);
1087 printf("Line %i: Scalar classify failed!\n", __LINE__
);
1092 for (i
= 0; i
< (int) RTE_DIM(results
); i
++) {
1093 if (results
[i
] != invalid_layout_data
[i
].allow
) {
1094 printf("Line %i: Wrong results at %i "
1095 "(result=%u, should be %u)!\n",
1096 __LINE__
, i
, results
[i
],
1097 invalid_layout_data
[i
].allow
);
1104 /* swap data back to cpu order so that next time tests don't fail */
1105 bswap_test_data(invalid_layout_data
, RTE_DIM(invalid_layout_data
), 0);
1110 /* swap data back to cpu order so that next time tests don't fail */
1111 bswap_test_data(invalid_layout_data
, RTE_DIM(invalid_layout_data
), 0);
1119 * Test creating and finding ACL contexts, and adding rules
1122 test_create_find_add(void)
1124 struct rte_acl_param param
;
1125 struct rte_acl_ctx
*acx
, *acx2
, *tmp
;
1126 struct rte_acl_ipv4vlan_rule rules
[LEN
];
1128 const uint32_t layout
[RTE_ACL_IPV4VLAN_NUM
] = {0};
1130 const char *acx_name
= "acx";
1131 const char *acx2_name
= "acx2";
1134 /* create two contexts */
1135 memcpy(¶m
, &acl_param
, sizeof(param
));
1136 param
.max_rule_num
= 2;
1138 param
.name
= acx_name
;
1139 acx
= rte_acl_create(¶m
);
1141 printf("Line %i: Error creating %s!\n", __LINE__
, acx_name
);
1145 param
.name
= acx2_name
;
1146 acx2
= rte_acl_create(¶m
);
1147 if (acx2
== NULL
|| acx2
== acx
) {
1148 printf("Line %i: Error creating %s!\n", __LINE__
, acx2_name
);
1153 /* try to create third one, with an existing name */
1154 param
.name
= acx_name
;
1155 tmp
= rte_acl_create(¶m
);
1157 printf("Line %i: Creating context with existing name "
1165 param
.name
= acx2_name
;
1166 tmp
= rte_acl_create(¶m
);
1168 printf("Line %i: Creating context with existing "
1169 "name test 2 failed!\n",
1176 /* try to find existing ACL contexts */
1177 tmp
= rte_acl_find_existing(acx_name
);
1179 printf("Line %i: Finding %s failed!\n", __LINE__
, acx_name
);
1185 tmp
= rte_acl_find_existing(acx2_name
);
1187 printf("Line %i: Finding %s failed!\n", __LINE__
, acx2_name
);
1193 /* try to find non-existing context */
1194 tmp
= rte_acl_find_existing("invalid");
1196 printf("Line %i: Non-existent ACL context found!\n", __LINE__
);
1204 /* create valid (but severely limited) acx */
1205 memcpy(¶m
, &acl_param
, sizeof(param
));
1206 param
.max_rule_num
= LEN
;
1208 acx
= rte_acl_create(¶m
);
1210 printf("Line %i: Error creating %s!\n", __LINE__
, param
.name
);
1214 /* create dummy acl */
1215 for (i
= 0; i
< LEN
; i
++) {
1216 memcpy(&rules
[i
], &acl_rule
,
1217 sizeof(struct rte_acl_ipv4vlan_rule
));
1219 rules
[i
].data
.userdata
= i
+ 1;
1220 /* one rule per category */
1221 rules
[i
].data
.category_mask
= 1 << i
;
1224 /* try filling up the context */
1225 ret
= rte_acl_ipv4vlan_add_rules(acx
, rules
, LEN
);
1227 printf("Line %i: Adding %i rules to ACL context failed!\n",
1232 /* try adding to a (supposedly) full context */
1233 ret
= rte_acl_ipv4vlan_add_rules(acx
, rules
, 1);
1235 printf("Line %i: Adding rules to full ACL context should"
1236 "have failed!\n", __LINE__
);
1240 /* try building the context */
1241 ret
= rte_acl_ipv4vlan_build(acx
, layout
, RTE_ACL_MAX_CATEGORIES
);
1243 printf("Line %i: Building ACL context failed!\n", __LINE__
);
1258 * test various invalid rules
1261 test_invalid_rules(void)
1263 struct rte_acl_ctx
*acx
;
1266 struct rte_acl_ipv4vlan_rule rule
;
1268 acx
= rte_acl_create(&acl_param
);
1270 printf("Line %i: Error creating ACL context!\n", __LINE__
);
1274 /* test inverted high/low source and destination ports.
1275 * originally, there was a problem with memory consumption when using
1278 /* create dummy acl */
1279 memcpy(&rule
, &acl_rule
, sizeof(struct rte_acl_ipv4vlan_rule
));
1280 rule
.data
.userdata
= 1;
1281 rule
.dst_port_low
= 0xfff0;
1282 rule
.dst_port_high
= 0x0010;
1284 /* add rules to context and try to build it */
1285 ret
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 1);
1287 printf("Line %i: Adding rules to ACL context "
1288 "should have failed!\n", __LINE__
);
1292 rule
.dst_port_low
= 0x0;
1293 rule
.dst_port_high
= 0xffff;
1294 rule
.src_port_low
= 0xfff0;
1295 rule
.src_port_high
= 0x0010;
1297 /* add rules to context and try to build it */
1298 ret
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 1);
1300 printf("Line %i: Adding rules to ACL context "
1301 "should have failed!\n", __LINE__
);
1305 rule
.dst_port_low
= 0x0;
1306 rule
.dst_port_high
= 0xffff;
1307 rule
.src_port_low
= 0x0;
1308 rule
.src_port_high
= 0xffff;
1310 rule
.dst_mask_len
= 33;
1312 /* add rules to context and try to build it */
1313 ret
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 1);
1315 printf("Line %i: Adding rules to ACL context "
1316 "should have failed!\n", __LINE__
);
1320 rule
.dst_mask_len
= 0;
1321 rule
.src_mask_len
= 33;
1323 /* add rules to context and try to build it */
1324 ret
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 1);
1326 printf("Line %i: Adding rules to ACL context "
1327 "should have failed!\n", __LINE__
);
1342 * test functions by passing invalid or
1343 * non-workable parameters.
1345 * we do very limited testing of classify functions here
1346 * because those are performance-critical and
1347 * thus don't do much parameter checking.
1350 test_invalid_parameters(void)
1352 struct rte_acl_param param
;
1353 struct rte_acl_ctx
*acx
;
1354 struct rte_acl_ipv4vlan_rule rule
;
1357 uint32_t layout
[RTE_ACL_IPV4VLAN_NUM
] = {0};
1365 acx
= rte_acl_create(NULL
);
1367 printf("Line %i: ACL context creation with NULL param "
1368 "should have failed!\n", __LINE__
);
1373 /* zero rule size */
1374 memcpy(¶m
, &acl_param
, sizeof(param
));
1375 param
.rule_size
= 0;
1377 acx
= rte_acl_create(¶m
);
1379 printf("Line %i: ACL context creation with zero rule len "
1380 "failed!\n", __LINE__
);
1385 /* zero max rule num */
1386 memcpy(¶m
, &acl_param
, sizeof(param
));
1387 param
.max_rule_num
= 0;
1389 acx
= rte_acl_create(¶m
);
1391 printf("Line %i: ACL context creation with zero rule num "
1392 "failed!\n", __LINE__
);
1397 /* invalid NUMA node */
1398 memcpy(¶m
, &acl_param
, sizeof(param
));
1399 param
.socket_id
= RTE_MAX_NUMA_NODES
+ 1;
1401 acx
= rte_acl_create(¶m
);
1403 printf("Line %i: ACL context creation with invalid NUMA "
1404 "should have failed!\n", __LINE__
);
1410 memcpy(¶m
, &acl_param
, sizeof(param
));
1413 acx
= rte_acl_create(¶m
);
1415 printf("Line %i: ACL context creation with NULL name "
1416 "should have failed!\n", __LINE__
);
1422 * rte_acl_find_existing
1425 acx
= rte_acl_find_existing(NULL
);
1427 printf("Line %i: NULL ACL context found!\n", __LINE__
);
1433 * rte_acl_ipv4vlan_add_rules
1436 /* initialize everything */
1437 memcpy(¶m
, &acl_param
, sizeof(param
));
1438 acx
= rte_acl_create(¶m
);
1440 printf("Line %i: ACL context creation failed!\n", __LINE__
);
1444 memcpy(&rule
, &acl_rule
, sizeof(rule
));
1447 result
= rte_acl_ipv4vlan_add_rules(NULL
, &rule
, 1);
1449 printf("Line %i: Adding rules with NULL ACL context "
1450 "should have failed!\n", __LINE__
);
1456 result
= rte_acl_ipv4vlan_add_rules(acx
, NULL
, 1);
1458 printf("Line %i: Adding NULL rule to ACL context "
1459 "should have failed!\n", __LINE__
);
1464 /* zero count (should succeed) */
1465 result
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 0);
1467 printf("Line %i: Adding 0 rules to ACL context failed!\n",
1473 /* free ACL context */
1478 * rte_acl_ipv4vlan_build
1481 /* reinitialize context */
1482 memcpy(¶m
, &acl_param
, sizeof(param
));
1483 acx
= rte_acl_create(¶m
);
1485 printf("Line %i: ACL context creation failed!\n", __LINE__
);
1490 result
= rte_acl_ipv4vlan_build(NULL
, layout
, 1);
1492 printf("Line %i: Building with NULL context "
1493 "should have failed!\n", __LINE__
);
1499 result
= rte_acl_ipv4vlan_build(acx
, NULL
, 1);
1501 printf("Line %i: Building with NULL layout "
1502 "should have failed!\n", __LINE__
);
1507 /* zero categories (should not fail) */
1508 result
= rte_acl_ipv4vlan_build(acx
, layout
, 0);
1510 printf("Line %i: Building with 0 categories should fail!\n",
1516 /* SSE classify test */
1518 /* cover zero categories in classify (should not fail) */
1519 result
= rte_acl_classify(acx
, NULL
, NULL
, 0, 0);
1521 printf("Line %i: SSE classify with zero categories "
1522 "failed!\n", __LINE__
);
1527 /* cover invalid but positive categories in classify */
1528 result
= rte_acl_classify(acx
, NULL
, NULL
, 0, 3);
1530 printf("Line %i: SSE classify with 3 categories "
1531 "should have failed!\n", __LINE__
);
1536 /* scalar classify test */
1538 /* cover zero categories in classify (should not fail) */
1539 result
= rte_acl_classify_alg(acx
, NULL
, NULL
, 0, 0,
1540 RTE_ACL_CLASSIFY_SCALAR
);
1542 printf("Line %i: Scalar classify with zero categories "
1543 "failed!\n", __LINE__
);
1548 /* cover invalid but positive categories in classify */
1549 result
= rte_acl_classify(acx
, NULL
, NULL
, 0, 3);
1551 printf("Line %i: Scalar classify with 3 categories "
1552 "should have failed!\n", __LINE__
);
1557 /* free ACL context */
1562 * make sure void functions don't crash with NULL parameters
1573 * Various tests that don't test much but improve coverage
1578 struct rte_acl_param param
;
1579 struct rte_acl_ctx
*acx
;
1581 /* create context */
1582 memcpy(¶m
, &acl_param
, sizeof(param
));
1584 acx
= rte_acl_create(¶m
);
1586 printf("Line %i: Error creating ACL context!\n", __LINE__
);
1590 /* dump context with rules - useful for coverage */
1591 rte_acl_list_dump();
1603 if (test_invalid_parameters() < 0)
1605 if (test_invalid_rules() < 0)
1607 if (test_create_find_add() < 0)
1609 if (test_invalid_layout() < 0)
1611 if (test_misc() < 0)
1613 if (test_classify() < 0)
1615 if (test_build_ports_range() < 0)
1617 if (test_convert() < 0)
1623 REGISTER_TEST_COMMAND(acl_autotest
, test_acl
);