FD.io VPP  v19.01.3-6-g70449b9b9
Vector Packet Processing
main.c
Go to the documentation of this file.
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 #define _GNU_SOURCE
17 #include <pthread.h>
18 #include <sched.h>
19 
20 #include <vppinfra/cpu.h>
21 #include <vlib/vlib.h>
22 #include <vlib/unix/unix.h>
23 #include <vnet/plugin/plugin.h>
24 #include <vnet/ethernet/ethernet.h>
25 #include <vpp/app/version.h>
26 #include <vpp/api/vpe_msg_enum.h>
27 #include <limits.h>
28 
29 /*
30  * Load plugins from /usr/lib/vpp_plugins by default
31  */
33 char *vlib_plugin_app_version = VPP_BUILD_VER;
34 
35 static void
37 {
38  extern char *vat_plugin_path;
39  char *p, path[PATH_MAX];
40  int rv;
41  u8 *s;
42 
43  /* find executable path */
44  if ((rv = readlink ("/proc/self/exe", path, PATH_MAX - 1)) == -1)
45  return;
46 
47  /* readlink doesn't provide null termination */
48  path[rv] = 0;
49 
50  /* strip filename */
51  if ((p = strrchr (path, '/')) == 0)
52  return;
53  *p = 0;
54 
55  /* strip bin/ */
56  if ((p = strrchr (path, '/')) == 0)
57  return;
58  *p = 0;
59 
60  s = format (0, "%s/lib/vpp_plugins", path);
61  vec_add1 (s, 0);
62  vlib_plugin_path = (char *) s;
63 
64  s = format (0, "%s/lib/vpp_api_test_plugins", path);
65  vec_add1 (s, 0);
66  vat_plugin_path = (char *) s;
67 }
68 
69 static void
71 {
72  void vat_plugin_hash_create (void);
73 
74  if (CLIB_DEBUG > 0)
75  vlib_unix_cli_set_prompt ("DBGvpp# ");
76  else
77  vlib_unix_cli_set_prompt ("vpp# ");
78 
79  /* Turn off network stack components which we don't want */
81 
82  /*
83  * Create the binary api plugin hashes before loading plugins
84  */
86 
87  if (!vlib_plugin_path)
89 }
90 
91 /*
92  * Default path for runtime data
93  */
95 
96 int
97 main (int argc, char *argv[])
98 {
99  int i;
102  uword main_heap_size = (1ULL << 30);
103  u8 *sizep;
104  u32 size;
105  int main_core = 1;
106  cpu_set_t cpuset;
107 
108 #if __x86_64__
109  CLIB_UNUSED (const char *msg)
110  = "ERROR: This binary requires CPU with %s extensions.\n";
111 #define _(a,b) \
112  if (!clib_cpu_supports_ ## a ()) \
113  { \
114  fprintf(stderr, msg, b); \
115  exit(1); \
116  }
117 
118 #if __AVX2__
119  _(avx2, "AVX2")
120 #endif
121 #if __AVX__
122  _(avx, "AVX")
123 #endif
124 #if __SSE4_2__
125  _(sse42, "SSE4.2")
126 #endif
127 #if __SSE4_1__
128  _(sse41, "SSE4.1")
129 #endif
130 #if __SSSE3__
131  _(ssse3, "SSSE3")
132 #endif
133 #if __SSE3__
134  _(sse3, "SSE3")
135 #endif
136 #undef _
137 #endif
138  /*
139  * Load startup config from file.
140  * usage: vpp -c /etc/vpp/startup.conf
141  */
142  if ((argc == 3) && !strncmp (argv[1], "-c", 2))
143  {
144  FILE *fp;
145  char inbuf[4096];
146  int argc_ = 1;
147  char **argv_ = NULL;
148  char *arg = NULL;
149  char *p;
150 
151  fp = fopen (argv[2], "r");
152  if (fp == NULL)
153  {
154  fprintf (stderr, "open configuration file '%s' failed\n", argv[2]);
155  return 1;
156  }
157  argv_ = calloc (1, sizeof (char *));
158  if (argv_ == NULL)
159  {
160  fclose (fp);
161  return 1;
162  }
163  arg = strndup (argv[0], 1024);
164  if (arg == NULL)
165  {
166  fclose (fp);
167  free (argv_);
168  return 1;
169  }
170  argv_[0] = arg;
171 
172  while (1)
173  {
174  if (fgets (inbuf, 4096, fp) == 0)
175  break;
176  p = strtok (inbuf, " \t\n");
177  while (p != NULL)
178  {
179  if (*p == '#')
180  break;
181  argc_++;
182  char **tmp = realloc (argv_, argc_ * sizeof (char *));
183  if (tmp == NULL)
184  return 1;
185  argv_ = tmp;
186  arg = strndup (p, 1024);
187  if (arg == NULL)
188  return 1;
189  argv_[argc_ - 1] = arg;
190  p = strtok (NULL, " \t\n");
191  }
192  }
193 
194  fclose (fp);
195 
196  char **tmp = realloc (argv_, (argc_ + 1) * sizeof (char *));
197  if (tmp == NULL)
198  return 1;
199  argv_ = tmp;
200  argv_[argc_] = NULL;
201 
202  argc = argc_;
203  argv = argv_;
204  }
205 
206  /*
207  * Look for and parse the "heapsize" config parameter.
208  * Manual since none of the clib infra has been bootstrapped yet.
209  *
210  * Format: heapsize <nn>[mM][gG]
211  */
212 
213  for (i = 1; i < (argc - 1); i++)
214  {
215  if (!strncmp (argv[i], "plugin_path", 11))
216  {
217  if (i < (argc - 1))
218  vlib_plugin_path = argv[++i];
219  }
220  else if (!strncmp (argv[i], "heapsize", 8))
221  {
222  sizep = (u8 *) argv[i + 1];
223  size = 0;
224  while (*sizep >= '0' && *sizep <= '9')
225  {
226  size *= 10;
227  size += *sizep++ - '0';
228  }
229  if (size == 0)
230  {
231  fprintf
232  (stderr,
233  "warning: heapsize parse error '%s', use default %lld\n",
234  argv[i], (long long int) main_heap_size);
235  goto defaulted;
236  }
237 
238  main_heap_size = size;
239 
240  if (*sizep == 'g' || *sizep == 'G')
241  main_heap_size <<= 30;
242  else if (*sizep == 'm' || *sizep == 'M')
243  main_heap_size <<= 20;
244  }
245  else if (!strncmp (argv[i], "main-core", 9))
246  {
247  if (i < (argc - 1))
248  {
249  errno = 0;
250  unsigned long x = strtol (argv[++i], 0, 0);
251  if (errno == 0)
252  main_core = x;
253  }
254  }
255  }
256 
257 defaulted:
258 
259  /* set process affinity for main thread */
260  CPU_ZERO (&cpuset);
261  CPU_SET (main_core, &cpuset);
262  pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
263 
264  /* Set up the plugin message ID allocator right now... */
266 
267  /* Allocate main heap */
268  if (clib_mem_init_thread_safe (0, main_heap_size))
269  {
270  vm->init_functions_called = hash_create (0, /* value bytes */ 0);
271  vpe_main_init (vm);
272  return vlib_unix_main (argc, argv);
273  }
274  else
275  {
276  {
277  int rv __attribute__ ((unused)) =
278  write (2, "Main heap allocation failure!\r\n", 31);
279  }
280  return 1;
281  }
282 }
283 
284 static clib_error_t *
286 {
287  u32 junk;
288 
290  {
291  if (unformat (input, "%dm", &junk)
292  || unformat (input, "%dM", &junk)
293  || unformat (input, "%dg", &junk) || unformat (input, "%dG", &junk))
294  return 0;
295  else
296  return clib_error_return (0, "unknown input '%U'",
297  format_unformat_error, input);
298  }
299  return 0;
300 }
301 
303 
304 static clib_error_t *
306 {
307  u8 *junk;
308 
310  {
311  if (unformat (input, "%s", &junk))
312  {
313  vec_free (junk);
314  return 0;
315  }
316  else
317  return clib_error_return (0, "unknown input '%U'",
318  format_unformat_error, input);
319  }
320  return 0;
321 }
322 
324 
325 void vl_msg_api_post_mortem_dump (void);
326 void elog_post_mortem_dump (void);
327 
328 void
329 os_panic (void)
330 {
333  abort ();
334 }
335 
336 void vhost_user_unmap_all (void) __attribute__ ((weak));
337 void
339 {
340 }
341 
342 void
343 os_exit (int code)
344 {
345  static int recursion_block;
346 
347  if (code)
348  {
349  if (recursion_block)
350  abort ();
351 
352  recursion_block = 1;
353 
357  abort ();
358  }
359  exit (code);
360 }
361 
362 #ifdef BARRIER_TRACING
363 void
364 vl_msg_api_barrier_trace_context (const char *context)
365 {
367 }
368 #endif
369 
370 void
372 {
374 }
375 
376 void
378 {
380 }
381 
382 /* This application needs 1 thread stack for the stats pthread */
383 u32
385 {
386  return 1;
387 }
388 
389 /*
390  * Depending on the configuration selected above,
391  * it may be necessary to generate stub graph nodes.
392  * It is never OK to ignore "node 'x' refers to unknown node 'y'
393  * messages!
394  */
395 
396 /*
397  * fd.io coding-style-patch-verification: ON
398  *
399  * Local Variables:
400  * eval: (c-set-style "gnu")
401  * End:
402  */
int vlib_unix_main(int argc, char *argv[])
Definition: main.c:635
u32 vlib_app_num_thread_stacks_needed(void)
Definition: main.c:384
vlib_main_t vlib_global_main
Definition: main.c:1850
#define CLIB_UNUSED(x)
Definition: clib.h:82
void vl_msg_api_barrier_sync(void)
Definition: main.c:371
static clib_error_t * plugin_path_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:305
#define NULL
Definition: clib.h:58
void vlib_unix_cli_set_prompt(char *prompt)
Set the CLI prompt.
Definition: cli.c:3061
static clib_error_t * heapsize_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:285
#define vlib_mark_init_function_complete(vm, x)
Definition: init.h:274
void vhost_user_unmap_all(void)
Definition: main.c:338
char * vat_plugin_path
Definition: plugin.c:183
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:525
int i
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define vl_msg_api_barrier_trace_context(X)
Definition: api_common.h:168
unsigned char u8
Definition: types.h:56
#define vlib_worker_thread_barrier_sync(X)
Definition: threads.h:204
char * vlib_default_runtime_dir
Definition: main.c:59
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned int u32
Definition: types.h:88
void os_exit(int code)
Definition: main.c:343
static clib_error_t * srp_init(vlib_main_t *vm)
Definition: node.c:866
void vl_msg_api_post_mortem_dump(void)
Definition: api_shared.c:787
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:36
uword size
const char * barrier_context
Definition: threads.h:107
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:172
void elog_post_mortem_dump(void)
Definition: main.c:736
uword * init_functions_called
Definition: main.h:176
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
vlib_main_t * vm
Definition: buffer.c:301
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
char * vlib_plugin_path
Definition: main.c:32
#define hash_create(elts, value_bytes)
Definition: hash.h:696
void vat_plugin_hash_create(void)
Definition: api_main.c:65
void vl_msg_api_barrier_release(void)
Definition: main.c:377
static void vpe_main_init(vlib_main_t *vm)
Definition: main.c:70
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u64 uword
Definition: types.h:112
static void vpp_find_plugin_path()
Definition: main.c:36
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
Definition: threads.c:1470
int main(int argc, char *argv[])
Definition: main.c:97
char * vlib_plugin_app_version
Definition: main.c:33
void * clib_mem_init_thread_safe(void *memory, uword memory_size)
Definition: mem_dlmalloc.c:226
void os_panic(void)
Definition: main.c:329
void vl_msg_api_set_first_available_msg_id(u16 first_avail)
Definition: api_shared.c:857
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170