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
19 #include "module_api.h"
20
21 static int
l3fwd_pattern_configure(void)22 l3fwd_pattern_configure(void)
23 {
24 /* Graph initialization. 8< */
25 static const char * const default_patterns[] = {
26 "ip4*",
27 "ethdev_tx-*",
28 "pkt_drop",
29 };
30 struct rte_graph_param graph_conf;
31 const char **node_patterns;
32 uint64_t pcap_pkts_count;
33 struct lcore_conf *qconf;
34 uint16_t nb_patterns;
35 uint8_t pcap_ena;
36 int rc, lcore_id;
37 char *pcap_file;
38
39 nb_patterns = RTE_DIM(default_patterns);
40 node_patterns = malloc((ETHDEV_RX_QUEUE_PER_LCORE_MAX + nb_patterns) *
41 sizeof(*node_patterns));
42 if (!node_patterns)
43 return -ENOMEM;
44 memcpy(node_patterns, default_patterns,
45 nb_patterns * sizeof(*node_patterns));
46
47 memset(&graph_conf, 0, sizeof(graph_conf));
48 graph_conf.node_patterns = node_patterns;
49
50 /* Pcap config */
51 graph_pcap_config_get(&pcap_ena, &pcap_pkts_count, &pcap_file);
52 graph_conf.pcap_enable = pcap_ena;
53 graph_conf.num_pkt_to_capture = pcap_pkts_count;
54 graph_conf.pcap_filename = strdup(pcap_file);
55
56 for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
57 rte_graph_t graph_id;
58 rte_edge_t i;
59
60 if (rte_lcore_is_enabled(lcore_id) == 0)
61 continue;
62
63 qconf = &lcore_conf[lcore_id];
64
65 /* Skip graph creation if no source exists */
66 if (!qconf->n_rx_queue)
67 continue;
68
69 /* Add rx node patterns of this lcore */
70 for (i = 0; i < qconf->n_rx_queue; i++) {
71 graph_conf.node_patterns[nb_patterns + i] =
72 qconf->rx_queue_list[i].node_name;
73 }
74
75 graph_conf.nb_node_patterns = nb_patterns + i;
76 graph_conf.socket_id = rte_lcore_to_socket_id(lcore_id);
77
78 snprintf(qconf->name, sizeof(qconf->name), "worker_%u",
79 lcore_id);
80
81 graph_id = rte_graph_create(qconf->name, &graph_conf);
82 if (graph_id == RTE_GRAPH_ID_INVALID)
83 rte_exit(EXIT_FAILURE,
84 "rte_graph_create(): graph_id invalid"
85 " for lcore %u\n", lcore_id);
86
87 qconf->graph_id = graph_id;
88 qconf->graph = rte_graph_lookup(qconf->name);
89 /* >8 End of graph initialization. */
90 if (!qconf->graph)
91 rte_exit(EXIT_FAILURE,
92 "rte_graph_lookup(): graph %s not found\n",
93 qconf->name);
94 }
95
96 rc = route_ip4_add_to_lookup();
97 if (rc < 0)
98 rte_exit(EXIT_FAILURE, "Unable to add v4 route to lookup table\n");
99
100 rc = route_ip6_add_to_lookup();
101 if (rc < 0)
102 rte_exit(EXIT_FAILURE, "Unable to add v6 route to lookup table\n");
103
104 rc = neigh_ip4_add_to_rewrite();
105 if (rc < 0)
106 rte_exit(EXIT_FAILURE, "Unable to add v4 to rewrite node\n");
107
108 rc = neigh_ip6_add_to_rewrite();
109 if (rc < 0)
110 rte_exit(EXIT_FAILURE, "Unable to add v6 to rewrite node\n");
111
112 /* Launch per-lcore init on every worker lcore */
113 rte_eal_mp_remote_launch(graph_walk_start, NULL, SKIP_MAIN);
114
115 /* Accumulate and print stats on main until exit */
116 if (rte_graph_has_stats_feature() && app_graph_stats_enabled())
117 graph_stats_print();
118
119 return rc;
120 }
121
122 int
usecase_l3fwd_configure(struct rte_node_ethdev_config * conf,uint16_t nb_confs,uint16_t nb_graphs)123 usecase_l3fwd_configure(struct rte_node_ethdev_config *conf, uint16_t nb_confs, uint16_t nb_graphs)
124 {
125 int rc;
126
127 rc = rte_node_eth_config(conf, nb_confs, nb_graphs);
128 if (rc)
129 rte_exit(EXIT_FAILURE, "rte_node_eth_config: err=%d\n", rc);
130
131 rc = l3fwd_pattern_configure();
132 if (rc)
133 rte_exit(EXIT_FAILURE, "l3fwd_pattern_failure: err=%d\n", rc);
134
135 return rc;
136 }
137