xref: /dpdk/app/test/test_acl.c (revision 73d85848eb1df9c9b376557aaa44d246748726b8)
1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson  * Copyright(c) 2010-2014 Intel Corporation
3a9de470cSBruce Richardson  */
4a9de470cSBruce Richardson 
5a9de470cSBruce Richardson #include <string.h>
6a9de470cSBruce Richardson #include <errno.h>
7a9de470cSBruce Richardson 
8a9de470cSBruce Richardson #include "test.h"
9a9de470cSBruce Richardson 
10a9de470cSBruce Richardson #include <rte_string_fns.h>
11a9de470cSBruce Richardson #include <rte_mbuf.h>
12a9de470cSBruce Richardson #include <rte_byteorder.h>
13a9de470cSBruce Richardson #include <rte_ip.h>
143c60274cSJie Zhou 
153c60274cSJie Zhou #ifdef RTE_EXEC_ENV_WINDOWS
163c60274cSJie Zhou static int
test_acl(void)173c60274cSJie Zhou test_acl(void)
183c60274cSJie Zhou {
193c60274cSJie Zhou 	printf("ACL not supported on Windows, skipping test\n");
203c60274cSJie Zhou 	return TEST_SKIPPED;
213c60274cSJie Zhou }
223c60274cSJie Zhou 
233c60274cSJie Zhou #else
24a9de470cSBruce Richardson #include <rte_acl.h>
25a9de470cSBruce Richardson #include <rte_common.h>
26a9de470cSBruce Richardson 
27a9de470cSBruce Richardson #include "test_acl.h"
28a9de470cSBruce Richardson 
29a9de470cSBruce Richardson #define	BIT_SIZEOF(x) (sizeof(x) * CHAR_BIT)
30a9de470cSBruce Richardson 
31a9de470cSBruce Richardson #define LEN RTE_ACL_MAX_CATEGORIES
32a9de470cSBruce Richardson 
33a9de470cSBruce Richardson RTE_ACL_RULE_DEF(acl_ipv4vlan_rule, RTE_ACL_IPV4VLAN_NUM_FIELDS);
34a9de470cSBruce Richardson 
35a9de470cSBruce Richardson struct rte_acl_param acl_param = {
36a9de470cSBruce Richardson 	.name = "acl_ctx",
37a9de470cSBruce Richardson 	.socket_id = SOCKET_ID_ANY,
38a9de470cSBruce Richardson 	.rule_size = RTE_ACL_IPV4VLAN_RULE_SZ,
39a9de470cSBruce Richardson 	.max_rule_num = 0x30000,
40a9de470cSBruce Richardson };
41a9de470cSBruce Richardson 
42a9de470cSBruce Richardson struct rte_acl_ipv4vlan_rule acl_rule = {
43a9de470cSBruce Richardson 		.data = { .priority = 1, .category_mask = 0xff },
44a9de470cSBruce Richardson 		.src_port_low = 0,
45a9de470cSBruce Richardson 		.src_port_high = UINT16_MAX,
46a9de470cSBruce Richardson 		.dst_port_low = 0,
47a9de470cSBruce Richardson 		.dst_port_high = UINT16_MAX,
48a9de470cSBruce Richardson };
49a9de470cSBruce Richardson 
50a9de470cSBruce Richardson const uint32_t ipv4_7tuple_layout[RTE_ACL_IPV4VLAN_NUM] = {
51a9de470cSBruce Richardson 	offsetof(struct ipv4_7tuple, proto),
52a9de470cSBruce Richardson 	offsetof(struct ipv4_7tuple, vlan),
53a9de470cSBruce Richardson 	offsetof(struct ipv4_7tuple, ip_src),
54a9de470cSBruce Richardson 	offsetof(struct ipv4_7tuple, ip_dst),
55a9de470cSBruce Richardson 	offsetof(struct ipv4_7tuple, port_src),
56a9de470cSBruce Richardson };
57a9de470cSBruce Richardson 
58a9de470cSBruce Richardson 
59a9de470cSBruce Richardson /* byteswap to cpu or network order */
60a9de470cSBruce Richardson static void
bswap_test_data(struct ipv4_7tuple * data,int len,int to_be)61a9de470cSBruce Richardson bswap_test_data(struct ipv4_7tuple *data, int len, int to_be)
62a9de470cSBruce Richardson {
63a9de470cSBruce Richardson 	int i;
64a9de470cSBruce Richardson 
65a9de470cSBruce Richardson 	for (i = 0; i < len; i++) {
66a9de470cSBruce Richardson 
67a9de470cSBruce Richardson 		if (to_be) {
68a9de470cSBruce Richardson 			/* swap all bytes so that they are in network order */
69a9de470cSBruce Richardson 			data[i].ip_dst = rte_cpu_to_be_32(data[i].ip_dst);
70a9de470cSBruce Richardson 			data[i].ip_src = rte_cpu_to_be_32(data[i].ip_src);
71a9de470cSBruce Richardson 			data[i].port_dst = rte_cpu_to_be_16(data[i].port_dst);
72a9de470cSBruce Richardson 			data[i].port_src = rte_cpu_to_be_16(data[i].port_src);
73a9de470cSBruce Richardson 			data[i].vlan = rte_cpu_to_be_16(data[i].vlan);
74a9de470cSBruce Richardson 			data[i].domain = rte_cpu_to_be_16(data[i].domain);
75a9de470cSBruce Richardson 		} else {
76a9de470cSBruce Richardson 			data[i].ip_dst = rte_be_to_cpu_32(data[i].ip_dst);
77a9de470cSBruce Richardson 			data[i].ip_src = rte_be_to_cpu_32(data[i].ip_src);
78a9de470cSBruce Richardson 			data[i].port_dst = rte_be_to_cpu_16(data[i].port_dst);
79a9de470cSBruce Richardson 			data[i].port_src = rte_be_to_cpu_16(data[i].port_src);
80a9de470cSBruce Richardson 			data[i].vlan = rte_be_to_cpu_16(data[i].vlan);
81a9de470cSBruce Richardson 			data[i].domain = rte_be_to_cpu_16(data[i].domain);
82a9de470cSBruce Richardson 		}
83a9de470cSBruce Richardson 	}
84a9de470cSBruce Richardson }
85a9de470cSBruce Richardson 
86a9de470cSBruce Richardson static int
acl_ipv4vlan_check_rule(const struct rte_acl_ipv4vlan_rule * rule)87a9de470cSBruce Richardson acl_ipv4vlan_check_rule(const struct rte_acl_ipv4vlan_rule *rule)
88a9de470cSBruce Richardson {
89a9de470cSBruce Richardson 	if (rule->src_port_low > rule->src_port_high ||
90a9de470cSBruce Richardson 			rule->dst_port_low > rule->dst_port_high ||
91a9de470cSBruce Richardson 			rule->src_mask_len > BIT_SIZEOF(rule->src_addr) ||
92a9de470cSBruce Richardson 			rule->dst_mask_len > BIT_SIZEOF(rule->dst_addr))
93a9de470cSBruce Richardson 		return -EINVAL;
94a9de470cSBruce Richardson 	return 0;
95a9de470cSBruce Richardson }
96a9de470cSBruce Richardson 
97a9de470cSBruce Richardson static void
acl_ipv4vlan_convert_rule(const struct rte_acl_ipv4vlan_rule * ri,struct acl_ipv4vlan_rule * ro)98a9de470cSBruce Richardson acl_ipv4vlan_convert_rule(const struct rte_acl_ipv4vlan_rule *ri,
99a9de470cSBruce Richardson 	struct acl_ipv4vlan_rule *ro)
100a9de470cSBruce Richardson {
101a9de470cSBruce Richardson 	ro->data = ri->data;
102a9de470cSBruce Richardson 
103a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto;
104a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan;
105a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain;
106a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr;
107a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr;
108a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low;
109a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low;
110a9de470cSBruce Richardson 
111a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask;
112a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask;
113a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 =
114a9de470cSBruce Richardson 		ri->domain_mask;
115a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
116a9de470cSBruce Richardson 		ri->src_mask_len;
117a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len;
118a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 =
119a9de470cSBruce Richardson 		ri->src_port_high;
120a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 =
121a9de470cSBruce Richardson 		ri->dst_port_high;
122a9de470cSBruce Richardson }
123a9de470cSBruce Richardson 
124a9de470cSBruce Richardson /*
125a9de470cSBruce Richardson  * Add ipv4vlan rules to an existing ACL context.
126a9de470cSBruce Richardson  * This function is not multi-thread safe.
127a9de470cSBruce Richardson  *
128a9de470cSBruce Richardson  * @param ctx
129a9de470cSBruce Richardson  *   ACL context to add patterns to.
130a9de470cSBruce Richardson  * @param rules
131a9de470cSBruce Richardson  *   Array of rules to add to the ACL context.
132a9de470cSBruce Richardson  *   Note that all fields in rte_acl_ipv4vlan_rule structures are expected
133a9de470cSBruce Richardson  *   to be in host byte order.
134a9de470cSBruce Richardson  * @param num
135a9de470cSBruce Richardson  *   Number of elements in the input array of rules.
136a9de470cSBruce Richardson  * @return
137a9de470cSBruce Richardson  *   - -ENOMEM if there is no space in the ACL context for these rules.
138a9de470cSBruce Richardson  *   - -EINVAL if the parameters are invalid.
139a9de470cSBruce Richardson  *   - Zero if operation completed successfully.
140a9de470cSBruce Richardson  */
141a9de470cSBruce Richardson static int
rte_acl_ipv4vlan_add_rules(struct rte_acl_ctx * ctx,const struct rte_acl_ipv4vlan_rule * rules,uint32_t num)142a9de470cSBruce Richardson rte_acl_ipv4vlan_add_rules(struct rte_acl_ctx *ctx,
143a9de470cSBruce Richardson 	const struct rte_acl_ipv4vlan_rule *rules,
144a9de470cSBruce Richardson 	uint32_t num)
145a9de470cSBruce Richardson {
146a9de470cSBruce Richardson 	int32_t rc;
147a9de470cSBruce Richardson 	uint32_t i;
148a9de470cSBruce Richardson 	struct acl_ipv4vlan_rule rv;
149a9de470cSBruce Richardson 
150a9de470cSBruce Richardson 	if (ctx == NULL || rules == NULL)
151a9de470cSBruce Richardson 		return -EINVAL;
152a9de470cSBruce Richardson 
153a9de470cSBruce Richardson 	/* check input rules. */
154a9de470cSBruce Richardson 	for (i = 0; i != num; i++) {
155a9de470cSBruce Richardson 		rc = acl_ipv4vlan_check_rule(rules + i);
156a9de470cSBruce Richardson 		if (rc != 0) {
157*73d85848SStephen Hemminger 			fprintf(stderr,  "%s: rule #%u is invalid\n",
158a9de470cSBruce Richardson 				__func__, i + 1);
159a9de470cSBruce Richardson 			return rc;
160a9de470cSBruce Richardson 		}
161a9de470cSBruce Richardson 	}
162a9de470cSBruce Richardson 
163a9de470cSBruce Richardson 	/* perform conversion to the internal format and add to the context. */
164a9de470cSBruce Richardson 	for (i = 0, rc = 0; i != num && rc == 0; i++) {
165a9de470cSBruce Richardson 		acl_ipv4vlan_convert_rule(rules + i, &rv);
166a9de470cSBruce Richardson 		rc = rte_acl_add_rules(ctx, (struct rte_acl_rule *)&rv, 1);
167a9de470cSBruce Richardson 	}
168a9de470cSBruce Richardson 
169a9de470cSBruce Richardson 	return rc;
170a9de470cSBruce Richardson }
171a9de470cSBruce Richardson 
172a9de470cSBruce Richardson static void
acl_ipv4vlan_config(struct rte_acl_config * cfg,const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],uint32_t num_categories)173a9de470cSBruce Richardson acl_ipv4vlan_config(struct rte_acl_config *cfg,
174a9de470cSBruce Richardson 	const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],
175a9de470cSBruce Richardson 	uint32_t num_categories)
176a9de470cSBruce Richardson {
177a9de470cSBruce Richardson 	static const struct rte_acl_field_def
178a9de470cSBruce Richardson 		ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = {
179a9de470cSBruce Richardson 		{
180a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_BITMASK,
181a9de470cSBruce Richardson 			.size = sizeof(uint8_t),
182a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD,
183a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_PROTO,
184a9de470cSBruce Richardson 		},
185a9de470cSBruce Richardson 		{
186a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_BITMASK,
187a9de470cSBruce Richardson 			.size = sizeof(uint16_t),
188a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD,
189a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_VLAN,
190a9de470cSBruce Richardson 		},
191a9de470cSBruce Richardson 		{
192a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_BITMASK,
193a9de470cSBruce Richardson 			.size = sizeof(uint16_t),
194a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD,
195a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_VLAN,
196a9de470cSBruce Richardson 		},
197a9de470cSBruce Richardson 		{
198a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_MASK,
199a9de470cSBruce Richardson 			.size = sizeof(uint32_t),
200a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_SRC_FIELD,
201a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_SRC,
202a9de470cSBruce Richardson 		},
203a9de470cSBruce Richardson 		{
204a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_MASK,
205a9de470cSBruce Richardson 			.size = sizeof(uint32_t),
206a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_DST_FIELD,
207a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_DST,
208a9de470cSBruce Richardson 		},
209a9de470cSBruce Richardson 		{
210a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_RANGE,
211a9de470cSBruce Richardson 			.size = sizeof(uint16_t),
212a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD,
213a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_PORTS,
214a9de470cSBruce Richardson 		},
215a9de470cSBruce Richardson 		{
216a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_RANGE,
217a9de470cSBruce Richardson 			.size = sizeof(uint16_t),
218a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD,
219a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_PORTS,
220a9de470cSBruce Richardson 		},
221a9de470cSBruce Richardson 	};
222a9de470cSBruce Richardson 
223a9de470cSBruce Richardson 	memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs));
224a9de470cSBruce Richardson 	cfg->num_fields = RTE_DIM(ipv4_defs);
225a9de470cSBruce Richardson 
226a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset =
227a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_PROTO];
228a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset =
229a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_VLAN];
230a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset =
231a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_VLAN] +
232a9de470cSBruce Richardson 		cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size;
233a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset =
234a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_SRC];
235a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset =
236a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_DST];
237a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset =
238a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_PORTS];
239a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset =
240a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_PORTS] +
241a9de470cSBruce Richardson 		cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size;
242a9de470cSBruce Richardson 
243a9de470cSBruce Richardson 	cfg->num_categories = num_categories;
244a9de470cSBruce Richardson }
245a9de470cSBruce Richardson 
246a9de470cSBruce Richardson /*
247a9de470cSBruce Richardson  * Analyze set of ipv4vlan rules and build required internal
248a9de470cSBruce Richardson  * run-time structures.
249a9de470cSBruce Richardson  * This function is not multi-thread safe.
250a9de470cSBruce Richardson  *
251a9de470cSBruce Richardson  * @param ctx
252a9de470cSBruce Richardson  *   ACL context to build.
253a9de470cSBruce Richardson  * @param layout
254a9de470cSBruce Richardson  *   Layout of input data to search through.
255a9de470cSBruce Richardson  * @param num_categories
256a9de470cSBruce Richardson  *   Maximum number of categories to use in that build.
257a9de470cSBruce Richardson  * @return
258a9de470cSBruce Richardson  *   - -ENOMEM if couldn't allocate enough memory.
259a9de470cSBruce Richardson  *   - -EINVAL if the parameters are invalid.
260a9de470cSBruce Richardson  *   - Negative error code if operation failed.
261a9de470cSBruce Richardson  *   - Zero if operation completed successfully.
262a9de470cSBruce Richardson  */
263a9de470cSBruce Richardson static int
rte_acl_ipv4vlan_build(struct rte_acl_ctx * ctx,const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],uint32_t num_categories)264a9de470cSBruce Richardson rte_acl_ipv4vlan_build(struct rte_acl_ctx *ctx,
265a9de470cSBruce Richardson 	const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],
266a9de470cSBruce Richardson 	uint32_t num_categories)
267a9de470cSBruce Richardson {
268a9de470cSBruce Richardson 	struct rte_acl_config cfg;
269a9de470cSBruce Richardson 
270a9de470cSBruce Richardson 	if (ctx == NULL || layout == NULL)
271a9de470cSBruce Richardson 		return -EINVAL;
272a9de470cSBruce Richardson 
273a9de470cSBruce Richardson 	memset(&cfg, 0, sizeof(cfg));
274a9de470cSBruce Richardson 	acl_ipv4vlan_config(&cfg, layout, num_categories);
275a9de470cSBruce Richardson 	return rte_acl_build(ctx, &cfg);
276a9de470cSBruce Richardson }
277a9de470cSBruce Richardson 
278a9de470cSBruce Richardson /*
279fdec15b8SKonstantin Ananyev  * Test ACL lookup (selected alg).
280a9de470cSBruce Richardson  */
281a9de470cSBruce Richardson static int
test_classify_alg(struct rte_acl_ctx * acx,struct ipv4_7tuple test_data[],const uint8_t * data[],size_t dim,enum rte_acl_classify_alg alg)282fdec15b8SKonstantin Ananyev test_classify_alg(struct rte_acl_ctx *acx, struct ipv4_7tuple test_data[],
283fdec15b8SKonstantin Ananyev 	const uint8_t *data[], size_t dim, enum rte_acl_classify_alg alg)
284a9de470cSBruce Richardson {
285fdec15b8SKonstantin Ananyev 	int32_t ret;
286fdec15b8SKonstantin Ananyev 	uint32_t i, result, count;
287e33afed9SKonstantin Ananyev 	uint32_t results[dim * RTE_ACL_MAX_CATEGORIES];
288a9de470cSBruce Richardson 
289fdec15b8SKonstantin Ananyev 	/* set given classify alg, skip test if alg is not supported */
290fdec15b8SKonstantin Ananyev 	ret = rte_acl_set_ctx_classify(acx, alg);
291fdec15b8SKonstantin Ananyev 	if (ret != 0)
292fdec15b8SKonstantin Ananyev 		return (ret == -ENOTSUP) ? 0 : ret;
293a9de470cSBruce Richardson 
294a9de470cSBruce Richardson 	/**
295a9de470cSBruce Richardson 	 * these will run quite a few times, it's necessary to test code paths
296a9de470cSBruce Richardson 	 * from num=0 to num>8
297a9de470cSBruce Richardson 	 */
298e33afed9SKonstantin Ananyev 	for (count = 0; count <= dim; count++) {
299a9de470cSBruce Richardson 		ret = rte_acl_classify(acx, data, results,
300a9de470cSBruce Richardson 				count, RTE_ACL_MAX_CATEGORIES);
301a9de470cSBruce Richardson 		if (ret != 0) {
302fdec15b8SKonstantin Ananyev 			printf("Line %i: classify(alg=%d) failed!\n",
303fdec15b8SKonstantin Ananyev 				__LINE__, alg);
304fdec15b8SKonstantin Ananyev 			return ret;
305a9de470cSBruce Richardson 		}
306a9de470cSBruce Richardson 
307a9de470cSBruce Richardson 		/* check if we allow everything we should allow */
308fdec15b8SKonstantin Ananyev 		for (i = 0; i < count; i++) {
309a9de470cSBruce Richardson 			result =
310a9de470cSBruce Richardson 				results[i * RTE_ACL_MAX_CATEGORIES + ACL_ALLOW];
311e33afed9SKonstantin Ananyev 			if (result != test_data[i].allow) {
312a9de470cSBruce Richardson 				printf("Line %i: Error in allow results at %i "
313a9de470cSBruce Richardson 					"(expected %"PRIu32" got %"PRIu32")!\n",
314e33afed9SKonstantin Ananyev 					__LINE__, i, test_data[i].allow,
315a9de470cSBruce Richardson 					result);
316fdec15b8SKonstantin Ananyev 				return -EINVAL;
317a9de470cSBruce Richardson 			}
318a9de470cSBruce Richardson 		}
319a9de470cSBruce Richardson 
320a9de470cSBruce Richardson 		/* check if we deny everything we should deny */
321fdec15b8SKonstantin Ananyev 		for (i = 0; i < count; i++) {
322a9de470cSBruce Richardson 			result = results[i * RTE_ACL_MAX_CATEGORIES + ACL_DENY];
323e33afed9SKonstantin Ananyev 			if (result != test_data[i].deny) {
324a9de470cSBruce Richardson 				printf("Line %i: Error in deny results at %i "
325a9de470cSBruce Richardson 					"(expected %"PRIu32" got %"PRIu32")!\n",
326e33afed9SKonstantin Ananyev 					__LINE__, i, test_data[i].deny,
327a9de470cSBruce Richardson 					result);
328fdec15b8SKonstantin Ananyev 				return -EINVAL;
329a9de470cSBruce Richardson 			}
330a9de470cSBruce Richardson 		}
331a9de470cSBruce Richardson 	}
332a9de470cSBruce Richardson 
333fdec15b8SKonstantin Ananyev 	/* restore default classify alg */
334fdec15b8SKonstantin Ananyev 	return rte_acl_set_ctx_classify(acx, RTE_ACL_CLASSIFY_DEFAULT);
335a9de470cSBruce Richardson }
336a9de470cSBruce Richardson 
337fdec15b8SKonstantin Ananyev /*
338fdec15b8SKonstantin Ananyev  * Test ACL lookup (all possible methods).
339fdec15b8SKonstantin Ananyev  */
340fdec15b8SKonstantin Ananyev static int
test_classify_run(struct rte_acl_ctx * acx,struct ipv4_7tuple test_data[],size_t dim)341fdec15b8SKonstantin Ananyev test_classify_run(struct rte_acl_ctx *acx, struct ipv4_7tuple test_data[],
342fdec15b8SKonstantin Ananyev 	size_t dim)
343fdec15b8SKonstantin Ananyev {
344fdec15b8SKonstantin Ananyev 	int32_t ret;
345fdec15b8SKonstantin Ananyev 	uint32_t i;
346fdec15b8SKonstantin Ananyev 	const uint8_t *data[dim];
347a9de470cSBruce Richardson 
348fdec15b8SKonstantin Ananyev 	static const enum rte_acl_classify_alg alg[] = {
349fdec15b8SKonstantin Ananyev 		RTE_ACL_CLASSIFY_SCALAR,
350fdec15b8SKonstantin Ananyev 		RTE_ACL_CLASSIFY_SSE,
351fdec15b8SKonstantin Ananyev 		RTE_ACL_CLASSIFY_AVX2,
352fdec15b8SKonstantin Ananyev 		RTE_ACL_CLASSIFY_NEON,
353fdec15b8SKonstantin Ananyev 		RTE_ACL_CLASSIFY_ALTIVEC,
354b64c2295SKonstantin Ananyev 		RTE_ACL_CLASSIFY_AVX512X16,
35545da22e4SKonstantin Ananyev 		RTE_ACL_CLASSIFY_AVX512X32,
356fdec15b8SKonstantin Ananyev 	};
357fdec15b8SKonstantin Ananyev 
358fdec15b8SKonstantin Ananyev 	/* swap all bytes in the data to network order */
359fdec15b8SKonstantin Ananyev 	bswap_test_data(test_data, dim, 1);
360fdec15b8SKonstantin Ananyev 
361fdec15b8SKonstantin Ananyev 	/* store pointers to test data */
362fdec15b8SKonstantin Ananyev 	for (i = 0; i < dim; i++)
363fdec15b8SKonstantin Ananyev 		data[i] = (uint8_t *)&test_data[i];
364a9de470cSBruce Richardson 
365a9de470cSBruce Richardson 	ret = 0;
366fdec15b8SKonstantin Ananyev 	for (i = 0; i != RTE_DIM(alg); i++) {
367fdec15b8SKonstantin Ananyev 		ret = test_classify_alg(acx, test_data, data, dim, alg[i]);
368fdec15b8SKonstantin Ananyev 		if (ret < 0) {
369fdec15b8SKonstantin Ananyev 			printf("Line %i: %s() for alg=%d failed, errno=%d\n",
370fdec15b8SKonstantin Ananyev 				__LINE__, __func__, alg[i], -ret);
371fdec15b8SKonstantin Ananyev 			break;
372fdec15b8SKonstantin Ananyev 		}
373fdec15b8SKonstantin Ananyev 	}
374a9de470cSBruce Richardson 
375a9de470cSBruce Richardson 	/* swap data back to cpu order so that next time tests don't fail */
376e33afed9SKonstantin Ananyev 	bswap_test_data(test_data, dim, 0);
377a9de470cSBruce Richardson 	return ret;
378a9de470cSBruce Richardson }
379a9de470cSBruce Richardson 
380a9de470cSBruce Richardson static int
test_classify_buid(struct rte_acl_ctx * acx,const struct rte_acl_ipv4vlan_rule * rules,uint32_t num)381a9de470cSBruce Richardson test_classify_buid(struct rte_acl_ctx *acx,
382a9de470cSBruce Richardson 	const struct rte_acl_ipv4vlan_rule *rules, uint32_t num)
383a9de470cSBruce Richardson {
384a9de470cSBruce Richardson 	int ret;
385a9de470cSBruce Richardson 
386a9de470cSBruce Richardson 	/* add rules to the context */
387a9de470cSBruce Richardson 	ret = rte_acl_ipv4vlan_add_rules(acx, rules, num);
388a9de470cSBruce Richardson 	if (ret != 0) {
389a9de470cSBruce Richardson 		printf("Line %i: Adding rules to ACL context failed!\n",
390a9de470cSBruce Richardson 			__LINE__);
391a9de470cSBruce Richardson 		return ret;
392a9de470cSBruce Richardson 	}
393a9de470cSBruce Richardson 
394a9de470cSBruce Richardson 	/* try building the context */
395a9de470cSBruce Richardson 	ret = rte_acl_ipv4vlan_build(acx, ipv4_7tuple_layout,
396a9de470cSBruce Richardson 		RTE_ACL_MAX_CATEGORIES);
397a9de470cSBruce Richardson 	if (ret != 0) {
398a9de470cSBruce Richardson 		printf("Line %i: Building ACL context failed!\n", __LINE__);
399a9de470cSBruce Richardson 		return ret;
400a9de470cSBruce Richardson 	}
401a9de470cSBruce Richardson 
402a9de470cSBruce Richardson 	return 0;
403a9de470cSBruce Richardson }
404a9de470cSBruce Richardson 
405a9de470cSBruce Richardson #define	TEST_CLASSIFY_ITER	4
406a9de470cSBruce Richardson 
407a9de470cSBruce Richardson /*
408a9de470cSBruce Richardson  * Test scalar and SSE ACL lookup.
409a9de470cSBruce Richardson  */
410a9de470cSBruce Richardson static int
test_classify(void)411a9de470cSBruce Richardson test_classify(void)
412a9de470cSBruce Richardson {
413a9de470cSBruce Richardson 	struct rte_acl_ctx *acx;
414a9de470cSBruce Richardson 	int i, ret;
415a9de470cSBruce Richardson 
416a9de470cSBruce Richardson 	acx = rte_acl_create(&acl_param);
417a9de470cSBruce Richardson 	if (acx == NULL) {
418a9de470cSBruce Richardson 		printf("Line %i: Error creating ACL context!\n", __LINE__);
419a9de470cSBruce Richardson 		return -1;
420a9de470cSBruce Richardson 	}
421a9de470cSBruce Richardson 
422a9de470cSBruce Richardson 	ret = 0;
423a9de470cSBruce Richardson 	for (i = 0; i != TEST_CLASSIFY_ITER; i++) {
424a9de470cSBruce Richardson 
425a9de470cSBruce Richardson 		if ((i & 1) == 0)
426a9de470cSBruce Richardson 			rte_acl_reset(acx);
427a9de470cSBruce Richardson 		else
428a9de470cSBruce Richardson 			rte_acl_reset_rules(acx);
429a9de470cSBruce Richardson 
430a9de470cSBruce Richardson 		ret = test_classify_buid(acx, acl_test_rules,
431a9de470cSBruce Richardson 			RTE_DIM(acl_test_rules));
432a9de470cSBruce Richardson 		if (ret != 0) {
433a9de470cSBruce Richardson 			printf("Line %i, iter: %d: "
434a9de470cSBruce Richardson 				"Adding rules to ACL context failed!\n",
435a9de470cSBruce Richardson 				__LINE__, i);
436a9de470cSBruce Richardson 			break;
437a9de470cSBruce Richardson 		}
438a9de470cSBruce Richardson 
439e33afed9SKonstantin Ananyev 		ret = test_classify_run(acx, acl_test_data,
440e33afed9SKonstantin Ananyev 			RTE_DIM(acl_test_data));
441a9de470cSBruce Richardson 		if (ret != 0) {
442a9de470cSBruce Richardson 			printf("Line %i, iter: %d: %s failed!\n",
443a9de470cSBruce Richardson 				__LINE__, i, __func__);
444a9de470cSBruce Richardson 			break;
445a9de470cSBruce Richardson 		}
446a9de470cSBruce Richardson 
447a9de470cSBruce Richardson 		/* reset rules and make sure that classify still works ok. */
448a9de470cSBruce Richardson 		rte_acl_reset_rules(acx);
449e33afed9SKonstantin Ananyev 		ret = test_classify_run(acx, acl_test_data,
450e33afed9SKonstantin Ananyev 			RTE_DIM(acl_test_data));
451a9de470cSBruce Richardson 		if (ret != 0) {
452a9de470cSBruce Richardson 			printf("Line %i, iter: %d: %s failed!\n",
453a9de470cSBruce Richardson 				__LINE__, i, __func__);
454a9de470cSBruce Richardson 			break;
455a9de470cSBruce Richardson 		}
456a9de470cSBruce Richardson 	}
457a9de470cSBruce Richardson 
458a9de470cSBruce Richardson 	rte_acl_free(acx);
459a9de470cSBruce Richardson 	return ret;
460a9de470cSBruce Richardson }
461a9de470cSBruce Richardson 
462a9de470cSBruce Richardson static int
test_build_ports_range(void)463a9de470cSBruce Richardson test_build_ports_range(void)
464a9de470cSBruce Richardson {
465a9de470cSBruce Richardson 	static const struct rte_acl_ipv4vlan_rule test_rules[] = {
466a9de470cSBruce Richardson 		{
467a9de470cSBruce Richardson 			/* match all packets. */
468a9de470cSBruce Richardson 			.data = {
469a9de470cSBruce Richardson 				.userdata = 1,
470a9de470cSBruce Richardson 				.category_mask = ACL_ALLOW_MASK,
471a9de470cSBruce Richardson 				.priority = 101,
472a9de470cSBruce Richardson 			},
473a9de470cSBruce Richardson 			.src_port_low = 0,
474a9de470cSBruce Richardson 			.src_port_high = UINT16_MAX,
475a9de470cSBruce Richardson 			.dst_port_low = 0,
476a9de470cSBruce Richardson 			.dst_port_high = UINT16_MAX,
477a9de470cSBruce Richardson 		},
478a9de470cSBruce Richardson 		{
479a9de470cSBruce Richardson 			/* match all packets with dst ports [54-65280]. */
480a9de470cSBruce Richardson 			.data = {
481a9de470cSBruce Richardson 				.userdata = 2,
482a9de470cSBruce Richardson 				.category_mask = ACL_ALLOW_MASK,
483a9de470cSBruce Richardson 				.priority = 102,
484a9de470cSBruce Richardson 			},
485a9de470cSBruce Richardson 			.src_port_low = 0,
486a9de470cSBruce Richardson 			.src_port_high = UINT16_MAX,
487a9de470cSBruce Richardson 			.dst_port_low = 54,
488a9de470cSBruce Richardson 			.dst_port_high = 65280,
489a9de470cSBruce Richardson 		},
490a9de470cSBruce Richardson 		{
491a9de470cSBruce Richardson 			/* match all packets with dst ports [0-52]. */
492a9de470cSBruce Richardson 			.data = {
493a9de470cSBruce Richardson 				.userdata = 3,
494a9de470cSBruce Richardson 				.category_mask = ACL_ALLOW_MASK,
495a9de470cSBruce Richardson 				.priority = 103,
496a9de470cSBruce Richardson 			},
497a9de470cSBruce Richardson 			.src_port_low = 0,
498a9de470cSBruce Richardson 			.src_port_high = UINT16_MAX,
499a9de470cSBruce Richardson 			.dst_port_low = 0,
500a9de470cSBruce Richardson 			.dst_port_high = 52,
501a9de470cSBruce Richardson 		},
502a9de470cSBruce Richardson 		{
503a9de470cSBruce Richardson 			/* match all packets with dst ports [53]. */
504a9de470cSBruce Richardson 			.data = {
505a9de470cSBruce Richardson 				.userdata = 4,
506a9de470cSBruce Richardson 				.category_mask = ACL_ALLOW_MASK,
507a9de470cSBruce Richardson 				.priority = 99,
508a9de470cSBruce Richardson 			},
509a9de470cSBruce Richardson 			.src_port_low = 0,
510a9de470cSBruce Richardson 			.src_port_high = UINT16_MAX,
511a9de470cSBruce Richardson 			.dst_port_low = 53,
512a9de470cSBruce Richardson 			.dst_port_high = 53,
513a9de470cSBruce Richardson 		},
514a9de470cSBruce Richardson 		{
515a9de470cSBruce Richardson 			/* match all packets with dst ports [65279-65535]. */
516a9de470cSBruce Richardson 			.data = {
517a9de470cSBruce Richardson 				.userdata = 5,
518a9de470cSBruce Richardson 				.category_mask = ACL_ALLOW_MASK,
519a9de470cSBruce Richardson 				.priority = 98,
520a9de470cSBruce Richardson 			},
521a9de470cSBruce Richardson 			.src_port_low = 0,
522a9de470cSBruce Richardson 			.src_port_high = UINT16_MAX,
523a9de470cSBruce Richardson 			.dst_port_low = 65279,
524a9de470cSBruce Richardson 			.dst_port_high = UINT16_MAX,
525a9de470cSBruce Richardson 		},
526a9de470cSBruce Richardson 	};
527a9de470cSBruce Richardson 
528a9de470cSBruce Richardson 	static struct ipv4_7tuple test_data[] = {
529a9de470cSBruce Richardson 		{
530a9de470cSBruce Richardson 			.proto = 6,
5310c9da755SDavid Marchand 			.ip_src = RTE_IPV4(10, 1, 1, 1),
5320c9da755SDavid Marchand 			.ip_dst = RTE_IPV4(192, 168, 0, 33),
533a9de470cSBruce Richardson 			.port_dst = 53,
534a9de470cSBruce Richardson 			.allow = 1,
535a9de470cSBruce Richardson 		},
536a9de470cSBruce Richardson 		{
537a9de470cSBruce Richardson 			.proto = 6,
5380c9da755SDavid Marchand 			.ip_src = RTE_IPV4(127, 84, 33, 1),
5390c9da755SDavid Marchand 			.ip_dst = RTE_IPV4(1, 2, 3, 4),
540a9de470cSBruce Richardson 			.port_dst = 65281,
541a9de470cSBruce Richardson 			.allow = 1,
542a9de470cSBruce Richardson 		},
543a9de470cSBruce Richardson 	};
544a9de470cSBruce Richardson 
545a9de470cSBruce Richardson 	struct rte_acl_ctx *acx;
546a9de470cSBruce Richardson 	int32_t ret, i, j;
547a9de470cSBruce Richardson 	uint32_t results[RTE_DIM(test_data)];
548a9de470cSBruce Richardson 	const uint8_t *data[RTE_DIM(test_data)];
549a9de470cSBruce Richardson 
550a9de470cSBruce Richardson 	acx = rte_acl_create(&acl_param);
551a9de470cSBruce Richardson 	if (acx == NULL) {
552a9de470cSBruce Richardson 		printf("Line %i: Error creating ACL context!\n", __LINE__);
553a9de470cSBruce Richardson 		return -1;
554a9de470cSBruce Richardson 	}
555a9de470cSBruce Richardson 
556a9de470cSBruce Richardson 	/* swap all bytes in the data to network order */
557a9de470cSBruce Richardson 	bswap_test_data(test_data, RTE_DIM(test_data), 1);
558a9de470cSBruce Richardson 
559a9de470cSBruce Richardson 	/* store pointers to test data */
560a9de470cSBruce Richardson 	for (i = 0; i != RTE_DIM(test_data); i++)
561a9de470cSBruce Richardson 		data[i] = (uint8_t *)&test_data[i];
562a9de470cSBruce Richardson 
563a9de470cSBruce Richardson 	for (i = 0; i != RTE_DIM(test_rules); i++) {
564a9de470cSBruce Richardson 		rte_acl_reset(acx);
565a9de470cSBruce Richardson 		ret = test_classify_buid(acx, test_rules, i + 1);
566a9de470cSBruce Richardson 		if (ret != 0) {
567a9de470cSBruce Richardson 			printf("Line %i, iter: %d: "
568a9de470cSBruce Richardson 				"Adding rules to ACL context failed!\n",
569a9de470cSBruce Richardson 				__LINE__, i);
570a9de470cSBruce Richardson 			break;
571a9de470cSBruce Richardson 		}
572a9de470cSBruce Richardson 		ret = rte_acl_classify(acx, data, results,
573a9de470cSBruce Richardson 			RTE_DIM(data), 1);
574a9de470cSBruce Richardson 		if (ret != 0) {
575a9de470cSBruce Richardson 			printf("Line %i, iter: %d: classify failed!\n",
576a9de470cSBruce Richardson 				__LINE__, i);
577a9de470cSBruce Richardson 			break;
578a9de470cSBruce Richardson 		}
579a9de470cSBruce Richardson 
580a9de470cSBruce Richardson 		/* check results */
581a9de470cSBruce Richardson 		for (j = 0; j != RTE_DIM(results); j++) {
582a9de470cSBruce Richardson 			if (results[j] != test_data[j].allow) {
583a9de470cSBruce Richardson 				printf("Line %i: Error in allow results at %i "
584a9de470cSBruce Richardson 					"(expected %"PRIu32" got %"PRIu32")!\n",
585a9de470cSBruce Richardson 					__LINE__, j, test_data[j].allow,
586a9de470cSBruce Richardson 					results[j]);
587a9de470cSBruce Richardson 				ret = -EINVAL;
588a9de470cSBruce Richardson 			}
589a9de470cSBruce Richardson 		}
590a9de470cSBruce Richardson 	}
591a9de470cSBruce Richardson 
592a9de470cSBruce Richardson 	bswap_test_data(test_data, RTE_DIM(test_data), 0);
593a9de470cSBruce Richardson 
594a9de470cSBruce Richardson 	rte_acl_free(acx);
595a9de470cSBruce Richardson 	return ret;
596a9de470cSBruce Richardson }
597a9de470cSBruce Richardson 
598a9de470cSBruce Richardson static void
convert_rule(const struct rte_acl_ipv4vlan_rule * ri,struct acl_ipv4vlan_rule * ro)599a9de470cSBruce Richardson convert_rule(const struct rte_acl_ipv4vlan_rule *ri,
600a9de470cSBruce Richardson 	struct acl_ipv4vlan_rule *ro)
601a9de470cSBruce Richardson {
602a9de470cSBruce Richardson 	ro->data = ri->data;
603a9de470cSBruce Richardson 
604a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].value.u8 = ri->proto;
605a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].value.u16 = ri->vlan;
606a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].value.u16 = ri->domain;
607a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = ri->src_addr;
608a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = ri->dst_addr;
609a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].value.u16 = ri->src_port_low;
610a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].value.u16 = ri->dst_port_low;
611a9de470cSBruce Richardson 
612a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_PROTO_FIELD].mask_range.u8 = ri->proto_mask;
613a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD].mask_range.u16 = ri->vlan_mask;
614a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD].mask_range.u16 =
615a9de470cSBruce Richardson 		ri->domain_mask;
616a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
617a9de470cSBruce Richardson 		ri->src_mask_len;
618a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = ri->dst_mask_len;
619a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD].mask_range.u16 =
620a9de470cSBruce Richardson 		ri->src_port_high;
621a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD].mask_range.u16 =
622a9de470cSBruce Richardson 		ri->dst_port_high;
623a9de470cSBruce Richardson }
624a9de470cSBruce Richardson 
625a9de470cSBruce Richardson /*
626a9de470cSBruce Richardson  * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
627a9de470cSBruce Richardson  * RTE_ACL_FIELD_TYPE_BITMASK.
628a9de470cSBruce Richardson  */
629a9de470cSBruce Richardson static void
convert_rule_1(const struct rte_acl_ipv4vlan_rule * ri,struct acl_ipv4vlan_rule * ro)630a9de470cSBruce Richardson convert_rule_1(const struct rte_acl_ipv4vlan_rule *ri,
631a9de470cSBruce Richardson 	struct acl_ipv4vlan_rule *ro)
632a9de470cSBruce Richardson {
633a9de470cSBruce Richardson 	uint32_t v;
634a9de470cSBruce Richardson 
635a9de470cSBruce Richardson 	convert_rule(ri, ro);
636a9de470cSBruce Richardson 	v = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32;
637a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 =
638a9de470cSBruce Richardson 		RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v));
639a9de470cSBruce Richardson 	v = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32;
640a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 =
641a9de470cSBruce Richardson 		RTE_ACL_MASKLEN_TO_BITMASK(v, sizeof(v));
642a9de470cSBruce Richardson }
643a9de470cSBruce Richardson 
644a9de470cSBruce Richardson /*
645a9de470cSBruce Richardson  * Convert IPV4 source and destination from RTE_ACL_FIELD_TYPE_MASK to
646a9de470cSBruce Richardson  * RTE_ACL_FIELD_TYPE_RANGE.
647a9de470cSBruce Richardson  */
648a9de470cSBruce Richardson static void
convert_rule_2(const struct rte_acl_ipv4vlan_rule * ri,struct acl_ipv4vlan_rule * ro)649a9de470cSBruce Richardson convert_rule_2(const struct rte_acl_ipv4vlan_rule *ri,
650a9de470cSBruce Richardson 	struct acl_ipv4vlan_rule *ro)
651a9de470cSBruce Richardson {
652a9de470cSBruce Richardson 	uint32_t hi, lo, mask;
653a9de470cSBruce Richardson 
654a9de470cSBruce Richardson 	convert_rule(ri, ro);
655a9de470cSBruce Richardson 
656a9de470cSBruce Richardson 	mask = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32;
657a9de470cSBruce Richardson 	mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask));
658a9de470cSBruce Richardson 	lo = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 & mask;
659a9de470cSBruce Richardson 	hi = lo + ~mask;
660a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].value.u32 = lo;
661a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD].mask_range.u32 = hi;
662a9de470cSBruce Richardson 
663a9de470cSBruce Richardson 	mask = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32;
664a9de470cSBruce Richardson 	mask = RTE_ACL_MASKLEN_TO_BITMASK(mask, sizeof(mask));
665a9de470cSBruce Richardson 	lo = ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 & mask;
666a9de470cSBruce Richardson 	hi = lo + ~mask;
667a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].value.u32 = lo;
668a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DST_FIELD].mask_range.u32 = hi;
669a9de470cSBruce Richardson }
670a9de470cSBruce Richardson 
671a9de470cSBruce Richardson /*
672a9de470cSBruce Richardson  * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule fields.
673a9de470cSBruce Richardson  */
674a9de470cSBruce Richardson static void
convert_rule_3(const struct rte_acl_ipv4vlan_rule * ri,struct acl_ipv4vlan_rule * ro)675a9de470cSBruce Richardson convert_rule_3(const struct rte_acl_ipv4vlan_rule *ri,
676a9de470cSBruce Richardson 	struct acl_ipv4vlan_rule *ro)
677a9de470cSBruce Richardson {
678a9de470cSBruce Richardson 	struct rte_acl_field t1, t2;
679a9de470cSBruce Richardson 
680a9de470cSBruce Richardson 	convert_rule(ri, ro);
681a9de470cSBruce Richardson 
682a9de470cSBruce Richardson 	t1 = ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD];
683a9de470cSBruce Richardson 	t2 = ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD];
684a9de470cSBruce Richardson 
685a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_VLAN1_FIELD] =
686a9de470cSBruce Richardson 		ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD];
687a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_VLAN2_FIELD] =
688a9de470cSBruce Richardson 		ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD];
689a9de470cSBruce Richardson 
690a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRCP_FIELD] = t1;
691a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DSTP_FIELD] = t2;
692a9de470cSBruce Richardson }
693a9de470cSBruce Richardson 
694a9de470cSBruce Richardson /*
695a9de470cSBruce Richardson  * Convert rte_acl_ipv4vlan_rule: swap SRC and DST IPv4 address rules.
696a9de470cSBruce Richardson  */
697a9de470cSBruce Richardson static void
convert_rule_4(const struct rte_acl_ipv4vlan_rule * ri,struct acl_ipv4vlan_rule * ro)698a9de470cSBruce Richardson convert_rule_4(const struct rte_acl_ipv4vlan_rule *ri,
699a9de470cSBruce Richardson 	struct acl_ipv4vlan_rule *ro)
700a9de470cSBruce Richardson {
701a9de470cSBruce Richardson 	struct rte_acl_field t;
702a9de470cSBruce Richardson 
703a9de470cSBruce Richardson 	convert_rule(ri, ro);
704a9de470cSBruce Richardson 
705a9de470cSBruce Richardson 	t = ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD];
706a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_SRC_FIELD] =
707a9de470cSBruce Richardson 		ro->field[RTE_ACL_IPV4VLAN_DST_FIELD];
708a9de470cSBruce Richardson 
709a9de470cSBruce Richardson 	ro->field[RTE_ACL_IPV4VLAN_DST_FIELD] = t;
710a9de470cSBruce Richardson }
711a9de470cSBruce Richardson 
712a9de470cSBruce Richardson static void
ipv4vlan_config(struct rte_acl_config * cfg,const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],uint32_t num_categories)713a9de470cSBruce Richardson ipv4vlan_config(struct rte_acl_config *cfg,
714a9de470cSBruce Richardson 	const uint32_t layout[RTE_ACL_IPV4VLAN_NUM],
715a9de470cSBruce Richardson 	uint32_t num_categories)
716a9de470cSBruce Richardson {
717a9de470cSBruce Richardson 	static const struct rte_acl_field_def
718a9de470cSBruce Richardson 		ipv4_defs[RTE_ACL_IPV4VLAN_NUM_FIELDS] = {
719a9de470cSBruce Richardson 		{
720a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_BITMASK,
721a9de470cSBruce Richardson 			.size = sizeof(uint8_t),
722a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_PROTO_FIELD,
723a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_PROTO,
724a9de470cSBruce Richardson 		},
725a9de470cSBruce Richardson 		{
726a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_BITMASK,
727a9de470cSBruce Richardson 			.size = sizeof(uint16_t),
728a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_VLAN1_FIELD,
729a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_VLAN,
730a9de470cSBruce Richardson 		},
731a9de470cSBruce Richardson 		{
732a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_BITMASK,
733a9de470cSBruce Richardson 			.size = sizeof(uint16_t),
734a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_VLAN2_FIELD,
735a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_VLAN,
736a9de470cSBruce Richardson 		},
737a9de470cSBruce Richardson 		{
738a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_MASK,
739a9de470cSBruce Richardson 			.size = sizeof(uint32_t),
740a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_SRC_FIELD,
741a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_SRC,
742a9de470cSBruce Richardson 		},
743a9de470cSBruce Richardson 		{
744a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_MASK,
745a9de470cSBruce Richardson 			.size = sizeof(uint32_t),
746a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_DST_FIELD,
747a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_DST,
748a9de470cSBruce Richardson 		},
749a9de470cSBruce Richardson 		{
750a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_RANGE,
751a9de470cSBruce Richardson 			.size = sizeof(uint16_t),
752a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_SRCP_FIELD,
753a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_PORTS,
754a9de470cSBruce Richardson 		},
755a9de470cSBruce Richardson 		{
756a9de470cSBruce Richardson 			.type = RTE_ACL_FIELD_TYPE_RANGE,
757a9de470cSBruce Richardson 			.size = sizeof(uint16_t),
758a9de470cSBruce Richardson 			.field_index = RTE_ACL_IPV4VLAN_DSTP_FIELD,
759a9de470cSBruce Richardson 			.input_index = RTE_ACL_IPV4VLAN_PORTS,
760a9de470cSBruce Richardson 		},
761a9de470cSBruce Richardson 	};
762a9de470cSBruce Richardson 
763a9de470cSBruce Richardson 	memcpy(&cfg->defs, ipv4_defs, sizeof(ipv4_defs));
764a9de470cSBruce Richardson 	cfg->num_fields = RTE_DIM(ipv4_defs);
765a9de470cSBruce Richardson 
766a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_PROTO_FIELD].offset =
767a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_PROTO];
768a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].offset =
769a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_VLAN];
770a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].offset =
771a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_VLAN] +
772a9de470cSBruce Richardson 		cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].size;
773a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].offset =
774a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_SRC];
775a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset =
776a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_DST];
777a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset =
778a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_PORTS];
779a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset =
780a9de470cSBruce Richardson 		layout[RTE_ACL_IPV4VLAN_PORTS] +
781a9de470cSBruce Richardson 		cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size;
782a9de470cSBruce Richardson 
783a9de470cSBruce Richardson 	cfg->num_categories = num_categories;
784a9de470cSBruce Richardson }
785a9de470cSBruce Richardson 
786a9de470cSBruce Richardson static int
convert_rules(struct rte_acl_ctx * acx,void (* convert)(const struct rte_acl_ipv4vlan_rule *,struct acl_ipv4vlan_rule *),const struct rte_acl_ipv4vlan_rule * rules,uint32_t num)787a9de470cSBruce Richardson convert_rules(struct rte_acl_ctx *acx,
788a9de470cSBruce Richardson 	void (*convert)(const struct rte_acl_ipv4vlan_rule *,
789a9de470cSBruce Richardson 	struct acl_ipv4vlan_rule *),
790a9de470cSBruce Richardson 	const struct rte_acl_ipv4vlan_rule *rules, uint32_t num)
791a9de470cSBruce Richardson {
792a9de470cSBruce Richardson 	int32_t rc;
793a9de470cSBruce Richardson 	uint32_t i;
794a9de470cSBruce Richardson 	struct acl_ipv4vlan_rule r;
795a9de470cSBruce Richardson 
796a9de470cSBruce Richardson 	for (i = 0; i != num; i++) {
797a9de470cSBruce Richardson 		convert(rules + i, &r);
798a9de470cSBruce Richardson 		rc = rte_acl_add_rules(acx, (struct rte_acl_rule *)&r, 1);
799a9de470cSBruce Richardson 		if (rc != 0) {
800a9de470cSBruce Richardson 			printf("Line %i: Adding rule %u to ACL context "
801a9de470cSBruce Richardson 				"failed with error code: %d\n",
802a9de470cSBruce Richardson 			__LINE__, i, rc);
803a9de470cSBruce Richardson 			return rc;
804a9de470cSBruce Richardson 		}
805a9de470cSBruce Richardson 	}
806a9de470cSBruce Richardson 
807a9de470cSBruce Richardson 	return 0;
808a9de470cSBruce Richardson }
809a9de470cSBruce Richardson 
810a9de470cSBruce Richardson static void
convert_config(struct rte_acl_config * cfg)811a9de470cSBruce Richardson convert_config(struct rte_acl_config *cfg)
812a9de470cSBruce Richardson {
813a9de470cSBruce Richardson 	ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
814a9de470cSBruce Richardson }
815a9de470cSBruce Richardson 
816a9de470cSBruce Richardson /*
817a9de470cSBruce Richardson  * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_BITMASK.
818a9de470cSBruce Richardson  */
819a9de470cSBruce Richardson static void
convert_config_1(struct rte_acl_config * cfg)820a9de470cSBruce Richardson convert_config_1(struct rte_acl_config *cfg)
821a9de470cSBruce Richardson {
822a9de470cSBruce Richardson 	ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
823a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK;
824a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_BITMASK;
825a9de470cSBruce Richardson }
826a9de470cSBruce Richardson 
827a9de470cSBruce Richardson /*
828a9de470cSBruce Richardson  * Convert rte_acl_ipv4vlan_rule to use RTE_ACL_FIELD_TYPE_RANGE.
829a9de470cSBruce Richardson  */
830a9de470cSBruce Richardson static void
convert_config_2(struct rte_acl_config * cfg)831a9de470cSBruce Richardson convert_config_2(struct rte_acl_config *cfg)
832a9de470cSBruce Richardson {
833a9de470cSBruce Richardson 	ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
834a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE;
835a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = RTE_ACL_FIELD_TYPE_RANGE;
836a9de470cSBruce Richardson }
837a9de470cSBruce Richardson 
838a9de470cSBruce Richardson /*
839a9de470cSBruce Richardson  * Convert rte_acl_ipv4vlan_rule: swap VLAN and PORTS rule definitions.
840a9de470cSBruce Richardson  */
841a9de470cSBruce Richardson static void
convert_config_3(struct rte_acl_config * cfg)842a9de470cSBruce Richardson convert_config_3(struct rte_acl_config *cfg)
843a9de470cSBruce Richardson {
844a9de470cSBruce Richardson 	struct rte_acl_field_def t1, t2;
845a9de470cSBruce Richardson 
846a9de470cSBruce Richardson 	ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
847a9de470cSBruce Richardson 
848a9de470cSBruce Richardson 	t1 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD];
849a9de470cSBruce Richardson 	t2 = cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD];
850a9de470cSBruce Richardson 
851a9de470cSBruce Richardson 	/* swap VLAN1 and SRCP rule definition. */
852a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD] =
853a9de470cSBruce Richardson 		cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD];
854a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].field_index = t1.field_index;
855a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_VLAN1_FIELD].input_index = t1.input_index;
856a9de470cSBruce Richardson 
857a9de470cSBruce Richardson 	/* swap VLAN2 and DSTP rule definition. */
858a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD] =
859a9de470cSBruce Richardson 		cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD];
860a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].field_index = t2.field_index;
861a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_VLAN2_FIELD].input_index = t2.input_index;
862a9de470cSBruce Richardson 
863a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].type = t1.type;
864a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].size = t1.size;
865a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRCP_FIELD].offset = t1.offset;
866a9de470cSBruce Richardson 
867a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].type = t2.type;
868a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].size = t2.size;
869a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DSTP_FIELD].offset = t2.offset;
870a9de470cSBruce Richardson }
871a9de470cSBruce Richardson 
872a9de470cSBruce Richardson /*
873a9de470cSBruce Richardson  * Convert rte_acl_ipv4vlan_rule: swap SRC and DST ip address rule definitions.
874a9de470cSBruce Richardson  */
875a9de470cSBruce Richardson static void
convert_config_4(struct rte_acl_config * cfg)876a9de470cSBruce Richardson convert_config_4(struct rte_acl_config *cfg)
877a9de470cSBruce Richardson {
878a9de470cSBruce Richardson 	struct rte_acl_field_def t;
879a9de470cSBruce Richardson 
880a9de470cSBruce Richardson 	ipv4vlan_config(cfg, ipv4_7tuple_layout, RTE_ACL_MAX_CATEGORIES);
881a9de470cSBruce Richardson 
882a9de470cSBruce Richardson 	t = cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD];
883a9de470cSBruce Richardson 
884a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD] =
885a9de470cSBruce Richardson 		cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD];
886a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].field_index = t.field_index;
887a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_SRC_FIELD].input_index = t.input_index;
888a9de470cSBruce Richardson 
889a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].type = t.type;
890a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].size = t.size;
891a9de470cSBruce Richardson 	cfg->defs[RTE_ACL_IPV4VLAN_DST_FIELD].offset = t.offset;
892a9de470cSBruce Richardson }
893a9de470cSBruce Richardson 
894a9de470cSBruce Richardson 
895a9de470cSBruce Richardson static int
build_convert_rules(struct rte_acl_ctx * acx,void (* config)(struct rte_acl_config *),size_t max_size)896a9de470cSBruce Richardson build_convert_rules(struct rte_acl_ctx *acx,
897a9de470cSBruce Richardson 	void (*config)(struct rte_acl_config *),
898a9de470cSBruce Richardson 	size_t max_size)
899a9de470cSBruce Richardson {
900a9de470cSBruce Richardson 	struct rte_acl_config cfg;
901a9de470cSBruce Richardson 
902a9de470cSBruce Richardson 	memset(&cfg, 0, sizeof(cfg));
903a9de470cSBruce Richardson 	config(&cfg);
904a9de470cSBruce Richardson 	cfg.max_size = max_size;
905a9de470cSBruce Richardson 	return rte_acl_build(acx, &cfg);
906a9de470cSBruce Richardson }
907a9de470cSBruce Richardson 
908a9de470cSBruce Richardson static int
test_convert_rules(const char * desc,void (* config)(struct rte_acl_config *),void (* convert)(const struct rte_acl_ipv4vlan_rule *,struct acl_ipv4vlan_rule *))909a9de470cSBruce Richardson test_convert_rules(const char *desc,
910a9de470cSBruce Richardson 	void (*config)(struct rte_acl_config *),
911a9de470cSBruce Richardson 	void (*convert)(const struct rte_acl_ipv4vlan_rule *,
912a9de470cSBruce Richardson 	struct acl_ipv4vlan_rule *))
913a9de470cSBruce Richardson {
914a9de470cSBruce Richardson 	struct rte_acl_ctx *acx;
915a9de470cSBruce Richardson 	int32_t rc;
916a9de470cSBruce Richardson 	uint32_t i;
917a9de470cSBruce Richardson 	static const size_t mem_sizes[] = {0, -1};
918a9de470cSBruce Richardson 
919a9de470cSBruce Richardson 	printf("running %s(%s)\n", __func__, desc);
920a9de470cSBruce Richardson 
921a9de470cSBruce Richardson 	acx = rte_acl_create(&acl_param);
922a9de470cSBruce Richardson 	if (acx == NULL) {
923a9de470cSBruce Richardson 		printf("Line %i: Error creating ACL context!\n", __LINE__);
924a9de470cSBruce Richardson 		return -1;
925a9de470cSBruce Richardson 	}
926a9de470cSBruce Richardson 
927a9de470cSBruce Richardson 	rc = convert_rules(acx, convert, acl_test_rules,
928a9de470cSBruce Richardson 		RTE_DIM(acl_test_rules));
929a9de470cSBruce Richardson 	if (rc != 0)
930a9de470cSBruce Richardson 		printf("Line %i: Error converting ACL rules!\n", __LINE__);
931a9de470cSBruce Richardson 
932a9de470cSBruce Richardson 	for (i = 0; rc == 0 && i != RTE_DIM(mem_sizes); i++) {
933a9de470cSBruce Richardson 
934a9de470cSBruce Richardson 		rc = build_convert_rules(acx, config, mem_sizes[i]);
935a9de470cSBruce Richardson 		if (rc != 0) {
936a9de470cSBruce Richardson 			printf("Line %i: Error @ build_convert_rules(%zu)!\n",
937a9de470cSBruce Richardson 				__LINE__, mem_sizes[i]);
938a9de470cSBruce Richardson 			break;
939a9de470cSBruce Richardson 		}
940a9de470cSBruce Richardson 
941e33afed9SKonstantin Ananyev 		rc = test_classify_run(acx, acl_test_data,
942e33afed9SKonstantin Ananyev 			RTE_DIM(acl_test_data));
943a9de470cSBruce Richardson 		if (rc != 0)
944a9de470cSBruce Richardson 			printf("%s failed at line %i, max_size=%zu\n",
945a9de470cSBruce Richardson 				__func__, __LINE__, mem_sizes[i]);
946a9de470cSBruce Richardson 	}
947a9de470cSBruce Richardson 
948a9de470cSBruce Richardson 	rte_acl_free(acx);
949a9de470cSBruce Richardson 	return rc;
950a9de470cSBruce Richardson }
951a9de470cSBruce Richardson 
952a9de470cSBruce Richardson static int
test_convert(void)953a9de470cSBruce Richardson test_convert(void)
954a9de470cSBruce Richardson {
955a9de470cSBruce Richardson 	static const struct {
956a9de470cSBruce Richardson 		const char *desc;
957a9de470cSBruce Richardson 		void (*config)(struct rte_acl_config *);
958a9de470cSBruce Richardson 		void (*convert)(const struct rte_acl_ipv4vlan_rule *,
959a9de470cSBruce Richardson 			struct acl_ipv4vlan_rule *);
960a9de470cSBruce Richardson 	} convert_param[] = {
961a9de470cSBruce Richardson 		{
962a9de470cSBruce Richardson 			"acl_ipv4vlan_tuple",
963a9de470cSBruce Richardson 			convert_config,
964a9de470cSBruce Richardson 			convert_rule,
965a9de470cSBruce Richardson 		},
966a9de470cSBruce Richardson 		{
967a9de470cSBruce Richardson 			"acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_BITMASK type "
968a9de470cSBruce Richardson 			"for IPv4",
969a9de470cSBruce Richardson 			convert_config_1,
970a9de470cSBruce Richardson 			convert_rule_1,
971a9de470cSBruce Richardson 		},
972a9de470cSBruce Richardson 		{
973a9de470cSBruce Richardson 			"acl_ipv4vlan_tuple, RTE_ACL_FIELD_TYPE_RANGE type "
974a9de470cSBruce Richardson 			"for IPv4",
975a9de470cSBruce Richardson 			convert_config_2,
976a9de470cSBruce Richardson 			convert_rule_2,
977a9de470cSBruce Richardson 		},
978a9de470cSBruce Richardson 		{
979a9de470cSBruce Richardson 			"acl_ipv4vlan_tuple: swap VLAN and PORTs order",
980a9de470cSBruce Richardson 			convert_config_3,
981a9de470cSBruce Richardson 			convert_rule_3,
982a9de470cSBruce Richardson 		},
983a9de470cSBruce Richardson 		{
984a9de470cSBruce Richardson 			"acl_ipv4vlan_tuple: swap SRC and DST IPv4 order",
985a9de470cSBruce Richardson 			convert_config_4,
986a9de470cSBruce Richardson 			convert_rule_4,
987a9de470cSBruce Richardson 		},
988a9de470cSBruce Richardson 	};
989a9de470cSBruce Richardson 
990a9de470cSBruce Richardson 	uint32_t i;
991a9de470cSBruce Richardson 	int32_t rc;
992a9de470cSBruce Richardson 
993a9de470cSBruce Richardson 	for (i = 0; i != RTE_DIM(convert_param); i++) {
994a9de470cSBruce Richardson 		rc = test_convert_rules(convert_param[i].desc,
995a9de470cSBruce Richardson 			convert_param[i].config,
996a9de470cSBruce Richardson 			convert_param[i].convert);
997a9de470cSBruce Richardson 		if (rc != 0) {
998a9de470cSBruce Richardson 			printf("%s for test-case: %s failed, error code: %d;\n",
999a9de470cSBruce Richardson 				__func__, convert_param[i].desc, rc);
1000a9de470cSBruce Richardson 			return rc;
1001a9de470cSBruce Richardson 		}
1002a9de470cSBruce Richardson 	}
1003a9de470cSBruce Richardson 
1004a9de470cSBruce Richardson 	return 0;
1005a9de470cSBruce Richardson }
1006a9de470cSBruce Richardson 
1007a9de470cSBruce Richardson /*
1008a9de470cSBruce Richardson  * Test wrong layout behavior
1009a9de470cSBruce Richardson  * This test supplies the ACL context with invalid layout, which results in
1010a9de470cSBruce Richardson  * ACL matching the wrong stuff. However, it should match the wrong stuff
1011a9de470cSBruce Richardson  * the right way. We switch around source and destination addresses,
1012a9de470cSBruce Richardson  * source and destination ports, and protocol will point to first byte of
1013a9de470cSBruce Richardson  * destination port.
1014a9de470cSBruce Richardson  */
1015a9de470cSBruce Richardson static int
test_invalid_layout(void)1016a9de470cSBruce Richardson test_invalid_layout(void)
1017a9de470cSBruce Richardson {
1018a9de470cSBruce Richardson 	struct rte_acl_ctx *acx;
1019a9de470cSBruce Richardson 	int ret, i;
1020a9de470cSBruce Richardson 
1021a9de470cSBruce Richardson 	uint32_t results[RTE_DIM(invalid_layout_data)];
1022a9de470cSBruce Richardson 	const uint8_t *data[RTE_DIM(invalid_layout_data)];
1023a9de470cSBruce Richardson 
1024a9de470cSBruce Richardson 	const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {
1025a9de470cSBruce Richardson 			/* proto points to destination port's first byte */
1026a9de470cSBruce Richardson 			offsetof(struct ipv4_7tuple, port_dst),
1027a9de470cSBruce Richardson 
1028a9de470cSBruce Richardson 			0, /* VLAN not used */
1029a9de470cSBruce Richardson 
1030a9de470cSBruce Richardson 			/* src and dst addresses are swapped */
1031a9de470cSBruce Richardson 			offsetof(struct ipv4_7tuple, ip_dst),
1032a9de470cSBruce Richardson 			offsetof(struct ipv4_7tuple, ip_src),
1033a9de470cSBruce Richardson 
1034a9de470cSBruce Richardson 			/*
1035a9de470cSBruce Richardson 			 * we can't swap ports here, so we will swap
1036a9de470cSBruce Richardson 			 * them in the data
1037a9de470cSBruce Richardson 			 */
1038a9de470cSBruce Richardson 			offsetof(struct ipv4_7tuple, port_src),
1039a9de470cSBruce Richardson 	};
1040a9de470cSBruce Richardson 
1041a9de470cSBruce Richardson 	acx = rte_acl_create(&acl_param);
1042a9de470cSBruce Richardson 	if (acx == NULL) {
1043a9de470cSBruce Richardson 		printf("Line %i: Error creating ACL context!\n", __LINE__);
1044a9de470cSBruce Richardson 		return -1;
1045a9de470cSBruce Richardson 	}
1046a9de470cSBruce Richardson 
1047a9de470cSBruce Richardson 	/* putting a lot of rules into the context results in greater
1048a9de470cSBruce Richardson 	 * coverage numbers. it doesn't matter if they are identical */
1049a9de470cSBruce Richardson 	for (i = 0; i < 1000; i++) {
1050a9de470cSBruce Richardson 		/* add rules to the context */
1051a9de470cSBruce Richardson 		ret = rte_acl_ipv4vlan_add_rules(acx, invalid_layout_rules,
1052a9de470cSBruce Richardson 				RTE_DIM(invalid_layout_rules));
1053a9de470cSBruce Richardson 		if (ret != 0) {
1054a9de470cSBruce Richardson 			printf("Line %i: Adding rules to ACL context failed!\n",
1055a9de470cSBruce Richardson 				__LINE__);
1056a9de470cSBruce Richardson 			rte_acl_free(acx);
1057a9de470cSBruce Richardson 			return -1;
1058a9de470cSBruce Richardson 		}
1059a9de470cSBruce Richardson 	}
1060a9de470cSBruce Richardson 
1061a9de470cSBruce Richardson 	/* try building the context */
1062a9de470cSBruce Richardson 	ret = rte_acl_ipv4vlan_build(acx, layout, 1);
1063a9de470cSBruce Richardson 	if (ret != 0) {
1064a9de470cSBruce Richardson 		printf("Line %i: Building ACL context failed!\n", __LINE__);
1065a9de470cSBruce Richardson 		rte_acl_free(acx);
1066a9de470cSBruce Richardson 		return -1;
1067a9de470cSBruce Richardson 	}
1068a9de470cSBruce Richardson 
1069a9de470cSBruce Richardson 	/* swap all bytes in the data to network order */
1070a9de470cSBruce Richardson 	bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 1);
1071a9de470cSBruce Richardson 
1072a9de470cSBruce Richardson 	/* prepare data */
1073a9de470cSBruce Richardson 	for (i = 0; i < (int) RTE_DIM(invalid_layout_data); i++) {
1074a9de470cSBruce Richardson 		data[i] = (uint8_t *)&invalid_layout_data[i];
1075a9de470cSBruce Richardson 	}
1076a9de470cSBruce Richardson 
1077a9de470cSBruce Richardson 	/* classify tuples */
1078a9de470cSBruce Richardson 	ret = rte_acl_classify_alg(acx, data, results,
1079a9de470cSBruce Richardson 			RTE_DIM(results), 1, RTE_ACL_CLASSIFY_SCALAR);
1080a9de470cSBruce Richardson 	if (ret != 0) {
1081a9de470cSBruce Richardson 		printf("Line %i: SSE classify failed!\n", __LINE__);
1082a9de470cSBruce Richardson 		rte_acl_free(acx);
1083a9de470cSBruce Richardson 		return -1;
1084a9de470cSBruce Richardson 	}
1085a9de470cSBruce Richardson 
1086a9de470cSBruce Richardson 	for (i = 0; i < (int) RTE_DIM(results); i++) {
1087a9de470cSBruce Richardson 		if (results[i] != invalid_layout_data[i].allow) {
1088a9de470cSBruce Richardson 			printf("Line %i: Wrong results at %i "
1089a9de470cSBruce Richardson 				"(result=%u, should be %u)!\n",
1090a9de470cSBruce Richardson 				__LINE__, i, results[i],
1091a9de470cSBruce Richardson 				invalid_layout_data[i].allow);
1092a9de470cSBruce Richardson 			goto err;
1093a9de470cSBruce Richardson 		}
1094a9de470cSBruce Richardson 	}
1095a9de470cSBruce Richardson 
1096a9de470cSBruce Richardson 	/* classify tuples (scalar) */
1097a9de470cSBruce Richardson 	ret = rte_acl_classify_alg(acx, data, results, RTE_DIM(results), 1,
1098a9de470cSBruce Richardson 		RTE_ACL_CLASSIFY_SCALAR);
1099a9de470cSBruce Richardson 
1100a9de470cSBruce Richardson 	if (ret != 0) {
1101a9de470cSBruce Richardson 		printf("Line %i: Scalar classify failed!\n", __LINE__);
1102a9de470cSBruce Richardson 		rte_acl_free(acx);
1103a9de470cSBruce Richardson 		return -1;
1104a9de470cSBruce Richardson 	}
1105a9de470cSBruce Richardson 
1106a9de470cSBruce Richardson 	for (i = 0; i < (int) RTE_DIM(results); i++) {
1107a9de470cSBruce Richardson 		if (results[i] != invalid_layout_data[i].allow) {
1108a9de470cSBruce Richardson 			printf("Line %i: Wrong results at %i "
1109a9de470cSBruce Richardson 				"(result=%u, should be %u)!\n",
1110a9de470cSBruce Richardson 				__LINE__, i, results[i],
1111a9de470cSBruce Richardson 				invalid_layout_data[i].allow);
1112a9de470cSBruce Richardson 			goto err;
1113a9de470cSBruce Richardson 		}
1114a9de470cSBruce Richardson 	}
1115a9de470cSBruce Richardson 
1116a9de470cSBruce Richardson 	rte_acl_free(acx);
1117a9de470cSBruce Richardson 
1118a9de470cSBruce Richardson 	/* swap data back to cpu order so that next time tests don't fail */
1119a9de470cSBruce Richardson 	bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0);
1120a9de470cSBruce Richardson 
1121a9de470cSBruce Richardson 	return 0;
1122a9de470cSBruce Richardson err:
1123a9de470cSBruce Richardson 
1124a9de470cSBruce Richardson 	/* swap data back to cpu order so that next time tests don't fail */
1125a9de470cSBruce Richardson 	bswap_test_data(invalid_layout_data, RTE_DIM(invalid_layout_data), 0);
1126a9de470cSBruce Richardson 
1127a9de470cSBruce Richardson 	rte_acl_free(acx);
1128a9de470cSBruce Richardson 
1129a9de470cSBruce Richardson 	return -1;
1130a9de470cSBruce Richardson }
1131a9de470cSBruce Richardson 
1132a9de470cSBruce Richardson /*
1133a9de470cSBruce Richardson  * Test creating and finding ACL contexts, and adding rules
1134a9de470cSBruce Richardson  */
1135a9de470cSBruce Richardson static int
test_create_find_add(void)1136a9de470cSBruce Richardson test_create_find_add(void)
1137a9de470cSBruce Richardson {
1138a9de470cSBruce Richardson 	struct rte_acl_param param;
1139a9de470cSBruce Richardson 	struct rte_acl_ctx *acx, *acx2, *tmp;
1140a9de470cSBruce Richardson 	struct rte_acl_ipv4vlan_rule rules[LEN];
1141a9de470cSBruce Richardson 
1142a9de470cSBruce Richardson 	const uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0};
1143a9de470cSBruce Richardson 
1144a9de470cSBruce Richardson 	const char *acx_name = "acx";
1145a9de470cSBruce Richardson 	const char *acx2_name = "acx2";
1146a9de470cSBruce Richardson 	int i, ret;
1147a9de470cSBruce Richardson 
1148a9de470cSBruce Richardson 	/* create two contexts */
1149a9de470cSBruce Richardson 	memcpy(&param, &acl_param, sizeof(param));
1150a9de470cSBruce Richardson 	param.max_rule_num = 2;
1151a9de470cSBruce Richardson 
1152a9de470cSBruce Richardson 	param.name = acx_name;
1153a9de470cSBruce Richardson 	acx = rte_acl_create(&param);
1154a9de470cSBruce Richardson 	if (acx == NULL) {
1155a9de470cSBruce Richardson 		printf("Line %i: Error creating %s!\n", __LINE__, acx_name);
1156a9de470cSBruce Richardson 		return -1;
1157a9de470cSBruce Richardson 	}
1158a9de470cSBruce Richardson 
1159a9de470cSBruce Richardson 	param.name = acx2_name;
1160a9de470cSBruce Richardson 	acx2 = rte_acl_create(&param);
1161a9de470cSBruce Richardson 	if (acx2 == NULL || acx2 == acx) {
1162a9de470cSBruce Richardson 		printf("Line %i: Error creating %s!\n", __LINE__, acx2_name);
1163a9de470cSBruce Richardson 		rte_acl_free(acx);
1164a9de470cSBruce Richardson 		return -1;
1165a9de470cSBruce Richardson 	}
1166a9de470cSBruce Richardson 
1167a9de470cSBruce Richardson 	/* try to create third one, with an existing name */
1168a9de470cSBruce Richardson 	param.name = acx_name;
1169a9de470cSBruce Richardson 	tmp = rte_acl_create(&param);
1170a9de470cSBruce Richardson 	if (tmp != acx) {
1171a9de470cSBruce Richardson 		printf("Line %i: Creating context with existing name "
1172a9de470cSBruce Richardson 			"test failed!\n",
1173a9de470cSBruce Richardson 			__LINE__);
1174a9de470cSBruce Richardson 		rte_acl_free(tmp);
1175a9de470cSBruce Richardson 		goto err;
1176a9de470cSBruce Richardson 	}
1177a9de470cSBruce Richardson 
1178a9de470cSBruce Richardson 	param.name = acx2_name;
1179a9de470cSBruce Richardson 	tmp = rte_acl_create(&param);
1180a9de470cSBruce Richardson 	if (tmp != acx2) {
1181a9de470cSBruce Richardson 		printf("Line %i: Creating context with existing "
1182a9de470cSBruce Richardson 			"name test 2 failed!\n",
1183a9de470cSBruce Richardson 			__LINE__);
1184a9de470cSBruce Richardson 		rte_acl_free(tmp);
1185a9de470cSBruce Richardson 		goto err;
1186a9de470cSBruce Richardson 	}
1187a9de470cSBruce Richardson 
1188a9de470cSBruce Richardson 	/* try to find existing ACL contexts */
1189a9de470cSBruce Richardson 	tmp = rte_acl_find_existing(acx_name);
1190a9de470cSBruce Richardson 	if (tmp != acx) {
1191a9de470cSBruce Richardson 		printf("Line %i: Finding %s failed!\n", __LINE__, acx_name);
1192a9de470cSBruce Richardson 		rte_acl_free(tmp);
1193a9de470cSBruce Richardson 		goto err;
1194a9de470cSBruce Richardson 	}
1195a9de470cSBruce Richardson 
1196a9de470cSBruce Richardson 	tmp = rte_acl_find_existing(acx2_name);
1197a9de470cSBruce Richardson 	if (tmp != acx2) {
1198a9de470cSBruce Richardson 		printf("Line %i: Finding %s failed!\n", __LINE__, acx2_name);
1199a9de470cSBruce Richardson 		rte_acl_free(tmp);
1200a9de470cSBruce Richardson 		goto err;
1201a9de470cSBruce Richardson 	}
1202a9de470cSBruce Richardson 
1203a9de470cSBruce Richardson 	/* try to find non-existing context */
1204a9de470cSBruce Richardson 	tmp = rte_acl_find_existing("invalid");
1205a9de470cSBruce Richardson 	if (tmp != NULL) {
1206a9de470cSBruce Richardson 		printf("Line %i: Non-existent ACL context found!\n", __LINE__);
1207a9de470cSBruce Richardson 		goto err;
1208a9de470cSBruce Richardson 	}
1209a9de470cSBruce Richardson 
1210a9de470cSBruce Richardson 	/* free context */
1211a9de470cSBruce Richardson 	rte_acl_free(acx);
1212a9de470cSBruce Richardson 
1213a9de470cSBruce Richardson 
1214a9de470cSBruce Richardson 	/* create valid (but severely limited) acx */
1215a9de470cSBruce Richardson 	memcpy(&param, &acl_param, sizeof(param));
1216a9de470cSBruce Richardson 	param.max_rule_num = LEN;
1217a9de470cSBruce Richardson 
1218a9de470cSBruce Richardson 	acx = rte_acl_create(&param);
1219a9de470cSBruce Richardson 	if (acx == NULL) {
1220a9de470cSBruce Richardson 		printf("Line %i: Error creating %s!\n", __LINE__, param.name);
1221a9de470cSBruce Richardson 		goto err;
1222a9de470cSBruce Richardson 	}
1223a9de470cSBruce Richardson 
1224a9de470cSBruce Richardson 	/* create dummy acl */
1225a9de470cSBruce Richardson 	for (i = 0; i < LEN; i++) {
1226a9de470cSBruce Richardson 		memcpy(&rules[i], &acl_rule,
1227a9de470cSBruce Richardson 			sizeof(struct rte_acl_ipv4vlan_rule));
1228a9de470cSBruce Richardson 		/* skip zero */
1229a9de470cSBruce Richardson 		rules[i].data.userdata = i + 1;
1230a9de470cSBruce Richardson 		/* one rule per category */
1231a9de470cSBruce Richardson 		rules[i].data.category_mask = 1 << i;
1232a9de470cSBruce Richardson 	}
1233a9de470cSBruce Richardson 
1234a9de470cSBruce Richardson 	/* try filling up the context */
1235a9de470cSBruce Richardson 	ret = rte_acl_ipv4vlan_add_rules(acx, rules, LEN);
1236a9de470cSBruce Richardson 	if (ret != 0) {
1237a9de470cSBruce Richardson 		printf("Line %i: Adding %i rules to ACL context failed!\n",
1238a9de470cSBruce Richardson 				__LINE__, LEN);
1239a9de470cSBruce Richardson 		goto err;
1240a9de470cSBruce Richardson 	}
1241a9de470cSBruce Richardson 
1242a9de470cSBruce Richardson 	/* try adding to a (supposedly) full context */
1243a9de470cSBruce Richardson 	ret = rte_acl_ipv4vlan_add_rules(acx, rules, 1);
1244a9de470cSBruce Richardson 	if (ret == 0) {
1245a9de470cSBruce Richardson 		printf("Line %i: Adding rules to full ACL context should"
1246a9de470cSBruce Richardson 				"have failed!\n", __LINE__);
1247a9de470cSBruce Richardson 		goto err;
1248a9de470cSBruce Richardson 	}
1249a9de470cSBruce Richardson 
1250a9de470cSBruce Richardson 	/* try building the context */
1251a9de470cSBruce Richardson 	ret = rte_acl_ipv4vlan_build(acx, layout, RTE_ACL_MAX_CATEGORIES);
1252a9de470cSBruce Richardson 	if (ret != 0) {
1253a9de470cSBruce Richardson 		printf("Line %i: Building ACL context failed!\n", __LINE__);
1254a9de470cSBruce Richardson 		goto err;
1255a9de470cSBruce Richardson 	}
1256a9de470cSBruce Richardson 
1257a9de470cSBruce Richardson 	rte_acl_free(acx);
1258a9de470cSBruce Richardson 	rte_acl_free(acx2);
1259a9de470cSBruce Richardson 
1260a9de470cSBruce Richardson 	return 0;
1261a9de470cSBruce Richardson err:
1262a9de470cSBruce Richardson 	rte_acl_free(acx);
1263a9de470cSBruce Richardson 	rte_acl_free(acx2);
1264a9de470cSBruce Richardson 	return -1;
1265a9de470cSBruce Richardson }
1266a9de470cSBruce Richardson 
1267a9de470cSBruce Richardson /*
1268a9de470cSBruce Richardson  * test various invalid rules
1269a9de470cSBruce Richardson  */
1270a9de470cSBruce Richardson static int
test_invalid_rules(void)1271a9de470cSBruce Richardson test_invalid_rules(void)
1272a9de470cSBruce Richardson {
1273a9de470cSBruce Richardson 	struct rte_acl_ctx *acx;
1274a9de470cSBruce Richardson 	int ret;
1275a9de470cSBruce Richardson 
1276a9de470cSBruce Richardson 	struct rte_acl_ipv4vlan_rule rule;
1277a9de470cSBruce Richardson 
1278a9de470cSBruce Richardson 	acx = rte_acl_create(&acl_param);
1279a9de470cSBruce Richardson 	if (acx == NULL) {
1280a9de470cSBruce Richardson 		printf("Line %i: Error creating ACL context!\n", __LINE__);
1281a9de470cSBruce Richardson 		return -1;
1282a9de470cSBruce Richardson 	}
1283a9de470cSBruce Richardson 
1284a9de470cSBruce Richardson 	/* test inverted high/low source and destination ports.
1285a9de470cSBruce Richardson 	 * originally, there was a problem with memory consumption when using
1286a9de470cSBruce Richardson 	 * such rules.
1287a9de470cSBruce Richardson 	 */
1288a9de470cSBruce Richardson 	/* create dummy acl */
1289a9de470cSBruce Richardson 	memcpy(&rule, &acl_rule, sizeof(struct rte_acl_ipv4vlan_rule));
1290a9de470cSBruce Richardson 	rule.data.userdata = 1;
1291a9de470cSBruce Richardson 	rule.dst_port_low = 0xfff0;
1292a9de470cSBruce Richardson 	rule.dst_port_high = 0x0010;
1293a9de470cSBruce Richardson 
1294a9de470cSBruce Richardson 	/* add rules to context and try to build it */
1295a9de470cSBruce Richardson 	ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1296a9de470cSBruce Richardson 	if (ret == 0) {
1297a9de470cSBruce Richardson 		printf("Line %i: Adding rules to ACL context "
1298a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1299a9de470cSBruce Richardson 		goto err;
1300a9de470cSBruce Richardson 	}
1301a9de470cSBruce Richardson 
1302a9de470cSBruce Richardson 	rule.dst_port_low = 0x0;
1303a9de470cSBruce Richardson 	rule.dst_port_high = 0xffff;
1304a9de470cSBruce Richardson 	rule.src_port_low = 0xfff0;
1305a9de470cSBruce Richardson 	rule.src_port_high = 0x0010;
1306a9de470cSBruce Richardson 
1307a9de470cSBruce Richardson 	/* add rules to context and try to build it */
1308a9de470cSBruce Richardson 	ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1309a9de470cSBruce Richardson 	if (ret == 0) {
1310a9de470cSBruce Richardson 		printf("Line %i: Adding rules to ACL context "
1311a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1312a9de470cSBruce Richardson 		goto err;
1313a9de470cSBruce Richardson 	}
1314a9de470cSBruce Richardson 
1315a9de470cSBruce Richardson 	rule.dst_port_low = 0x0;
1316a9de470cSBruce Richardson 	rule.dst_port_high = 0xffff;
1317a9de470cSBruce Richardson 	rule.src_port_low = 0x0;
1318a9de470cSBruce Richardson 	rule.src_port_high = 0xffff;
1319a9de470cSBruce Richardson 
1320a9de470cSBruce Richardson 	rule.dst_mask_len = 33;
1321a9de470cSBruce Richardson 
1322a9de470cSBruce Richardson 	/* add rules to context and try to build it */
1323a9de470cSBruce Richardson 	ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1324a9de470cSBruce Richardson 	if (ret == 0) {
1325a9de470cSBruce Richardson 		printf("Line %i: Adding rules to ACL context "
1326a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1327a9de470cSBruce Richardson 		goto err;
1328a9de470cSBruce Richardson 	}
1329a9de470cSBruce Richardson 
1330a9de470cSBruce Richardson 	rule.dst_mask_len = 0;
1331a9de470cSBruce Richardson 	rule.src_mask_len = 33;
1332a9de470cSBruce Richardson 
1333a9de470cSBruce Richardson 	/* add rules to context and try to build it */
1334a9de470cSBruce Richardson 	ret = rte_acl_ipv4vlan_add_rules(acx, &rule, 1);
1335a9de470cSBruce Richardson 	if (ret == 0) {
1336a9de470cSBruce Richardson 		printf("Line %i: Adding rules to ACL context "
1337a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1338a9de470cSBruce Richardson 		goto err;
1339a9de470cSBruce Richardson 	}
1340a9de470cSBruce Richardson 
1341a9de470cSBruce Richardson 	rte_acl_free(acx);
1342a9de470cSBruce Richardson 
1343a9de470cSBruce Richardson 	return 0;
1344a9de470cSBruce Richardson 
1345a9de470cSBruce Richardson err:
1346a9de470cSBruce Richardson 	rte_acl_free(acx);
1347a9de470cSBruce Richardson 
1348a9de470cSBruce Richardson 	return -1;
1349a9de470cSBruce Richardson }
1350a9de470cSBruce Richardson 
1351a9de470cSBruce Richardson /*
1352a9de470cSBruce Richardson  * test functions by passing invalid or
1353a9de470cSBruce Richardson  * non-workable parameters.
1354a9de470cSBruce Richardson  *
1355a9de470cSBruce Richardson  * we do very limited testing of classify functions here
1356a9de470cSBruce Richardson  * because those are performance-critical and
1357a9de470cSBruce Richardson  * thus don't do much parameter checking.
1358a9de470cSBruce Richardson  */
1359a9de470cSBruce Richardson static int
test_invalid_parameters(void)1360a9de470cSBruce Richardson test_invalid_parameters(void)
1361a9de470cSBruce Richardson {
1362a9de470cSBruce Richardson 	struct rte_acl_param param;
1363a9de470cSBruce Richardson 	struct rte_acl_ctx *acx;
1364a9de470cSBruce Richardson 	struct rte_acl_ipv4vlan_rule rule;
1365a9de470cSBruce Richardson 	int result;
1366a9de470cSBruce Richardson 
1367a9de470cSBruce Richardson 	uint32_t layout[RTE_ACL_IPV4VLAN_NUM] = {0};
1368a9de470cSBruce Richardson 
1369a9de470cSBruce Richardson 
1370a9de470cSBruce Richardson 	/**
1371a9de470cSBruce Richardson 	 * rte_ac_create()
1372a9de470cSBruce Richardson 	 */
1373a9de470cSBruce Richardson 
1374a9de470cSBruce Richardson 	/* NULL param */
1375a9de470cSBruce Richardson 	acx = rte_acl_create(NULL);
1376a9de470cSBruce Richardson 	if (acx != NULL) {
1377a9de470cSBruce Richardson 		printf("Line %i: ACL context creation with NULL param "
1378a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1379a9de470cSBruce Richardson 		rte_acl_free(acx);
1380a9de470cSBruce Richardson 		return -1;
1381a9de470cSBruce Richardson 	}
1382a9de470cSBruce Richardson 
1383a9de470cSBruce Richardson 	/* zero rule size */
1384a9de470cSBruce Richardson 	memcpy(&param, &acl_param, sizeof(param));
1385a9de470cSBruce Richardson 	param.rule_size = 0;
1386a9de470cSBruce Richardson 
1387a9de470cSBruce Richardson 	acx = rte_acl_create(&param);
1388a9de470cSBruce Richardson 	if (acx == NULL) {
1389a9de470cSBruce Richardson 		printf("Line %i: ACL context creation with zero rule len "
1390a9de470cSBruce Richardson 				"failed!\n", __LINE__);
1391a9de470cSBruce Richardson 		return -1;
1392a9de470cSBruce Richardson 	} else
1393a9de470cSBruce Richardson 		rte_acl_free(acx);
1394a9de470cSBruce Richardson 
1395a9de470cSBruce Richardson 	/* zero max rule num */
1396a9de470cSBruce Richardson 	memcpy(&param, &acl_param, sizeof(param));
1397a9de470cSBruce Richardson 	param.max_rule_num = 0;
1398a9de470cSBruce Richardson 
1399a9de470cSBruce Richardson 	acx = rte_acl_create(&param);
1400a9de470cSBruce Richardson 	if (acx == NULL) {
1401a9de470cSBruce Richardson 		printf("Line %i: ACL context creation with zero rule num "
1402a9de470cSBruce Richardson 				"failed!\n", __LINE__);
1403a9de470cSBruce Richardson 		return -1;
1404a9de470cSBruce Richardson 	} else
1405a9de470cSBruce Richardson 		rte_acl_free(acx);
1406a9de470cSBruce Richardson 
140727fb5dd2SRuifeng Wang 	if (rte_eal_has_hugepages()) {
1408a9de470cSBruce Richardson 		/* invalid NUMA node */
1409a9de470cSBruce Richardson 		memcpy(&param, &acl_param, sizeof(param));
1410a9de470cSBruce Richardson 		param.socket_id = RTE_MAX_NUMA_NODES + 1;
1411a9de470cSBruce Richardson 
1412a9de470cSBruce Richardson 		acx = rte_acl_create(&param);
1413a9de470cSBruce Richardson 		if (acx != NULL) {
141427fb5dd2SRuifeng Wang 			printf("Line %i: ACL context creation with invalid "
141527fb5dd2SRuifeng Wang 					"NUMA should have failed!\n", __LINE__);
1416a9de470cSBruce Richardson 			rte_acl_free(acx);
1417a9de470cSBruce Richardson 			return -1;
1418a9de470cSBruce Richardson 		}
141927fb5dd2SRuifeng Wang 	}
1420a9de470cSBruce Richardson 
1421a9de470cSBruce Richardson 	/* NULL name */
1422a9de470cSBruce Richardson 	memcpy(&param, &acl_param, sizeof(param));
1423a9de470cSBruce Richardson 	param.name = NULL;
1424a9de470cSBruce Richardson 
1425a9de470cSBruce Richardson 	acx = rte_acl_create(&param);
1426a9de470cSBruce Richardson 	if (acx != NULL) {
1427a9de470cSBruce Richardson 		printf("Line %i: ACL context creation with NULL name "
1428a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1429a9de470cSBruce Richardson 		rte_acl_free(acx);
1430a9de470cSBruce Richardson 		return -1;
1431a9de470cSBruce Richardson 	}
1432a9de470cSBruce Richardson 
1433a9de470cSBruce Richardson 	/**
1434a9de470cSBruce Richardson 	 * rte_acl_find_existing
1435a9de470cSBruce Richardson 	 */
1436a9de470cSBruce Richardson 
1437a9de470cSBruce Richardson 	acx = rte_acl_find_existing(NULL);
1438a9de470cSBruce Richardson 	if (acx != NULL) {
1439a9de470cSBruce Richardson 		printf("Line %i: NULL ACL context found!\n", __LINE__);
1440a9de470cSBruce Richardson 		rte_acl_free(acx);
1441a9de470cSBruce Richardson 		return -1;
1442a9de470cSBruce Richardson 	}
1443a9de470cSBruce Richardson 
1444a9de470cSBruce Richardson 	/**
1445a9de470cSBruce Richardson 	 * rte_acl_ipv4vlan_add_rules
1446a9de470cSBruce Richardson 	 */
1447a9de470cSBruce Richardson 
1448a9de470cSBruce Richardson 	/* initialize everything */
1449a9de470cSBruce Richardson 	memcpy(&param, &acl_param, sizeof(param));
1450a9de470cSBruce Richardson 	acx = rte_acl_create(&param);
1451a9de470cSBruce Richardson 	if (acx == NULL) {
1452a9de470cSBruce Richardson 		printf("Line %i: ACL context creation failed!\n", __LINE__);
1453a9de470cSBruce Richardson 		return -1;
1454a9de470cSBruce Richardson 	}
1455a9de470cSBruce Richardson 
1456a9de470cSBruce Richardson 	memcpy(&rule, &acl_rule, sizeof(rule));
1457a9de470cSBruce Richardson 
1458a9de470cSBruce Richardson 	/* NULL context */
1459a9de470cSBruce Richardson 	result = rte_acl_ipv4vlan_add_rules(NULL, &rule, 1);
1460a9de470cSBruce Richardson 	if (result == 0) {
1461a9de470cSBruce Richardson 		printf("Line %i: Adding rules with NULL ACL context "
1462a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1463a9de470cSBruce Richardson 		rte_acl_free(acx);
1464a9de470cSBruce Richardson 		return -1;
1465a9de470cSBruce Richardson 	}
1466a9de470cSBruce Richardson 
1467a9de470cSBruce Richardson 	/* NULL rule */
1468a9de470cSBruce Richardson 	result = rte_acl_ipv4vlan_add_rules(acx, NULL, 1);
1469a9de470cSBruce Richardson 	if (result == 0) {
1470a9de470cSBruce Richardson 		printf("Line %i: Adding NULL rule to ACL context "
1471a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1472a9de470cSBruce Richardson 		rte_acl_free(acx);
1473a9de470cSBruce Richardson 		return -1;
1474a9de470cSBruce Richardson 	}
1475a9de470cSBruce Richardson 
1476a9de470cSBruce Richardson 	/* zero count (should succeed) */
1477a9de470cSBruce Richardson 	result = rte_acl_ipv4vlan_add_rules(acx, &rule, 0);
1478a9de470cSBruce Richardson 	if (result != 0) {
1479a9de470cSBruce Richardson 		printf("Line %i: Adding 0 rules to ACL context failed!\n",
1480a9de470cSBruce Richardson 			__LINE__);
1481a9de470cSBruce Richardson 		rte_acl_free(acx);
1482a9de470cSBruce Richardson 		return -1;
1483a9de470cSBruce Richardson 	}
1484a9de470cSBruce Richardson 
1485a9de470cSBruce Richardson 	/* free ACL context */
1486a9de470cSBruce Richardson 	rte_acl_free(acx);
1487a9de470cSBruce Richardson 
1488a9de470cSBruce Richardson 
1489a9de470cSBruce Richardson 	/**
1490a9de470cSBruce Richardson 	 * rte_acl_ipv4vlan_build
1491a9de470cSBruce Richardson 	 */
1492a9de470cSBruce Richardson 
1493a9de470cSBruce Richardson 	/* reinitialize context */
1494a9de470cSBruce Richardson 	memcpy(&param, &acl_param, sizeof(param));
1495a9de470cSBruce Richardson 	acx = rte_acl_create(&param);
1496a9de470cSBruce Richardson 	if (acx == NULL) {
1497a9de470cSBruce Richardson 		printf("Line %i: ACL context creation failed!\n", __LINE__);
1498a9de470cSBruce Richardson 		return -1;
1499a9de470cSBruce Richardson 	}
1500a9de470cSBruce Richardson 
1501a9de470cSBruce Richardson 	/* NULL context */
1502a9de470cSBruce Richardson 	result = rte_acl_ipv4vlan_build(NULL, layout, 1);
1503a9de470cSBruce Richardson 	if (result == 0) {
1504a9de470cSBruce Richardson 		printf("Line %i: Building with NULL context "
1505a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1506a9de470cSBruce Richardson 		rte_acl_free(acx);
1507a9de470cSBruce Richardson 		return -1;
1508a9de470cSBruce Richardson 	}
1509a9de470cSBruce Richardson 
1510a9de470cSBruce Richardson 	/* NULL layout */
1511a9de470cSBruce Richardson 	result = rte_acl_ipv4vlan_build(acx, NULL, 1);
1512a9de470cSBruce Richardson 	if (result == 0) {
1513a9de470cSBruce Richardson 		printf("Line %i: Building with NULL layout "
1514a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1515a9de470cSBruce Richardson 		rte_acl_free(acx);
1516a9de470cSBruce Richardson 		return -1;
1517a9de470cSBruce Richardson 	}
1518a9de470cSBruce Richardson 
1519a9de470cSBruce Richardson 	/* zero categories (should not fail) */
1520a9de470cSBruce Richardson 	result = rte_acl_ipv4vlan_build(acx, layout, 0);
1521a9de470cSBruce Richardson 	if (result == 0) {
1522a9de470cSBruce Richardson 		printf("Line %i: Building with 0 categories should fail!\n",
1523a9de470cSBruce Richardson 			__LINE__);
1524a9de470cSBruce Richardson 		rte_acl_free(acx);
1525a9de470cSBruce Richardson 		return -1;
1526a9de470cSBruce Richardson 	}
1527a9de470cSBruce Richardson 
1528a9de470cSBruce Richardson 	/* SSE classify test */
1529a9de470cSBruce Richardson 
1530a9de470cSBruce Richardson 	/* cover zero categories in classify (should not fail) */
1531a9de470cSBruce Richardson 	result = rte_acl_classify(acx, NULL, NULL, 0, 0);
1532a9de470cSBruce Richardson 	if (result != 0) {
1533a9de470cSBruce Richardson 		printf("Line %i: SSE classify with zero categories "
1534a9de470cSBruce Richardson 				"failed!\n", __LINE__);
1535a9de470cSBruce Richardson 		rte_acl_free(acx);
1536a9de470cSBruce Richardson 		return -1;
1537a9de470cSBruce Richardson 	}
1538a9de470cSBruce Richardson 
1539a9de470cSBruce Richardson 	/* cover invalid but positive categories in classify */
1540a9de470cSBruce Richardson 	result = rte_acl_classify(acx, NULL, NULL, 0, 3);
1541a9de470cSBruce Richardson 	if (result == 0) {
1542a9de470cSBruce Richardson 		printf("Line %i: SSE classify with 3 categories "
1543a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1544a9de470cSBruce Richardson 		rte_acl_free(acx);
1545a9de470cSBruce Richardson 		return -1;
1546a9de470cSBruce Richardson 	}
1547a9de470cSBruce Richardson 
1548a9de470cSBruce Richardson 	/* scalar classify test */
1549a9de470cSBruce Richardson 
1550a9de470cSBruce Richardson 	/* cover zero categories in classify (should not fail) */
1551a9de470cSBruce Richardson 	result = rte_acl_classify_alg(acx, NULL, NULL, 0, 0,
1552a9de470cSBruce Richardson 		RTE_ACL_CLASSIFY_SCALAR);
1553a9de470cSBruce Richardson 	if (result != 0) {
1554a9de470cSBruce Richardson 		printf("Line %i: Scalar classify with zero categories "
1555a9de470cSBruce Richardson 				"failed!\n", __LINE__);
1556a9de470cSBruce Richardson 		rte_acl_free(acx);
1557a9de470cSBruce Richardson 		return -1;
1558a9de470cSBruce Richardson 	}
1559a9de470cSBruce Richardson 
1560a9de470cSBruce Richardson 	/* cover invalid but positive categories in classify */
1561a9de470cSBruce Richardson 	result = rte_acl_classify(acx, NULL, NULL, 0, 3);
1562a9de470cSBruce Richardson 	if (result == 0) {
1563a9de470cSBruce Richardson 		printf("Line %i: Scalar classify with 3 categories "
1564a9de470cSBruce Richardson 				"should have failed!\n", __LINE__);
1565a9de470cSBruce Richardson 		rte_acl_free(acx);
1566a9de470cSBruce Richardson 		return -1;
1567a9de470cSBruce Richardson 	}
1568a9de470cSBruce Richardson 
1569a9de470cSBruce Richardson 	/* free ACL context */
1570a9de470cSBruce Richardson 	rte_acl_free(acx);
1571a9de470cSBruce Richardson 
1572a9de470cSBruce Richardson 
1573a9de470cSBruce Richardson 	/**
1574a9de470cSBruce Richardson 	 * make sure void functions don't crash with NULL parameters
1575a9de470cSBruce Richardson 	 */
1576a9de470cSBruce Richardson 
1577a9de470cSBruce Richardson 	rte_acl_free(NULL);
1578a9de470cSBruce Richardson 
1579a9de470cSBruce Richardson 	rte_acl_dump(NULL);
1580a9de470cSBruce Richardson 
1581a9de470cSBruce Richardson 	return 0;
1582a9de470cSBruce Richardson }
1583a9de470cSBruce Richardson 
1584a9de470cSBruce Richardson /**
1585a9de470cSBruce Richardson  * Various tests that don't test much but improve coverage
1586a9de470cSBruce Richardson  */
1587a9de470cSBruce Richardson static int
test_misc(void)1588a9de470cSBruce Richardson test_misc(void)
1589a9de470cSBruce Richardson {
1590a9de470cSBruce Richardson 	struct rte_acl_param param;
1591a9de470cSBruce Richardson 	struct rte_acl_ctx *acx;
1592a9de470cSBruce Richardson 
1593a9de470cSBruce Richardson 	/* create context */
1594a9de470cSBruce Richardson 	memcpy(&param, &acl_param, sizeof(param));
1595a9de470cSBruce Richardson 
1596a9de470cSBruce Richardson 	acx = rte_acl_create(&param);
1597a9de470cSBruce Richardson 	if (acx == NULL) {
1598a9de470cSBruce Richardson 		printf("Line %i: Error creating ACL context!\n", __LINE__);
1599a9de470cSBruce Richardson 		return -1;
1600a9de470cSBruce Richardson 	}
1601a9de470cSBruce Richardson 
1602a9de470cSBruce Richardson 	/* dump context with rules - useful for coverage */
1603a9de470cSBruce Richardson 	rte_acl_list_dump();
1604a9de470cSBruce Richardson 
1605a9de470cSBruce Richardson 	rte_acl_dump(acx);
1606a9de470cSBruce Richardson 
1607a9de470cSBruce Richardson 	rte_acl_free(acx);
1608a9de470cSBruce Richardson 
1609a9de470cSBruce Richardson 	return 0;
1610a9de470cSBruce Richardson }
1611a9de470cSBruce Richardson 
1612e33afed9SKonstantin Ananyev static uint32_t
get_u32_range_max(void)1613e33afed9SKonstantin Ananyev get_u32_range_max(void)
1614e33afed9SKonstantin Ananyev {
1615e33afed9SKonstantin Ananyev 	uint32_t i, max;
1616e33afed9SKonstantin Ananyev 
1617e33afed9SKonstantin Ananyev 	max = 0;
1618e33afed9SKonstantin Ananyev 	for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++)
1619e33afed9SKonstantin Ananyev 		max = RTE_MAX(max, acl_u32_range_test_rules[i].src_mask_len);
1620e33afed9SKonstantin Ananyev 	return max;
1621e33afed9SKonstantin Ananyev }
1622e33afed9SKonstantin Ananyev 
1623e33afed9SKonstantin Ananyev static uint32_t
get_u32_range_min(void)1624e33afed9SKonstantin Ananyev get_u32_range_min(void)
1625e33afed9SKonstantin Ananyev {
1626e33afed9SKonstantin Ananyev 	uint32_t i, min;
1627e33afed9SKonstantin Ananyev 
1628e33afed9SKonstantin Ananyev 	min = UINT32_MAX;
1629e33afed9SKonstantin Ananyev 	for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++)
1630e33afed9SKonstantin Ananyev 		min = RTE_MIN(min, acl_u32_range_test_rules[i].src_addr);
1631e33afed9SKonstantin Ananyev 	return min;
1632e33afed9SKonstantin Ananyev }
1633e33afed9SKonstantin Ananyev 
1634e33afed9SKonstantin Ananyev static const struct rte_acl_ipv4vlan_rule *
find_u32_range_rule(uint32_t val)1635e33afed9SKonstantin Ananyev find_u32_range_rule(uint32_t val)
1636e33afed9SKonstantin Ananyev {
1637e33afed9SKonstantin Ananyev 	uint32_t i;
1638e33afed9SKonstantin Ananyev 
1639e33afed9SKonstantin Ananyev 	for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++) {
1640e33afed9SKonstantin Ananyev 		if (val >= acl_u32_range_test_rules[i].src_addr &&
1641e33afed9SKonstantin Ananyev 				val <= acl_u32_range_test_rules[i].src_mask_len)
1642e33afed9SKonstantin Ananyev 			return acl_u32_range_test_rules + i;
1643e33afed9SKonstantin Ananyev 	}
1644e33afed9SKonstantin Ananyev 	return NULL;
1645e33afed9SKonstantin Ananyev }
1646e33afed9SKonstantin Ananyev 
1647e33afed9SKonstantin Ananyev static void
fill_u32_range_data(struct ipv4_7tuple tdata[],uint32_t start,uint32_t num)1648e33afed9SKonstantin Ananyev fill_u32_range_data(struct ipv4_7tuple tdata[], uint32_t start, uint32_t num)
1649e33afed9SKonstantin Ananyev {
1650e33afed9SKonstantin Ananyev 	uint32_t i;
1651e33afed9SKonstantin Ananyev 	const struct rte_acl_ipv4vlan_rule *r;
1652e33afed9SKonstantin Ananyev 
1653e33afed9SKonstantin Ananyev 	for (i = 0; i != num; i++) {
1654e33afed9SKonstantin Ananyev 		tdata[i].ip_src = start + i;
1655e33afed9SKonstantin Ananyev 		r = find_u32_range_rule(start + i);
1656e33afed9SKonstantin Ananyev 		if (r != NULL)
1657e33afed9SKonstantin Ananyev 			tdata[i].allow = r->data.userdata;
1658e33afed9SKonstantin Ananyev 	}
1659e33afed9SKonstantin Ananyev }
1660e33afed9SKonstantin Ananyev 
1661e33afed9SKonstantin Ananyev static int
test_u32_range(void)1662e33afed9SKonstantin Ananyev test_u32_range(void)
1663e33afed9SKonstantin Ananyev {
1664e33afed9SKonstantin Ananyev 	int32_t rc;
1665e33afed9SKonstantin Ananyev 	uint32_t i, k, max, min;
1666e33afed9SKonstantin Ananyev 	struct rte_acl_ctx *acx;
1667e33afed9SKonstantin Ananyev 	struct acl_ipv4vlan_rule r;
1668e33afed9SKonstantin Ananyev 	struct ipv4_7tuple test_data[64];
1669e33afed9SKonstantin Ananyev 
1670e33afed9SKonstantin Ananyev 	acx = rte_acl_create(&acl_param);
1671e33afed9SKonstantin Ananyev 	if (acx == NULL) {
1672e33afed9SKonstantin Ananyev 		printf("%s#%i: Error creating ACL context!\n",
1673e33afed9SKonstantin Ananyev 			__func__, __LINE__);
1674e33afed9SKonstantin Ananyev 		return -1;
1675e33afed9SKonstantin Ananyev 	}
1676e33afed9SKonstantin Ananyev 
1677e33afed9SKonstantin Ananyev 	for (i = 0; i != RTE_DIM(acl_u32_range_test_rules); i++) {
1678e33afed9SKonstantin Ananyev 		convert_rule(&acl_u32_range_test_rules[i], &r);
1679e33afed9SKonstantin Ananyev 		rc = rte_acl_add_rules(acx, (struct rte_acl_rule *)&r, 1);
1680e33afed9SKonstantin Ananyev 		if (rc != 0) {
1681e33afed9SKonstantin Ananyev 			printf("%s#%i: Adding rule to ACL context "
1682e33afed9SKonstantin Ananyev 				"failed with error code: %d\n",
1683e33afed9SKonstantin Ananyev 				__func__, __LINE__, rc);
1684e33afed9SKonstantin Ananyev 			rte_acl_free(acx);
1685e33afed9SKonstantin Ananyev 			return rc;
1686e33afed9SKonstantin Ananyev 		}
1687e33afed9SKonstantin Ananyev 	}
1688e33afed9SKonstantin Ananyev 
1689e33afed9SKonstantin Ananyev 	rc = build_convert_rules(acx, convert_config_2, 0);
1690e33afed9SKonstantin Ananyev 	if (rc != 0) {
1691e33afed9SKonstantin Ananyev 		printf("%s#%i Error @ build_convert_rules!\n",
1692e33afed9SKonstantin Ananyev 			__func__, __LINE__);
1693e33afed9SKonstantin Ananyev 		rte_acl_free(acx);
1694e33afed9SKonstantin Ananyev 		return rc;
1695e33afed9SKonstantin Ananyev 	}
1696e33afed9SKonstantin Ananyev 
1697e33afed9SKonstantin Ananyev 	max = get_u32_range_max();
1698e33afed9SKonstantin Ananyev 	min = get_u32_range_min();
1699e33afed9SKonstantin Ananyev 
1700e33afed9SKonstantin Ananyev 	max = RTE_MAX(max, max + 1);
1701e33afed9SKonstantin Ananyev 	min = RTE_MIN(min, min - 1);
1702e33afed9SKonstantin Ananyev 
1703e33afed9SKonstantin Ananyev 	printf("%s#%d starting range test from %u to %u\n",
1704e33afed9SKonstantin Ananyev 		__func__, __LINE__, min, max);
1705e33afed9SKonstantin Ananyev 
1706e33afed9SKonstantin Ananyev 	for (i = min; i <= max; i += k) {
1707e33afed9SKonstantin Ananyev 
1708e33afed9SKonstantin Ananyev 		k = RTE_MIN(max - i + 1, RTE_DIM(test_data));
1709e33afed9SKonstantin Ananyev 
1710e33afed9SKonstantin Ananyev 		memset(test_data, 0, sizeof(test_data));
1711e33afed9SKonstantin Ananyev 		fill_u32_range_data(test_data, i, k);
1712e33afed9SKonstantin Ananyev 
1713e33afed9SKonstantin Ananyev 		rc = test_classify_run(acx, test_data, k);
1714e33afed9SKonstantin Ananyev 		if (rc != 0) {
1715e33afed9SKonstantin Ananyev 			printf("%s#%d failed at [%u, %u) interval\n",
1716e33afed9SKonstantin Ananyev 				__func__, __LINE__, i, i + k);
1717e33afed9SKonstantin Ananyev 			break;
1718e33afed9SKonstantin Ananyev 		}
1719e33afed9SKonstantin Ananyev 	}
1720e33afed9SKonstantin Ananyev 
1721e33afed9SKonstantin Ananyev 	rte_acl_free(acx);
1722e33afed9SKonstantin Ananyev 	return rc;
1723e33afed9SKonstantin Ananyev }
1724e33afed9SKonstantin Ananyev 
1725a9de470cSBruce Richardson static int
test_acl(void)1726a9de470cSBruce Richardson test_acl(void)
1727a9de470cSBruce Richardson {
1728a9de470cSBruce Richardson 	if (test_invalid_parameters() < 0)
1729a9de470cSBruce Richardson 		return -1;
1730a9de470cSBruce Richardson 	if (test_invalid_rules() < 0)
1731a9de470cSBruce Richardson 		return -1;
1732a9de470cSBruce Richardson 	if (test_create_find_add() < 0)
1733a9de470cSBruce Richardson 		return -1;
1734a9de470cSBruce Richardson 	if (test_invalid_layout() < 0)
1735a9de470cSBruce Richardson 		return -1;
1736a9de470cSBruce Richardson 	if (test_misc() < 0)
1737a9de470cSBruce Richardson 		return -1;
1738a9de470cSBruce Richardson 	if (test_classify() < 0)
1739a9de470cSBruce Richardson 		return -1;
1740a9de470cSBruce Richardson 	if (test_build_ports_range() < 0)
1741a9de470cSBruce Richardson 		return -1;
1742a9de470cSBruce Richardson 	if (test_convert() < 0)
1743a9de470cSBruce Richardson 		return -1;
1744e33afed9SKonstantin Ananyev 	if (test_u32_range() < 0)
1745e33afed9SKonstantin Ananyev 		return -1;
1746a9de470cSBruce Richardson 
1747a9de470cSBruce Richardson 	return 0;
1748a9de470cSBruce Richardson }
1749a9de470cSBruce Richardson 
17503c60274cSJie Zhou #endif /* !RTE_EXEC_ENV_WINDOWS */
17513c60274cSJie Zhou 
1752e0a8442cSBruce Richardson REGISTER_FAST_TEST(acl_autotest, true, true, test_acl);
1753