Retire vpp_lite
[vpp.git] / src / vpp / vnet / main.c
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15
16 #include <vppinfra/cpu.h>
17 #include <vlib/vlib.h>
18 #include <vlib/unix/unix.h>
19 #include <vnet/plugin/plugin.h>
20 #include <vnet/ethernet/ethernet.h>
21 #include <vpp/app/version.h>
22 #include <vpp/api/vpe_msg_enum.h>
23
24
25 static void
26 vpe_main_init (vlib_main_t * vm)
27 {
28   void vat_plugin_hash_create (void);
29
30   if (CLIB_DEBUG > 0)
31     vlib_unix_cli_set_prompt ("DBGvpp# ");
32   else
33     vlib_unix_cli_set_prompt ("vpp# ");
34
35   /* Turn off network stack components which we don't want */
36   vlib_mark_init_function_complete (vm, srp_init);
37
38   /*
39    * Create the binary api plugin hashes before loading plugins
40    */
41   vat_plugin_hash_create ();
42 }
43
44 /*
45  * Load plugins from /usr/lib/vpp_plugins by default
46  */
47 char *vlib_plugin_path = "/usr/lib/vpp_plugins";
48 char *vlib_plugin_app_version = VPP_BUILD_VER;
49
50 int
51 main (int argc, char *argv[])
52 {
53   int i;
54   vlib_main_t *vm = &vlib_global_main;
55   void vl_msg_api_set_first_available_msg_id (u16);
56   uword main_heap_size = (1ULL << 30);
57   u8 *sizep;
58   u32 size;
59
60 #if __x86_64__
61   CLIB_UNUSED (const char *msg)
62     = "ERROR: This binary requires CPU with %s extensions.\n";
63 #define _(a,b)                                  \
64     if (!clib_cpu_supports_ ## a ())            \
65       {                                         \
66         fprintf(stderr, msg, b);                \
67         exit(1);                                \
68       }
69
70 #if __AVX2__
71   _(avx2, "AVX2")
72 #endif
73 #if __AVX__
74     _(avx, "AVX")
75 #endif
76 #if __SSE4_2__
77     _(sse42, "SSE4.2")
78 #endif
79 #if __SSE4_1__
80     _(sse41, "SSE4.1")
81 #endif
82 #if __SSSE3__
83     _(ssse3, "SSSE3")
84 #endif
85 #if __SSE3__
86     _(sse3, "SSE3")
87 #endif
88 #undef _
89 #endif
90     /*
91      * Load startup config from file.
92      * usage: vpp -c /etc/vpp/startup.conf
93      */
94     if ((argc == 3) && !strncmp (argv[1], "-c", 2))
95     {
96       FILE *fp;
97       char inbuf[4096];
98       int argc_ = 1;
99       char **argv_ = NULL;
100       char *arg = NULL;
101       char *p;
102
103       fp = fopen (argv[2], "r");
104       if (fp == NULL)
105         {
106           fprintf (stderr, "open configuration file '%s' failed\n", argv[2]);
107           return 1;
108         }
109       argv_ = calloc (1, sizeof (char *));
110       if (argv_ == NULL)
111         return 1;
112       arg = strndup (argv[0], 1024);
113       if (arg == NULL)
114         return 1;
115       argv_[0] = arg;
116
117       while (1)
118         {
119           if (fgets (inbuf, 4096, fp) == 0)
120             break;
121           p = strtok (inbuf, " \t\n");
122           while (p != NULL)
123             {
124               if (*p == '#')
125                 break;
126               argc_++;
127               char **tmp = realloc (argv_, argc_ * sizeof (char *));
128               if (tmp == NULL)
129                 return 1;
130               argv_ = tmp;
131               arg = strndup (p, 1024);
132               if (arg == NULL)
133                 return 1;
134               argv_[argc_ - 1] = arg;
135               p = strtok (NULL, " \t\n");
136             }
137         }
138
139       fclose (fp);
140
141       char **tmp = realloc (argv_, (argc_ + 1) * sizeof (char *));
142       if (tmp == NULL)
143         return 1;
144       argv_ = tmp;
145       argv_[argc_] = NULL;
146
147       argc = argc_;
148       argv = argv_;
149     }
150
151   /*
152    * Look for and parse the "heapsize" config parameter.
153    * Manual since none of the clib infra has been bootstrapped yet.
154    *
155    * Format: heapsize <nn>[mM][gG]
156    */
157
158   for (i = 1; i < (argc - 1); i++)
159     {
160       if (!strncmp (argv[i], "plugin_path", 11))
161         {
162           if (i < (argc - 1))
163             vlib_plugin_path = argv[++i];
164         }
165       else if (!strncmp (argv[i], "heapsize", 8))
166         {
167           sizep = (u8 *) argv[i + 1];
168           size = 0;
169           while (*sizep >= '0' && *sizep <= '9')
170             {
171               size *= 10;
172               size += *sizep++ - '0';
173             }
174           if (size == 0)
175             {
176               fprintf
177                 (stderr,
178                  "warning: heapsize parse error '%s', use default %lld\n",
179                  argv[i], (long long int) main_heap_size);
180               goto defaulted;
181             }
182
183           main_heap_size = size;
184
185           if (*sizep == 'g' || *sizep == 'G')
186             main_heap_size <<= 30;
187           else if (*sizep == 'm' || *sizep == 'M')
188             main_heap_size <<= 20;
189         }
190     }
191
192 defaulted:
193
194   /* Set up the plugin message ID allocator right now... */
195   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
196
197   /* Allocate main heap */
198   if (clib_mem_init (0, main_heap_size))
199     {
200       vm->init_functions_called = hash_create (0, /* value bytes */ 0);
201       vpe_main_init (vm);
202       return vlib_unix_main (argc, argv);
203     }
204   else
205     {
206       {
207         int rv __attribute__ ((unused)) =
208           write (2, "Main heap allocation failure!\r\n", 31);
209       }
210       return 1;
211     }
212 }
213
214 static clib_error_t *
215 heapsize_config (vlib_main_t * vm, unformat_input_t * input)
216 {
217   u32 junk;
218
219   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
220     {
221       if (unformat (input, "%dm", &junk)
222           || unformat (input, "%dM", &junk)
223           || unformat (input, "%dg", &junk) || unformat (input, "%dG", &junk))
224         return 0;
225       else
226         return clib_error_return (0, "unknown input '%U'",
227                                   format_unformat_error, input);
228     }
229   return 0;
230 }
231
232 VLIB_CONFIG_FUNCTION (heapsize_config, "heapsize");
233
234 static clib_error_t *
235 plugin_path_config (vlib_main_t * vm, unformat_input_t * input)
236 {
237   u8 *junk;
238
239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
240     {
241       if (unformat (input, "%s", &junk))
242         {
243           vec_free (junk);
244           return 0;
245         }
246       else
247         return clib_error_return (0, "unknown input '%U'",
248                                   format_unformat_error, input);
249     }
250   return 0;
251 }
252
253 VLIB_CONFIG_FUNCTION (plugin_path_config, "plugin_path");
254
255 void vl_msg_api_post_mortem_dump (void);
256
257 void
258 os_panic (void)
259 {
260   vl_msg_api_post_mortem_dump ();
261   abort ();
262 }
263
264 void vhost_user_unmap_all (void) __attribute__ ((weak));
265 void
266 vhost_user_unmap_all (void)
267 {
268 }
269
270 void
271 os_exit (int code)
272 {
273   static int recursion_block;
274
275   if (code)
276     {
277       if (recursion_block)
278         abort ();
279
280       recursion_block = 1;
281
282       vl_msg_api_post_mortem_dump ();
283       vhost_user_unmap_all ();
284       abort ();
285     }
286   exit (code);
287 }
288
289 void
290 vl_msg_api_barrier_sync (void)
291 {
292   vlib_worker_thread_barrier_sync (vlib_get_main ());
293 }
294
295 void
296 vl_msg_api_barrier_release (void)
297 {
298   vlib_worker_thread_barrier_release (vlib_get_main ());
299 }
300
301 /* This application needs 1 thread stack for the stats pthread */
302 u32
303 vlib_app_num_thread_stacks_needed (void)
304 {
305   return 1;
306 }
307
308 /*
309  * Depending on the configuration selected above,
310  * it may be necessary to generate stub graph nodes.
311  * It is never OK to ignore "node 'x' refers to unknown node 'y'
312  * messages!
313  */
314
315 #if CLIB_DEBUG > 0
316
317 static clib_error_t *
318 test_crash_command_fn (vlib_main_t * vm,
319                        unformat_input_t * input, vlib_cli_command_t * cmd)
320 {
321   u64 *p = (u64 *) 0xdefec8ed;
322
323   *p = 0xdeadbeef;
324
325   /* Not so much... */
326   return 0;
327 }
328
329 /* *INDENT-OFF* */
330 VLIB_CLI_COMMAND (test_crash_command, static) = {
331   .path = "test crash",
332   .short_help = "crash the bus!",
333   .function = test_crash_command_fn,
334 };
335 /* *INDENT-ON* */
336
337 #endif
338
339 /*
340  * fd.io coding-style-patch-verification: ON
341  *
342  * Local Variables:
343  * eval: (c-set-style "gnu")
344  * End:
345  */