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(¶m, &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(¶m);
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(¶m);
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(¶m);
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(¶m);
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(¶m, &acl_param, sizeof(param));
1216a9de470cSBruce Richardson param.max_rule_num = LEN;
1217a9de470cSBruce Richardson
1218a9de470cSBruce Richardson acx = rte_acl_create(¶m);
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(¶m, &acl_param, sizeof(param));
1385a9de470cSBruce Richardson param.rule_size = 0;
1386a9de470cSBruce Richardson
1387a9de470cSBruce Richardson acx = rte_acl_create(¶m);
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(¶m, &acl_param, sizeof(param));
1397a9de470cSBruce Richardson param.max_rule_num = 0;
1398a9de470cSBruce Richardson
1399a9de470cSBruce Richardson acx = rte_acl_create(¶m);
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(¶m, &acl_param, sizeof(param));
1410a9de470cSBruce Richardson param.socket_id = RTE_MAX_NUMA_NODES + 1;
1411a9de470cSBruce Richardson
1412a9de470cSBruce Richardson acx = rte_acl_create(¶m);
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(¶m, &acl_param, sizeof(param));
1423a9de470cSBruce Richardson param.name = NULL;
1424a9de470cSBruce Richardson
1425a9de470cSBruce Richardson acx = rte_acl_create(¶m);
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(¶m, &acl_param, sizeof(param));
1450a9de470cSBruce Richardson acx = rte_acl_create(¶m);
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(¶m, &acl_param, sizeof(param));
1495a9de470cSBruce Richardson acx = rte_acl_create(¶m);
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(¶m, &acl_param, sizeof(param));
1595a9de470cSBruce Richardson
1596a9de470cSBruce Richardson acx = rte_acl_create(¶m);
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