Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2016 Intel Corporation
3 : : */
4 : :
5 : : #include <stdio.h>
6 : : #include <stdlib.h>
7 : : #include <stdint.h>
8 : :
9 : : #include <rte_log.h>
10 : : #include <rte_ethdev.h>
11 : : #include <rte_ether.h>
12 : : #include <rte_ip.h>
13 : : #include <rte_byteorder.h>
14 : :
15 : : #include <rte_port_ring.h>
16 : : #include <rte_table_lpm.h>
17 : : #include <rte_pipeline.h>
18 : :
19 : : #include "main.h"
20 : :
21 : : #ifndef PIPELINE_LPM_TABLE_NUMBER_TABLE8s
22 : : #define PIPELINE_LPM_TABLE_NUMBER_TABLE8s 256
23 : : #endif
24 : :
25 : : void
26 : 0 : app_main_loop_worker_pipeline_lpm(void) {
27 : 0 : struct rte_pipeline_params pipeline_params = {
28 : : .name = "pipeline",
29 : 0 : .socket_id = rte_socket_id(),
30 : : };
31 : :
32 : : struct rte_pipeline *p;
33 : : uint32_t port_in_id[APP_MAX_PORTS];
34 : : uint32_t port_out_id[APP_MAX_PORTS];
35 : : uint32_t table_id;
36 : : uint32_t i;
37 : :
38 : 0 : RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with "
39 : : "LPM table)\n", rte_lcore_id());
40 : :
41 : : /* Pipeline configuration */
42 : 0 : p = rte_pipeline_create(&pipeline_params);
43 : 0 : if (p == NULL)
44 : 0 : rte_panic("Unable to configure the pipeline\n");
45 : :
46 : : /* Input port configuration */
47 : 0 : for (i = 0; i < app.n_ports; i++) {
48 : 0 : struct rte_port_ring_reader_params port_ring_params = {
49 : 0 : .ring = app.rings_rx[i],
50 : : };
51 : :
52 : 0 : struct rte_pipeline_port_in_params port_params = {
53 : : .ops = &rte_port_ring_reader_ops,
54 : : .arg_create = (void *) &port_ring_params,
55 : : .f_action = NULL,
56 : : .arg_ah = NULL,
57 : 0 : .burst_size = app.burst_size_worker_read,
58 : : };
59 : :
60 : 0 : if (rte_pipeline_port_in_create(p, &port_params,
61 : : &port_in_id[i]))
62 : 0 : rte_panic("Unable to configure input port for "
63 : : "ring %d\n", i);
64 : : }
65 : :
66 : : /* Output port configuration */
67 : 0 : for (i = 0; i < app.n_ports; i++) {
68 : 0 : struct rte_port_ring_writer_params port_ring_params = {
69 : 0 : .ring = app.rings_tx[i],
70 : 0 : .tx_burst_sz = app.burst_size_worker_write,
71 : : };
72 : :
73 : 0 : struct rte_pipeline_port_out_params port_params = {
74 : : .ops = &rte_port_ring_writer_ops,
75 : : .arg_create = (void *) &port_ring_params,
76 : : .f_action = NULL,
77 : : .arg_ah = NULL,
78 : : };
79 : :
80 : 0 : if (rte_pipeline_port_out_create(p, &port_params,
81 : : &port_out_id[i]))
82 : 0 : rte_panic("Unable to configure output port for "
83 : : "ring %d\n", i);
84 : : }
85 : :
86 : : /* Table configuration */
87 : : {
88 : 0 : struct rte_table_lpm_params table_lpm_params = {
89 : : .name = "LPM",
90 : : .n_rules = 1 << 24,
91 : : .number_tbl8s = PIPELINE_LPM_TABLE_NUMBER_TABLE8s,
92 : : .flags = 0,
93 : : .entry_unique_size =
94 : : sizeof(struct rte_pipeline_table_entry),
95 : : .offset = APP_METADATA_OFFSET(32),
96 : : };
97 : :
98 : 0 : struct rte_pipeline_table_params table_params = {
99 : : .ops = &rte_table_lpm_ops,
100 : : .arg_create = &table_lpm_params,
101 : : .f_action_hit = NULL,
102 : : .f_action_miss = NULL,
103 : : .arg_ah = NULL,
104 : : .action_data_size = 0,
105 : : };
106 : :
107 : 0 : if (rte_pipeline_table_create(p, &table_params, &table_id))
108 : 0 : rte_panic("Unable to configure the LPM table\n");
109 : : }
110 : :
111 : : /* Interconnecting ports and tables */
112 : 0 : for (i = 0; i < app.n_ports; i++)
113 : 0 : if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
114 : : table_id))
115 : 0 : rte_panic("Unable to connect input port %u to "
116 : : "table %u\n", port_in_id[i], table_id);
117 : :
118 : : /* Add entries to tables */
119 : 0 : for (i = 0; i < app.n_ports; i++) {
120 : 0 : struct rte_pipeline_table_entry entry = {
121 : : .action = RTE_PIPELINE_ACTION_PORT,
122 : 0 : {.port_id = port_out_id[i & (app.n_ports - 1)]},
123 : : };
124 : :
125 : 0 : struct rte_table_lpm_key key = {
126 : 0 : .ip = i << (24 - rte_popcount32(app.n_ports - 1)),
127 : 0 : .depth = 8 + rte_popcount32(app.n_ports - 1),
128 : : };
129 : :
130 : : struct rte_pipeline_table_entry *entry_ptr;
131 : :
132 : : int key_found, status;
133 : :
134 : 0 : printf("Adding rule to LPM table (IPv4 destination = %"
135 : : PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "/%" PRIu8
136 : : " => port out = %" PRIu32 ")\n",
137 : : (key.ip & 0xFF000000) >> 24,
138 : 0 : (key.ip & 0x00FF0000) >> 16,
139 : 0 : (key.ip & 0x0000FF00) >> 8,
140 : : key.ip & 0x000000FF,
141 : : key.depth,
142 : : i);
143 : :
144 : 0 : status = rte_pipeline_table_entry_add(p, table_id, &key, &entry,
145 : : &key_found, &entry_ptr);
146 : 0 : if (status < 0)
147 : 0 : rte_panic("Unable to add entry to table %u (%d)\n",
148 : : table_id, status);
149 : : }
150 : :
151 : : /* Enable input ports */
152 : 0 : for (i = 0; i < app.n_ports; i++)
153 : 0 : if (rte_pipeline_port_in_enable(p, port_in_id[i]))
154 : 0 : rte_panic("Unable to enable input port %u\n",
155 : : port_in_id[i]);
156 : :
157 : : /* Check pipeline consistency */
158 : 0 : if (rte_pipeline_check(p) < 0)
159 : 0 : rte_panic("Pipeline consistency check failed\n");
160 : :
161 : : /* Run-time */
162 : : #if APP_FLUSH == 0
163 : 0 : while (!force_quit)
164 : 0 : rte_pipeline_run(p);
165 : : #else
166 : : i = 0;
167 : : while (!force_quit) {
168 : : rte_pipeline_run(p);
169 : :
170 : : if ((i & APP_FLUSH) == 0)
171 : : rte_pipeline_flush(p);
172 : : i++;
173 : : }
174 : : #endif
175 : 0 : }
|