xref: /dpdk/examples/ip_pipeline/main.c (revision 09442498ef736d0a96632cf8b8c15d8ca78a6468)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2018 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 "kni.h"
18 #include "cryptodev.h"
19 #include "link.h"
20 #include "mempool.h"
21 #include "pipeline.h"
22 #include "swq.h"
23 #include "tap.h"
24 #include "thread.h"
25 #include "tmgr.h"
26 
27 static const char usage[] =
28 	"%s EAL_ARGS -- [-h HOST] [-p PORT] [-s SCRIPT]\n";
29 
30 static const char welcome[] =
31 	"\n"
32 	"Welcome to IP Pipeline!\n"
33 	"\n";
34 
35 static const char prompt[] = "pipeline> ";
36 
37 static struct app_params {
38 	struct conn_params conn;
39 	char *script_name;
40 } app = {
41 	.conn = {
42 		.welcome = welcome,
43 		.prompt = prompt,
44 		.addr = "0.0.0.0",
45 		.port = 8086,
46 		.buf_size = 1024 * 1024,
47 		.msg_in_len_max = 1024,
48 		.msg_out_len_max = 1024 * 1024,
49 		.msg_handle = cli_process,
50 	},
51 	.script_name = NULL,
52 };
53 
54 static int
55 parse_args(int argc, char **argv)
56 {
57 	char *app_name = argv[0];
58 	struct option lgopts[] = {
59 		{ NULL,  0, 0, 0 }
60 	};
61 	int opt, option_index;
62 	int h_present, p_present, s_present, n_args, i;
63 
64 	/* Skip EAL input args */
65 	n_args = argc;
66 	for (i = 0; i < n_args; i++)
67 		if (strcmp(argv[i], "--") == 0) {
68 			argc -= i;
69 			argv += i;
70 			break;
71 		}
72 
73 	if (i == n_args)
74 		return 0;
75 
76 	/* Parse args */
77 	h_present = 0;
78 	p_present = 0;
79 	s_present = 0;
80 
81 	while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index))
82 			!= EOF)
83 		switch (opt) {
84 		case 'h':
85 			if (h_present) {
86 				printf("Error: Multiple -h arguments\n");
87 				return -1;
88 			}
89 			h_present = 1;
90 
91 			if (!strlen(optarg)) {
92 				printf("Error: Argument for -h not provided\n");
93 				return -1;
94 			}
95 
96 			app.conn.addr = strdup(optarg);
97 			if (app.conn.addr == NULL) {
98 				printf("Error: Not enough memory\n");
99 				return -1;
100 			}
101 			break;
102 
103 		case 'p':
104 			if (p_present) {
105 				printf("Error: Multiple -p arguments\n");
106 				return -1;
107 			}
108 			p_present = 1;
109 
110 			if (!strlen(optarg)) {
111 				printf("Error: Argument for -p not provided\n");
112 				return -1;
113 			}
114 
115 			app.conn.port = (uint16_t) atoi(optarg);
116 			break;
117 
118 		case 's':
119 			if (s_present) {
120 				printf("Error: Multiple -s arguments\n");
121 				return -1;
122 			}
123 			s_present = 1;
124 
125 			if (!strlen(optarg)) {
126 				printf("Error: Argument for -s not provided\n");
127 				return -1;
128 			}
129 
130 			app.script_name = strdup(optarg);
131 			if (app.script_name == NULL) {
132 				printf("Error: Not enough memory\n");
133 				return -1;
134 			}
135 			break;
136 
137 		default:
138 			printf(usage, app_name);
139 			return -1;
140 		}
141 
142 	optind = 1; /* reset getopt lib */
143 
144 	return 0;
145 }
146 
147 int
148 main(int argc, char **argv)
149 {
150 	struct conn *conn;
151 	int status;
152 
153 	/* Parse application arguments */
154 	status = parse_args(argc, argv);
155 	if (status < 0)
156 		return status;
157 
158 	/* EAL */
159 	status = rte_eal_init(argc, argv);
160 	if (status < 0) {
161 		printf("Error: EAL initialization failed (%d)\n", status);
162 		return status;
163 	};
164 
165 	/* Connectivity */
166 	conn = conn_init(&app.conn);
167 	if (conn == NULL) {
168 		printf("Error: Connectivity initialization failed (%d)\n",
169 			status);
170 		return status;
171 	};
172 
173 	/* Mempool */
174 	status = mempool_init();
175 	if (status) {
176 		printf("Error: Mempool initialization failed (%d)\n", status);
177 		return status;
178 	}
179 
180 	/* Link */
181 	status = link_init();
182 	if (status) {
183 		printf("Error: Link initialization failed (%d)\n", status);
184 		return status;
185 	}
186 
187 	/* SWQ */
188 	status = swq_init();
189 	if (status) {
190 		printf("Error: SWQ initialization failed (%d)\n", status);
191 		return status;
192 	}
193 
194 	/* Traffic Manager */
195 	status = tmgr_init();
196 	if (status) {
197 		printf("Error: TMGR initialization failed (%d)\n", status);
198 		return status;
199 	}
200 
201 	/* TAP */
202 	status = tap_init();
203 	if (status) {
204 		printf("Error: TAP initialization failed (%d)\n", status);
205 		return status;
206 	}
207 
208 	/* KNI */
209 	status = kni_init();
210 	if (status) {
211 		printf("Error: KNI initialization failed (%d)\n", status);
212 		return status;
213 	}
214 
215 	/* Sym Crypto */
216 	status = cryptodev_init();
217 	if (status) {
218 		printf("Error: Cryptodev initialization failed (%d)\n",
219 				status);
220 		return status;
221 	}
222 
223 	/* Action */
224 	status = port_in_action_profile_init();
225 	if (status) {
226 		printf("Error: Input port action profile initialization failed (%d)\n", status);
227 		return status;
228 	}
229 
230 	status = table_action_profile_init();
231 	if (status) {
232 		printf("Error: Action profile initialization failed (%d)\n",
233 			status);
234 		return status;
235 	}
236 
237 	/* Pipeline */
238 	status = pipeline_init();
239 	if (status) {
240 		printf("Error: Pipeline initialization failed (%d)\n", status);
241 		return status;
242 	}
243 
244 	/* Thread */
245 	status = thread_init();
246 	if (status) {
247 		printf("Error: Thread initialization failed (%d)\n", status);
248 		return status;
249 	}
250 
251 	rte_eal_mp_remote_launch(
252 		thread_main,
253 		NULL,
254 		SKIP_MAIN);
255 
256 	/* Script */
257 	if (app.script_name)
258 		cli_script_process(app.script_name,
259 			app.conn.msg_in_len_max,
260 			app.conn.msg_out_len_max);
261 
262 	/* Dispatch loop */
263 	for ( ; ; ) {
264 		conn_poll_for_conn(conn);
265 
266 		conn_poll_for_msg(conn);
267 
268 		kni_handle_request();
269 	}
270 }
271