xref: /dpdk/app/test/test_table_pipeline.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 
7a9de470cSBruce Richardson #include <string.h>
8a9de470cSBruce Richardson #include <rte_pipeline.h>
9a9de470cSBruce Richardson #include <inttypes.h>
10a9de470cSBruce Richardson #include <rte_hexdump.h>
11a9de470cSBruce Richardson #include "test_table.h"
12a9de470cSBruce Richardson #include "test_table_pipeline.h"
13a9de470cSBruce Richardson 
14a9de470cSBruce Richardson #if 0
15a9de470cSBruce Richardson 
16a9de470cSBruce Richardson static rte_pipeline_port_out_action_handler port_action_0x00
17a9de470cSBruce Richardson 	(struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
18a9de470cSBruce Richardson static rte_pipeline_port_out_action_handler port_action_0xFF
19a9de470cSBruce Richardson 	(struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
20a9de470cSBruce Richardson static rte_pipeline_port_out_action_handler port_action_stub
21a9de470cSBruce Richardson 	(struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
22a9de470cSBruce Richardson 
23a9de470cSBruce Richardson 
24a9de470cSBruce Richardson rte_pipeline_port_out_action_handler port_action_0x00(struct rte_mbuf **pkts,
25a9de470cSBruce Richardson 	uint32_t n,
26a9de470cSBruce Richardson 	uint64_t *pkts_mask,
27a9de470cSBruce Richardson 	void *arg)
28a9de470cSBruce Richardson {
29a9de470cSBruce Richardson 	RTE_SET_USED(pkts);
30a9de470cSBruce Richardson 	RTE_SET_USED(n);
31a9de470cSBruce Richardson 	RTE_SET_USED(arg);
32a9de470cSBruce Richardson 	printf("Port Action 0x00\n");
33a9de470cSBruce Richardson 	*pkts_mask = 0x00;
34a9de470cSBruce Richardson 	return 0;
35a9de470cSBruce Richardson }
36a9de470cSBruce Richardson 
37a9de470cSBruce Richardson rte_pipeline_port_out_action_handler port_action_0xFF(struct rte_mbuf **pkts,
38a9de470cSBruce Richardson 	uint32_t n,
39a9de470cSBruce Richardson 	uint64_t *pkts_mask,
40a9de470cSBruce Richardson 	void *arg)
41a9de470cSBruce Richardson {
42a9de470cSBruce Richardson 	RTE_SET_USED(pkts);
43a9de470cSBruce Richardson 	RTE_SET_USED(n);
44a9de470cSBruce Richardson 	RTE_SET_USED(arg);
45a9de470cSBruce Richardson 	printf("Port Action 0xFF\n");
46a9de470cSBruce Richardson 	*pkts_mask = 0xFF;
47a9de470cSBruce Richardson 	return 0;
48a9de470cSBruce Richardson }
49a9de470cSBruce Richardson 
50a9de470cSBruce Richardson rte_pipeline_port_out_action_handler port_action_stub(struct rte_mbuf **pkts,
51a9de470cSBruce Richardson 	uint32_t n,
52a9de470cSBruce Richardson 	uint64_t *pkts_mask,
53a9de470cSBruce Richardson 	void *arg)
54a9de470cSBruce Richardson {
55a9de470cSBruce Richardson 	RTE_SET_USED(pkts);
56a9de470cSBruce Richardson 	RTE_SET_USED(n);
57a9de470cSBruce Richardson 	RTE_SET_USED(pkts_mask);
58a9de470cSBruce Richardson 	RTE_SET_USED(arg);
59a9de470cSBruce Richardson 	printf("Port Action stub\n");
60a9de470cSBruce Richardson 	return 0;
61a9de470cSBruce Richardson }
62a9de470cSBruce Richardson 
63a9de470cSBruce Richardson #endif
64a9de470cSBruce Richardson 
65a9de470cSBruce Richardson rte_pipeline_table_action_handler_hit
66a9de470cSBruce Richardson table_action_0x00(struct rte_pipeline *p, struct rte_mbuf **pkts,
67a9de470cSBruce Richardson 	uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
68a9de470cSBruce Richardson 
69a9de470cSBruce Richardson rte_pipeline_table_action_handler_hit
70a9de470cSBruce Richardson table_action_stub_hit(struct rte_pipeline *p, struct rte_mbuf **pkts,
71a9de470cSBruce Richardson 	uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
72a9de470cSBruce Richardson 
73a9de470cSBruce Richardson static int
74a9de470cSBruce Richardson table_action_stub_miss(struct rte_pipeline *p, struct rte_mbuf **pkts,
75a9de470cSBruce Richardson 	uint64_t pkts_mask, struct rte_pipeline_table_entry *entry, void *arg);
76a9de470cSBruce Richardson 
77a9de470cSBruce Richardson rte_pipeline_table_action_handler_hit
table_action_0x00(__rte_unused struct rte_pipeline * p,__rte_unused struct rte_mbuf ** pkts,uint64_t pkts_mask,__rte_unused struct rte_pipeline_table_entry ** entry,__rte_unused void * arg)78f2fc83b4SThomas Monjalon table_action_0x00(__rte_unused struct rte_pipeline *p,
79f2fc83b4SThomas Monjalon 	__rte_unused struct rte_mbuf **pkts,
80a9de470cSBruce Richardson 	uint64_t pkts_mask,
81f2fc83b4SThomas Monjalon 	__rte_unused struct rte_pipeline_table_entry **entry,
82f2fc83b4SThomas Monjalon 	__rte_unused void *arg)
83a9de470cSBruce Richardson {
84a9de470cSBruce Richardson 	printf("Table Action, setting pkts_mask to 0x00\n");
85a9de470cSBruce Richardson 	pkts_mask = ~0x00;
86a9de470cSBruce Richardson 	rte_pipeline_ah_packet_drop(p, pkts_mask);
87a9de470cSBruce Richardson 	return 0;
88a9de470cSBruce Richardson }
89a9de470cSBruce Richardson 
90a9de470cSBruce Richardson rte_pipeline_table_action_handler_hit
table_action_stub_hit(__rte_unused struct rte_pipeline * p,__rte_unused struct rte_mbuf ** pkts,uint64_t pkts_mask,__rte_unused struct rte_pipeline_table_entry ** entry,__rte_unused void * arg)91f2fc83b4SThomas Monjalon table_action_stub_hit(__rte_unused struct rte_pipeline *p,
92f2fc83b4SThomas Monjalon 	__rte_unused struct rte_mbuf **pkts,
93a9de470cSBruce Richardson 	uint64_t pkts_mask,
94f2fc83b4SThomas Monjalon 	__rte_unused struct rte_pipeline_table_entry **entry,
95f2fc83b4SThomas Monjalon 	__rte_unused void *arg)
96a9de470cSBruce Richardson {
97a9de470cSBruce Richardson 	printf("STUB Table Action Hit - doing nothing\n");
98a9de470cSBruce Richardson 	printf("STUB Table Action Hit - setting mask to 0x%"PRIx64"\n",
99a9de470cSBruce Richardson 		override_hit_mask);
100a9de470cSBruce Richardson 	pkts_mask = (~override_hit_mask) & 0x3;
101a9de470cSBruce Richardson 	rte_pipeline_ah_packet_drop(p, pkts_mask);
102a9de470cSBruce Richardson 	return 0;
103a9de470cSBruce Richardson }
104a9de470cSBruce Richardson 
105a9de470cSBruce Richardson static int
table_action_stub_miss(struct rte_pipeline * p,__rte_unused struct rte_mbuf ** pkts,uint64_t pkts_mask,__rte_unused struct rte_pipeline_table_entry * entry,__rte_unused void * arg)106a9de470cSBruce Richardson table_action_stub_miss(struct rte_pipeline *p,
107f2fc83b4SThomas Monjalon 	__rte_unused struct rte_mbuf **pkts,
108a9de470cSBruce Richardson 	uint64_t pkts_mask,
109f2fc83b4SThomas Monjalon 	__rte_unused struct rte_pipeline_table_entry *entry,
110f2fc83b4SThomas Monjalon 	__rte_unused void *arg)
111a9de470cSBruce Richardson {
112a9de470cSBruce Richardson 	printf("STUB Table Action Miss - setting mask to 0x%"PRIx64"\n",
113a9de470cSBruce Richardson 		override_miss_mask);
114a9de470cSBruce Richardson 	pkts_mask = (~override_miss_mask) & 0x3;
115a9de470cSBruce Richardson 	rte_pipeline_ah_packet_drop(p, pkts_mask);
116a9de470cSBruce Richardson 	return 0;
117a9de470cSBruce Richardson }
118a9de470cSBruce Richardson 
119a9de470cSBruce Richardson enum e_test_type {
120a9de470cSBruce Richardson 	e_TEST_STUB = 0,
121a9de470cSBruce Richardson 	e_TEST_LPM,
122a9de470cSBruce Richardson 	e_TEST_LPM6,
123a9de470cSBruce Richardson 	e_TEST_HASH_LRU_8,
124a9de470cSBruce Richardson 	e_TEST_HASH_LRU_16,
125a9de470cSBruce Richardson 	e_TEST_HASH_LRU_32,
126a9de470cSBruce Richardson 	e_TEST_HASH_EXT_8,
127a9de470cSBruce Richardson 	e_TEST_HASH_EXT_16,
128a9de470cSBruce Richardson 	e_TEST_HASH_EXT_32
129a9de470cSBruce Richardson };
130a9de470cSBruce Richardson 
131a9de470cSBruce Richardson char pipeline_test_names[][64] = {
132a9de470cSBruce Richardson 	"Stub",
133a9de470cSBruce Richardson 	"LPM",
134a9de470cSBruce Richardson 	"LPMv6",
135a9de470cSBruce Richardson 	"8-bit LRU Hash",
136a9de470cSBruce Richardson 	"16-bit LRU Hash",
137a9de470cSBruce Richardson 	"32-bit LRU Hash",
138a9de470cSBruce Richardson 	"16-bit Ext Hash",
139a9de470cSBruce Richardson 	"8-bit Ext Hash",
140a9de470cSBruce Richardson 	"32-bit Ext Hash",
141a9de470cSBruce Richardson 	""
142a9de470cSBruce Richardson };
143a9de470cSBruce Richardson 
144a9de470cSBruce Richardson 
145a9de470cSBruce Richardson static int
cleanup_pipeline(void)146a9de470cSBruce Richardson cleanup_pipeline(void)
147a9de470cSBruce Richardson {
148a9de470cSBruce Richardson 
149a9de470cSBruce Richardson 	rte_pipeline_free(p);
150a9de470cSBruce Richardson 
151a9de470cSBruce Richardson 	return 0;
152a9de470cSBruce Richardson }
153a9de470cSBruce Richardson 
154a9de470cSBruce Richardson 
155a9de470cSBruce Richardson static int check_pipeline_invalid_params(void);
156a9de470cSBruce Richardson 
157a9de470cSBruce Richardson static int
check_pipeline_invalid_params(void)158a9de470cSBruce Richardson check_pipeline_invalid_params(void)
159a9de470cSBruce Richardson {
160a9de470cSBruce Richardson 	struct rte_pipeline_params pipeline_params_1 = {
161a9de470cSBruce Richardson 		.name = NULL,
162a9de470cSBruce Richardson 		.socket_id = 0,
163a9de470cSBruce Richardson 	};
164a9de470cSBruce Richardson 	struct rte_pipeline_params pipeline_params_2 = {
165a9de470cSBruce Richardson 		.name = "PIPELINE",
166a9de470cSBruce Richardson 		.socket_id = -1,
167a9de470cSBruce Richardson 	};
168a9de470cSBruce Richardson 	struct rte_pipeline_params pipeline_params_3 = {
169a9de470cSBruce Richardson 		.name = "PIPELINE",
170a9de470cSBruce Richardson 		.socket_id = 127,
171a9de470cSBruce Richardson 	};
172a9de470cSBruce Richardson 
173a9de470cSBruce Richardson 	p = rte_pipeline_create(NULL);
174a9de470cSBruce Richardson 	if (p != NULL) {
175*f541aa2dSStephen Hemminger 		fprintf(stderr,
176a9de470cSBruce Richardson 			"%s: configured pipeline with null params\n",
177a9de470cSBruce Richardson 			__func__);
178a9de470cSBruce Richardson 		goto fail;
179a9de470cSBruce Richardson 	}
180a9de470cSBruce Richardson 	p = rte_pipeline_create(&pipeline_params_1);
181a9de470cSBruce Richardson 	if (p != NULL) {
182*f541aa2dSStephen Hemminger 		fprintf(stderr,
183*f541aa2dSStephen Hemminger 			"%s: Configure pipeline with NULL name\n", __func__);
184a9de470cSBruce Richardson 		goto fail;
185a9de470cSBruce Richardson 	}
186a9de470cSBruce Richardson 
187a9de470cSBruce Richardson 	p = rte_pipeline_create(&pipeline_params_2);
188a9de470cSBruce Richardson 	if (p != NULL) {
189*f541aa2dSStephen Hemminger 		fprintf(stderr,
190*f541aa2dSStephen Hemminger 			"%s: Configure pipeline with invalid socket\n", __func__);
191a9de470cSBruce Richardson 		goto fail;
192a9de470cSBruce Richardson 	}
193a9de470cSBruce Richardson 
19427fb5dd2SRuifeng Wang 	if (rte_eal_has_hugepages()) {
195a9de470cSBruce Richardson 		p = rte_pipeline_create(&pipeline_params_3);
196a9de470cSBruce Richardson 		if (p != NULL) {
197*f541aa2dSStephen Hemminger 			fprintf(stderr,
198*f541aa2dSStephen Hemminger 				"%s: Configure pipeline with invalid socket\n",
199*f541aa2dSStephen Hemminger 				__func__);
200a9de470cSBruce Richardson 			goto fail;
201a9de470cSBruce Richardson 		}
20227fb5dd2SRuifeng Wang 	}
203a9de470cSBruce Richardson 
204a9de470cSBruce Richardson 	/* Check pipeline consistency */
205a9de470cSBruce Richardson 	if (!rte_pipeline_check(p)) {
206a9de470cSBruce Richardson 		rte_panic("Pipeline consistency reported as OK\n");
207a9de470cSBruce Richardson 		goto fail;
208a9de470cSBruce Richardson 	}
209a9de470cSBruce Richardson 
210a9de470cSBruce Richardson 
211a9de470cSBruce Richardson 	return 0;
212a9de470cSBruce Richardson fail:
213a9de470cSBruce Richardson 	return -1;
214a9de470cSBruce Richardson }
215a9de470cSBruce Richardson 
216a9de470cSBruce Richardson 
217a9de470cSBruce Richardson static int
setup_pipeline(int test_type)218a9de470cSBruce Richardson setup_pipeline(int test_type)
219a9de470cSBruce Richardson {
220a9de470cSBruce Richardson 	int ret;
221a9de470cSBruce Richardson 	int i;
222a9de470cSBruce Richardson 	struct rte_pipeline_params pipeline_params = {
223a9de470cSBruce Richardson 		.name = "PIPELINE",
224a9de470cSBruce Richardson 		.socket_id = 0,
225a9de470cSBruce Richardson 	};
226a9de470cSBruce Richardson 
227*f541aa2dSStephen Hemminger 	fprintf(stderr, "%s: **** Setting up %s test\n",
228a9de470cSBruce Richardson 		__func__, pipeline_test_names[test_type]);
229a9de470cSBruce Richardson 
230a9de470cSBruce Richardson 	/* Pipeline configuration */
231a9de470cSBruce Richardson 	p = rte_pipeline_create(&pipeline_params);
232a9de470cSBruce Richardson 	if (p == NULL) {
233*f541aa2dSStephen Hemminger 		fprintf(stderr, "%s: Failed to configure pipeline\n",
234a9de470cSBruce Richardson 			__func__);
235a9de470cSBruce Richardson 		goto fail;
236a9de470cSBruce Richardson 	}
237a9de470cSBruce Richardson 
238a9de470cSBruce Richardson 	ret = rte_pipeline_free(p);
239a9de470cSBruce Richardson 	if (ret != 0) {
240*f541aa2dSStephen Hemminger 		fprintf(stderr, "%s: Failed to free pipeline\n",
241a9de470cSBruce Richardson 			__func__);
242a9de470cSBruce Richardson 		goto fail;
243a9de470cSBruce Richardson 	}
244a9de470cSBruce Richardson 
245a9de470cSBruce Richardson 	/* Pipeline configuration */
246a9de470cSBruce Richardson 	p = rte_pipeline_create(&pipeline_params);
247a9de470cSBruce Richardson 	if (p == NULL) {
248*f541aa2dSStephen Hemminger 		fprintf(stderr, "%s: Failed to configure pipeline\n",
249a9de470cSBruce Richardson 			__func__);
250a9de470cSBruce Richardson 		goto fail;
251a9de470cSBruce Richardson 	}
252a9de470cSBruce Richardson 
253a9de470cSBruce Richardson 
254a9de470cSBruce Richardson 	/* Input port configuration */
255a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
256a9de470cSBruce Richardson 		struct rte_port_ring_reader_params port_ring_params = {
257a9de470cSBruce Richardson 			.ring = rings_rx[i],
258a9de470cSBruce Richardson 		};
259a9de470cSBruce Richardson 
260a9de470cSBruce Richardson 		struct rte_pipeline_port_in_params port_params = {
261a9de470cSBruce Richardson 			.ops = &rte_port_ring_reader_ops,
262a9de470cSBruce Richardson 			.arg_create = (void *) &port_ring_params,
263a9de470cSBruce Richardson 			.f_action = NULL,
264a9de470cSBruce Richardson 			.burst_size = BURST_SIZE,
265a9de470cSBruce Richardson 		};
266a9de470cSBruce Richardson 
267a9de470cSBruce Richardson 		/* Put in action for some ports */
268a9de470cSBruce Richardson 		if (i)
269a9de470cSBruce Richardson 			port_params.f_action = NULL;
270a9de470cSBruce Richardson 
271a9de470cSBruce Richardson 		ret = rte_pipeline_port_in_create(p, &port_params,
272a9de470cSBruce Richardson 			&port_in_id[i]);
273a9de470cSBruce Richardson 		if (ret) {
274a9de470cSBruce Richardson 			rte_panic("Unable to configure input port %d, ret:%d\n",
275a9de470cSBruce Richardson 				i, ret);
276a9de470cSBruce Richardson 			goto fail;
277a9de470cSBruce Richardson 		}
278a9de470cSBruce Richardson 	}
279a9de470cSBruce Richardson 
280a9de470cSBruce Richardson 	/* output Port configuration */
281a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
282a9de470cSBruce Richardson 		struct rte_port_ring_writer_params port_ring_params = {
283a9de470cSBruce Richardson 			.ring = rings_tx[i],
284a9de470cSBruce Richardson 			.tx_burst_sz = BURST_SIZE,
285a9de470cSBruce Richardson 		};
286a9de470cSBruce Richardson 
287a9de470cSBruce Richardson 		struct rte_pipeline_port_out_params port_params = {
288a9de470cSBruce Richardson 			.ops = &rte_port_ring_writer_ops,
289a9de470cSBruce Richardson 			.arg_create = (void *) &port_ring_params,
290a9de470cSBruce Richardson 			.f_action = NULL,
291a9de470cSBruce Richardson 			.arg_ah = NULL,
292a9de470cSBruce Richardson 		};
293a9de470cSBruce Richardson 
294a9de470cSBruce Richardson 		if (i)
295a9de470cSBruce Richardson 			port_params.f_action = port_out_action;
296a9de470cSBruce Richardson 
297a9de470cSBruce Richardson 		if (rte_pipeline_port_out_create(p, &port_params,
298a9de470cSBruce Richardson 			&port_out_id[i])) {
299a9de470cSBruce Richardson 			rte_panic("Unable to configure output port %d\n", i);
300a9de470cSBruce Richardson 			goto fail;
301a9de470cSBruce Richardson 		}
302a9de470cSBruce Richardson 	}
303a9de470cSBruce Richardson 
304a9de470cSBruce Richardson 	/* Table configuration  */
305a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
306a9de470cSBruce Richardson 		struct rte_pipeline_table_params table_params = {
307a9de470cSBruce Richardson 				.ops = &rte_table_stub_ops,
308a9de470cSBruce Richardson 				.arg_create = NULL,
309a9de470cSBruce Richardson 				.f_action_hit = action_handler_hit,
310a9de470cSBruce Richardson 				.f_action_miss = action_handler_miss,
311a9de470cSBruce Richardson 				.action_data_size = 0,
312a9de470cSBruce Richardson 		};
313a9de470cSBruce Richardson 
314a9de470cSBruce Richardson 		if (rte_pipeline_table_create(p, &table_params, &table_id[i])) {
315a9de470cSBruce Richardson 			rte_panic("Unable to configure table %u\n", i);
316a9de470cSBruce Richardson 			goto fail;
317a9de470cSBruce Richardson 		}
318a9de470cSBruce Richardson 
319a9de470cSBruce Richardson 		if (connect_miss_action_to_table)
320a9de470cSBruce Richardson 			if (rte_pipeline_table_create(p, &table_params,
321a9de470cSBruce Richardson 				&table_id[i+2])) {
322a9de470cSBruce Richardson 				rte_panic("Unable to configure table %u\n", i);
323a9de470cSBruce Richardson 				goto fail;
324a9de470cSBruce Richardson 			}
325a9de470cSBruce Richardson 	}
326a9de470cSBruce Richardson 
327a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++)
328a9de470cSBruce Richardson 		if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
329a9de470cSBruce Richardson 			table_id[i])) {
330a9de470cSBruce Richardson 			rte_panic("Unable to connect input port %u to "
331a9de470cSBruce Richardson 				"table %u\n", port_in_id[i],  table_id[i]);
332a9de470cSBruce Richardson 			goto fail;
333a9de470cSBruce Richardson 		}
334a9de470cSBruce Richardson 
335a9de470cSBruce Richardson 	/* Add entries to tables */
336a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
337a9de470cSBruce Richardson 		struct rte_pipeline_table_entry default_entry = {
338a9de470cSBruce Richardson 			.action = (enum rte_pipeline_action)
339a9de470cSBruce Richardson 				table_entry_default_action,
340a9de470cSBruce Richardson 			{.port_id = port_out_id[i^1]},
341a9de470cSBruce Richardson 		};
342a9de470cSBruce Richardson 		struct rte_pipeline_table_entry *default_entry_ptr;
343a9de470cSBruce Richardson 
344a9de470cSBruce Richardson 		if (connect_miss_action_to_table) {
345a9de470cSBruce Richardson 			printf("Setting first table to output to next table\n");
346a9de470cSBruce Richardson 			default_entry.action = RTE_PIPELINE_ACTION_TABLE;
347a9de470cSBruce Richardson 			default_entry.table_id = table_id[i+2];
348a9de470cSBruce Richardson 		}
349a9de470cSBruce Richardson 
350a9de470cSBruce Richardson 		/* Add the default action for the table. */
351a9de470cSBruce Richardson 		ret = rte_pipeline_table_default_entry_add(p, table_id[i],
352a9de470cSBruce Richardson 			&default_entry, &default_entry_ptr);
353a9de470cSBruce Richardson 		if (ret < 0) {
354a9de470cSBruce Richardson 			rte_panic("Unable to add default entry to table %u "
355a9de470cSBruce Richardson 				"code %d\n", table_id[i], ret);
356a9de470cSBruce Richardson 			goto fail;
357a9de470cSBruce Richardson 		} else
358a9de470cSBruce Richardson 			printf("Added default entry to table id %d with "
359a9de470cSBruce Richardson 				"action %x\n",
360a9de470cSBruce Richardson 				table_id[i], default_entry.action);
361a9de470cSBruce Richardson 
362a9de470cSBruce Richardson 		if (connect_miss_action_to_table) {
363a9de470cSBruce Richardson 			/* We create a second table so the first can pass
364a9de470cSBruce Richardson 			traffic into it */
365a9de470cSBruce Richardson 			struct rte_pipeline_table_entry default_entry = {
366a9de470cSBruce Richardson 				.action = RTE_PIPELINE_ACTION_PORT,
367a9de470cSBruce Richardson 				{.port_id = port_out_id[i^1]},
368a9de470cSBruce Richardson 			};
3697be78d02SJosh Soref 			printf("Setting second table to output to port\n");
370a9de470cSBruce Richardson 
371a9de470cSBruce Richardson 			/* Add the default action for the table. */
372a9de470cSBruce Richardson 			ret = rte_pipeline_table_default_entry_add(p,
373a9de470cSBruce Richardson 				table_id[i+2],
374a9de470cSBruce Richardson 				&default_entry, &default_entry_ptr);
375a9de470cSBruce Richardson 			if (ret < 0) {
376a9de470cSBruce Richardson 				rte_panic("Unable to add default entry to "
377a9de470cSBruce Richardson 					"table %u code %d\n",
378a9de470cSBruce Richardson 					table_id[i], ret);
379a9de470cSBruce Richardson 				goto fail;
380a9de470cSBruce Richardson 			} else
381a9de470cSBruce Richardson 				printf("Added default entry to table id %d "
382a9de470cSBruce Richardson 					"with action %x\n",
383a9de470cSBruce Richardson 					table_id[i], default_entry.action);
384a9de470cSBruce Richardson 		}
385a9de470cSBruce Richardson 	}
386a9de470cSBruce Richardson 
387a9de470cSBruce Richardson 	/* Enable input ports */
388a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS ; i++)
389a9de470cSBruce Richardson 		if (rte_pipeline_port_in_enable(p, port_in_id[i]))
390a9de470cSBruce Richardson 			rte_panic("Unable to enable input port %u\n",
391a9de470cSBruce Richardson 				port_in_id[i]);
392a9de470cSBruce Richardson 
393a9de470cSBruce Richardson 	/* Check pipeline consistency */
394a9de470cSBruce Richardson 	if (rte_pipeline_check(p) < 0) {
395a9de470cSBruce Richardson 		rte_panic("Pipeline consistency check failed\n");
396a9de470cSBruce Richardson 		goto fail;
397a9de470cSBruce Richardson 	} else
398a9de470cSBruce Richardson 		printf("Pipeline Consistency OK!\n");
399a9de470cSBruce Richardson 
400a9de470cSBruce Richardson 	return 0;
401a9de470cSBruce Richardson fail:
402a9de470cSBruce Richardson 
403a9de470cSBruce Richardson 	return -1;
404a9de470cSBruce Richardson }
405a9de470cSBruce Richardson 
406a9de470cSBruce Richardson static int
test_pipeline_single_filter(int test_type,int expected_count)407a9de470cSBruce Richardson test_pipeline_single_filter(int test_type, int expected_count)
408a9de470cSBruce Richardson {
409a9de470cSBruce Richardson 	int i;
410a9de470cSBruce Richardson 	int j;
411a9de470cSBruce Richardson 	int ret;
412a9de470cSBruce Richardson 	int tx_count;
413a9de470cSBruce Richardson 
414*f541aa2dSStephen Hemminger 	fprintf(stderr, "%s: **** Running %s test\n",
415a9de470cSBruce Richardson 		__func__, pipeline_test_names[test_type]);
416a9de470cSBruce Richardson 	/* Run pipeline once */
417a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++)
418a9de470cSBruce Richardson 		rte_pipeline_run(p);
419a9de470cSBruce Richardson 
420a9de470cSBruce Richardson 
421a9de470cSBruce Richardson 	ret = rte_pipeline_flush(NULL);
422a9de470cSBruce Richardson 	if (ret != -EINVAL) {
423*f541aa2dSStephen Hemminger 		fprintf(stderr,
424a9de470cSBruce Richardson 			"%s: No pipeline flush error NULL pipeline (%d)\n",
425a9de470cSBruce Richardson 			__func__, ret);
426a9de470cSBruce Richardson 		goto fail;
427a9de470cSBruce Richardson 	}
428a9de470cSBruce Richardson 
429a9de470cSBruce Richardson 	/*
430a9de470cSBruce Richardson 	 * Allocate a few mbufs and manually insert into the rings. */
431a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++)
432a9de470cSBruce Richardson 		for (j = 0; j < N_PORTS; j++) {
433a9de470cSBruce Richardson 			struct rte_mbuf *m;
434a9de470cSBruce Richardson 			uint8_t *key;
435a9de470cSBruce Richardson 			uint32_t *k32;
436a9de470cSBruce Richardson 
437a9de470cSBruce Richardson 			m = rte_pktmbuf_alloc(pool);
438a9de470cSBruce Richardson 			if (m == NULL) {
439a9de470cSBruce Richardson 				rte_panic("Failed to alloc mbuf from pool\n");
440a9de470cSBruce Richardson 				return -1;
441a9de470cSBruce Richardson 			}
442a9de470cSBruce Richardson 			key = RTE_MBUF_METADATA_UINT8_PTR(m,
443a9de470cSBruce Richardson 					APP_METADATA_OFFSET(32));
444a9de470cSBruce Richardson 
445a9de470cSBruce Richardson 			k32 = (uint32_t *) key;
446a9de470cSBruce Richardson 			k32[0] = 0xadadadad >> (j % 2);
447a9de470cSBruce Richardson 
448*f541aa2dSStephen Hemminger 			fprintf(stderr, "%s: Enqueue onto ring %d\n",
449a9de470cSBruce Richardson 				__func__, i);
450a9de470cSBruce Richardson 			rte_ring_enqueue(rings_rx[i], m);
451a9de470cSBruce Richardson 		}
452a9de470cSBruce Richardson 
453a9de470cSBruce Richardson 	/* Run pipeline once */
454a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++)
455a9de470cSBruce Richardson 		rte_pipeline_run(p);
456a9de470cSBruce Richardson 
457a9de470cSBruce Richardson    /*
458a9de470cSBruce Richardson 	* need to flush the pipeline, as there may be less hits than the burst
459a9de470cSBruce Richardson 	size and they will not have been flushed to the tx rings. */
460a9de470cSBruce Richardson 	rte_pipeline_flush(p);
461a9de470cSBruce Richardson 
462a9de470cSBruce Richardson    /*
463a9de470cSBruce Richardson 	* Now we'll see what we got back on the tx rings. We should see whatever
464a9de470cSBruce Richardson 	* packets we had hits on that were destined for the output ports.
465a9de470cSBruce Richardson 	*/
466a9de470cSBruce Richardson 	tx_count = 0;
467a9de470cSBruce Richardson 
468a9de470cSBruce Richardson 	for (i = 0; i < N_PORTS; i++) {
469a9de470cSBruce Richardson 		void *objs[RING_TX_SIZE];
470a9de470cSBruce Richardson 		struct rte_mbuf *mbuf;
471a9de470cSBruce Richardson 
472a9de470cSBruce Richardson 		ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL);
473a9de470cSBruce Richardson 		if (ret <= 0)
474a9de470cSBruce Richardson 			printf("Got no objects from ring %d - error code %d\n",
475a9de470cSBruce Richardson 				i, ret);
476a9de470cSBruce Richardson 		else {
477a9de470cSBruce Richardson 			printf("Got %d object(s) from ring %d!\n", ret, i);
478a9de470cSBruce Richardson 			for (j = 0; j < ret; j++) {
479a9de470cSBruce Richardson 				mbuf = objs[j];
480a9de470cSBruce Richardson 				rte_hexdump(stdout, "Object:",
481a9de470cSBruce Richardson 					rte_pktmbuf_mtod(mbuf, char *),
482a9de470cSBruce Richardson 					mbuf->data_len);
483a9de470cSBruce Richardson 				rte_pktmbuf_free(mbuf);
484a9de470cSBruce Richardson 			}
485a9de470cSBruce Richardson 			tx_count += ret;
486a9de470cSBruce Richardson 		}
487a9de470cSBruce Richardson 	}
488a9de470cSBruce Richardson 
489a9de470cSBruce Richardson 	if (tx_count != expected_count) {
490*f541aa2dSStephen Hemminger 		fprintf(stderr,
491*f541aa2dSStephen Hemminger 			"%s: Unexpected packets out for %s test, expected %d, got %d\n",
492*f541aa2dSStephen Hemminger 			__func__, pipeline_test_names[test_type],
493a9de470cSBruce Richardson 			expected_count, tx_count);
494a9de470cSBruce Richardson 		goto fail;
495a9de470cSBruce Richardson 	}
496a9de470cSBruce Richardson 
497a9de470cSBruce Richardson 	cleanup_pipeline();
498a9de470cSBruce Richardson 
499a9de470cSBruce Richardson 	return 0;
500a9de470cSBruce Richardson fail:
501a9de470cSBruce Richardson 	return -1;
502a9de470cSBruce Richardson 
503a9de470cSBruce Richardson }
504a9de470cSBruce Richardson 
505a9de470cSBruce Richardson int
test_table_pipeline(void)506a9de470cSBruce Richardson test_table_pipeline(void)
507a9de470cSBruce Richardson {
508a9de470cSBruce Richardson 	/* TEST - All packets dropped */
509a9de470cSBruce Richardson 	action_handler_hit = NULL;
510a9de470cSBruce Richardson 	action_handler_miss = NULL;
511a9de470cSBruce Richardson 	table_entry_default_action = RTE_PIPELINE_ACTION_DROP;
512a9de470cSBruce Richardson 	setup_pipeline(e_TEST_STUB);
513a9de470cSBruce Richardson 	if (test_pipeline_single_filter(e_TEST_STUB, 0) < 0)
514a9de470cSBruce Richardson 		return -1;
515a9de470cSBruce Richardson 
516a9de470cSBruce Richardson 	/* TEST - All packets passed through */
517a9de470cSBruce Richardson 	table_entry_default_action = RTE_PIPELINE_ACTION_PORT;
518a9de470cSBruce Richardson 	setup_pipeline(e_TEST_STUB);
519a9de470cSBruce Richardson 	if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
520a9de470cSBruce Richardson 		return -1;
521a9de470cSBruce Richardson 
522a9de470cSBruce Richardson 	/* TEST - one packet per port */
523a9de470cSBruce Richardson 	action_handler_hit = NULL;
524a9de470cSBruce Richardson 	action_handler_miss = table_action_stub_miss;
525a9de470cSBruce Richardson 	table_entry_default_action = RTE_PIPELINE_ACTION_PORT;
526a9de470cSBruce Richardson 	override_miss_mask = 0x01; /* one packet per port */
527a9de470cSBruce Richardson 	setup_pipeline(e_TEST_STUB);
528a9de470cSBruce Richardson 	if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
529a9de470cSBruce Richardson 		return -1;
530a9de470cSBruce Richardson 
531a9de470cSBruce Richardson 	/* TEST - one packet per port */
532a9de470cSBruce Richardson 	override_miss_mask = 0x02; /*all per port */
533a9de470cSBruce Richardson 	setup_pipeline(e_TEST_STUB);
534a9de470cSBruce Richardson 	if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
535a9de470cSBruce Richardson 		return -1;
536a9de470cSBruce Richardson 
537a9de470cSBruce Richardson 	/* TEST - all packets per port */
538a9de470cSBruce Richardson 	override_miss_mask = 0x03; /*all per port */
539a9de470cSBruce Richardson 	setup_pipeline(e_TEST_STUB);
540a9de470cSBruce Richardson 	if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
541a9de470cSBruce Richardson 		return -1;
542a9de470cSBruce Richardson 
543a9de470cSBruce Richardson    /*
544a9de470cSBruce Richardson 	* This test will set up two tables in the pipeline. the first table
545a9de470cSBruce Richardson 	* will forward to another table on miss, and the second table will
546a9de470cSBruce Richardson 	* forward to port.
547a9de470cSBruce Richardson 	*/
548a9de470cSBruce Richardson 	connect_miss_action_to_table = 1;
549a9de470cSBruce Richardson 	table_entry_default_action = RTE_PIPELINE_ACTION_TABLE;
550a9de470cSBruce Richardson 	action_handler_hit = NULL;  /* not for stub, hitmask always zero */
551a9de470cSBruce Richardson 	action_handler_miss = NULL;
552a9de470cSBruce Richardson 	setup_pipeline(e_TEST_STUB);
553a9de470cSBruce Richardson 	if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
554a9de470cSBruce Richardson 		return -1;
555a9de470cSBruce Richardson 	connect_miss_action_to_table = 0;
556a9de470cSBruce Richardson 
557a9de470cSBruce Richardson 	printf("TEST - two tables, hitmask override to 0x01\n");
558a9de470cSBruce Richardson 	connect_miss_action_to_table = 1;
559a9de470cSBruce Richardson 	action_handler_miss = table_action_stub_miss;
560a9de470cSBruce Richardson 	override_miss_mask = 0x01;
561a9de470cSBruce Richardson 	setup_pipeline(e_TEST_STUB);
562a9de470cSBruce Richardson 	if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
563a9de470cSBruce Richardson 		return -1;
564a9de470cSBruce Richardson 	connect_miss_action_to_table = 0;
565a9de470cSBruce Richardson 
566a9de470cSBruce Richardson 	if (check_pipeline_invalid_params()) {
567*f541aa2dSStephen Hemminger 		fprintf(stderr, "%s: Check pipeline invalid params failed.\n",
568*f541aa2dSStephen Hemminger 			__func__);
569a9de470cSBruce Richardson 		return -1;
570a9de470cSBruce Richardson 	}
571a9de470cSBruce Richardson 
572a9de470cSBruce Richardson 	return 0;
573a9de470cSBruce Richardson }
5743c60274cSJie Zhou 
5753c60274cSJie Zhou #endif /* !RTE_EXEC_ENV_WINDOWS */
576