FD.io VPP  v16.06
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 #include <vlib/vlib.h>
16 #include <vlib/unix/unix.h>
17 #include <vnet/plugin/plugin.h>
18 #include <vnet/ethernet/ethernet.h>
19 
20 #include <api/vpe_msg_enum.h>
21 
22 #if DPDK
23 #include <vnet/devices/dpdk/dpdk.h>
24 #endif
25 
26 static void
28 {
29  if (CLIB_DEBUG > 0)
30  vlib_unix_cli_set_prompt ("DBGvpp# ");
31  else
32  vlib_unix_cli_set_prompt ("vpp# ");
33 
34  /* Turn off network stack components which we don't want */
36 }
37 
38 /*
39  * Load plugins from /usr/lib/vpp_plugins by default
40  */
41 char *vlib_plugin_path = "/usr/lib/vpp_plugins";
42 
44 {
45  static vnet_plugin_handoff_t _rv, *rv = &_rv;
46 
47  rv->vnet_main = vnet_get_main();
49  return (void *)rv;
50 }
51 
52 int main (int argc, char * argv[])
53 {
54  int i;
57  uword main_heap_size = (1ULL << 30);
58  u8 * sizep;
59  u32 size;
60  void vlib_set_get_handoff_structure_cb (void *cb);
61 
62 #if __x86_64__ && !defined(__clang__)
63  __builtin_cpu_init ();
64  const char * msg = "ERROR: This binary requires CPU with %s extensions.\n";
65 #define _(a,b) \
66  if (!__builtin_cpu_supports(a)) \
67  { \
68  fprintf(stderr, msg, b); \
69  exit(1); \
70  }
71 
72 #if __AVX2__
73  _("avx2", "AVX2")
74 #endif
75 #if __AVX__
76  _("avx", "AVX")
77 #endif
78 #if __SSE4_2__
79  _("sse4.2", "SSE4.2")
80 #endif
81 #if __SSE4_1__
82  _("sse4.1", "SSE4.1")
83 #endif
84 #if __SSSE3__
85  _("ssse3", "SSSE3")
86 #endif
87 #if __SSE3__
88  _("sse3", "SSE3")
89 #endif
90 #undef _
91 #endif
92 
93  /*
94  * Load startup config from file.
95  * usage: vpp -c /etc/vpp/startup.conf
96  */
97  if ((argc == 3) && !strncmp(argv[1], "-c", 2))
98  {
99  FILE * fp;
100  char inbuf[4096];
101  int argc_ = 1;
102  char ** argv_ = NULL;
103  char * arg = NULL;
104  char * p;
105 
106  fp = fopen (argv[2], "r");
107  if (fp == NULL)
108  {
109  fprintf(stderr, "open configuration file '%s' failed\n", argv[2]);
110  return 1;
111  }
112  argv_ = calloc(1, sizeof(char *));
113  if (argv_ == NULL)
114  return 1;
115  arg = strndup(argv[0], 1024);
116  if (arg == NULL)
117  return 1;
118  argv_[0] = arg;
119 
120  while (1) {
121  if (fgets(inbuf, 4096, fp) == 0)
122  break;
123  p = strtok(inbuf, " \t\n");
124  while (p != NULL) {
125  if (*p == '#')
126  break;
127  argc_++;
128  char ** tmp = realloc(argv_, argc_ * sizeof(char *));
129  if (tmp == NULL)
130  return 1;
131  argv_ = tmp;
132  arg = strndup(p, 1024);
133  if (arg == NULL)
134  return 1;
135  argv_[argc_ - 1] = arg;
136  p = strtok(NULL, " \t\n");
137  }
138  }
139 
140  fclose(fp);
141 
142  char ** tmp = realloc(argv_, (argc_ + 1) * sizeof(char *));
143  if (tmp == NULL)
144  return 1;
145  argv_ = tmp;
146  argv_[argc_] = NULL;
147 
148  argc = argc_;
149  argv = argv_;
150  }
151 
152  /*
153  * Look for and parse the "heapsize" config parameter.
154  * Manual since none of the clib infra has been bootstrapped yet.
155  *
156  * Format: heapsize <nn>[mM][gG]
157  */
158 
159  for (i = 1; i < (argc-1); i++) {
160  if (!strncmp (argv[i], "plugin_path", 11)) {
161  if (i < (argc-1))
162  vlib_plugin_path = argv[++i];
163  } else if (!strncmp (argv[i], "heapsize", 8)) {
164  sizep = (u8 *) argv[i+1];
165  size = 0;
166  while (*sizep >= '0' && *sizep <= '9') {
167  size *= 10;
168  size += *sizep++ - '0';
169  }
170  if (size == 0) {
171  fprintf
172  (stderr,
173  "warning: heapsize parse error '%s', use default %lld\n",
174  argv[i], (long long int) main_heap_size);
175  goto defaulted;
176  }
177 
178  main_heap_size = size;
179 
180  if (*sizep == 'g' || *sizep == 'G')
181  main_heap_size <<= 30;
182  else if (*sizep == 'm' || *sizep == 'M')
183  main_heap_size <<= 20;
184  }
185  }
186 
187 defaulted:
188 
189  /* Set up the plugin message ID allocator right now... */
191 
192  /* Allocate main heap */
193  if (clib_mem_init (0, main_heap_size)) {
194  vm->init_functions_called = hash_create (0, /* value bytes */ 0);
195  vpe_main_init(vm);
196 #if DPDK
197 #if !DPDK_SHARED_LIB
199 #endif
200 #else
201  unix_physmem_init(vm, 0 /* fail_if_physical_memory_not_present */);
202 #endif
204  return vlib_unix_main (argc, argv);
205  } else {
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 *
216 {
217  u32 junk;
218 
219  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
220  if (unformat (input, "%dm", &junk)
221  || unformat (input, "%dM", &junk)
222  || unformat (input, "%dg", &junk)
223  || 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 
233 
234 static clib_error_t *
236 {
237  u8 * junk;
238 
239  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
240  if (unformat (input, "%s", &junk)) {
241  vec_free(junk);
242  return 0;
243  }
244  else
245  return clib_error_return (0, "unknown input '%U'",
246  format_unformat_error, input);
247  }
248  return 0;
249 }
250 
252 
253 void vl_msg_api_post_mortem_dump(void);
254 
255 void os_panic (void)
256 {
258  abort ();
259 }
260 
261 void vhost_user_unmap_all (void) __attribute__((weak));
262 void vhost_user_unmap_all (void) { }
263 
264 void os_exit (int code)
265 {
266  static int recursion_block;
267 
268  if (code)
269  {
270  if (recursion_block)
271  abort();
272 
273  recursion_block = 1;
274 
277  abort();
278  }
279  exit (code);
280 }
281 
283 {
285 }
286 
288 {
290 }
291 
292 /* This application needs 1 thread stack for the stats pthread */
294 {
295  return 1;
296 }
297 
298 /*
299  * Depending on the configuration selected above,
300  * it may be necessary to generate stub graph nodes.
301  * It is never OK to ignore "node 'x' refers to unknown node 'y'
302  * messages!
303  */
304 
305 #if CLIB_DEBUG > 0
306 
307 static clib_error_t *
309  unformat_input_t * input,
310  vlib_cli_command_t * cmd)
311 {
312  u64 * p = (u64 *)0xdefec8ed;
313 
314  *p = 0xdeadbeef;
315 
316  /* Not so much... */
317  return 0;
318 }
319 
320 VLIB_CLI_COMMAND (test_crash_command, static) = {
321  .path = "test crash",
322  .short_help = "crash the bus!",
323  .function = test_crash_command_fn,
324 };
325 
326 #endif
327 
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:267
char * vlib_plugin_path
Definition: main.c:41
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:942
void vl_msg_api_barrier_sync(void)
Definition: main.c:282
int main(int argc, char *argv[])
Definition: main.c:52
#define UNFORMAT_END_OF_INPUT
Definition: format.h:142
#define NULL
Definition: clib.h:55
#define vlib_mark_init_function_complete(vm, x)
Definition: init.h:173
static void dpdk_pmd_constructor_init()
Definition: dpdk.h:606
always_inline vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
void vl_msg_api_set_first_available_msg_id(u16 first_avail)
Definition: api_shared.c:1101
always_inline uword unformat_check_input(unformat_input_t *i)
Definition: format.h:168
ethernet_main_t * ethernet_main
Definition: plugin.h:27
ethernet_main_t ethernet_main
Definition: ethernet.h:226
vnet_main_t * vnet_get_main(void)
Definition: misc.c:45
void vl_msg_api_barrier_release(void)
Definition: main.c:287
unsigned long u64
Definition: types.h:89
static void vpe_main_init(vlib_main_t *vm)
Definition: main.c:27
void vlib_set_get_handoff_structure_cb(void *cb)
Definition: plugin.c:24
void vl_msg_api_post_mortem_dump(void)
Definition: api_shared.c:1036
void os_panic(void)
Definition: main.c:255
void vlib_unix_cli_set_prompt(char *prompt)
Set the CLI prompt.
Definition: cli.c:2189
static clib_error_t * plugin_path_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:235
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:116
void vhost_user_unmap_all(void)
Definition: main.c:262
uword * init_functions_called
Definition: main.h:156
void * clib_mem_init(void *heap, uword size)
Definition: mem_mheap.c:65
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:298
vlib_main_t vlib_global_main
Definition: main.c:1505
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:150
#define hash_create(elts, value_bytes)
Definition: hash.h:615
void vlib_worker_thread_barrier_sync(vlib_main_t *vm)
Definition: threads.c:1100
unsigned int u32
Definition: types.h:88
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:87
void os_exit(int code)
Definition: main.c:264
u32 size
Definition: vhost-user.h:74
u32 vlib_app_num_thread_stacks_needed(void)
Definition: main.c:293
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
Definition: threads.c:1131
u64 uword
Definition: types.h:112
void * vnet_get_handoff_structure(void)
Definition: main.c:43
unsigned short u16
Definition: types.h:57
unsigned char u8
Definition: types.h:56
clib_error_t * unix_physmem_init(vlib_main_t *vm, int physical_memory_required)
Definition: physmem.c:204
int vlib_unix_main(int argc, char *argv[])
Definition: main.c:431
vnet_main_t * vnet_main
Definition: plugin.h:26
static clib_error_t * heapsize_config(vlib_main_t *vm, unformat_input_t *input)
Definition: main.c:215
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:308
#define clib_error_return(e, args...)
Definition: error.h:112
struct _unformat_input_t unformat_input_t