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 <fcntl.h>
7 : : #include <getopt.h>
8 : : #include <signal.h>
9 : : #include <stdio.h>
10 : : #include <stdlib.h>
11 : : #include <string.h>
12 : : #include <sys/select.h>
13 : : #include <unistd.h>
14 : :
15 : : #include <rte_cycles.h>
16 : : #include <rte_eal.h>
17 : : #include <rte_launch.h>
18 : :
19 : : #include "module_api.h"
20 : :
21 : : volatile bool force_quit;
22 : : struct conn *conn;
23 : :
24 : : static const char usage[] = "%s EAL_ARGS -- -s SCRIPT [-h HOST] [-p PORT] [--enable-graph-stats] "
25 : : "[--help]\n";
26 : :
27 : : static struct app_params {
28 : : struct conn_params conn;
29 : : char *script_name;
30 : : bool enable_graph_stats;
31 : : bool enable_feature_arc;
32 : : } app = {
33 : : .conn = {
34 : : .welcome = "\nWelcome!\n\n",
35 : : .prompt = "graph> ",
36 : : .addr = "0.0.0.0",
37 : : .port = 8086,
38 : : .buf_size = 1024 * 1024,
39 : : .msg_in_len_max = 1024,
40 : : .msg_out_len_max = 1024 * 1024,
41 : : .msg_handle = cli_process,
42 : : .msg_handle_arg = NULL, /* set later. */
43 : : },
44 : : .script_name = NULL,
45 : : .enable_graph_stats = false,
46 : : .enable_feature_arc = false,
47 : : };
48 : :
49 : : static void
50 : 0 : signal_handler(int signum)
51 : : {
52 : 0 : if (signum == SIGINT || signum == SIGTERM) {
53 : : printf("\n\nSignal %d received, preparing to exit...\n", signum);
54 : 0 : force_quit = true;
55 : : }
56 : 0 : }
57 : :
58 : : static int
59 : 0 : app_args_parse(int argc, char **argv)
60 : : {
61 : 0 : struct option lgopts[] = {
62 : : {"help", 0, 0, 'H'},
63 : : {"enable-graph-stats", 0, 0, 'g'},
64 : : {"enable-graph-feature-arc", 0, 0, 'f'},
65 : : };
66 : : int h_present, p_present, s_present, n_args, i;
67 : 0 : char *app_name = argv[0];
68 : : int opt, option_index;
69 : :
70 : : /* Skip EAL input args */
71 : : n_args = argc;
72 : 0 : for (i = 0; i < n_args; i++)
73 : 0 : if (strcmp(argv[i], "--") == 0) {
74 : 0 : argc -= i;
75 : : argv += i;
76 : 0 : break;
77 : : }
78 : :
79 : 0 : if (i == n_args)
80 : : return 0;
81 : :
82 : : /* Parse args */
83 : : h_present = 0;
84 : : p_present = 0;
85 : : s_present = 0;
86 : :
87 : 0 : while ((opt = getopt_long(argc, argv, "h:p:s:f", lgopts, &option_index)) != EOF) {
88 : 0 : switch (opt) {
89 : 0 : case 'h':
90 : 0 : if (h_present) {
91 : : printf("Error: Multiple -h arguments\n");
92 : 0 : return -1;
93 : : }
94 : : h_present = 1;
95 : :
96 : 0 : if (!strlen(optarg)) {
97 : : printf("Error: Argument for -h not provided\n");
98 : 0 : return -1;
99 : : }
100 : :
101 : 0 : app.conn.addr = strdup(optarg);
102 : 0 : if (app.conn.addr == NULL) {
103 : : printf("Error: Not enough memory\n");
104 : 0 : return -1;
105 : : }
106 : : break;
107 : :
108 : 0 : case 'p':
109 : 0 : if (p_present) {
110 : : printf("Error: Multiple -p arguments\n");
111 : 0 : return -1;
112 : : }
113 : : p_present = 1;
114 : :
115 : 0 : if (!strlen(optarg)) {
116 : : printf("Error: Argument for -p not provided\n");
117 : 0 : return -1;
118 : : }
119 : :
120 : 0 : app.conn.port = (uint16_t)strtoul(optarg, NULL, 10);
121 : 0 : break;
122 : :
123 : 0 : case 's':
124 : 0 : if (s_present) {
125 : : printf("Error: Multiple -s arguments\n");
126 : 0 : return -1;
127 : : }
128 : : s_present = 1;
129 : :
130 : 0 : if (!strlen(optarg)) {
131 : : printf("Error: Argument for -s not provided\n");
132 : 0 : return -1;
133 : : }
134 : :
135 : 0 : app.script_name = strdup(optarg);
136 : 0 : if (app.script_name == NULL) {
137 : : printf("Error: Not enough memory\n");
138 : 0 : return -1;
139 : : }
140 : : break;
141 : :
142 : 0 : case 'g':
143 : 0 : app.enable_graph_stats = true;
144 : : printf("WARNING! Telnet session can not be accessed with"
145 : : "--enable-graph-stats");
146 : : break;
147 : :
148 : 0 : case 'f':
149 : 0 : app.enable_feature_arc = true;
150 : 0 : break;
151 : :
152 : : case 'H':
153 : : default:
154 : : printf(usage, app_name);
155 : 0 : return -1;
156 : : }
157 : : }
158 : 0 : optind = 1; /* reset getopt lib */
159 : :
160 : 0 : return 0;
161 : : }
162 : :
163 : : bool
164 : 0 : app_graph_stats_enabled(void)
165 : : {
166 : 0 : return app.enable_graph_stats;
167 : : }
168 : :
169 : : bool
170 : 0 : app_graph_feature_arc_enabled(void)
171 : : {
172 : 0 : return app.enable_feature_arc;
173 : : }
174 : :
175 : : bool
176 : 0 : app_graph_exit(void)
177 : : {
178 : : struct timeval tv;
179 : : fd_set fds;
180 : : int ret;
181 : : char c;
182 : :
183 : 0 : FD_ZERO(&fds);
184 : 0 : FD_SET(0, &fds);
185 : 0 : tv.tv_sec = 0;
186 : 0 : tv.tv_usec = 100;
187 : 0 : ret = select(1, &fds, NULL, NULL, &tv);
188 : 0 : if ((ret < 0 && errno == EINTR) || (ret == 1 && read(0, &c, 1) > 0))
189 : 0 : return true;
190 : : else
191 : 0 : return false;
192 : :
193 : : }
194 : :
195 : : int
196 : 0 : main(int argc, char **argv)
197 : : {
198 : : int rc;
199 : :
200 : : /* Parse application arguments */
201 : 0 : rc = app_args_parse(argc, argv);
202 : 0 : if (rc < 0)
203 : : return rc;
204 : :
205 : : /* EAL */
206 : 0 : rc = rte_eal_init(argc, argv);
207 : 0 : if (rc < 0) {
208 : : printf("Error: EAL initialization failed (%d)\n", rc);
209 : 0 : return rc;
210 : : };
211 : :
212 : 0 : force_quit = false;
213 : 0 : signal(SIGINT, signal_handler);
214 : 0 : signal(SIGTERM, signal_handler);
215 : :
216 : 0 : cli_init();
217 : :
218 : : /* Script */
219 : 0 : if (app.script_name) {
220 : 0 : cli_script_process(app.script_name, app.conn.msg_in_len_max,
221 : : app.conn.msg_out_len_max, NULL);
222 : : }
223 : :
224 : : /* Connectivity */
225 : 0 : app.conn.msg_handle_arg = NULL;
226 : 0 : conn = conn_init(&app.conn);
227 : 0 : if (!conn) {
228 : : printf("Error: Connectivity initialization failed\n");
229 : 0 : goto exit;
230 : : };
231 : :
232 : : rte_delay_ms(1);
233 : : printf("Press enter to exit\n");
234 : :
235 : : /* Dispatch loop */
236 : 0 : while (!force_quit) {
237 : 0 : conn_req_poll(conn);
238 : :
239 : 0 : conn_msg_poll(conn);
240 : 0 : if (app_graph_exit())
241 : 0 : force_quit = true;
242 : : }
243 : :
244 : 0 : exit:
245 : 0 : conn_free(conn);
246 : 0 : ethdev_stop();
247 : 0 : cli_exit();
248 : 0 : rte_eal_cleanup();
249 : 0 : return 0;
250 : : }
|