4 * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 #include <rte_string_fns.h>
41 #include <rte_byteorder.h>
44 #include <rte_common.h>
48 #define BIT_SIZEOF(x) (sizeof(x) * CHAR_BIT)
50 #define LEN RTE_ACL_MAX_CATEGORIES
52 RTE_ACL_RULE_DEF(acl_ipv4vlan_rule
, RTE_ACL_IPV4VLAN_NUM_FIELDS
);
54 struct rte_acl_param acl_param
= {
56 .socket_id
= SOCKET_ID_ANY
,
57 .rule_size
= RTE_ACL_IPV4VLAN_RULE_SZ
,
58 .max_rule_num
= 0x30000,
61 struct rte_acl_ipv4vlan_rule acl_rule
= {
62 .data
= { .priority
= 1, .category_mask
= 0xff },
64 .src_port_high
= UINT16_MAX
,
66 .dst_port_high
= UINT16_MAX
,
69 const uint32_t ipv4_7tuple_layout
[RTE_ACL_IPV4VLAN_NUM
] = {
70 offsetof(struct ipv4_7tuple
, proto
),
71 offsetof(struct ipv4_7tuple
, vlan
),
72 offsetof(struct ipv4_7tuple
, ip_src
),
73 offsetof(struct ipv4_7tuple
, ip_dst
),
74 offsetof(struct ipv4_7tuple
, port_src
),
78 /* byteswap to cpu or network order */
80 bswap_test_data(struct ipv4_7tuple
*data
, int len
, int to_be
)
84 for (i
= 0; i
< len
; i
++) {
87 /* swap all bytes so that they are in network order */
88 data
[i
].ip_dst
= rte_cpu_to_be_32(data
[i
].ip_dst
);
89 data
[i
].ip_src
= rte_cpu_to_be_32(data
[i
].ip_src
);
90 data
[i
].port_dst
= rte_cpu_to_be_16(data
[i
].port_dst
);
91 data
[i
].port_src
= rte_cpu_to_be_16(data
[i
].port_src
);
92 data
[i
].vlan
= rte_cpu_to_be_16(data
[i
].vlan
);
93 data
[i
].domain
= rte_cpu_to_be_16(data
[i
].domain
);
95 data
[i
].ip_dst
= rte_be_to_cpu_32(data
[i
].ip_dst
);
96 data
[i
].ip_src
= rte_be_to_cpu_32(data
[i
].ip_src
);
97 data
[i
].port_dst
= rte_be_to_cpu_16(data
[i
].port_dst
);
98 data
[i
].port_src
= rte_be_to_cpu_16(data
[i
].port_src
);
99 data
[i
].vlan
= rte_be_to_cpu_16(data
[i
].vlan
);
100 data
[i
].domain
= rte_be_to_cpu_16(data
[i
].domain
);
106 acl_ipv4vlan_check_rule(const struct rte_acl_ipv4vlan_rule
*rule
)
108 if (rule
->src_port_low
> rule
->src_port_high
||
109 rule
->dst_port_low
> rule
->dst_port_high
||
110 rule
->src_mask_len
> BIT_SIZEOF(rule
->src_addr
) ||
111 rule
->dst_mask_len
> BIT_SIZEOF(rule
->dst_addr
))
117 acl_ipv4vlan_convert_rule(const struct rte_acl_ipv4vlan_rule
*ri
,
118 struct acl_ipv4vlan_rule
*ro
)
122 ro
->field
[RTE_ACL_IPV4VLAN_PROTO_FIELD
].value
.u8
= ri
->proto
;
123 ro
->field
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].value
.u16
= ri
->vlan
;
124 ro
->field
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].value
.u16
= ri
->domain
;
125 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].value
.u32
= ri
->src_addr
;
126 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].value
.u32
= ri
->dst_addr
;
127 ro
->field
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].value
.u16
= ri
->src_port_low
;
128 ro
->field
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].value
.u16
= ri
->dst_port_low
;
130 ro
->field
[RTE_ACL_IPV4VLAN_PROTO_FIELD
].mask_range
.u8
= ri
->proto_mask
;
131 ro
->field
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].mask_range
.u16
= ri
->vlan_mask
;
132 ro
->field
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].mask_range
.u16
=
134 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
=
136 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
= ri
->dst_mask_len
;
137 ro
->field
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].mask_range
.u16
=
139 ro
->field
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].mask_range
.u16
=
144 * Add ipv4vlan rules to an existing ACL context.
145 * This function is not multi-thread safe.
148 * ACL context to add patterns to.
150 * Array of rules to add to the ACL context.
151 * Note that all fields in rte_acl_ipv4vlan_rule structures are expected
152 * to be in host byte order.
154 * Number of elements in the input array of rules.
156 * - -ENOMEM if there is no space in the ACL context for these rules.
157 * - -EINVAL if the parameters are invalid.
158 * - Zero if operation completed successfully.
161 rte_acl_ipv4vlan_add_rules(struct rte_acl_ctx
*ctx
,
162 const struct rte_acl_ipv4vlan_rule
*rules
,
167 struct acl_ipv4vlan_rule rv
;
169 if (ctx
== NULL
|| rules
== NULL
)
172 /* check input rules. */
173 for (i
= 0; i
!= num
; i
++) {
174 rc
= acl_ipv4vlan_check_rule(rules
+ i
);
176 RTE_LOG(ERR
, ACL
, "%s: rule #%u is invalid\n",
182 /* perform conversion to the internal format and add to the context. */
183 for (i
= 0, rc
= 0; i
!= num
&& rc
== 0; i
++) {
184 acl_ipv4vlan_convert_rule(rules
+ i
, &rv
);
185 rc
= rte_acl_add_rules(ctx
, (struct rte_acl_rule
*)&rv
, 1);
192 acl_ipv4vlan_config(struct rte_acl_config
*cfg
,
193 const uint32_t layout
[RTE_ACL_IPV4VLAN_NUM
],
194 uint32_t num_categories
)
196 static const struct rte_acl_field_def
197 ipv4_defs
[RTE_ACL_IPV4VLAN_NUM_FIELDS
] = {
199 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
200 .size
= sizeof(uint8_t),
201 .field_index
= RTE_ACL_IPV4VLAN_PROTO_FIELD
,
202 .input_index
= RTE_ACL_IPV4VLAN_PROTO
,
205 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
206 .size
= sizeof(uint16_t),
207 .field_index
= RTE_ACL_IPV4VLAN_VLAN1_FIELD
,
208 .input_index
= RTE_ACL_IPV4VLAN_VLAN
,
211 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
212 .size
= sizeof(uint16_t),
213 .field_index
= RTE_ACL_IPV4VLAN_VLAN2_FIELD
,
214 .input_index
= RTE_ACL_IPV4VLAN_VLAN
,
217 .type
= RTE_ACL_FIELD_TYPE_MASK
,
218 .size
= sizeof(uint32_t),
219 .field_index
= RTE_ACL_IPV4VLAN_SRC_FIELD
,
220 .input_index
= RTE_ACL_IPV4VLAN_SRC
,
223 .type
= RTE_ACL_FIELD_TYPE_MASK
,
224 .size
= sizeof(uint32_t),
225 .field_index
= RTE_ACL_IPV4VLAN_DST_FIELD
,
226 .input_index
= RTE_ACL_IPV4VLAN_DST
,
229 .type
= RTE_ACL_FIELD_TYPE_RANGE
,
230 .size
= sizeof(uint16_t),
231 .field_index
= RTE_ACL_IPV4VLAN_SRCP_FIELD
,
232 .input_index
= RTE_ACL_IPV4VLAN_PORTS
,
235 .type
= RTE_ACL_FIELD_TYPE_RANGE
,
236 .size
= sizeof(uint16_t),
237 .field_index
= RTE_ACL_IPV4VLAN_DSTP_FIELD
,
238 .input_index
= RTE_ACL_IPV4VLAN_PORTS
,
242 memcpy(&cfg
->defs
, ipv4_defs
, sizeof(ipv4_defs
));
243 cfg
->num_fields
= RTE_DIM(ipv4_defs
);
245 cfg
->defs
[RTE_ACL_IPV4VLAN_PROTO_FIELD
].offset
=
246 layout
[RTE_ACL_IPV4VLAN_PROTO
];
247 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].offset
=
248 layout
[RTE_ACL_IPV4VLAN_VLAN
];
249 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].offset
=
250 layout
[RTE_ACL_IPV4VLAN_VLAN
] +
251 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].size
;
252 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].offset
=
253 layout
[RTE_ACL_IPV4VLAN_SRC
];
254 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].offset
=
255 layout
[RTE_ACL_IPV4VLAN_DST
];
256 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].offset
=
257 layout
[RTE_ACL_IPV4VLAN_PORTS
];
258 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].offset
=
259 layout
[RTE_ACL_IPV4VLAN_PORTS
] +
260 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].size
;
262 cfg
->num_categories
= num_categories
;
266 * Analyze set of ipv4vlan rules and build required internal
267 * run-time structures.
268 * This function is not multi-thread safe.
271 * ACL context to build.
273 * Layout of input data to search through.
274 * @param num_categories
275 * Maximum number of categories to use in that build.
277 * - -ENOMEM if couldn't allocate enough memory.
278 * - -EINVAL if the parameters are invalid.
279 * - Negative error code if operation failed.
280 * - Zero if operation completed successfully.
283 rte_acl_ipv4vlan_build(struct rte_acl_ctx
*ctx
,
284 const uint32_t layout
[RTE_ACL_IPV4VLAN_NUM
],
285 uint32_t num_categories
)
287 struct rte_acl_config cfg
;
289 if (ctx
== NULL
|| layout
== NULL
)
292 memset(&cfg
, 0, sizeof(cfg
));
293 acl_ipv4vlan_config(&cfg
, layout
, num_categories
);
294 return rte_acl_build(ctx
, &cfg
);
298 * Test scalar and SSE ACL lookup.
301 test_classify_run(struct rte_acl_ctx
*acx
)
304 uint32_t result
, count
;
305 uint32_t results
[RTE_DIM(acl_test_data
) * RTE_ACL_MAX_CATEGORIES
];
306 const uint8_t *data
[RTE_DIM(acl_test_data
)];
308 /* swap all bytes in the data to network order */
309 bswap_test_data(acl_test_data
, RTE_DIM(acl_test_data
), 1);
311 /* store pointers to test data */
312 for (i
= 0; i
< (int) RTE_DIM(acl_test_data
); i
++)
313 data
[i
] = (uint8_t *)&acl_test_data
[i
];
316 * these will run quite a few times, it's necessary to test code paths
317 * from num=0 to num>8
319 for (count
= 0; count
<= RTE_DIM(acl_test_data
); count
++) {
320 ret
= rte_acl_classify(acx
, data
, results
,
321 count
, RTE_ACL_MAX_CATEGORIES
);
323 printf("Line %i: SSE classify failed!\n", __LINE__
);
327 /* check if we allow everything we should allow */
328 for (i
= 0; i
< (int) count
; i
++) {
330 results
[i
* RTE_ACL_MAX_CATEGORIES
+ ACL_ALLOW
];
331 if (result
!= acl_test_data
[i
].allow
) {
332 printf("Line %i: Error in allow results at %i "
333 "(expected %"PRIu32
" got %"PRIu32
")!\n",
334 __LINE__
, i
, acl_test_data
[i
].allow
,
341 /* check if we deny everything we should deny */
342 for (i
= 0; i
< (int) count
; i
++) {
343 result
= results
[i
* RTE_ACL_MAX_CATEGORIES
+ ACL_DENY
];
344 if (result
!= acl_test_data
[i
].deny
) {
345 printf("Line %i: Error in deny results at %i "
346 "(expected %"PRIu32
" got %"PRIu32
")!\n",
347 __LINE__
, i
, acl_test_data
[i
].deny
,
355 /* make a quick check for scalar */
356 ret
= rte_acl_classify_alg(acx
, data
, results
,
357 RTE_DIM(acl_test_data
), RTE_ACL_MAX_CATEGORIES
,
358 RTE_ACL_CLASSIFY_SCALAR
);
360 printf("Line %i: scalar classify failed!\n", __LINE__
);
364 /* check if we allow everything we should allow */
365 for (i
= 0; i
< (int) RTE_DIM(acl_test_data
); i
++) {
366 result
= results
[i
* RTE_ACL_MAX_CATEGORIES
+ ACL_ALLOW
];
367 if (result
!= acl_test_data
[i
].allow
) {
368 printf("Line %i: Error in allow results at %i "
369 "(expected %"PRIu32
" got %"PRIu32
")!\n",
370 __LINE__
, i
, acl_test_data
[i
].allow
,
377 /* check if we deny everything we should deny */
378 for (i
= 0; i
< (int) RTE_DIM(acl_test_data
); i
++) {
379 result
= results
[i
* RTE_ACL_MAX_CATEGORIES
+ ACL_DENY
];
380 if (result
!= acl_test_data
[i
].deny
) {
381 printf("Line %i: Error in deny results at %i "
382 "(expected %"PRIu32
" got %"PRIu32
")!\n",
383 __LINE__
, i
, acl_test_data
[i
].deny
,
393 /* swap data back to cpu order so that next time tests don't fail */
394 bswap_test_data(acl_test_data
, RTE_DIM(acl_test_data
), 0);
399 test_classify_buid(struct rte_acl_ctx
*acx
,
400 const struct rte_acl_ipv4vlan_rule
*rules
, uint32_t num
)
404 /* add rules to the context */
405 ret
= rte_acl_ipv4vlan_add_rules(acx
, rules
, num
);
407 printf("Line %i: Adding rules to ACL context failed!\n",
412 /* try building the context */
413 ret
= rte_acl_ipv4vlan_build(acx
, ipv4_7tuple_layout
,
414 RTE_ACL_MAX_CATEGORIES
);
416 printf("Line %i: Building ACL context failed!\n", __LINE__
);
423 #define TEST_CLASSIFY_ITER 4
426 * Test scalar and SSE ACL lookup.
431 struct rte_acl_ctx
*acx
;
434 acx
= rte_acl_create(&acl_param
);
436 printf("Line %i: Error creating ACL context!\n", __LINE__
);
441 for (i
= 0; i
!= TEST_CLASSIFY_ITER
; i
++) {
446 rte_acl_reset_rules(acx
);
448 ret
= test_classify_buid(acx
, acl_test_rules
,
449 RTE_DIM(acl_test_rules
));
451 printf("Line %i, iter: %d: "
452 "Adding rules to ACL context failed!\n",
457 ret
= test_classify_run(acx
);
459 printf("Line %i, iter: %d: %s failed!\n",
460 __LINE__
, i
, __func__
);
464 /* reset rules and make sure that classify still works ok. */
465 rte_acl_reset_rules(acx
);
466 ret
= test_classify_run(acx
);
468 printf("Line %i, iter: %d: %s failed!\n",
469 __LINE__
, i
, __func__
);
479 test_build_ports_range(void)
481 static const struct rte_acl_ipv4vlan_rule test_rules
[] = {
483 /* match all packets. */
486 .category_mask
= ACL_ALLOW_MASK
,
490 .src_port_high
= UINT16_MAX
,
492 .dst_port_high
= UINT16_MAX
,
495 /* match all packets with dst ports [54-65280]. */
498 .category_mask
= ACL_ALLOW_MASK
,
502 .src_port_high
= UINT16_MAX
,
504 .dst_port_high
= 65280,
507 /* match all packets with dst ports [0-52]. */
510 .category_mask
= ACL_ALLOW_MASK
,
514 .src_port_high
= UINT16_MAX
,
519 /* match all packets with dst ports [53]. */
522 .category_mask
= ACL_ALLOW_MASK
,
526 .src_port_high
= UINT16_MAX
,
531 /* match all packets with dst ports [65279-65535]. */
534 .category_mask
= ACL_ALLOW_MASK
,
538 .src_port_high
= UINT16_MAX
,
539 .dst_port_low
= 65279,
540 .dst_port_high
= UINT16_MAX
,
544 static struct ipv4_7tuple test_data
[] = {
547 .ip_src
= IPv4(10, 1, 1, 1),
548 .ip_dst
= IPv4(192, 168, 0, 33),
554 .ip_src
= IPv4(127, 84, 33, 1),
555 .ip_dst
= IPv4(1, 2, 3, 4),
561 struct rte_acl_ctx
*acx
;
563 uint32_t results
[RTE_DIM(test_data
)];
564 const uint8_t *data
[RTE_DIM(test_data
)];
566 acx
= rte_acl_create(&acl_param
);
568 printf("Line %i: Error creating ACL context!\n", __LINE__
);
572 /* swap all bytes in the data to network order */
573 bswap_test_data(test_data
, RTE_DIM(test_data
), 1);
575 /* store pointers to test data */
576 for (i
= 0; i
!= RTE_DIM(test_data
); i
++)
577 data
[i
] = (uint8_t *)&test_data
[i
];
579 for (i
= 0; i
!= RTE_DIM(test_rules
); i
++) {
581 ret
= test_classify_buid(acx
, test_rules
, i
+ 1);
583 printf("Line %i, iter: %d: "
584 "Adding rules to ACL context failed!\n",
588 ret
= rte_acl_classify(acx
, data
, results
,
591 printf("Line %i, iter: %d: classify failed!\n",
597 for (j
= 0; j
!= RTE_DIM(results
); j
++) {
598 if (results
[j
] != test_data
[j
].allow
) {
599 printf("Line %i: Error in allow results at %i "
600 "(expected %"PRIu32
" got %"PRIu32
")!\n",
601 __LINE__
, j
, test_data
[j
].allow
,
608 bswap_test_data(test_data
, RTE_DIM(test_data
), 0);
615 convert_rule(const struct rte_acl_ipv4vlan_rule
*ri
,
616 struct acl_ipv4vlan_rule
*ro
)
620 ro
->field
[RTE_ACL_IPV4VLAN_PROTO_FIELD
].value
.u8
= ri
->proto
;
621 ro
->field
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].value
.u16
= ri
->vlan
;
622 ro
->field
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].value
.u16
= ri
->domain
;
623 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].value
.u32
= ri
->src_addr
;
624 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].value
.u32
= ri
->dst_addr
;
625 ro
->field
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].value
.u16
= ri
->src_port_low
;
626 ro
->field
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].value
.u16
= ri
->dst_port_low
;
628 ro
->field
[RTE_ACL_IPV4VLAN_PROTO_FIELD
].mask_range
.u8
= ri
->proto_mask
;
629 ro
->field
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].mask_range
.u16
= ri
->vlan_mask
;
630 ro
->field
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].mask_range
.u16
=
632 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
=
634 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
= ri
->dst_mask_len
;
635 ro
->field
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].mask_range
.u16
=
637 ro
->field
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].mask_range
.u16
=
642 * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
643 * RTE_ACL_FIELD_TYPE_BITMASK.
646 convert_rule_1(const struct rte_acl_ipv4vlan_rule
*ri
,
647 struct acl_ipv4vlan_rule
*ro
)
651 convert_rule(ri
, ro
);
652 v
= ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
;
653 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
=
654 RTE_ACL_MASKLEN_TO_BITMASK(v
, sizeof(v
));
655 v
= ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
;
656 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
=
657 RTE_ACL_MASKLEN_TO_BITMASK(v
, sizeof(v
));
661 * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
662 * RTE_ACL_FIELD_TYPE_RANGE.
665 convert_rule_2(const struct rte_acl_ipv4vlan_rule
*ri
,
666 struct acl_ipv4vlan_rule
*ro
)
668 uint32_t hi
, lo
, mask
;
670 convert_rule(ri
, ro
);
672 mask
= ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
;
673 mask
= RTE_ACL_MASKLEN_TO_BITMASK(mask
, sizeof(mask
));
674 lo
= ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].value
.u32
& mask
;
676 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].value
.u32
= lo
;
677 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
].mask_range
.u32
= hi
;
679 mask
= ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
;
680 mask
= RTE_ACL_MASKLEN_TO_BITMASK(mask
, sizeof(mask
));
681 lo
= ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].value
.u32
& mask
;
683 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].value
.u32
= lo
;
684 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
].mask_range
.u32
= hi
;
688 * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule fields.
691 convert_rule_3(const struct rte_acl_ipv4vlan_rule
*ri
,
692 struct acl_ipv4vlan_rule
*ro
)
694 struct rte_acl_field t1
, t2
;
696 convert_rule(ri
, ro
);
698 t1
= ro
->field
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
];
699 t2
= ro
->field
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
];
701 ro
->field
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
] =
702 ro
->field
[RTE_ACL_IPV4VLAN_SRCP_FIELD
];
703 ro
->field
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
] =
704 ro
->field
[RTE_ACL_IPV4VLAN_DSTP_FIELD
];
706 ro
->field
[RTE_ACL_IPV4VLAN_SRCP_FIELD
] = t1
;
707 ro
->field
[RTE_ACL_IPV4VLAN_DSTP_FIELD
] = t2
;
711 * Convert rte_acl_ipv4vlan_rule: swap SRC and DST IPv4 address rules.
714 convert_rule_4(const struct rte_acl_ipv4vlan_rule
*ri
,
715 struct acl_ipv4vlan_rule
*ro
)
717 struct rte_acl_field t
;
719 convert_rule(ri
, ro
);
721 t
= ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
];
722 ro
->field
[RTE_ACL_IPV4VLAN_SRC_FIELD
] =
723 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
];
725 ro
->field
[RTE_ACL_IPV4VLAN_DST_FIELD
] = t
;
729 ipv4vlan_config(struct rte_acl_config
*cfg
,
730 const uint32_t layout
[RTE_ACL_IPV4VLAN_NUM
],
731 uint32_t num_categories
)
733 static const struct rte_acl_field_def
734 ipv4_defs
[RTE_ACL_IPV4VLAN_NUM_FIELDS
] = {
736 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
737 .size
= sizeof(uint8_t),
738 .field_index
= RTE_ACL_IPV4VLAN_PROTO_FIELD
,
739 .input_index
= RTE_ACL_IPV4VLAN_PROTO
,
742 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
743 .size
= sizeof(uint16_t),
744 .field_index
= RTE_ACL_IPV4VLAN_VLAN1_FIELD
,
745 .input_index
= RTE_ACL_IPV4VLAN_VLAN
,
748 .type
= RTE_ACL_FIELD_TYPE_BITMASK
,
749 .size
= sizeof(uint16_t),
750 .field_index
= RTE_ACL_IPV4VLAN_VLAN2_FIELD
,
751 .input_index
= RTE_ACL_IPV4VLAN_VLAN
,
754 .type
= RTE_ACL_FIELD_TYPE_MASK
,
755 .size
= sizeof(uint32_t),
756 .field_index
= RTE_ACL_IPV4VLAN_SRC_FIELD
,
757 .input_index
= RTE_ACL_IPV4VLAN_SRC
,
760 .type
= RTE_ACL_FIELD_TYPE_MASK
,
761 .size
= sizeof(uint32_t),
762 .field_index
= RTE_ACL_IPV4VLAN_DST_FIELD
,
763 .input_index
= RTE_ACL_IPV4VLAN_DST
,
766 .type
= RTE_ACL_FIELD_TYPE_RANGE
,
767 .size
= sizeof(uint16_t),
768 .field_index
= RTE_ACL_IPV4VLAN_SRCP_FIELD
,
769 .input_index
= RTE_ACL_IPV4VLAN_PORTS
,
772 .type
= RTE_ACL_FIELD_TYPE_RANGE
,
773 .size
= sizeof(uint16_t),
774 .field_index
= RTE_ACL_IPV4VLAN_DSTP_FIELD
,
775 .input_index
= RTE_ACL_IPV4VLAN_PORTS
,
779 memcpy(&cfg
->defs
, ipv4_defs
, sizeof(ipv4_defs
));
780 cfg
->num_fields
= RTE_DIM(ipv4_defs
);
782 cfg
->defs
[RTE_ACL_IPV4VLAN_PROTO_FIELD
].offset
=
783 layout
[RTE_ACL_IPV4VLAN_PROTO
];
784 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].offset
=
785 layout
[RTE_ACL_IPV4VLAN_VLAN
];
786 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].offset
=
787 layout
[RTE_ACL_IPV4VLAN_VLAN
] +
788 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].size
;
789 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].offset
=
790 layout
[RTE_ACL_IPV4VLAN_SRC
];
791 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].offset
=
792 layout
[RTE_ACL_IPV4VLAN_DST
];
793 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].offset
=
794 layout
[RTE_ACL_IPV4VLAN_PORTS
];
795 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].offset
=
796 layout
[RTE_ACL_IPV4VLAN_PORTS
] +
797 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].size
;
799 cfg
->num_categories
= num_categories
;
803 convert_rules(struct rte_acl_ctx
*acx
,
804 void (*convert
)(const struct rte_acl_ipv4vlan_rule
*,
805 struct acl_ipv4vlan_rule
*),
806 const struct rte_acl_ipv4vlan_rule
*rules
, uint32_t num
)
810 struct acl_ipv4vlan_rule r
;
812 for (i
= 0; i
!= num
; i
++) {
813 convert(rules
+ i
, &r
);
814 rc
= rte_acl_add_rules(acx
, (struct rte_acl_rule
*)&r
, 1);
816 printf("Line %i: Adding rule %u to ACL context "
817 "failed with error code: %d\n",
827 convert_config(struct rte_acl_config
*cfg
)
829 ipv4vlan_config(cfg
, ipv4_7tuple_layout
, RTE_ACL_MAX_CATEGORIES
);
833 * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_BITMASK.
836 convert_config_1(struct rte_acl_config
*cfg
)
838 ipv4vlan_config(cfg
, ipv4_7tuple_layout
, RTE_ACL_MAX_CATEGORIES
);
839 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].type
= RTE_ACL_FIELD_TYPE_BITMASK
;
840 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].type
= RTE_ACL_FIELD_TYPE_BITMASK
;
844 * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_RANGE.
847 convert_config_2(struct rte_acl_config
*cfg
)
849 ipv4vlan_config(cfg
, ipv4_7tuple_layout
, RTE_ACL_MAX_CATEGORIES
);
850 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].type
= RTE_ACL_FIELD_TYPE_RANGE
;
851 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].type
= RTE_ACL_FIELD_TYPE_RANGE
;
855 * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule definitions.
858 convert_config_3(struct rte_acl_config
*cfg
)
860 struct rte_acl_field_def t1
, t2
;
862 ipv4vlan_config(cfg
, ipv4_7tuple_layout
, RTE_ACL_MAX_CATEGORIES
);
864 t1
= cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
];
865 t2
= cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
];
867 /* swap VLAN1 and SRCP rule definition. */
868 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
] =
869 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
];
870 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].field_index
= t1
.field_index
;
871 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN1_FIELD
].input_index
= t1
.input_index
;
873 /* swap VLAN2 and DSTP rule definition. */
874 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
] =
875 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
];
876 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].field_index
= t2
.field_index
;
877 cfg
->defs
[RTE_ACL_IPV4VLAN_VLAN2_FIELD
].input_index
= t2
.input_index
;
879 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].type
= t1
.type
;
880 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].size
= t1
.size
;
881 cfg
->defs
[RTE_ACL_IPV4VLAN_SRCP_FIELD
].offset
= t1
.offset
;
883 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].type
= t2
.type
;
884 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].size
= t2
.size
;
885 cfg
->defs
[RTE_ACL_IPV4VLAN_DSTP_FIELD
].offset
= t2
.offset
;
889 * Convert rte_acl_ipv4vlan_rule: swap SRC and DST ip address rule definitions.
892 convert_config_4(struct rte_acl_config
*cfg
)
894 struct rte_acl_field_def t
;
896 ipv4vlan_config(cfg
, ipv4_7tuple_layout
, RTE_ACL_MAX_CATEGORIES
);
898 t
= cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
];
900 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
] =
901 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
];
902 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].field_index
= t
.field_index
;
903 cfg
->defs
[RTE_ACL_IPV4VLAN_SRC_FIELD
].input_index
= t
.input_index
;
905 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].type
= t
.type
;
906 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].size
= t
.size
;
907 cfg
->defs
[RTE_ACL_IPV4VLAN_DST_FIELD
].offset
= t
.offset
;
912 build_convert_rules(struct rte_acl_ctx
*acx
,
913 void (*config
)(struct rte_acl_config
*),
916 struct rte_acl_config cfg
;
918 memset(&cfg
, 0, sizeof(cfg
));
920 cfg
.max_size
= max_size
;
921 return rte_acl_build(acx
, &cfg
);
925 test_convert_rules(const char *desc
,
926 void (*config
)(struct rte_acl_config
*),
927 void (*convert
)(const struct rte_acl_ipv4vlan_rule
*,
928 struct acl_ipv4vlan_rule
*))
930 struct rte_acl_ctx
*acx
;
933 static const size_t mem_sizes
[] = {0, -1};
935 printf("running %s(%s)\n", __func__
, desc
);
937 acx
= rte_acl_create(&acl_param
);
939 printf("Line %i: Error creating ACL context!\n", __LINE__
);
943 rc
= convert_rules(acx
, convert
, acl_test_rules
,
944 RTE_DIM(acl_test_rules
));
946 printf("Line %i: Error converting ACL rules!\n", __LINE__
);
948 for (i
= 0; rc
== 0 && i
!= RTE_DIM(mem_sizes
); i
++) {
950 rc
= build_convert_rules(acx
, config
, mem_sizes
[i
]);
952 printf("Line %i: Error @ build_convert_rules(%zu)!\n",
953 __LINE__
, mem_sizes
[i
]);
957 rc
= test_classify_run(acx
);
959 printf("%s failed at line %i, max_size=%zu\n",
960 __func__
, __LINE__
, mem_sizes
[i
]);
970 static const struct {
972 void (*config
)(struct rte_acl_config
*);
973 void (*convert
)(const struct rte_acl_ipv4vlan_rule
*,
974 struct acl_ipv4vlan_rule
*);
975 } convert_param
[] = {
977 "acl_ipv4vlan_tuple",
982 "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_BITMASK type "
988 "acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_RANGE type "
994 "acl_ipv4vlan_tuple: swap VLAN and PORTs order",
999 "acl_ipv4vlan_tuple: swap SRC and DST IPv4 order",
1008 for (i
= 0; i
!= RTE_DIM(convert_param
); i
++) {
1009 rc
= test_convert_rules(convert_param
[i
].desc
,
1010 convert_param
[i
].config
,
1011 convert_param
[i
].convert
);
1013 printf("%s for test-case: %s failed, error code: %d;\n",
1014 __func__
, convert_param
[i
].desc
, rc
);
1023 * Test wrong layout behavior
1024 * This test supplies the ACL context with invalid layout, which results in
1025 * ACL matching the wrong stuff. However, it should match the wrong stuff
1026 * the right way. We switch around source and destination addresses,
1027 * source and destination ports, and protocol will point to first byte of
1031 test_invalid_layout(void)
1033 struct rte_acl_ctx
*acx
;
1036 uint32_t results
[RTE_DIM(invalid_layout_data
)];
1037 const uint8_t *data
[RTE_DIM(invalid_layout_data
)];
1039 const uint32_t layout
[RTE_ACL_IPV4VLAN_NUM
] = {
1040 /* proto points to destination port's first byte */
1041 offsetof(struct ipv4_7tuple
, port_dst
),
1043 0, /* VLAN not used */
1045 /* src and dst addresses are swapped */
1046 offsetof(struct ipv4_7tuple
, ip_dst
),
1047 offsetof(struct ipv4_7tuple
, ip_src
),
1050 * we can't swap ports here, so we will swap
1053 offsetof(struct ipv4_7tuple
, port_src
),
1056 acx
= rte_acl_create(&acl_param
);
1058 printf("Line %i: Error creating ACL context!\n", __LINE__
);
1062 /* putting a lot of rules into the context results in greater
1063 * coverage numbers. it doesn't matter if they are identical */
1064 for (i
= 0; i
< 1000; i
++) {
1065 /* add rules to the context */
1066 ret
= rte_acl_ipv4vlan_add_rules(acx
, invalid_layout_rules
,
1067 RTE_DIM(invalid_layout_rules
));
1069 printf("Line %i: Adding rules to ACL context failed!\n",
1076 /* try building the context */
1077 ret
= rte_acl_ipv4vlan_build(acx
, layout
, 1);
1079 printf("Line %i: Building ACL context failed!\n", __LINE__
);
1084 /* swap all bytes in the data to network order */
1085 bswap_test_data(invalid_layout_data
, RTE_DIM(invalid_layout_data
), 1);
1088 for (i
= 0; i
< (int) RTE_DIM(invalid_layout_data
); i
++) {
1089 data
[i
] = (uint8_t *)&invalid_layout_data
[i
];
1092 /* classify tuples */
1093 ret
= rte_acl_classify_alg(acx
, data
, results
,
1094 RTE_DIM(results
), 1, RTE_ACL_CLASSIFY_SCALAR
);
1096 printf("Line %i: SSE classify failed!\n", __LINE__
);
1101 for (i
= 0; i
< (int) RTE_DIM(results
); i
++) {
1102 if (results
[i
] != invalid_layout_data
[i
].allow
) {
1103 printf("Line %i: Wrong results at %i "
1104 "(result=%u, should be %u)!\n",
1105 __LINE__
, i
, results
[i
],
1106 invalid_layout_data
[i
].allow
);
1111 /* classify tuples (scalar) */
1112 ret
= rte_acl_classify_alg(acx
, data
, results
, RTE_DIM(results
), 1,
1113 RTE_ACL_CLASSIFY_SCALAR
);
1116 printf("Line %i: Scalar classify failed!\n", __LINE__
);
1121 for (i
= 0; i
< (int) RTE_DIM(results
); i
++) {
1122 if (results
[i
] != invalid_layout_data
[i
].allow
) {
1123 printf("Line %i: Wrong results at %i "
1124 "(result=%u, should be %u)!\n",
1125 __LINE__
, i
, results
[i
],
1126 invalid_layout_data
[i
].allow
);
1133 /* swap data back to cpu order so that next time tests don't fail */
1134 bswap_test_data(invalid_layout_data
, RTE_DIM(invalid_layout_data
), 0);
1139 /* swap data back to cpu order so that next time tests don't fail */
1140 bswap_test_data(invalid_layout_data
, RTE_DIM(invalid_layout_data
), 0);
1148 * Test creating and finding ACL contexts, and adding rules
1151 test_create_find_add(void)
1153 struct rte_acl_param param
;
1154 struct rte_acl_ctx
*acx
, *acx2
, *tmp
;
1155 struct rte_acl_ipv4vlan_rule rules
[LEN
];
1157 const uint32_t layout
[RTE_ACL_IPV4VLAN_NUM
] = {0};
1159 const char *acx_name
= "acx";
1160 const char *acx2_name
= "acx2";
1163 /* create two contexts */
1164 memcpy(¶m
, &acl_param
, sizeof(param
));
1165 param
.max_rule_num
= 2;
1167 param
.name
= acx_name
;
1168 acx
= rte_acl_create(¶m
);
1170 printf("Line %i: Error creating %s!\n", __LINE__
, acx_name
);
1174 param
.name
= acx2_name
;
1175 acx2
= rte_acl_create(¶m
);
1176 if (acx2
== NULL
|| acx2
== acx
) {
1177 printf("Line %i: Error creating %s!\n", __LINE__
, acx2_name
);
1182 /* try to create third one, with an existing name */
1183 param
.name
= acx_name
;
1184 tmp
= rte_acl_create(¶m
);
1186 printf("Line %i: Creating context with existing name "
1194 param
.name
= acx2_name
;
1195 tmp
= rte_acl_create(¶m
);
1197 printf("Line %i: Creating context with existing "
1198 "name test 2 failed!\n",
1205 /* try to find existing ACL contexts */
1206 tmp
= rte_acl_find_existing(acx_name
);
1208 printf("Line %i: Finding %s failed!\n", __LINE__
, acx_name
);
1214 tmp
= rte_acl_find_existing(acx2_name
);
1216 printf("Line %i: Finding %s failed!\n", __LINE__
, acx2_name
);
1222 /* try to find non-existing context */
1223 tmp
= rte_acl_find_existing("invalid");
1225 printf("Line %i: Non-existent ACL context found!\n", __LINE__
);
1233 /* create valid (but severely limited) acx */
1234 memcpy(¶m
, &acl_param
, sizeof(param
));
1235 param
.max_rule_num
= LEN
;
1237 acx
= rte_acl_create(¶m
);
1239 printf("Line %i: Error creating %s!\n", __LINE__
, param
.name
);
1243 /* create dummy acl */
1244 for (i
= 0; i
< LEN
; i
++) {
1245 memcpy(&rules
[i
], &acl_rule
,
1246 sizeof(struct rte_acl_ipv4vlan_rule
));
1248 rules
[i
].data
.userdata
= i
+ 1;
1249 /* one rule per category */
1250 rules
[i
].data
.category_mask
= 1 << i
;
1253 /* try filling up the context */
1254 ret
= rte_acl_ipv4vlan_add_rules(acx
, rules
, LEN
);
1256 printf("Line %i: Adding %i rules to ACL context failed!\n",
1261 /* try adding to a (supposedly) full context */
1262 ret
= rte_acl_ipv4vlan_add_rules(acx
, rules
, 1);
1264 printf("Line %i: Adding rules to full ACL context should"
1265 "have failed!\n", __LINE__
);
1269 /* try building the context */
1270 ret
= rte_acl_ipv4vlan_build(acx
, layout
, RTE_ACL_MAX_CATEGORIES
);
1272 printf("Line %i: Building ACL context failed!\n", __LINE__
);
1287 * test various invalid rules
1290 test_invalid_rules(void)
1292 struct rte_acl_ctx
*acx
;
1295 struct rte_acl_ipv4vlan_rule rule
;
1297 acx
= rte_acl_create(&acl_param
);
1299 printf("Line %i: Error creating ACL context!\n", __LINE__
);
1303 /* test inverted high/low source and destination ports.
1304 * originally, there was a problem with memory consumption when using
1307 /* create dummy acl */
1308 memcpy(&rule
, &acl_rule
, sizeof(struct rte_acl_ipv4vlan_rule
));
1309 rule
.data
.userdata
= 1;
1310 rule
.dst_port_low
= 0xfff0;
1311 rule
.dst_port_high
= 0x0010;
1313 /* add rules to context and try to build it */
1314 ret
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 1);
1316 printf("Line %i: Adding rules to ACL context "
1317 "should have failed!\n", __LINE__
);
1321 rule
.dst_port_low
= 0x0;
1322 rule
.dst_port_high
= 0xffff;
1323 rule
.src_port_low
= 0xfff0;
1324 rule
.src_port_high
= 0x0010;
1326 /* add rules to context and try to build it */
1327 ret
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 1);
1329 printf("Line %i: Adding rules to ACL context "
1330 "should have failed!\n", __LINE__
);
1334 rule
.dst_port_low
= 0x0;
1335 rule
.dst_port_high
= 0xffff;
1336 rule
.src_port_low
= 0x0;
1337 rule
.src_port_high
= 0xffff;
1339 rule
.dst_mask_len
= 33;
1341 /* add rules to context and try to build it */
1342 ret
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 1);
1344 printf("Line %i: Adding rules to ACL context "
1345 "should have failed!\n", __LINE__
);
1349 rule
.dst_mask_len
= 0;
1350 rule
.src_mask_len
= 33;
1352 /* add rules to context and try to build it */
1353 ret
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 1);
1355 printf("Line %i: Adding rules to ACL context "
1356 "should have failed!\n", __LINE__
);
1360 rule
.dst_mask_len
= 0;
1361 rule
.src_mask_len
= 0;
1362 rule
.data
.userdata
= 0;
1364 /* try adding this rule (it should fail because userdata is invalid) */
1365 ret
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 1);
1367 printf("Line %i: Adding a rule with invalid user data "
1368 "should have failed!\n", __LINE__
);
1384 * test functions by passing invalid or
1385 * non-workable parameters.
1387 * we do very limited testing of classify functions here
1388 * because those are performance-critical and
1389 * thus don't do much parameter checking.
1392 test_invalid_parameters(void)
1394 struct rte_acl_param param
;
1395 struct rte_acl_ctx
*acx
;
1396 struct rte_acl_ipv4vlan_rule rule
;
1399 uint32_t layout
[RTE_ACL_IPV4VLAN_NUM
] = {0};
1407 acx
= rte_acl_create(NULL
);
1409 printf("Line %i: ACL context creation with NULL param "
1410 "should have failed!\n", __LINE__
);
1415 /* zero rule size */
1416 memcpy(¶m
, &acl_param
, sizeof(param
));
1417 param
.rule_size
= 0;
1419 acx
= rte_acl_create(¶m
);
1421 printf("Line %i: ACL context creation with zero rule len "
1422 "failed!\n", __LINE__
);
1427 /* zero max rule num */
1428 memcpy(¶m
, &acl_param
, sizeof(param
));
1429 param
.max_rule_num
= 0;
1431 acx
= rte_acl_create(¶m
);
1433 printf("Line %i: ACL context creation with zero rule num "
1434 "failed!\n", __LINE__
);
1439 /* invalid NUMA node */
1440 memcpy(¶m
, &acl_param
, sizeof(param
));
1441 param
.socket_id
= RTE_MAX_NUMA_NODES
+ 1;
1443 acx
= rte_acl_create(¶m
);
1445 printf("Line %i: ACL context creation with invalid NUMA "
1446 "should have failed!\n", __LINE__
);
1452 memcpy(¶m
, &acl_param
, sizeof(param
));
1455 acx
= rte_acl_create(¶m
);
1457 printf("Line %i: ACL context creation with NULL name "
1458 "should have failed!\n", __LINE__
);
1464 * rte_acl_find_existing
1467 acx
= rte_acl_find_existing(NULL
);
1469 printf("Line %i: NULL ACL context found!\n", __LINE__
);
1475 * rte_acl_ipv4vlan_add_rules
1478 /* initialize everything */
1479 memcpy(¶m
, &acl_param
, sizeof(param
));
1480 acx
= rte_acl_create(¶m
);
1482 printf("Line %i: ACL context creation failed!\n", __LINE__
);
1486 memcpy(&rule
, &acl_rule
, sizeof(rule
));
1489 result
= rte_acl_ipv4vlan_add_rules(NULL
, &rule
, 1);
1491 printf("Line %i: Adding rules with NULL ACL context "
1492 "should have failed!\n", __LINE__
);
1498 result
= rte_acl_ipv4vlan_add_rules(acx
, NULL
, 1);
1500 printf("Line %i: Adding NULL rule to ACL context "
1501 "should have failed!\n", __LINE__
);
1506 /* zero count (should succeed) */
1507 result
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 0);
1509 printf("Line %i: Adding 0 rules to ACL context failed!\n",
1515 /* free ACL context */
1518 /* set wrong rule_size so that adding any rules would fail */
1519 param
.rule_size
= RTE_ACL_IPV4VLAN_RULE_SZ
+ 4;
1520 acx
= rte_acl_create(¶m
);
1522 printf("Line %i: ACL context creation failed!\n", __LINE__
);
1526 /* try adding a rule with size different from context rule_size */
1527 result
= rte_acl_ipv4vlan_add_rules(acx
, &rule
, 1);
1529 printf("Line %i: Adding an invalid sized rule "
1530 "should have failed!\n", __LINE__
);
1535 /* free ACL context */
1540 * rte_acl_ipv4vlan_build
1543 /* reinitialize context */
1544 memcpy(¶m
, &acl_param
, sizeof(param
));
1545 acx
= rte_acl_create(¶m
);
1547 printf("Line %i: ACL context creation failed!\n", __LINE__
);
1552 result
= rte_acl_ipv4vlan_build(NULL
, layout
, 1);
1554 printf("Line %i: Building with NULL context "
1555 "should have failed!\n", __LINE__
);
1561 result
= rte_acl_ipv4vlan_build(acx
, NULL
, 1);
1563 printf("Line %i: Building with NULL layout "
1564 "should have failed!\n", __LINE__
);
1569 /* zero categories (should not fail) */
1570 result
= rte_acl_ipv4vlan_build(acx
, layout
, 0);
1572 printf("Line %i: Building with 0 categories should fail!\n",
1578 /* SSE classify test */
1580 /* cover zero categories in classify (should not fail) */
1581 result
= rte_acl_classify(acx
, NULL
, NULL
, 0, 0);
1583 printf("Line %i: SSE classify with zero categories "
1584 "failed!\n", __LINE__
);
1589 /* cover invalid but positive categories in classify */
1590 result
= rte_acl_classify(acx
, NULL
, NULL
, 0, 3);
1592 printf("Line %i: SSE classify with 3 categories "
1593 "should have failed!\n", __LINE__
);
1598 /* scalar classify test */
1600 /* cover zero categories in classify (should not fail) */
1601 result
= rte_acl_classify_alg(acx
, NULL
, NULL
, 0, 0,
1602 RTE_ACL_CLASSIFY_SCALAR
);
1604 printf("Line %i: Scalar classify with zero categories "
1605 "failed!\n", __LINE__
);
1610 /* cover invalid but positive categories in classify */
1611 result
= rte_acl_classify(acx
, NULL
, NULL
, 0, 3);
1613 printf("Line %i: Scalar classify with 3 categories "
1614 "should have failed!\n", __LINE__
);
1619 /* free ACL context */
1624 * make sure void functions don't crash with NULL parameters
1635 * Various tests that don't test much but improve coverage
1640 struct rte_acl_param param
;
1641 struct rte_acl_ctx
*acx
;
1643 /* create context */
1644 memcpy(¶m
, &acl_param
, sizeof(param
));
1646 acx
= rte_acl_create(¶m
);
1648 printf("Line %i: Error creating ACL context!\n", __LINE__
);
1652 /* dump context with rules - useful for coverage */
1653 rte_acl_list_dump();
1665 if (test_invalid_parameters() < 0)
1667 if (test_invalid_rules() < 0)
1669 if (test_create_find_add() < 0)
1671 if (test_invalid_layout() < 0)
1673 if (test_misc() < 0)
1675 if (test_classify() < 0)
1677 if (test_build_ports_range() < 0)
1679 if (test_convert() < 0)
1685 REGISTER_TEST_COMMAND(acl_autotest
, test_acl
);