FD.io VPP  v21.10.1-2-g0a485f517
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 <vlib/threads.h>
24 #include <vnet/plugin/plugin.h>
25 #include <vnet/ethernet/ethernet.h>
26 #include <vpp/app/version.h>
27 #include <vpp/vnet/config.h>
28 #include <vpp/api/vpe_msg_enum.h>
29 #include <limits.h>
30 
31 /*
32  * Load plugins from /usr/lib/vpp_plugins by default
33  */
34 char *vlib_plugin_path = NULL;
35 char *vlib_plugin_app_version = VPP_BUILD_VER;
36 char *vat_plugin_path = NULL;
37 
38 static void
40 {
41  extern char *vat_plugin_path;
42  char *p, path[PATH_MAX];
43  int rv;
44  u8 *s;
45 
46  /* find executable path */
47  if ((rv = readlink ("/proc/self/exe", path, PATH_MAX - 1)) == -1)
48  return;
49 
50  /* readlink doesn't provide null termination */
51  path[rv] = 0;
52 
53  /* strip filename */
54  if ((p = strrchr (path, '/')) == 0)
55  return;
56  *p = 0;
57 
58  /* strip bin/ */
59  if ((p = strrchr (path, '/')) == 0)
60  return;
61  *p = 0;
62 
63  s = format (0, "%s/lib/" CLIB_TARGET_TRIPLET "/vpp_plugins:"
64  "%s/lib/vpp_plugins", path, path);
65  vec_add1 (s, 0);
66  vlib_plugin_path = (char *) s;
67 
68  s = format (0, "%s/lib/" CLIB_TARGET_TRIPLET "/vpp_api_test_plugins:"
69  "%s/lib/vpp_api_test_plugins", path, path);
70  vec_add1 (s, 0);
71  vat_plugin_path = (char *) s;
72 }
73 
74 static void
76 {
77 #if VPP_API_TEST_BUILTIN > 0
78  void vat_plugin_hash_create (void);
79 #endif
80 
81  if (CLIB_DEBUG > 0)
82  vlib_unix_cli_set_prompt ("DBGvpp# ");
83  else
84  vlib_unix_cli_set_prompt ("vpp# ");
85 
86  /* Turn off network stack components which we don't want */
88 
89  /*
90  * Create the binary api plugin hashes before loading plugins
91  */
92 #if VPP_API_TEST_BUILTIN > 0
94 #endif
95 
96  if (!vlib_plugin_path)
98 }
99 
100 /*
101  * Default path for runtime data
102  */
104 
105 int
106 main (int argc, char *argv[])
107 {
108  int i;
110  uword main_heap_size = (1ULL << 30);
111  u8 *sizep;
112  u32 size;
113  clib_mem_page_sz_t main_heap_log2_page_sz = CLIB_MEM_PAGE_SZ_DEFAULT;
114  clib_mem_page_sz_t default_log2_hugepage_sz = CLIB_MEM_PAGE_SZ_UNKNOWN;
115  unformat_input_t input, sub_input;
116  u8 *s = 0, *v = 0;
117  int main_core = 1;
118  cpu_set_t cpuset;
119  void *main_heap;
120 
121 #if __x86_64__
122  CLIB_UNUSED (const char *msg)
123  = "ERROR: This binary requires CPU with %s extensions.\n";
124 #define _(a,b) \
125  if (!clib_cpu_supports_ ## a ()) \
126  { \
127  fprintf(stderr, msg, b); \
128  exit(1); \
129  }
130 
131 #if __AVX2__
132  _(avx2, "AVX2")
133 #endif
134 #if __AVX__
135  _(avx, "AVX")
136 #endif
137 #if __SSE4_2__
138  _(sse42, "SSE4.2")
139 #endif
140 #if __SSE4_1__
141  _(sse41, "SSE4.1")
142 #endif
143 #if __SSSE3__
144  _(ssse3, "SSSE3")
145 #endif
146 #if __SSE3__
147  _(sse3, "SSE3")
148 #endif
149 #undef _
150 #endif
151  /*
152  * Load startup config from file.
153  * usage: vpp -c /etc/vpp/startup.conf
154  */
155  if ((argc == 3) && !strncmp (argv[1], "-c", 2))
156  {
157  FILE *fp;
158  char inbuf[4096];
159  int argc_ = 1;
160  char **argv_ = NULL;
161  char *arg = NULL;
162  char *p;
163 
164  fp = fopen (argv[2], "r");
165  if (fp == NULL)
166  {
167  fprintf (stderr, "open configuration file '%s' failed\n", argv[2]);
168  return 1;
169  }
170  argv_ = calloc (1, sizeof (char *));
171  if (argv_ == NULL)
172  {
173  fclose (fp);
174  return 1;
175  }
176  arg = strndup (argv[0], 1024);
177  if (arg == NULL)
178  {
179  fclose (fp);
180  free (argv_);
181  return 1;
182  }
183  argv_[0] = arg;
184 
185  while (1)
186  {
187  if (fgets (inbuf, 4096, fp) == 0)
188  break;
189  p = strtok (inbuf, " \t\n");
190  while (p != NULL)
191  {
192  if (*p == '#')
193  break;
194  argc_++;
195  char **tmp = realloc (argv_, argc_ * sizeof (char *));
196  if (tmp == NULL)
197  return 1;
198  argv_ = tmp;
199  arg = strndup (p, 1024);
200  if (arg == NULL)
201  return 1;
202  argv_[argc_ - 1] = arg;
203  p = strtok (NULL, " \t\n");
204  }
205  }
206 
207  fclose (fp);
208 
209  char **tmp = realloc (argv_, (argc_ + 1) * sizeof (char *));
210  if (tmp == NULL)
211  return 1;
212  argv_ = tmp;
213  argv_[argc_] = NULL;
214 
215  argc = argc_;
216  argv = argv_;
217  }
218 
219  /*
220  * Look for and parse the "heapsize" config parameter.
221  * Manual since none of the clib infra has been bootstrapped yet.
222  *
223  * Format: heapsize <nn>[mM][gG]
224  */
225 
226  for (i = 1; i < (argc - 1); i++)
227  {
228  if (!strncmp (argv[i], "plugin_path", 11))
229  {
230  if (i < (argc - 1))
231  vlib_plugin_path = argv[++i];
232  }
233  if (!strncmp (argv[i], "test_plugin_path", 16))
234  {
235  if (i < (argc - 1))
236  vat_plugin_path = argv[++i];
237  }
238  else if (!strncmp (argv[i], "heapsize", 8))
239  {
240  sizep = (u8 *) argv[i + 1];
241  size = 0;
242  while (*sizep >= '0' && *sizep <= '9')
243  {
244  size *= 10;
245  size += *sizep++ - '0';
246  }
247  if (size == 0)
248  {
249  fprintf
250  (stderr,
251  "warning: heapsize parse error '%s', use default %lld\n",
252  argv[i], (long long int) main_heap_size);
253  goto defaulted;
254  }
255 
256  main_heap_size = size;
257 
258  if (*sizep == 'g' || *sizep == 'G')
259  main_heap_size <<= 30;
260  else if (*sizep == 'm' || *sizep == 'M')
261  main_heap_size <<= 20;
262  }
263  else if (!strncmp (argv[i], "main-core", 9))
264  {
265  if (i < (argc - 1))
266  {
267  errno = 0;
268  unsigned long x = strtol (argv[++i], 0, 0);
269  if (errno == 0)
270  main_core = x;
271  }
272  }
273  }
274 defaulted:
275 
276  /* temporary heap */
277  clib_mem_init (0, 1 << 20);
278  unformat_init_command_line (&input, (char **) argv);
279 
280  while (unformat_check_input (&input) != UNFORMAT_END_OF_INPUT)
281  {
282  if (unformat (&input, "memory %v", &v))
283  {
284  unformat_init_vector (&sub_input, v);
285  v = 0;
286  while (unformat_check_input (&sub_input) != UNFORMAT_END_OF_INPUT)
287  {
288  if (unformat (&sub_input, "main-heap-size %U",
289  unformat_memory_size, &main_heap_size))
290  ;
291  else if (unformat (&sub_input, "main-heap-page-size %U",
293  &main_heap_log2_page_sz))
294  ;
295  else if (unformat (&sub_input, "default-hugepage-size %U",
297  &default_log2_hugepage_sz))
298  ;
299  else
300  {
301  fformat (stderr, "unknown 'memory' config input '%U'\n",
302  format_unformat_error, &sub_input);
303  exit (1);
304  }
305 
306  }
307  unformat_free (&sub_input);
308  }
309  else if (!unformat (&input, "%s %v", &s, &v))
310  break;
311 
312  vec_reset_length (s);
313  vec_reset_length (v);
314  }
315  vec_free (s);
316  vec_free (v);
317 
318  unformat_free (&input);
319 
320  /* set process affinity for main thread */
321  CPU_ZERO (&cpuset);
322  CPU_SET (main_core, &cpuset);
323  pthread_setaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
324 
325  /* Set up the plugin message ID allocator right now... */
327 
328  /* destroy temporary heap and create main one */
329  clib_mem_destroy ();
330 
331  if ((main_heap = clib_mem_init_with_page_size (main_heap_size,
332  main_heap_log2_page_sz)))
333  {
334  /* Figure out which numa runs the main thread */
335  __os_numa_index = clib_get_current_numa_node ();
336 
337  if (default_log2_hugepage_sz != CLIB_MEM_PAGE_SZ_UNKNOWN)
338  clib_mem_set_log2_default_hugepage_size (default_log2_hugepage_sz);
339 
340  /* and use the main heap as that numa's numa heap */
341  clib_mem_set_per_numa_heap (main_heap);
342  vlib_main_init ();
344  return vlib_unix_main (argc, argv);
345  }
346  else
347  {
348  {
349  int rv __attribute__ ((unused)) =
350  write (2, "Main heap allocation failure!\r\n", 31);
351  }
352  return 1;
353  }
354 }
355 
356 static clib_error_t *
358 {
359  return 0;
360 }
361 
363 
364 static clib_error_t *
366 {
367  return 0;
368 }
369 
371 
372 static clib_error_t *
374 {
375  u8 *junk;
376 
378  {
379  if (unformat (input, "%s", &junk))
380  {
381  vec_free (junk);
382  return 0;
383  }
384  else
385  return clib_error_return (0, "unknown input '%U'",
386  format_unformat_error, input);
387  }
388  return 0;
389 }
390 
391 static clib_error_t *
393 {
394  return placeholder_path_config (vm, input);
395 }
396 
398 
399 static clib_error_t *
401 {
402  return placeholder_path_config (vm, input);
403 }
404 
405 VLIB_CONFIG_FUNCTION (test_plugin_path_config, "test_plugin_path");
406 
407 void vl_msg_api_post_mortem_dump (void);
408 void vlib_post_mortem_dump (void);
409 
410 void
411 os_panic (void)
412 {
415  abort ();
416 }
417 
418 void vhost_user_unmap_all (void) __attribute__ ((weak));
419 void
421 {
422 }
423 
424 void
425 os_exit (int code)
426 {
427  static int recursion_block;
428 
429  if (code)
430  {
431  if (recursion_block)
432  abort ();
433 
434  recursion_block = 1;
435 
439  abort ();
440  }
441  exit (code);
442 }
443 
444 #ifdef BARRIER_TRACING
445 void
447 {
449 }
450 #endif
451 
452 void
454 {
456 }
457 
458 void
460 {
462 }
463 
464 /* This application needs 1 thread stack for the stats pthread */
465 u32
467 {
468  return 1;
469 }
470 
471 /*
472  * Depending on the configuration selected above,
473  * it may be necessary to generate stub graph nodes.
474  * It is never OK to ignore "node 'x' refers to unknown node 'y'
475  * messages!
476  */
477 
478 #include <vppinfra/bihash_8_8.h>
479 
480 static clib_error_t *
482  unformat_input_t * input, vlib_cli_command_t * cmd)
483 {
484  int i;
485  clib_bihash_8_8_t *h;
486  int verbose = 0;
487 
488  if (unformat (input, "verbose"))
489  verbose = 1;
490 
491  for (i = 0; i < vec_len (clib_all_bihashes); i++)
492  {
493  h = (clib_bihash_8_8_t *) clib_all_bihashes[i];
494  vlib_cli_output (vm, "\n%U", h->fmt_fn, h, verbose);
495  }
496 
497  return 0;
498 }
499 
500 /* *INDENT-OFF* */
502 {
503  .path = "show bihash",
504  .short_help = "show bihash",
505  .function = show_bihash_command_fn,
506 };
507 /* *INDENT-ON* */
508 
509 #ifdef CLIB_SANITIZE_ADDR
510 /* default options for Address Sanitizer */
511 const char *
512 __asan_default_options (void)
513 {
514  return VPP_SANITIZE_ADDR_OPTIONS;
515 }
516 #endif /* CLIB_SANITIZE_ADDR */
517 
518 /*
519  * fd.io coding-style-patch-verification: ON
520  *
521  * Local Variables:
522  * eval: (c-set-style "gnu")
523  * End:
524  */
vec_reset_length
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Definition: vec_bootstrap.h:194
vlib.h
os_panic
void os_panic(void)
Definition: main.c:411
tmp
u32 * tmp
Definition: interface_output.c:1096
vat_plugin_path
char * vat_plugin_path
Definition: main.c:36
vlib_worker_thread_barrier_release
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
Definition: threads.c:1375
show_bihash_command
static vlib_cli_command_t show_bihash_command
(constructor) VLIB_CLI_COMMAND (show_bihash_command)
Definition: main.c:501
unformat_init_vector
void unformat_init_vector(unformat_input_t *input, u8 *vector_string)
Definition: unformat.c:1037
show_bihash_command_fn
static clib_error_t * show_bihash_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: main.c:481
plugin_path_config
static clib_error_t * plugin_path_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:392
bihash_8_8.h
realloc
void * realloc(void *p, size_t size)
Definition: mem.c:67
VL_MSG_FIRST_AVAILABLE
@ VL_MSG_FIRST_AVAILABLE
Definition: vpe_msg_enum.h:25
path
vl_api_fib_path_t path
Definition: mfib_types.api:44
threads.h
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
vlib_cli_command_t::path
char * path
Definition: cli.h:96
u16
unsigned short u16
Definition: types.h:57
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
vhost_user_unmap_all
void vhost_user_unmap_all(void)
Definition: main.c:420
vl_msg_api_set_first_available_msg_id
void vl_msg_api_set_first_available_msg_id(u16 first_avail)
Definition: api_shared.c:1039
unformat_input_t
struct _unformat_input_t unformat_input_t
vlib_worker_threads
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:35
clib_mem_set_per_numa_heap
static void * clib_mem_set_per_numa_heap(void *new_heap)
Definition: mem.h:187
vlib_plugin_app_version
char * vlib_plugin_app_version
Definition: main.c:35
ethernet.h
h
h
Definition: flowhash_template.h:372
VLIB_CONFIG_FUNCTION
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:181
vlib_unix_main
int vlib_unix_main(int argc, char *argv[])
Definition: main.c:694
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
unformat_memory_size
unformat_function_t unformat_memory_size
Definition: format.h:288
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
vat_plugin_hash_create
void vat_plugin_hash_create(void)
Definition: api_main.c:87
unformat_free
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
vlib_app_num_thread_stacks_needed
u32 vlib_app_num_thread_stacks_needed(void)
Definition: main.c:466
vpe_main_init
static void vpe_main_init(vlib_main_t *vm)
Definition: main.c:75
clib_all_bihashes
__clib_export void ** clib_all_bihashes
Definition: bihash_all_vector.c:19
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vlib_worker_thread_barrier_sync
#define vlib_worker_thread_barrier_sync(X)
Definition: threads.h:173
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
vlib_config_function_runtime_t
Definition: init.h:68
srp_init
static clib_error_t * srp_init(vlib_main_t *vm)
Definition: node.c:875
vl_msg_api_barrier_release
void vl_msg_api_barrier_release(void)
Definition: main.c:459
uword
u64 uword
Definition: types.h:112
clib_mem_destroy
void clib_mem_destroy(void)
Definition: mem_dlmalloc.c:287
vlib_worker_thread_t::barrier_context
const char * barrier_context
Definition: threads.h:102
clib_mem_set_log2_default_hugepage_size
static_always_inline void clib_mem_set_log2_default_hugepage_size(clib_mem_page_sz_t log2_page_sz)
Definition: mem.h:477
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
clib_get_current_numa_node
__clib_export u32 clib_get_current_numa_node()
Definition: cpu.c:234
vlib_main_init
static void vlib_main_init()
Definition: main.h:464
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
cpu.h
plugin.h
test_plugin_path_config
static clib_error_t * test_plugin_path_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:400
placeholder_path_config
static clib_error_t * placeholder_path_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:373
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
size
u32 size
Definition: vhost_user.h:125
main
int main(int argc, char *argv[])
Definition: main.c:106
heapsize_config
static clib_error_t * heapsize_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:365
format
description fragment has unexpected format
Definition: map.api:433
vl_msg_api_barrier_trace_context
#define vl_msg_api_barrier_trace_context(X)
Definition: api_common.h:192
u32
unsigned int u32
Definition: types.h:88
vlib_post_mortem_dump
void vlib_post_mortem_dump(void)
Definition: main.c:748
CLIB_MEM_PAGE_SZ_DEFAULT
@ CLIB_MEM_PAGE_SZ_DEFAULT
Definition: mem.h:60
vlib_get_first_main
static vlib_main_t * vlib_get_first_main(void)
Definition: global_funcs.h:44
vpe_msg_enum.h
vl_msg_api_post_mortem_dump
void vl_msg_api_post_mortem_dump(void)
Definition: api_shared.c:969
vlib_mark_init_function_complete
#define vlib_mark_init_function_complete(vm, x)
Definition: init.h:274
vl_msg_api_barrier_sync
void vl_msg_api_barrier_sync(void)
Definition: main.c:453
fformat
__clib_export word fformat(FILE *f, char *fmt,...)
Definition: format.c:466
memory_config
static clib_error_t * memory_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:357
vpp_find_plugin_path
static void vpp_find_plugin_path()
Definition: main.c:39
clib_mem_init
void * clib_mem_init(void *base, uword size)
Definition: mem_dlmalloc.c:266
vlib_main_t
Definition: main.h:102
calloc
void * calloc(size_t nmemb, size_t size)
Definition: mem.c:54
clib_mem_page_sz_t
clib_mem_page_sz_t
Definition: mem.h:57
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
unix.h
i
int i
Definition: flowhash_template.h:376
free
void free(void *p)
Definition: mem.c:42
unformat_log2_page_size
unformat_function_t unformat_log2_page_size
Definition: format.h:294
unformat_init_command_line
void unformat_init_command_line(unformat_input_t *input, char *argv[])
Definition: unformat.c:1013
clib_mem_init_with_page_size
void * clib_mem_init_with_page_size(uword memory_size, clib_mem_page_sz_t log2_page_sz)
Definition: mem_dlmalloc.c:273
context
u32 context
Definition: ip.api:852
rv
int __clib_unused rv
Definition: application.c:491
vlib_plugin_path
char * vlib_plugin_path
Definition: main.c:34
os_exit
void os_exit(int code)
Definition: main.c:425
vlib_cli_command_t
Definition: cli.h:92
CLIB_MEM_PAGE_SZ_UNKNOWN
@ CLIB_MEM_PAGE_SZ_UNKNOWN
Definition: mem.h:59
vlib_unix_cli_set_prompt
void vlib_unix_cli_set_prompt(char *prompt)
Set the CLI prompt.
Definition: cli.c:3288
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
vlib_default_runtime_dir
char * vlib_default_runtime_dir
Definition: main.c:59