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