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