1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Intel Corporation
3 */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <getopt.h>
11
12 #include <rte_launch.h>
13 #include <rte_eal.h>
14
15 #include "cli.h"
16 #include "conn.h"
17 #include "obj.h"
18 #include "thread.h"
19
20 static const char usage[] =
21 "%s EAL_ARGS -- [-h HOST] [-p PORT] [-s SCRIPT]\n";
22
23 static struct app_params {
24 struct conn_params conn;
25 char *script_name;
26 } app = {
27 .conn = {
28 .welcome = "\nWelcome!\n\n",
29 .prompt = "pipeline> ",
30 .addr = "0.0.0.0",
31 .port = 8086,
32 .buf_size = 1024 * 1024,
33 .msg_in_len_max = 1024,
34 .msg_out_len_max = 1024 * 1024,
35 .msg_handle = cli_process,
36 .msg_handle_arg = NULL, /* set later. */
37 },
38 .script_name = NULL,
39 };
40
41 static int
parse_args(int argc,char ** argv)42 parse_args(int argc, char **argv)
43 {
44 char *app_name = argv[0];
45 struct option lgopts[] = {
46 { NULL, 0, 0, 0 }
47 };
48 int opt, option_index;
49 int h_present, p_present, s_present, n_args, i;
50
51 /* Skip EAL input args */
52 n_args = argc;
53 for (i = 0; i < n_args; i++)
54 if (strcmp(argv[i], "--") == 0) {
55 argc -= i;
56 argv += i;
57 break;
58 }
59
60 if (i == n_args)
61 return 0;
62
63 /* Parse args */
64 h_present = 0;
65 p_present = 0;
66 s_present = 0;
67
68 while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index))
69 != EOF)
70 switch (opt) {
71 case 'h':
72 if (h_present) {
73 printf("Error: Multiple -h arguments\n");
74 return -1;
75 }
76 h_present = 1;
77
78 if (!strlen(optarg)) {
79 printf("Error: Argument for -h not provided\n");
80 return -1;
81 }
82
83 app.conn.addr = strdup(optarg);
84 if (app.conn.addr == NULL) {
85 printf("Error: Not enough memory\n");
86 return -1;
87 }
88 break;
89
90 case 'p':
91 if (p_present) {
92 printf("Error: Multiple -p arguments\n");
93 return -1;
94 }
95 p_present = 1;
96
97 if (!strlen(optarg)) {
98 printf("Error: Argument for -p not provided\n");
99 return -1;
100 }
101
102 app.conn.port = (uint16_t) atoi(optarg);
103 break;
104
105 case 's':
106 if (s_present) {
107 printf("Error: Multiple -s arguments\n");
108 return -1;
109 }
110 s_present = 1;
111
112 if (!strlen(optarg)) {
113 printf("Error: Argument for -s not provided\n");
114 return -1;
115 }
116
117 app.script_name = strdup(optarg);
118 if (app.script_name == NULL) {
119 printf("Error: Not enough memory\n");
120 return -1;
121 }
122 break;
123
124 default:
125 printf(usage, app_name);
126 return -1;
127 }
128
129 optind = 1; /* reset getopt lib */
130
131 return 0;
132 }
133
134 int
main(int argc,char ** argv)135 main(int argc, char **argv)
136 {
137 struct conn *conn;
138 int status;
139
140 /* Parse application arguments */
141 status = parse_args(argc, argv);
142 if (status < 0)
143 return status;
144
145 /* EAL */
146 status = rte_eal_init(argc, argv);
147 if (status < 0) {
148 printf("Error: EAL initialization failed (%d)\n", status);
149 return status;
150 };
151
152 /* Thread */
153 status = thread_init();
154 if (status) {
155 printf("Error: Thread initialization failed (%d)\n", status);
156 return status;
157 }
158
159 rte_eal_mp_remote_launch(
160 thread_main,
161 NULL,
162 SKIP_MAIN);
163
164 /* Script */
165 if (app.script_name)
166 cli_script_process(app.script_name,
167 app.conn.msg_in_len_max,
168 app.conn.msg_out_len_max,
169 NULL);
170
171 /* Connectivity */
172 app.conn.msg_handle_arg = NULL;
173 conn = conn_init(&app.conn);
174 if (!conn) {
175 printf("Error: Connectivity initialization failed (%d)\n",
176 status);
177 return status;
178 };
179
180 /* Dispatch loop */
181 for ( ; ; ) {
182 conn_poll_for_conn(conn);
183
184 conn_poll_for_msg(conn);
185 }
186
187 /* clean up the EAL */
188 rte_eal_cleanup();
189 }
190