xref: /dpdk/app/test/test_table_acl.c (revision f541aa2d41f8939b687e4d145a5dd18bd16f593e)
1a9de470cSBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2a9de470cSBruce Richardson  * Copyright(c) 2010-2014 Intel Corporation
3a9de470cSBruce Richardson  */
4a9de470cSBruce Richardson 
53c60274cSJie Zhou #ifndef RTE_EXEC_ENV_WINDOWS
63c60274cSJie Zhou 
7fd1a85cbSDavid Marchand #include <rte_ip.h>
86723c0fcSBruce Richardson #include <rte_string_fns.h>
9a9de470cSBruce Richardson #include <rte_hexdump.h>
10a9de470cSBruce Richardson #include "test_table.h"
11a9de470cSBruce Richardson #include "test_table_acl.h"
12a9de470cSBruce Richardson 
13a9de470cSBruce Richardson /*
14a9de470cSBruce Richardson  * Rule and trace formats definitions.
15a9de470cSBruce Richardson  **/
16a9de470cSBruce Richardson 
17a9de470cSBruce Richardson struct ipv4_5tuple {
18a9de470cSBruce Richardson 	uint8_t  proto;
19a9de470cSBruce Richardson 	uint32_t ip_src;
20a9de470cSBruce Richardson 	uint32_t ip_dst;
21a9de470cSBruce Richardson 	uint16_t port_src;
22a9de470cSBruce Richardson 	uint16_t port_dst;
23a9de470cSBruce Richardson };
24a9de470cSBruce Richardson 
25a9de470cSBruce Richardson enum {
26a9de470cSBruce Richardson 	PROTO_FIELD_IPV4,
27a9de470cSBruce Richardson 	SRC_FIELD_IPV4,
28a9de470cSBruce Richardson 	DST_FIELD_IPV4,
29a9de470cSBruce Richardson 	SRCP_FIELD_IPV4,
30a9de470cSBruce Richardson 	DSTP_FIELD_IPV4,
31a9de470cSBruce Richardson 	NUM_FIELDS_IPV4
32a9de470cSBruce Richardson };
33a9de470cSBruce Richardson 
34a9de470cSBruce Richardson struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = {
35a9de470cSBruce Richardson 	{
36a9de470cSBruce Richardson 		.type = RTE_ACL_FIELD_TYPE_BITMASK,
37a9de470cSBruce Richardson 		.size = sizeof(uint8_t),
38a9de470cSBruce Richardson 		.field_index = PROTO_FIELD_IPV4,
39a9de470cSBruce Richardson 		.input_index = PROTO_FIELD_IPV4,
40a9de470cSBruce Richardson 		.offset = offsetof(struct ipv4_5tuple, proto),
41a9de470cSBruce Richardson 	},
42a9de470cSBruce Richardson 	{
43a9de470cSBruce Richardson 		.type = RTE_ACL_FIELD_TYPE_MASK,
44a9de470cSBruce Richardson 		.size = sizeof(uint32_t),
45a9de470cSBruce Richardson 		.field_index = SRC_FIELD_IPV4,
46a9de470cSBruce Richardson 		.input_index = SRC_FIELD_IPV4,
47a9de470cSBruce Richardson 		.offset = offsetof(struct ipv4_5tuple, ip_src),
48a9de470cSBruce Richardson 	},
49a9de470cSBruce Richardson 	{
50a9de470cSBruce Richardson 		.type = RTE_ACL_FIELD_TYPE_MASK,
51a9de470cSBruce Richardson 		.size = sizeof(uint32_t),
52a9de470cSBruce Richardson 		.field_index = DST_FIELD_IPV4,
53a9de470cSBruce Richardson 		.input_index = DST_FIELD_IPV4,
54a9de470cSBruce Richardson 		.offset = offsetof(struct ipv4_5tuple, ip_dst),
55a9de470cSBruce Richardson 	},
56a9de470cSBruce Richardson 	{
57a9de470cSBruce Richardson 		.type = RTE_ACL_FIELD_TYPE_RANGE,
58a9de470cSBruce Richardson 		.size = sizeof(uint16_t),
59a9de470cSBruce Richardson 		.field_index = SRCP_FIELD_IPV4,
60a9de470cSBruce Richardson 		.input_index = SRCP_FIELD_IPV4,
61a9de470cSBruce Richardson 		.offset = offsetof(struct ipv4_5tuple, port_src),
62a9de470cSBruce Richardson 	},
63a9de470cSBruce Richardson 	{
64a9de470cSBruce Richardson 		.type = RTE_ACL_FIELD_TYPE_RANGE,
65a9de470cSBruce Richardson 		.size = sizeof(uint16_t),
66a9de470cSBruce Richardson 		.field_index = DSTP_FIELD_IPV4,
67a9de470cSBruce Richardson 		.input_index = SRCP_FIELD_IPV4,
68a9de470cSBruce Richardson 		.offset = offsetof(struct ipv4_5tuple, port_dst),
69a9de470cSBruce Richardson 	},
70a9de470cSBruce Richardson };
71a9de470cSBruce Richardson 
72a9de470cSBruce Richardson struct rte_table_acl_rule_add_params table_acl_IPv4_rule;
73a9de470cSBruce Richardson 
74a9de470cSBruce Richardson typedef int (*parse_5tuple)(char *text,
75a9de470cSBruce Richardson 	struct rte_table_acl_rule_add_params *rule);
76a9de470cSBruce Richardson 
77a9de470cSBruce Richardson /*
78a9de470cSBruce Richardson * The order of the fields in the rule string after the initial '@'
79a9de470cSBruce Richardson */
80a9de470cSBruce Richardson enum {
81a9de470cSBruce Richardson 	CB_FLD_SRC_ADDR,
82a9de470cSBruce Richardson 	CB_FLD_DST_ADDR,
83a9de470cSBruce Richardson 	CB_FLD_SRC_PORT_RANGE,
84a9de470cSBruce Richardson 	CB_FLD_DST_PORT_RANGE,
85a9de470cSBruce Richardson 	CB_FLD_PROTO,
86a9de470cSBruce Richardson 	CB_FLD_NUM,
87a9de470cSBruce Richardson };
88a9de470cSBruce Richardson 
89a9de470cSBruce Richardson 
90a9de470cSBruce Richardson #define GET_CB_FIELD(in, fd, base, lim, dlm)				\
91a9de470cSBruce Richardson do {									\
92a9de470cSBruce Richardson 	unsigned long val;						\
93a9de470cSBruce Richardson 	char *end;							\
94a9de470cSBruce Richardson 									\
95a9de470cSBruce Richardson 	errno = 0;							\
96a9de470cSBruce Richardson 	val = strtoul((in), &end, (base));				\
97a9de470cSBruce Richardson 	if (errno != 0 || end[0] != (dlm) || val > (lim))		\
98a9de470cSBruce Richardson 		return -EINVAL;						\
99a9de470cSBruce Richardson 	(fd) = (typeof(fd)) val;					\
100a9de470cSBruce Richardson 	(in) = end + 1;							\
101a9de470cSBruce Richardson } while (0)
102a9de470cSBruce Richardson 
103a9de470cSBruce Richardson 
104a9de470cSBruce Richardson 
105a9de470cSBruce Richardson 
106a9de470cSBruce Richardson static int
parse_ipv4_net(const char * in,uint32_t * addr,uint32_t * mask_len)107a9de470cSBruce Richardson parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len)
108a9de470cSBruce Richardson {
109a9de470cSBruce Richardson 	uint8_t a, b, c, d, m;
110a9de470cSBruce Richardson 
111a9de470cSBruce Richardson 	GET_CB_FIELD(in, a, 0, UINT8_MAX, '.');
112a9de470cSBruce Richardson 	GET_CB_FIELD(in, b, 0, UINT8_MAX, '.');
113a9de470cSBruce Richardson 	GET_CB_FIELD(in, c, 0, UINT8_MAX, '.');
114a9de470cSBruce Richardson 	GET_CB_FIELD(in, d, 0, UINT8_MAX, '/');
115a9de470cSBruce Richardson 	GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0);
116a9de470cSBruce Richardson 
1170c9da755SDavid Marchand 	addr[0] = RTE_IPV4(a, b, c, d);
118a9de470cSBruce Richardson 	mask_len[0] = m;
119a9de470cSBruce Richardson 
120a9de470cSBruce Richardson 	return 0;
121a9de470cSBruce Richardson }
122a9de470cSBruce Richardson 
123a9de470cSBruce Richardson static int
parse_port_range(const char * in,uint16_t * port_low,uint16_t * port_high)124a9de470cSBruce Richardson parse_port_range(const char *in, uint16_t *port_low, uint16_t *port_high)
125a9de470cSBruce Richardson {
126a9de470cSBruce Richardson 	uint16_t a, b;
127a9de470cSBruce Richardson 
128a9de470cSBruce Richardson 	GET_CB_FIELD(in, a, 0, UINT16_MAX, ':');
129a9de470cSBruce Richardson 	GET_CB_FIELD(in, b, 0, UINT16_MAX, 0);
130a9de470cSBruce Richardson 
131a9de470cSBruce Richardson 	port_low[0] = a;
132a9de470cSBruce Richardson 	port_high[0] = b;
133a9de470cSBruce Richardson 
134a9de470cSBruce Richardson 	return 0;
135a9de470cSBruce Richardson }
136a9de470cSBruce Richardson 
137a9de470cSBruce Richardson static int
parse_cb_ipv4_rule(char * str,struct rte_table_acl_rule_add_params * v)138a9de470cSBruce Richardson parse_cb_ipv4_rule(char *str, struct rte_table_acl_rule_add_params *v)
139a9de470cSBruce Richardson {
140a9de470cSBruce Richardson 	int i, rc;
141a9de470cSBruce Richardson 	char *s, *sp, *in[CB_FLD_NUM];
142a9de470cSBruce Richardson 	static const char *dlm = " \t\n";
143a9de470cSBruce Richardson 
144a9de470cSBruce Richardson 	/*
145a9de470cSBruce Richardson 	** Skip leading '@'
146a9de470cSBruce Richardson 	*/
147a9de470cSBruce Richardson 	if (strchr(str, '@') != str)
148a9de470cSBruce Richardson 		return -EINVAL;
149a9de470cSBruce Richardson 
150a9de470cSBruce Richardson 	s = str + 1;
151a9de470cSBruce Richardson 
152a9de470cSBruce Richardson 	/*
153a9de470cSBruce Richardson 	* Populate the 'in' array with the location of each
154a9de470cSBruce Richardson 	* field in the string we're parsing
155a9de470cSBruce Richardson 	*/
156a9de470cSBruce Richardson 	for (i = 0; i != DIM(in); i++) {
157a9de470cSBruce Richardson 		in[i] = strtok_r(s, dlm, &sp);
158a9de470cSBruce Richardson 		if (in[i] == NULL)
159a9de470cSBruce Richardson 			return -EINVAL;
160a9de470cSBruce Richardson 		s = NULL;
161a9de470cSBruce Richardson 	}
162a9de470cSBruce Richardson 
163a9de470cSBruce Richardson 	/* Parse x.x.x.x/x */
164a9de470cSBruce Richardson 	rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
165a9de470cSBruce Richardson 		&v->field_value[SRC_FIELD_IPV4].value.u32,
166a9de470cSBruce Richardson 		&v->field_value[SRC_FIELD_IPV4].mask_range.u32);
167a9de470cSBruce Richardson 	if (rc != 0) {
168*f541aa2dSStephen Hemminger 		fprintf(stderr, "failed to read src address/mask: %s\n",
169a9de470cSBruce Richardson 			in[CB_FLD_SRC_ADDR]);
170a9de470cSBruce Richardson 		return rc;
171a9de470cSBruce Richardson 	}
172a9de470cSBruce Richardson 
173a9de470cSBruce Richardson 	printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
174a9de470cSBruce Richardson 		v->field_value[SRC_FIELD_IPV4].mask_range.u32);
175a9de470cSBruce Richardson 
176a9de470cSBruce Richardson 	/* Parse x.x.x.x/x */
177a9de470cSBruce Richardson 	rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
178a9de470cSBruce Richardson 		&v->field_value[DST_FIELD_IPV4].value.u32,
179a9de470cSBruce Richardson 		&v->field_value[DST_FIELD_IPV4].mask_range.u32);
180a9de470cSBruce Richardson 	if (rc != 0) {
181*f541aa2dSStephen Hemminger 		fprintf(stderr, "failed to read dest address/mask: %s\n",
182a9de470cSBruce Richardson 			in[CB_FLD_DST_ADDR]);
183a9de470cSBruce Richardson 		return rc;
184a9de470cSBruce Richardson 	}
185a9de470cSBruce Richardson 
186a9de470cSBruce Richardson 	printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
187a9de470cSBruce Richardson 	v->field_value[DST_FIELD_IPV4].mask_range.u32);
188a9de470cSBruce Richardson 	/* Parse n:n */
189a9de470cSBruce Richardson 	rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
190a9de470cSBruce Richardson 		&v->field_value[SRCP_FIELD_IPV4].value.u16,
191a9de470cSBruce Richardson 		&v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
192a9de470cSBruce Richardson 	if (rc != 0) {
193*f541aa2dSStephen Hemminger 		fprintf(stderr, "failed to read source port range: %s\n",
194a9de470cSBruce Richardson 			in[CB_FLD_SRC_PORT_RANGE]);
195a9de470cSBruce Richardson 		return rc;
196a9de470cSBruce Richardson 	}
197a9de470cSBruce Richardson 
198a9de470cSBruce Richardson 	printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
199a9de470cSBruce Richardson 		v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
200a9de470cSBruce Richardson 	/* Parse n:n */
201a9de470cSBruce Richardson 	rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
202a9de470cSBruce Richardson 		&v->field_value[DSTP_FIELD_IPV4].value.u16,
203a9de470cSBruce Richardson 		&v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
204a9de470cSBruce Richardson 	if (rc != 0) {
205*f541aa2dSStephen Hemminger 		fprintf(stderr, "failed to read dest port range: %s\n",
206a9de470cSBruce Richardson 			in[CB_FLD_DST_PORT_RANGE]);
207a9de470cSBruce Richardson 		return rc;
208a9de470cSBruce Richardson 	}
209a9de470cSBruce Richardson 
210a9de470cSBruce Richardson 	printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
211a9de470cSBruce Richardson 		v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
212a9de470cSBruce Richardson 	/* parse 0/0xnn */
213a9de470cSBruce Richardson 	GET_CB_FIELD(in[CB_FLD_PROTO],
214a9de470cSBruce Richardson 		v->field_value[PROTO_FIELD_IPV4].value.u8,
215a9de470cSBruce Richardson 		0, UINT8_MAX, '/');
216a9de470cSBruce Richardson 	GET_CB_FIELD(in[CB_FLD_PROTO],
217a9de470cSBruce Richardson 		v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
218a9de470cSBruce Richardson 		0, UINT8_MAX, 0);
219a9de470cSBruce Richardson 
220a9de470cSBruce Richardson 	printf("V=%u, mask=%u\n",
221a9de470cSBruce Richardson 		(unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
222a9de470cSBruce Richardson 		v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
223a9de470cSBruce Richardson 	return 0;
224a9de470cSBruce Richardson }
225a9de470cSBruce Richardson 
226a9de470cSBruce Richardson static int
parse_cb_ipv4_rule_del(char * str,struct rte_table_acl_rule_delete_params * v)227a9de470cSBruce Richardson parse_cb_ipv4_rule_del(char *str, struct rte_table_acl_rule_delete_params *v)
228a9de470cSBruce Richardson {
229a9de470cSBruce Richardson 	int i, rc;
230a9de470cSBruce Richardson 	char *s, *sp, *in[CB_FLD_NUM];
231a9de470cSBruce Richardson 	static const char *dlm = " \t\n";
232a9de470cSBruce Richardson 
233a9de470cSBruce Richardson 	/*
234a9de470cSBruce Richardson 	** Skip leading '@'
235a9de470cSBruce Richardson 	*/
236a9de470cSBruce Richardson 	if (strchr(str, '@') != str)
237a9de470cSBruce Richardson 		return -EINVAL;
238a9de470cSBruce Richardson 
239a9de470cSBruce Richardson 	s = str + 1;
240a9de470cSBruce Richardson 
241a9de470cSBruce Richardson 	/*
242a9de470cSBruce Richardson 	* Populate the 'in' array with the location of each
243a9de470cSBruce Richardson 	* field in the string we're parsing
244a9de470cSBruce Richardson 	*/
245a9de470cSBruce Richardson 	for (i = 0; i != DIM(in); i++) {
246a9de470cSBruce Richardson 		in[i] = strtok_r(s, dlm, &sp);
247a9de470cSBruce Richardson 		if (in[i] == NULL)
248a9de470cSBruce Richardson 			return -EINVAL;
249a9de470cSBruce Richardson 		s = NULL;
250a9de470cSBruce Richardson 	}
251a9de470cSBruce Richardson 
252a9de470cSBruce Richardson 	/* Parse x.x.x.x/x */
253a9de470cSBruce Richardson 	rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
254a9de470cSBruce Richardson 		&v->field_value[SRC_FIELD_IPV4].value.u32,
255a9de470cSBruce Richardson 		&v->field_value[SRC_FIELD_IPV4].mask_range.u32);
256a9de470cSBruce Richardson 	if (rc != 0) {
257*f541aa2dSStephen Hemminger 		fprintf(stderr, "failed to read src address/mask: %s\n",
258a9de470cSBruce Richardson 			in[CB_FLD_SRC_ADDR]);
259a9de470cSBruce Richardson 		return rc;
260a9de470cSBruce Richardson 	}
261a9de470cSBruce Richardson 
262a9de470cSBruce Richardson 	printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
263a9de470cSBruce Richardson 		v->field_value[SRC_FIELD_IPV4].mask_range.u32);
264a9de470cSBruce Richardson 
265a9de470cSBruce Richardson 	/* Parse x.x.x.x/x */
266a9de470cSBruce Richardson 	rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
267a9de470cSBruce Richardson 		&v->field_value[DST_FIELD_IPV4].value.u32,
268a9de470cSBruce Richardson 		&v->field_value[DST_FIELD_IPV4].mask_range.u32);
269a9de470cSBruce Richardson 	if (rc != 0) {
270*f541aa2dSStephen Hemminger 		fprintf(stderr, "failed to read dest address/mask: %s\n",
271a9de470cSBruce Richardson 			in[CB_FLD_DST_ADDR]);
272a9de470cSBruce Richardson 		return rc;
273a9de470cSBruce Richardson 	}
274a9de470cSBruce Richardson 
275a9de470cSBruce Richardson 	printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
276a9de470cSBruce Richardson 	v->field_value[DST_FIELD_IPV4].mask_range.u32);
277a9de470cSBruce Richardson 	/* Parse n:n */
278a9de470cSBruce Richardson 	rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
279a9de470cSBruce Richardson 		&v->field_value[SRCP_FIELD_IPV4].value.u16,
280a9de470cSBruce Richardson 		&v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
281a9de470cSBruce Richardson 	if (rc != 0) {
282*f541aa2dSStephen Hemminger 		fprintf(stderr, "failed to read source port range: %s\n",
283a9de470cSBruce Richardson 			in[CB_FLD_SRC_PORT_RANGE]);
284a9de470cSBruce Richardson 		return rc;
285a9de470cSBruce Richardson 	}
286a9de470cSBruce Richardson 
287a9de470cSBruce Richardson 	printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
288a9de470cSBruce Richardson 		v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
289a9de470cSBruce Richardson 	/* Parse n:n */
290a9de470cSBruce Richardson 	rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
291a9de470cSBruce Richardson 		&v->field_value[DSTP_FIELD_IPV4].value.u16,
292a9de470cSBruce Richardson 		&v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
293a9de470cSBruce Richardson 	if (rc != 0) {
294*f541aa2dSStephen Hemminger 		fprintf(stderr, "failed to read dest port range: %s\n",
295a9de470cSBruce Richardson 			in[CB_FLD_DST_PORT_RANGE]);
296a9de470cSBruce Richardson 		return rc;
297a9de470cSBruce Richardson 	}
298a9de470cSBruce Richardson 
299a9de470cSBruce Richardson 	printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
300a9de470cSBruce Richardson 		v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
301a9de470cSBruce Richardson 	/* parse 0/0xnn */
302a9de470cSBruce Richardson 	GET_CB_FIELD(in[CB_FLD_PROTO],
303a9de470cSBruce Richardson 		v->field_value[PROTO_FIELD_IPV4].value.u8,
304a9de470cSBruce Richardson 		0, UINT8_MAX, '/');
305a9de470cSBruce Richardson 	GET_CB_FIELD(in[CB_FLD_PROTO],
306a9de470cSBruce Richardson 		v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
307a9de470cSBruce Richardson 		0, UINT8_MAX, 0);
308a9de470cSBruce Richardson 
309a9de470cSBruce Richardson 	printf("V=%u, mask=%u\n",
310a9de470cSBruce Richardson 		(unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
311a9de470cSBruce Richardson 		v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
312a9de470cSBruce Richardson 	return 0;
313a9de470cSBruce Richardson }
314a9de470cSBruce Richardson 
315a9de470cSBruce Richardson /*
316a9de470cSBruce Richardson  * The format for these rules DO NOT need the port ranges to be
317a9de470cSBruce Richardson  * separated by ' : ', just ':'. It's a lot more readable and
318a9de470cSBruce Richardson  * cleaner, IMO.
319a9de470cSBruce Richardson  */
320a9de470cSBruce Richardson char lines[][128] = {
321a9de470cSBruce Richardson 	"@0.0.0.0/0 0.0.0.0/0 0:65535 0:65535 2/0xff", /* Protocol check */
322a9de470cSBruce Richardson 	"@192.168.3.1/32 0.0.0.0/0 0:65535 0:65535 0/0", /* Src IP checl */
323a9de470cSBruce Richardson 	"@0.0.0.0/0 10.4.4.1/32 0:65535 0:65535 0/0", /* dst IP check */
324a9de470cSBruce Richardson 	"@0.0.0.0/0 0.0.0.0/0 105:105 0:65535 0/0", /* src port check */
325a9de470cSBruce Richardson 	"@0.0.0.0/0 0.0.0.0/0 0:65535 206:206 0/0", /* dst port check */
326a9de470cSBruce Richardson };
327a9de470cSBruce Richardson 
328a9de470cSBruce Richardson char line[128];
329a9de470cSBruce Richardson 
330a9de470cSBruce Richardson 
331a9de470cSBruce Richardson static int
setup_acl_pipeline(void)332a9de470cSBruce Richardson setup_acl_pipeline(void)
333a9de470cSBruce Richardson {
334a9de470cSBruce Richardson 	int ret;
335a9de470cSBruce Richardson 	int i;
336a9de470cSBruce Richardson 	struct rte_pipeline_params pipeline_params = {
337a9de470cSBruce Richardson 		.name = "PIPELINE",
338a9de470cSBruce Richardson 		.socket_id = 0,
339a9de470cSBruce Richardson 	};
340a9de470cSBruce Richardson 	uint32_t n;
341a9de470cSBruce Richardson 	struct rte_table_acl_rule_add_params rule_params;
342a9de470cSBruce Richardson 	struct rte_pipeline_table_acl_rule_delete_params *delete_params;
343a9de470cSBruce Richardson 	parse_5tuple parser;
344a9de470cSBruce Richardson 	char acl_name[64];
345a9de470cSBruce Richardson 
346a9de470cSBruce Richardson 	/* Pipeline configuration */
347a9de470cSBruce Richardson 	p = rte_pipeline_create(&pipeline_params);
348a9de470cSBruce Richardson 	if (p == NULL) {
349*f541aa2dSStephen Hemminger 		fprintf(stderr, "%s: Failed to configure pipeline\n",
350a9de470cSBruce Richardson 			__func__);
351a9de470cSBruce Richardson 		goto fail;
352a9de470cSBruce Richardson 	}
353a9de470cSBruce Richardson 
354a9de470cSBruce Richardson 	/* Input port configuration */
355a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
356a9de470cSBruce Richardson 		struct rte_port_ring_reader_params port_ring_params = {
357a9de470cSBruce Richardson 			.ring = rings_rx[i],
358a9de470cSBruce Richardson 		};
359a9de470cSBruce Richardson 
360a9de470cSBruce Richardson 		struct rte_pipeline_port_in_params port_params = {
361a9de470cSBruce Richardson 			.ops = &rte_port_ring_reader_ops,
362a9de470cSBruce Richardson 			.arg_create = (void *) &port_ring_params,
363a9de470cSBruce Richardson 			.f_action = NULL,
364a9de470cSBruce Richardson 			.burst_size = BURST_SIZE,
365a9de470cSBruce Richardson 		};
366a9de470cSBruce Richardson 
367a9de470cSBruce Richardson 		/* Put in action for some ports */
368a9de470cSBruce Richardson 		if (i)
369a9de470cSBruce Richardson 			port_params.f_action = port_in_action;
370a9de470cSBruce Richardson 
371a9de470cSBruce Richardson 		ret = rte_pipeline_port_in_create(p, &port_params,
372a9de470cSBruce Richardson 			&port_in_id[i]);
373a9de470cSBruce Richardson 		if (ret) {
374a9de470cSBruce Richardson 			rte_panic("Unable to configure input port %d, ret:%d\n",
375a9de470cSBruce Richardson 				i, ret);
376a9de470cSBruce Richardson 			goto fail;
377a9de470cSBruce Richardson 		}
378a9de470cSBruce Richardson 	}
379a9de470cSBruce Richardson 
380a9de470cSBruce Richardson 	/* output Port configuration */
381a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
382a9de470cSBruce Richardson 		struct rte_port_ring_writer_params port_ring_params = {
383a9de470cSBruce Richardson 			.ring = rings_tx[i],
384a9de470cSBruce Richardson 			.tx_burst_sz = BURST_SIZE,
385a9de470cSBruce Richardson 		};
386a9de470cSBruce Richardson 
387a9de470cSBruce Richardson 		struct rte_pipeline_port_out_params port_params = {
388a9de470cSBruce Richardson 			.ops = &rte_port_ring_writer_ops,
389a9de470cSBruce Richardson 			.arg_create = (void *) &port_ring_params,
390a9de470cSBruce Richardson 			.f_action = NULL,
391a9de470cSBruce Richardson 			.arg_ah = NULL,
392a9de470cSBruce Richardson 		};
393a9de470cSBruce Richardson 
394a9de470cSBruce Richardson 
395a9de470cSBruce Richardson 		if (rte_pipeline_port_out_create(p, &port_params,
396a9de470cSBruce Richardson 			&port_out_id[i])) {
397a9de470cSBruce Richardson 			rte_panic("Unable to configure output port %d\n", i);
398a9de470cSBruce Richardson 			goto fail;
399a9de470cSBruce Richardson 		}
400a9de470cSBruce Richardson 	}
401a9de470cSBruce Richardson 
402a9de470cSBruce Richardson 	/* Table configuration  */
403a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
404a9de470cSBruce Richardson 		struct rte_pipeline_table_params table_params;
405a9de470cSBruce Richardson 
406a9de470cSBruce Richardson 		/* Set up defaults for stub */
407a9de470cSBruce Richardson 		table_params.ops = &rte_table_stub_ops;
408a9de470cSBruce Richardson 		table_params.arg_create = NULL;
409a9de470cSBruce Richardson 		table_params.f_action_hit = action_handler_hit;
410a9de470cSBruce Richardson 		table_params.f_action_miss = NULL;
411a9de470cSBruce Richardson 		table_params.action_data_size = 0;
412a9de470cSBruce Richardson 
413*f541aa2dSStephen Hemminger 		printf("miss_action=%x\n",
414a9de470cSBruce Richardson 			table_entry_miss_action);
415a9de470cSBruce Richardson 
416a9de470cSBruce Richardson 		printf("RTE_ACL_RULE_SZ(%zu) = %zu\n", DIM(ipv4_defs),
417a9de470cSBruce Richardson 			RTE_ACL_RULE_SZ(DIM(ipv4_defs)));
418a9de470cSBruce Richardson 
419a9de470cSBruce Richardson 		struct rte_table_acl_params acl_params;
420a9de470cSBruce Richardson 
421a9de470cSBruce Richardson 		acl_params.n_rules = 1 << 5;
422a9de470cSBruce Richardson 		acl_params.n_rule_fields = DIM(ipv4_defs);
423a9de470cSBruce Richardson 		snprintf(acl_name, sizeof(acl_name), "ACL%d", i);
424a9de470cSBruce Richardson 		acl_params.name = acl_name;
425a9de470cSBruce Richardson 		memcpy(acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));
426a9de470cSBruce Richardson 
427a9de470cSBruce Richardson 		table_params.ops = &rte_table_acl_ops;
428a9de470cSBruce Richardson 		table_params.arg_create = &acl_params;
429a9de470cSBruce Richardson 
430a9de470cSBruce Richardson 		if (rte_pipeline_table_create(p, &table_params, &table_id[i])) {
431a9de470cSBruce Richardson 			rte_panic("Unable to configure table %u\n", i);
432a9de470cSBruce Richardson 			goto fail;
433a9de470cSBruce Richardson 		}
434a9de470cSBruce Richardson 
435a9de470cSBruce Richardson 		if (connect_miss_action_to_table) {
436a9de470cSBruce Richardson 			if (rte_pipeline_table_create(p, &table_params,
437a9de470cSBruce Richardson 				&table_id[i+2])) {
438a9de470cSBruce Richardson 				rte_panic("Unable to configure table %u\n", i);
439a9de470cSBruce Richardson 				goto fail;
440a9de470cSBruce Richardson 			}
441a9de470cSBruce Richardson 		}
442a9de470cSBruce Richardson 	}
443a9de470cSBruce Richardson 
444a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
445a9de470cSBruce Richardson 		if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
446a9de470cSBruce Richardson 			table_id[i])) {
447a9de470cSBruce Richardson 			rte_panic("Unable to connect input port %u to "
448a9de470cSBruce Richardson 				"table %u\n",
449a9de470cSBruce Richardson 				port_in_id[i],  table_id[i]);
450a9de470cSBruce Richardson 			goto fail;
451a9de470cSBruce Richardson 		}
452a9de470cSBruce Richardson 	}
453a9de470cSBruce Richardson 
454a9de470cSBruce Richardson 	/* Add bulk entries to tables */
455a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
456a9de470cSBruce Richardson 		struct rte_table_acl_rule_add_params keys[5];
457a9de470cSBruce Richardson 		struct rte_pipeline_table_entry entries[5];
458a9de470cSBruce Richardson 		struct rte_table_acl_rule_add_params *key_array[5];
459a9de470cSBruce Richardson 		struct rte_pipeline_table_entry *table_entries[5];
460a9de470cSBruce Richardson 		int key_found[5];
461a9de470cSBruce Richardson 		struct rte_pipeline_table_entry *table_entries_ptr[5];
462a9de470cSBruce Richardson 		struct rte_pipeline_table_entry entries_ptr[5];
463a9de470cSBruce Richardson 
464a9de470cSBruce Richardson 		parser = parse_cb_ipv4_rule;
465a9de470cSBruce Richardson 		for (n = 0; n < 5; n++) {
466a9de470cSBruce Richardson 			memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_add_params));
467a9de470cSBruce Richardson 			key_array[n] = &keys[n];
468a9de470cSBruce Richardson 
4696723c0fcSBruce Richardson 			strlcpy(line, lines[n], sizeof(line));
470a9de470cSBruce Richardson 			printf("PARSING [%s]\n", line);
471a9de470cSBruce Richardson 
472a9de470cSBruce Richardson 			ret = parser(line, &keys[n]);
473a9de470cSBruce Richardson 			if (ret != 0) {
474*f541aa2dSStephen Hemminger 				fprintf(stderr,
475*f541aa2dSStephen Hemminger 					"line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
476a9de470cSBruce Richardson 					n, ret, strerror(-ret));
477a9de470cSBruce Richardson 				return ret;
478a9de470cSBruce Richardson 			}
479a9de470cSBruce Richardson 
480a9de470cSBruce Richardson 			keys[n].priority = RTE_ACL_MAX_PRIORITY - n - 1;
481a9de470cSBruce Richardson 
482a9de470cSBruce Richardson 			entries[n].action = RTE_PIPELINE_ACTION_PORT;
483a9de470cSBruce Richardson 			entries[n].port_id = port_out_id[i^1];
484a9de470cSBruce Richardson 			table_entries[n] = &entries[n];
485a9de470cSBruce Richardson 			table_entries_ptr[n] = &entries_ptr[n];
486a9de470cSBruce Richardson 		}
487a9de470cSBruce Richardson 
488a9de470cSBruce Richardson 		ret = rte_pipeline_table_entry_add_bulk(p, table_id[i],
489a9de470cSBruce Richardson 				(void **)key_array, table_entries, 5, key_found, table_entries_ptr);
490a9de470cSBruce Richardson 		if (ret < 0) {
491a9de470cSBruce Richardson 			rte_panic("Add entry bulk to table %u failed (%d)\n",
492a9de470cSBruce Richardson 				table_id[i], ret);
493a9de470cSBruce Richardson 			goto fail;
494a9de470cSBruce Richardson 		}
495a9de470cSBruce Richardson 	}
496a9de470cSBruce Richardson 
497a9de470cSBruce Richardson 	/* Delete bulk entries from tables */
498a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
499a9de470cSBruce Richardson 		struct rte_table_acl_rule_delete_params keys[5];
500a9de470cSBruce Richardson 		struct rte_table_acl_rule_delete_params *key_array[5];
501a9de470cSBruce Richardson 		struct rte_pipeline_table_entry *table_entries[5];
502a9de470cSBruce Richardson 		int key_found[5];
503a9de470cSBruce Richardson 
504a9de470cSBruce Richardson 		memset(table_entries, 0, sizeof(table_entries));
505a9de470cSBruce Richardson 
506a9de470cSBruce Richardson 		for (n = 0; n < 5; n++) {
507a9de470cSBruce Richardson 			memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_delete_params));
508a9de470cSBruce Richardson 			key_array[n] = &keys[n];
509a9de470cSBruce Richardson 
5106723c0fcSBruce Richardson 			strlcpy(line, lines[n], sizeof(line));
511a9de470cSBruce Richardson 			printf("PARSING [%s]\n", line);
512a9de470cSBruce Richardson 
513a9de470cSBruce Richardson 			ret = parse_cb_ipv4_rule_del(line, &keys[n]);
514a9de470cSBruce Richardson 			if (ret != 0) {
515*f541aa2dSStephen Hemminger 				fprintf(stderr,
516*f541aa2dSStephen Hemminger 					"line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
517a9de470cSBruce Richardson 					n, ret, strerror(-ret));
518a9de470cSBruce Richardson 				return ret;
519a9de470cSBruce Richardson 			}
520a9de470cSBruce Richardson 		}
521a9de470cSBruce Richardson 
522a9de470cSBruce Richardson 		ret = rte_pipeline_table_entry_delete_bulk(p, table_id[i],
523a9de470cSBruce Richardson 			(void **)key_array, 5, key_found, table_entries);
524a9de470cSBruce Richardson 		if (ret < 0) {
525a9de470cSBruce Richardson 			rte_panic("Delete bulk entries from table %u failed (%d)\n",
526a9de470cSBruce Richardson 				table_id[i], ret);
527a9de470cSBruce Richardson 			goto fail;
528a9de470cSBruce Richardson 		} else
529a9de470cSBruce Richardson 			printf("Bulk deleted rules.\n");
530a9de470cSBruce Richardson 	}
531a9de470cSBruce Richardson 
532a9de470cSBruce Richardson 	/* Add entries to tables */
533a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
534a9de470cSBruce Richardson 		struct rte_pipeline_table_entry table_entry = {
535a9de470cSBruce Richardson 			.action = RTE_PIPELINE_ACTION_PORT,
536a9de470cSBruce Richardson 			{.port_id = port_out_id[i^1]},
537a9de470cSBruce Richardson 		};
538a9de470cSBruce Richardson 		int key_found;
539a9de470cSBruce Richardson 		struct rte_pipeline_table_entry *entry_ptr;
540a9de470cSBruce Richardson 
541a9de470cSBruce Richardson 		memset(&rule_params, 0, sizeof(rule_params));
542a9de470cSBruce Richardson 		parser = parse_cb_ipv4_rule;
543a9de470cSBruce Richardson 
544a9de470cSBruce Richardson 		for (n = 1; n <= 5; n++) {
5456723c0fcSBruce Richardson 			strlcpy(line, lines[n - 1], sizeof(line));
546a9de470cSBruce Richardson 			printf("PARSING [%s]\n", line);
547a9de470cSBruce Richardson 
548a9de470cSBruce Richardson 			ret = parser(line, &rule_params);
549a9de470cSBruce Richardson 			if (ret != 0) {
550*f541aa2dSStephen Hemminger 				fprintf(stderr,
551*f541aa2dSStephen Hemminger 					"line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
552a9de470cSBruce Richardson 					n, ret, strerror(-ret));
553a9de470cSBruce Richardson 				return ret;
554a9de470cSBruce Richardson 			}
555a9de470cSBruce Richardson 
556a9de470cSBruce Richardson 			rule_params.priority = RTE_ACL_MAX_PRIORITY - n;
557a9de470cSBruce Richardson 
558a9de470cSBruce Richardson 			ret = rte_pipeline_table_entry_add(p, table_id[i],
559a9de470cSBruce Richardson 				&rule_params,
560a9de470cSBruce Richardson 				&table_entry, &key_found, &entry_ptr);
561a9de470cSBruce Richardson 			if (ret < 0) {
562a9de470cSBruce Richardson 				rte_panic("Add entry to table %u failed (%d)\n",
563a9de470cSBruce Richardson 					table_id[i], ret);
564a9de470cSBruce Richardson 				goto fail;
565a9de470cSBruce Richardson 			}
566a9de470cSBruce Richardson 		}
567a9de470cSBruce Richardson 
568a9de470cSBruce Richardson 		/* delete a few rules */
569a9de470cSBruce Richardson 		for (n = 2; n <= 3; n++) {
5706723c0fcSBruce Richardson 			strlcpy(line, lines[n - 1], sizeof(line));
571a9de470cSBruce Richardson 			printf("PARSING [%s]\n", line);
572a9de470cSBruce Richardson 
573a9de470cSBruce Richardson 			ret = parser(line, &rule_params);
574a9de470cSBruce Richardson 			if (ret != 0) {
575*f541aa2dSStephen Hemminger 				fprintf(stderr,
576*f541aa2dSStephen Hemminger 					"line %u: parse rule failed, error code: %d (%s)\n",
577a9de470cSBruce Richardson 					n, ret, strerror(-ret));
578a9de470cSBruce Richardson 				return ret;
579a9de470cSBruce Richardson 			}
580a9de470cSBruce Richardson 
581a9de470cSBruce Richardson 			delete_params = (struct
582a9de470cSBruce Richardson 				rte_pipeline_table_acl_rule_delete_params *)
583a9de470cSBruce Richardson 				&(rule_params.field_value[0]);
584a9de470cSBruce Richardson 			ret = rte_pipeline_table_entry_delete(p, table_id[i],
585a9de470cSBruce Richardson 				delete_params, &key_found, NULL);
586a9de470cSBruce Richardson 			if (ret < 0) {
587a9de470cSBruce Richardson 				rte_panic("Add entry to table %u failed (%d)\n",
588a9de470cSBruce Richardson 					table_id[i], ret);
589a9de470cSBruce Richardson 				goto fail;
590a9de470cSBruce Richardson 			} else
591a9de470cSBruce Richardson 				printf("Deleted Rule.\n");
592a9de470cSBruce Richardson 		}
593a9de470cSBruce Richardson 
594a9de470cSBruce Richardson 
595a9de470cSBruce Richardson 		/* Try to add duplicates */
596a9de470cSBruce Richardson 		for (n = 1; n <= 5; n++) {
5976723c0fcSBruce Richardson 			strlcpy(line, lines[n - 1], sizeof(line));
598a9de470cSBruce Richardson 			printf("PARSING [%s]\n", line);
599a9de470cSBruce Richardson 
600a9de470cSBruce Richardson 			ret = parser(line, &rule_params);
601a9de470cSBruce Richardson 			if (ret != 0) {
602*f541aa2dSStephen Hemminger 				fprintf(stderr,
603*f541aa2dSStephen Hemminger 					"line %u: parse rule failed, error code: %d (%s)\n",
604a9de470cSBruce Richardson 					n, ret, strerror(-ret));
605a9de470cSBruce Richardson 				return ret;
606a9de470cSBruce Richardson 			}
607a9de470cSBruce Richardson 
608a9de470cSBruce Richardson 			rule_params.priority = RTE_ACL_MAX_PRIORITY - n;
609a9de470cSBruce Richardson 
610a9de470cSBruce Richardson 			ret = rte_pipeline_table_entry_add(p, table_id[i],
611a9de470cSBruce Richardson 				&rule_params,
612a9de470cSBruce Richardson 				&table_entry, &key_found, &entry_ptr);
613a9de470cSBruce Richardson 			if (ret < 0) {
614a9de470cSBruce Richardson 				rte_panic("Add entry to table %u failed (%d)\n",
615a9de470cSBruce Richardson 					table_id[i], ret);
616a9de470cSBruce Richardson 				goto fail;
617a9de470cSBruce Richardson 			}
618a9de470cSBruce Richardson 		}
619a9de470cSBruce Richardson 	}
620a9de470cSBruce Richardson 
621a9de470cSBruce Richardson 	/* Enable input ports */
622a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS ; i++)
623a9de470cSBruce Richardson 		if (rte_pipeline_port_in_enable(p, port_in_id[i]))
624a9de470cSBruce Richardson 			rte_panic("Unable to enable input port %u\n",
625a9de470cSBruce Richardson 				port_in_id[i]);
626a9de470cSBruce Richardson 
627a9de470cSBruce Richardson 	/* Check pipeline consistency */
628a9de470cSBruce Richardson 	if (rte_pipeline_check(p) < 0) {
629a9de470cSBruce Richardson 		rte_panic("Pipeline consistency check failed\n");
630a9de470cSBruce Richardson 		goto fail;
631a9de470cSBruce Richardson 	}
632a9de470cSBruce Richardson 
633a9de470cSBruce Richardson 	return  0;
634a9de470cSBruce Richardson fail:
635a9de470cSBruce Richardson 
636a9de470cSBruce Richardson 	return -1;
637a9de470cSBruce Richardson }
638a9de470cSBruce Richardson 
639a9de470cSBruce Richardson static int
test_pipeline_single_filter(int expected_count)640a9de470cSBruce Richardson test_pipeline_single_filter(int expected_count)
641a9de470cSBruce Richardson {
642a9de470cSBruce Richardson 	int i, j, ret, tx_count;
643a9de470cSBruce Richardson 	struct ipv4_5tuple five_tuple;
644a9de470cSBruce Richardson 
645a9de470cSBruce Richardson 	/* Allocate a few mbufs and manually insert into the rings. */
646a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
647a9de470cSBruce Richardson 		for (j = 0; j < 8; j++) {
648a9de470cSBruce Richardson 			struct rte_mbuf *mbuf;
649a9de470cSBruce Richardson 
650a9de470cSBruce Richardson 			mbuf = rte_pktmbuf_alloc(pool);
651a9de470cSBruce Richardson 			if (mbuf == NULL)
652a9de470cSBruce Richardson 				/* this will cause test failure after cleanup
653a9de470cSBruce Richardson 				 * of already enqueued mbufs, as the mbuf
654a9de470cSBruce Richardson 				 * counts won't match */
655a9de470cSBruce Richardson 				break;
656a9de470cSBruce Richardson 			memset(rte_pktmbuf_mtod(mbuf, char *), 0x00,
657a9de470cSBruce Richardson 				sizeof(struct ipv4_5tuple));
658a9de470cSBruce Richardson 
659a9de470cSBruce Richardson 			five_tuple.proto = j;
6600c9da755SDavid Marchand 			five_tuple.ip_src = rte_bswap32(RTE_IPV4(192, 168, j, 1));
6610c9da755SDavid Marchand 			five_tuple.ip_dst = rte_bswap32(RTE_IPV4(10, 4, j, 1));
662a9de470cSBruce Richardson 			five_tuple.port_src = rte_bswap16(100 + j);
663a9de470cSBruce Richardson 			five_tuple.port_dst = rte_bswap16(200 + j);
664a9de470cSBruce Richardson 
665a9de470cSBruce Richardson 			memcpy(rte_pktmbuf_mtod(mbuf, char *), &five_tuple,
666a9de470cSBruce Richardson 				sizeof(struct ipv4_5tuple));
667*f541aa2dSStephen Hemminger 			printf("%s: Enqueue onto ring %d\n",
668a9de470cSBruce Richardson 				__func__, i);
669a9de470cSBruce Richardson 			rte_ring_enqueue(rings_rx[i], mbuf);
670a9de470cSBruce Richardson 		}
671a9de470cSBruce Richardson 	}
672a9de470cSBruce Richardson 
673a9de470cSBruce Richardson 	/* Run pipeline once */
674a9de470cSBruce Richardson 	for (i = 0; i< N_PORTS; i++)
675a9de470cSBruce Richardson 		rte_pipeline_run(p);
676a9de470cSBruce Richardson 
677a9de470cSBruce Richardson 	rte_pipeline_flush(p);
678a9de470cSBruce Richardson 
679a9de470cSBruce Richardson 	tx_count = 0;
680a9de470cSBruce Richardson 
681a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
682a9de470cSBruce Richardson 		void *objs[RING_TX_SIZE];
683a9de470cSBruce Richardson 		struct rte_mbuf *mbuf;
684a9de470cSBruce Richardson 
685a9de470cSBruce Richardson 		ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL);
686a9de470cSBruce Richardson 		if (ret <= 0) {
687a9de470cSBruce Richardson 			printf("Got no objects from ring %d - error code %d\n",
688a9de470cSBruce Richardson 				i, ret);
689a9de470cSBruce Richardson 		} else {
690a9de470cSBruce Richardson 			printf("Got %d object(s) from ring %d!\n", ret, i);
691a9de470cSBruce Richardson 			for (j = 0; j < ret; j++) {
692a9de470cSBruce Richardson 				mbuf = objs[j];
693a9de470cSBruce Richardson 				rte_hexdump(stdout, "mbuf",
694a9de470cSBruce Richardson 					rte_pktmbuf_mtod(mbuf, char *), 64);
695a9de470cSBruce Richardson 				rte_pktmbuf_free(mbuf);
696a9de470cSBruce Richardson 			}
697a9de470cSBruce Richardson 			tx_count += ret;
698a9de470cSBruce Richardson 		}
699a9de470cSBruce Richardson 	}
700a9de470cSBruce Richardson 
701a9de470cSBruce Richardson 	if (tx_count != expected_count) {
702*f541aa2dSStephen Hemminger 		fprintf(stderr,
703*f541aa2dSStephen Hemminger 			"%s: Unexpected packets for ACL test, expected %d, got %d\n",
704a9de470cSBruce Richardson 			__func__, expected_count, tx_count);
705a9de470cSBruce Richardson 		goto fail;
706a9de470cSBruce Richardson 	}
707a9de470cSBruce Richardson 
708a9de470cSBruce Richardson 	rte_pipeline_free(p);
709a9de470cSBruce Richardson 
710a9de470cSBruce Richardson 	return  0;
711a9de470cSBruce Richardson fail:
712a9de470cSBruce Richardson 	return -1;
713a9de470cSBruce Richardson 
714a9de470cSBruce Richardson }
715a9de470cSBruce Richardson 
716a9de470cSBruce Richardson int
test_table_acl(void)717a9de470cSBruce Richardson test_table_acl(void)
718a9de470cSBruce Richardson {
719a9de470cSBruce Richardson 
720a9de470cSBruce Richardson 
721a9de470cSBruce Richardson 	override_hit_mask = 0xFF; /* All packets are a hit */
722a9de470cSBruce Richardson 
723a9de470cSBruce Richardson 	setup_acl_pipeline();
724a9de470cSBruce Richardson 	if (test_pipeline_single_filter(10) < 0)
725a9de470cSBruce Richardson 		return -1;
726a9de470cSBruce Richardson 
727a9de470cSBruce Richardson 	return 0;
728a9de470cSBruce Richardson }
7293c60274cSJie Zhou 
7303c60274cSJie Zhou #endif /* !RTE_EXEC_ENV_WINDOWS */
731