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