1474572d2SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause
2474572d2SBruce Richardson * Copyright(c) 2010-2016 Intel Corporation
3474572d2SBruce Richardson */
4474572d2SBruce Richardson
5474572d2SBruce Richardson #include <stdio.h>
6474572d2SBruce Richardson #include <stdlib.h>
7474572d2SBruce Richardson #include <stdint.h>
8474572d2SBruce Richardson
9474572d2SBruce Richardson #include <rte_log.h>
10474572d2SBruce Richardson #include <rte_ethdev.h>
11474572d2SBruce Richardson #include <rte_ether.h>
12474572d2SBruce Richardson #include <rte_ip.h>
13474572d2SBruce Richardson #include <rte_byteorder.h>
14474572d2SBruce Richardson
15474572d2SBruce Richardson #include <rte_port_ring.h>
16474572d2SBruce Richardson #include <rte_table_lpm.h>
17474572d2SBruce Richardson #include <rte_pipeline.h>
18474572d2SBruce Richardson
19474572d2SBruce Richardson #include "main.h"
20474572d2SBruce Richardson
21474572d2SBruce Richardson #ifndef PIPELINE_LPM_TABLE_NUMBER_TABLE8s
22474572d2SBruce Richardson #define PIPELINE_LPM_TABLE_NUMBER_TABLE8s 256
23474572d2SBruce Richardson #endif
24474572d2SBruce Richardson
25474572d2SBruce Richardson void
app_main_loop_worker_pipeline_lpm(void)26474572d2SBruce Richardson app_main_loop_worker_pipeline_lpm(void) {
27474572d2SBruce Richardson struct rte_pipeline_params pipeline_params = {
28474572d2SBruce Richardson .name = "pipeline",
29474572d2SBruce Richardson .socket_id = rte_socket_id(),
30474572d2SBruce Richardson };
31474572d2SBruce Richardson
32474572d2SBruce Richardson struct rte_pipeline *p;
33474572d2SBruce Richardson uint32_t port_in_id[APP_MAX_PORTS];
34474572d2SBruce Richardson uint32_t port_out_id[APP_MAX_PORTS];
35474572d2SBruce Richardson uint32_t table_id;
36474572d2SBruce Richardson uint32_t i;
37474572d2SBruce Richardson
38474572d2SBruce Richardson RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with "
39474572d2SBruce Richardson "LPM table)\n", rte_lcore_id());
40474572d2SBruce Richardson
41474572d2SBruce Richardson /* Pipeline configuration */
42474572d2SBruce Richardson p = rte_pipeline_create(&pipeline_params);
43474572d2SBruce Richardson if (p == NULL)
44474572d2SBruce Richardson rte_panic("Unable to configure the pipeline\n");
45474572d2SBruce Richardson
46474572d2SBruce Richardson /* Input port configuration */
47474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) {
48474572d2SBruce Richardson struct rte_port_ring_reader_params port_ring_params = {
49474572d2SBruce Richardson .ring = app.rings_rx[i],
50474572d2SBruce Richardson };
51474572d2SBruce Richardson
52474572d2SBruce Richardson struct rte_pipeline_port_in_params port_params = {
53474572d2SBruce Richardson .ops = &rte_port_ring_reader_ops,
54474572d2SBruce Richardson .arg_create = (void *) &port_ring_params,
55474572d2SBruce Richardson .f_action = NULL,
56474572d2SBruce Richardson .arg_ah = NULL,
57474572d2SBruce Richardson .burst_size = app.burst_size_worker_read,
58474572d2SBruce Richardson };
59474572d2SBruce Richardson
60474572d2SBruce Richardson if (rte_pipeline_port_in_create(p, &port_params,
61474572d2SBruce Richardson &port_in_id[i]))
62474572d2SBruce Richardson rte_panic("Unable to configure input port for "
63474572d2SBruce Richardson "ring %d\n", i);
64474572d2SBruce Richardson }
65474572d2SBruce Richardson
66474572d2SBruce Richardson /* Output port configuration */
67474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) {
68474572d2SBruce Richardson struct rte_port_ring_writer_params port_ring_params = {
69474572d2SBruce Richardson .ring = app.rings_tx[i],
70474572d2SBruce Richardson .tx_burst_sz = app.burst_size_worker_write,
71474572d2SBruce Richardson };
72474572d2SBruce Richardson
73474572d2SBruce Richardson struct rte_pipeline_port_out_params port_params = {
74474572d2SBruce Richardson .ops = &rte_port_ring_writer_ops,
75474572d2SBruce Richardson .arg_create = (void *) &port_ring_params,
76474572d2SBruce Richardson .f_action = NULL,
77474572d2SBruce Richardson .arg_ah = NULL,
78474572d2SBruce Richardson };
79474572d2SBruce Richardson
80474572d2SBruce Richardson if (rte_pipeline_port_out_create(p, &port_params,
81474572d2SBruce Richardson &port_out_id[i]))
82474572d2SBruce Richardson rte_panic("Unable to configure output port for "
83474572d2SBruce Richardson "ring %d\n", i);
84474572d2SBruce Richardson }
85474572d2SBruce Richardson
86474572d2SBruce Richardson /* Table configuration */
87474572d2SBruce Richardson {
88474572d2SBruce Richardson struct rte_table_lpm_params table_lpm_params = {
89474572d2SBruce Richardson .name = "LPM",
90474572d2SBruce Richardson .n_rules = 1 << 24,
91474572d2SBruce Richardson .number_tbl8s = PIPELINE_LPM_TABLE_NUMBER_TABLE8s,
92474572d2SBruce Richardson .flags = 0,
93474572d2SBruce Richardson .entry_unique_size =
94474572d2SBruce Richardson sizeof(struct rte_pipeline_table_entry),
95474572d2SBruce Richardson .offset = APP_METADATA_OFFSET(32),
96474572d2SBruce Richardson };
97474572d2SBruce Richardson
98474572d2SBruce Richardson struct rte_pipeline_table_params table_params = {
99474572d2SBruce Richardson .ops = &rte_table_lpm_ops,
100474572d2SBruce Richardson .arg_create = &table_lpm_params,
101474572d2SBruce Richardson .f_action_hit = NULL,
102474572d2SBruce Richardson .f_action_miss = NULL,
103474572d2SBruce Richardson .arg_ah = NULL,
104474572d2SBruce Richardson .action_data_size = 0,
105474572d2SBruce Richardson };
106474572d2SBruce Richardson
107474572d2SBruce Richardson if (rte_pipeline_table_create(p, &table_params, &table_id))
108474572d2SBruce Richardson rte_panic("Unable to configure the LPM table\n");
109474572d2SBruce Richardson }
110474572d2SBruce Richardson
111474572d2SBruce Richardson /* Interconnecting ports and tables */
112474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++)
113474572d2SBruce Richardson if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
114474572d2SBruce Richardson table_id))
115474572d2SBruce Richardson rte_panic("Unable to connect input port %u to "
116474572d2SBruce Richardson "table %u\n", port_in_id[i], table_id);
117474572d2SBruce Richardson
118474572d2SBruce Richardson /* Add entries to tables */
119474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++) {
120474572d2SBruce Richardson struct rte_pipeline_table_entry entry = {
121474572d2SBruce Richardson .action = RTE_PIPELINE_ACTION_PORT,
122474572d2SBruce Richardson {.port_id = port_out_id[i & (app.n_ports - 1)]},
123474572d2SBruce Richardson };
124474572d2SBruce Richardson
125474572d2SBruce Richardson struct rte_table_lpm_key key = {
1263d4e27fdSDavid Marchand .ip = i << (24 - rte_popcount32(app.n_ports - 1)),
1273d4e27fdSDavid Marchand .depth = 8 + rte_popcount32(app.n_ports - 1),
128474572d2SBruce Richardson };
129474572d2SBruce Richardson
130474572d2SBruce Richardson struct rte_pipeline_table_entry *entry_ptr;
131474572d2SBruce Richardson
132474572d2SBruce Richardson int key_found, status;
133474572d2SBruce Richardson
134474572d2SBruce Richardson printf("Adding rule to LPM table (IPv4 destination = %"
135474572d2SBruce Richardson PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "/%" PRIu8
136474572d2SBruce Richardson " => port out = %" PRIu32 ")\n",
137474572d2SBruce Richardson (key.ip & 0xFF000000) >> 24,
138474572d2SBruce Richardson (key.ip & 0x00FF0000) >> 16,
139474572d2SBruce Richardson (key.ip & 0x0000FF00) >> 8,
140474572d2SBruce Richardson key.ip & 0x000000FF,
141474572d2SBruce Richardson key.depth,
142474572d2SBruce Richardson i);
143474572d2SBruce Richardson
144474572d2SBruce Richardson status = rte_pipeline_table_entry_add(p, table_id, &key, &entry,
145474572d2SBruce Richardson &key_found, &entry_ptr);
146474572d2SBruce Richardson if (status < 0)
147474572d2SBruce Richardson rte_panic("Unable to add entry to table %u (%d)\n",
148474572d2SBruce Richardson table_id, status);
149474572d2SBruce Richardson }
150474572d2SBruce Richardson
151474572d2SBruce Richardson /* Enable input ports */
152474572d2SBruce Richardson for (i = 0; i < app.n_ports; i++)
153474572d2SBruce Richardson if (rte_pipeline_port_in_enable(p, port_in_id[i]))
154474572d2SBruce Richardson rte_panic("Unable to enable input port %u\n",
155474572d2SBruce Richardson port_in_id[i]);
156474572d2SBruce Richardson
157474572d2SBruce Richardson /* Check pipeline consistency */
158474572d2SBruce Richardson if (rte_pipeline_check(p) < 0)
159474572d2SBruce Richardson rte_panic("Pipeline consistency check failed\n");
160474572d2SBruce Richardson
161474572d2SBruce Richardson /* Run-time */
162474572d2SBruce Richardson #if APP_FLUSH == 0
163*f6897b23SFeifei Wang while (!force_quit)
164474572d2SBruce Richardson rte_pipeline_run(p);
165474572d2SBruce Richardson #else
166*f6897b23SFeifei Wang i = 0;
167*f6897b23SFeifei Wang while (!force_quit) {
168474572d2SBruce Richardson rte_pipeline_run(p);
169474572d2SBruce Richardson
170474572d2SBruce Richardson if ((i & APP_FLUSH) == 0)
171474572d2SBruce Richardson rte_pipeline_flush(p);
172*f6897b23SFeifei Wang i++;
173474572d2SBruce Richardson }
174474572d2SBruce Richardson #endif
175474572d2SBruce Richardson }
176