New upstream version 18.08
[deb_dpdk.git] / examples / ip_pipeline / main.c
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 }