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