FD.io VPP  v17.01.1-3-gc6833f8
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 #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 
22 #include <vpp-api/vpe_msg_enum.h>
23 
24 #if DPDK
25 #include <vnet/devices/dpdk/dpdk.h>
26 
27 /*
28  * Called by the dpdk driver's rte_delay_us() function.
29  * Return 0 to have the dpdk do a regular delay loop.
30  * Return 1 if to skip the delay loop because we are suspending
31  * the calling vlib process instead.
32  */
33 int
34 rte_delay_us_override (unsigned us)
35 {
36  vlib_main_t *vm;
37 
38  /* Don't bother intercepting for short delays */
39  if (us < 10)
40  return 0;
41 
42  /*
43  * Only intercept if we are in a vlib process.
44  * If we are called from a vlib worker thread or the vlib main
45  * thread then do not intercept. (Must not be called from an
46  * independent pthread).
47  */
48  if (os_get_cpu_number () == 0)
49  {
50  /*
51  * We're in the vlib main thread or a vlib process. Make sure
52  * the process is running and we're not still initializing.
53  */
54  vm = vlib_get_main ();
55  if (vlib_in_process_context (vm))
56  {
57  /* Only suspend for the admin_down_process */
59  if (!(proc->flags & VLIB_PROCESS_IS_RUNNING) ||
61  return 0;
62 
63  f64 delay = 1e-6 * us;
64  vlib_process_suspend (vm, delay);
65  return 1;
66  }
67  }
68  return 0; // no override
69 }
70 
71 #if RTE_VERSION >= RTE_VERSION_NUM(16, 11, 0, 0)
72 static void
74 {
75  if (rte_delay_us_override (us) == 0)
76  rte_delay_us_block (us);
77 }
78 #endif
79 #endif
80 
81 static void
83 {
84  if (CLIB_DEBUG > 0)
85  vlib_unix_cli_set_prompt ("DBGvpp# ");
86  else
87  vlib_unix_cli_set_prompt ("vpp# ");
88 
89  /* Turn off network stack components which we don't want */
91 
92 #if DPDK
93 #if RTE_VERSION >= RTE_VERSION_NUM(16, 11, 0, 0)
94  /* register custom delay function */
95  rte_delay_us_callback_register (rte_delay_us_override_cb);
96 #endif
97 #endif
98 }
99 
100 /*
101  * Load plugins from /usr/lib/vpp_plugins by default
102  */
103 char *vlib_plugin_path = "/usr/lib/vpp_plugins";
104 
105 void *
107 {
108  static vnet_plugin_handoff_t _rv, *rv = &_rv;
109 
110  rv->vnet_main = vnet_get_main ();
112  return (void *) rv;
113 }
114 
115 int
116 main (int argc, char *argv[])
117 {
118  int i;
121  uword main_heap_size = (1ULL << 30);
122  u8 *sizep;
123  u32 size;
124  void vlib_set_get_handoff_structure_cb (void *cb);
125 
126 #if __x86_64__
127  const char *msg = "ERROR: This binary requires CPU with %s extensions.\n";
128 #define _(a,b) \
129  if (!clib_cpu_supports_ ## a ()) \
130  { \
131  fprintf(stderr, msg, b); \
132  exit(1); \
133  }
134 
135 #if __AVX2__
136  _(avx2, "AVX2")
137 #endif
138 #if __AVX__
139  _(avx, "AVX")
140 #endif
141 #if __SSE4_2__
142  _(sse42, "SSE4.2")
143 #endif
144 #if __SSE4_1__
145  _(sse41, "SSE4.1")
146 #endif
147 #if __SSSE3__
148  _(ssse3, "SSSE3")
149 #endif
150 #if __SSE3__
151  _(sse3, "SSE3")
152 #endif
153 #undef _
154 #endif
155  /*
156  * Load startup config from file.
157  * usage: vpp -c /etc/vpp/startup.conf
158  */
159  if ((argc == 3) && !strncmp (argv[1], "-c", 2))
160  {
161  FILE *fp;
162  char inbuf[4096];
163  int argc_ = 1;
164  char **argv_ = NULL;
165  char *arg = NULL;
166  char *p;
167 
168  fp = fopen (argv[2], "r");
169  if (fp == NULL)
170  {
171  fprintf (stderr, "open configuration file '%s' failed\n", argv[2]);
172  return 1;
173  }
174  argv_ = calloc (1, sizeof (char *));
175  if (argv_ == NULL)
176  return 1;
177  arg = strndup (argv[0], 1024);
178  if (arg == NULL)
179  return 1;
180  argv_[0] = arg;
181 
182  while (1)
183  {
184  if (fgets (inbuf, 4096, fp) == 0)
185  break;
186  p = strtok (inbuf, " \t\n");
187  while (p != NULL)
188  {
189  if (*p == '#')
190  break;
191  argc_++;
192  char **tmp = realloc (argv_, argc_ * sizeof (char *));
193  if (tmp == NULL)
194  return 1;
195  argv_ = tmp;
196  arg = strndup (p, 1024);
197  if (arg == NULL)
198  return 1;
199  argv_[argc_ - 1] = arg;
200  p = strtok (NULL, " \t\n");
201  }
202  }
203 
204  fclose (fp);
205 
206  char **tmp = realloc (argv_, (argc_ + 1) * sizeof (char *));
207  if (tmp == NULL)
208  return 1;
209  argv_ = tmp;
210  argv_[argc_] = NULL;
211 
212  argc = argc_;
213  argv = argv_;
214  }
215 
216  /*
217  * Look for and parse the "heapsize" config parameter.
218  * Manual since none of the clib infra has been bootstrapped yet.
219  *
220  * Format: heapsize <nn>[mM][gG]
221  */
222 
223  for (i = 1; i < (argc - 1); i++)
224  {
225  if (!strncmp (argv[i], "plugin_path", 11))
226  {
227  if (i < (argc - 1))
228  vlib_plugin_path = argv[++i];
229  }
230  else if (!strncmp (argv[i], "heapsize", 8))
231  {
232  sizep = (u8 *) argv[i + 1];
233  size = 0;
234  while (*sizep >= '0' && *sizep <= '9')
235  {
236  size *= 10;
237  size += *sizep++ - '0';
238  }
239  if (size == 0)
240  {
241  fprintf
242  (stderr,
243  "warning: heapsize parse error '%s', use default %lld\n",
244  argv[i], (long long int) main_heap_size);
245  goto defaulted;
246  }
247 
248  main_heap_size = size;
249 
250  if (*sizep == 'g' || *sizep == 'G')
251  main_heap_size <<= 30;
252  else if (*sizep == 'm' || *sizep == 'M')
253  main_heap_size <<= 20;
254  }
255  }
256 
257 defaulted:
258 
259  /* Set up the plugin message ID allocator right now... */
261 
262  /* Allocate main heap */
263  if (clib_mem_init (0, main_heap_size))
264  {
265  vm->init_functions_called = hash_create (0, /* value bytes */ 0);
266  vpe_main_init (vm);
267 #if DPDK == 0
268  unix_physmem_init (vm, 0 /* fail_if_physical_memory_not_present */ );
269 #endif
271  return vlib_unix_main (argc, argv);
272  }
273  else
274  {
275  {
276  int rv __attribute__ ((unused)) =
277  write (2, "Main heap allocation failure!\r\n", 31);
278  }
279  return 1;
280  }
281 }
282 
283 static clib_error_t *
285 {
286  u32 junk;
287 
289  {
290  if (unformat (input, "%dm", &junk)
291  || unformat (input, "%dM", &junk)
292  || unformat (input, "%dg", &junk) || unformat (input, "%dG", &junk))
293  return 0;
294  else
295  return clib_error_return (0, "unknown input '%U'",
296  format_unformat_error, input);
297  }
298  return 0;
299 }
300 
302 
303 static clib_error_t *
305 {
306  u8 *junk;
307 
309  {
310  if (unformat (input, "%s", &junk))
311  {
312  vec_free (junk);
313  return 0;
314  }
315  else
316  return clib_error_return (0, "unknown input '%U'",
317  format_unformat_error, input);
318  }
319  return 0;
320 }
321 
323 
324 void vl_msg_api_post_mortem_dump (void);
325 
326 void
327 os_panic (void)
328 {
330  abort ();
331 }
332 
333 void vhost_user_unmap_all (void) __attribute__ ((weak));
334 void
336 {
337 }
338 
339 void
340 os_exit (int code)
341 {
342  static int recursion_block;
343 
344  if (code)
345  {
346  if (recursion_block)
347  abort ();
348 
349  recursion_block = 1;
350 
353  abort ();
354  }
355  exit (code);
356 }
357 
358 void
360 {
362 }
363 
364 void
366 {
368 }
369 
370 /* This application needs 1 thread stack for the stats pthread */
371 u32
373 {
374  return 1;
375 }
376 
377 /*
378  * Depending on the configuration selected above,
379  * it may be necessary to generate stub graph nodes.
380  * It is never OK to ignore "node 'x' refers to unknown node 'y'
381  * messages!
382  */
383 
384 #if CLIB_DEBUG > 0
385 
386 static clib_error_t *
388  unformat_input_t * input, vlib_cli_command_t * cmd)
389 {
390  u64 *p = (u64 *) 0xdefec8ed;
391 
392  *p = 0xdeadbeef;
393 
394  /* Not so much... */
395  return 0;
396 }
397 
398 /* *INDENT-OFF* */
399 VLIB_CLI_COMMAND (test_crash_command, static) = {
400  .path = "test crash",
401  .short_help = "crash the bus!",
402  .function = test_crash_command_fn,
403 };
404 /* *INDENT-ON* */
405 
406 #endif
407 
408 /*
409  * fd.io coding-style-patch-verification: ON
410  *
411  * Local Variables:
412  * eval: (c-set-style "gnu")
413  * End:
414  */
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
char * vlib_plugin_path
Definition: main.c:103
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
void vl_msg_api_barrier_sync(void)
Definition: main.c:359
vlib_node_runtime_t node_runtime
Definition: node.h:491
int main(int argc, char *argv[])
Definition: main.c:116
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
int rte_delay_us_override(unsigned us)
Definition: main.c:34
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
#define NULL
Definition: clib.h:55
#define vlib_mark_init_function_complete(vm, x)
Definition: init.h:175
uword admin_up_down_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: device.c:783
void vl_msg_api_set_first_available_msg_id(u16 first_avail)
Definition: api_shared.c:1301
ethernet_main_t * ethernet_main
Definition: plugin.h:27
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
Definition: node_funcs.h:432
ethernet_main_t ethernet_main
Definition: ethernet.h:270
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
vlib_node_function_t * function
Definition: node.h:416
void vl_msg_api_barrier_release(void)
Definition: main.c:365
unsigned long u64
Definition: types.h:89
static void vpe_main_init(vlib_main_t *vm)
Definition: main.c:82
void vlib_set_get_handoff_structure_cb(void *cb)
Definition: plugin.c:25
void vl_msg_api_post_mortem_dump(void)
Definition: api_shared.c:1231
void os_panic(void)
Definition: main.c:327
void vlib_unix_cli_set_prompt(char *prompt)
Set the CLI prompt.
Definition: cli.c:2536
uword os_get_cpu_number(void)
Definition: unix-misc.c:224
static clib_error_t * plugin_path_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:304
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:118
void vhost_user_unmap_all(void)
Definition: main.c:335
uword * init_functions_called
Definition: main.h:156
void * clib_mem_init(void *heap, uword size)
Definition: mem_mheap.c:60
static vlib_process_t * vlib_get_current_process(vlib_main_t *vm)
Definition: node_funcs.h:397
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
vlib_main_t vlib_global_main
Definition: main.c:1562
void vlib_worker_thread_barrier_sync(vlib_main_t *vm)
Definition: threads.c:1163
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define hash_create(elts, value_bytes)
Definition: hash.h:658
unsigned int u32
Definition: types.h:88
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
void os_exit(int code)
Definition: main.c:340
u64 size
Definition: vhost-user.h:74
static void rte_delay_us_override_cb(unsigned us)
Definition: main.c:73
u32 vlib_app_num_thread_stacks_needed(void)
Definition: main.c:372
u64 uword
Definition: types.h:112
void * vnet_get_handoff_structure(void)
Definition: main.c:106
unsigned short u16
Definition: types.h:57
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
clib_error_t * unix_physmem_init(vlib_main_t *vm, int physical_memory_required)
Definition: physmem.c:209
int vlib_unix_main(int argc, char *argv[])
Definition: main.c:492
vnet_main_t * vnet_main
Definition: plugin.h:26
u16 flags
Definition: node.h:504
static uword vlib_in_process_context(vlib_main_t *vm)
Definition: node_funcs.h:404
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
Definition: threads.c:1195
static clib_error_t * heapsize_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:284
static clib_error_t * srp_init(vlib_main_t *vm)
Definition: node.c:918
static clib_error_t * test_crash_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: main.c:387
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
#define VLIB_PROCESS_IS_RUNNING
Definition: node.h:511