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