Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2023 Marvell.
3 : : */
4 : :
5 : : #include <errno.h>
6 : : #include <stdbool.h>
7 : : #include <stdint.h>
8 : : #include <stdio.h>
9 : : #include <stdlib.h>
10 : : #include <string.h>
11 : :
12 : : #include <rte_common.h>
13 : : #include <rte_ethdev.h>
14 : : #include <rte_graph.h>
15 : : #include <rte_graph_worker.h>
16 : : #include <rte_lcore.h>
17 : : #include <rte_node_eth_api.h>
18 : : #include <rte_node_ip4_api.h>
19 : : #include <rte_node_ip6_api.h>
20 : : #include <rte_node_pkt_cls_api.h>
21 : :
22 : : #include "module_api.h"
23 : :
24 : : static int
25 : : setup_fib(int socket)
26 : : {
27 : : struct rte_fib_conf conf;
28 : :
29 : : #define FIB_MAX_ROUTES (UINT16_MAX)
30 : : #define FIB_NUM_TBL8 (UINT16_MAX / 2)
31 : 0 : conf.type = RTE_FIB_DIR24_8;
32 : 0 : conf.max_routes = FIB_MAX_ROUTES;
33 : 0 : conf.rib_ext_sz = 0;
34 : 0 : conf.dir24_8.nh_sz = RTE_FIB_DIR24_8_4B;
35 : 0 : conf.dir24_8.num_tbl8 = FIB_NUM_TBL8;
36 : 0 : conf.flags = 0;
37 : :
38 : 0 : return rte_node_ip4_fib_create(socket, &conf);
39 : : }
40 : :
41 : : static int
42 : : setup_fib6(int socket)
43 : : {
44 : : struct rte_fib6_conf conf;
45 : :
46 : : #define FIB6_MAX_ROUTES (UINT16_MAX)
47 : : #define FIB6_NUM_TBL8 (UINT16_MAX / 2)
48 : 0 : conf.type = RTE_FIB6_TRIE;
49 : 0 : conf.max_routes = FIB6_MAX_ROUTES;
50 : 0 : conf.rib_ext_sz = 0;
51 : 0 : conf.trie.nh_sz = RTE_FIB6_TRIE_4B;
52 : 0 : conf.trie.num_tbl8 = FIB6_NUM_TBL8;
53 : :
54 : 0 : return rte_node_ip6_fib_create(socket, &conf);
55 : : }
56 : :
57 : : static int
58 : 0 : l3fwd_pattern_configure(void)
59 : : {
60 : : /* Graph initialization. 8< */
61 : : static const char * const default_patterns[] = {
62 : : "ip4*",
63 : : "ethdev_tx-*",
64 : : "pkt_drop",
65 : : };
66 : : struct rte_graph_param graph_conf;
67 : : const char **node_patterns;
68 : : uint64_t pcap_pkts_count;
69 : : struct lcore_conf *qconf;
70 : : uint16_t nb_patterns;
71 : : uint8_t pcap_ena;
72 : : int rc, lcore_id;
73 : : char *pcap_file;
74 : :
75 : : nb_patterns = RTE_DIM(default_patterns);
76 : 0 : node_patterns = malloc((ETHDEV_RX_QUEUE_PER_LCORE_MAX + nb_patterns) *
77 : : sizeof(*node_patterns));
78 : 0 : if (!node_patterns)
79 : : return -ENOMEM;
80 : : memcpy(node_patterns, default_patterns,
81 : : nb_patterns * sizeof(*node_patterns));
82 : :
83 : : memset(&graph_conf, 0, sizeof(graph_conf));
84 : 0 : graph_conf.node_patterns = node_patterns;
85 : :
86 : : /* Pcap config */
87 : 0 : graph_pcap_config_get(&pcap_ena, &pcap_pkts_count, &pcap_file);
88 : 0 : graph_conf.pcap_enable = pcap_ena;
89 : 0 : graph_conf.num_pkt_to_capture = pcap_pkts_count;
90 : 0 : graph_conf.pcap_filename = strdup(pcap_file);
91 : :
92 : 0 : if (ip4_lookup_m == IP4_LOOKUP_FIB) {
93 : 0 : const char *fib_n = "ip4_lookup_fib";
94 : 0 : const char *lpm_n = "ip4_lookup";
95 : : rte_node_t pkt_cls;
96 : :
97 : 0 : pkt_cls = rte_node_from_name("pkt_cls");
98 : 0 : rte_node_edge_update(pkt_cls, RTE_NODE_PKT_CLS_NEXT_IP4_LOOKUP, &fib_n, 1);
99 : 0 : rte_node_edge_update(pkt_cls, RTE_NODE_PKT_CLS_NEXT_IP4_LOOKUP_FIB, &lpm_n, 1);
100 : : }
101 : :
102 : 0 : if (ip6_lookup_m == IP6_LOOKUP_FIB) {
103 : 0 : const char *fib6_n = "ip6_lookup_fib";
104 : 0 : const char *lpm6_n = "ip6_lookup";
105 : : rte_node_t pkt_cls;
106 : :
107 : 0 : pkt_cls = rte_node_from_name("pkt_cls");
108 : 0 : rte_node_edge_update(pkt_cls, RTE_NODE_PKT_CLS_NEXT_IP6_LOOKUP, &fib6_n, 1);
109 : 0 : rte_node_edge_update(pkt_cls, RTE_NODE_PKT_CLS_NEXT_IP6_LOOKUP_FIB, &lpm6_n, 1);
110 : : }
111 : :
112 : 0 : for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
113 : : rte_graph_t graph_id;
114 : : rte_edge_t i;
115 : :
116 : 0 : if (rte_lcore_is_enabled(lcore_id) == 0)
117 : 0 : continue;
118 : :
119 : : qconf = &lcore_conf[lcore_id];
120 : :
121 : : /* Skip graph creation if no source exists */
122 : 0 : if (!qconf->n_rx_queue)
123 : 0 : continue;
124 : :
125 : : /* Add rx node patterns of this lcore */
126 : 0 : for (i = 0; i < qconf->n_rx_queue; i++) {
127 : 0 : graph_conf.node_patterns[nb_patterns + i] =
128 : 0 : qconf->rx_queue_list[i].node_name;
129 : : }
130 : :
131 : 0 : graph_conf.nb_node_patterns = nb_patterns + i;
132 : 0 : graph_conf.socket_id = rte_lcore_to_socket_id(lcore_id);
133 : :
134 : 0 : snprintf(qconf->name, sizeof(qconf->name), "worker_%u",
135 : : lcore_id);
136 : :
137 : 0 : if (ip4_lookup_m == IP4_LOOKUP_FIB) {
138 : 0 : rc = setup_fib(graph_conf.socket_id);
139 : 0 : if (rc < 0)
140 : 0 : rte_exit(EXIT_FAILURE, "Unable to setup fib for socket %u\n",
141 : : graph_conf.socket_id);
142 : : }
143 : :
144 : 0 : if (ip6_lookup_m == IP6_LOOKUP_FIB) {
145 : 0 : rc = setup_fib6(graph_conf.socket_id);
146 : 0 : if (rc < 0)
147 : 0 : rte_exit(EXIT_FAILURE, "Unable to setup fib6 for socket %u\n",
148 : : graph_conf.socket_id);
149 : : }
150 : :
151 : 0 : graph_id = rte_graph_create(qconf->name, &graph_conf);
152 : 0 : if (graph_id == RTE_GRAPH_ID_INVALID)
153 : 0 : rte_exit(EXIT_FAILURE,
154 : : "rte_graph_create(): graph_id invalid"
155 : : " for lcore %u\n", lcore_id);
156 : :
157 : 0 : qconf->graph_id = graph_id;
158 : 0 : qconf->graph = rte_graph_lookup(qconf->name);
159 : : /* >8 End of graph initialization. */
160 : 0 : if (!qconf->graph)
161 : 0 : rte_exit(EXIT_FAILURE,
162 : : "rte_graph_lookup(): graph %s not found\n",
163 : : qconf->name);
164 : : }
165 : :
166 : 0 : rc = route_ip4_add_to_lookup();
167 : 0 : if (rc < 0)
168 : 0 : rte_exit(EXIT_FAILURE, "Unable to add v4 route to lookup table\n");
169 : :
170 : 0 : rc = route_ip6_add_to_lookup();
171 : 0 : if (rc < 0)
172 : 0 : rte_exit(EXIT_FAILURE, "Unable to add v6 route to lookup table\n");
173 : :
174 : 0 : rc = neigh_ip4_add_to_rewrite();
175 : 0 : if (rc < 0)
176 : 0 : rte_exit(EXIT_FAILURE, "Unable to add v4 to rewrite node\n");
177 : :
178 : 0 : rc = neigh_ip6_add_to_rewrite();
179 : 0 : if (rc < 0)
180 : 0 : rte_exit(EXIT_FAILURE, "Unable to add v6 to rewrite node\n");
181 : :
182 : : /* Launch per-lcore init on every worker lcore */
183 : 0 : rte_eal_mp_remote_launch(graph_walk_start, NULL, SKIP_MAIN);
184 : :
185 : : /* Accumulate and print stats on main until exit */
186 : 0 : if (rte_graph_has_stats_feature() && app_graph_stats_enabled())
187 : 0 : graph_stats_print();
188 : :
189 : : return rc;
190 : : }
191 : :
192 : : int
193 : 0 : usecase_l3fwd_configure(struct rte_node_ethdev_config *conf, uint16_t nb_confs, uint16_t nb_graphs)
194 : : {
195 : : int rc;
196 : :
197 : 0 : rc = rte_node_eth_config(conf, nb_confs, nb_graphs);
198 : 0 : if (rc)
199 : 0 : rte_exit(EXIT_FAILURE, "rte_node_eth_config: err=%d\n", rc);
200 : :
201 : 0 : rc = l3fwd_pattern_configure();
202 : 0 : if (rc)
203 : 0 : rte_exit(EXIT_FAILURE, "l3fwd_pattern_failure: err=%d\n", rc);
204 : :
205 : 0 : return rc;
206 : : }
|