FD.io VPP  v18.01.2-1-g9b554f3
Vector Packet Processing
builtin_http_server.c
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2015-2017 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 <vnet/vnet.h>
19 
20 typedef enum
21 {
24 
25 typedef struct
26 {
29  u8 *data;
31 
32 typedef struct
33 {
37 
39 
41 
42  /* Sever's event queue */
44 
45  /* API client handle */
47 
49 
50  /* process node index for evnt scheduling */
52 
58 
60 
61 static void
63 {
67  vlib_node_t *n;
68  u32 node_index;
69  builtin_http_server_args **save_args;
70 
71  node_index = args->node_index;
72  ASSERT (node_index != 0);
73 
74  n = vlib_get_node (vm, node_index);
75  rt = vlib_node_get_runtime (vm, n->index);
76  save_args = vlib_node_get_runtime_data (vm, n->index);
77 
78  /* Reset process session pointer */
79  clib_mem_free (*save_args);
80  *save_args = 0;
81 
82  /* Turn off the process node */
83  vlib_node_set_state (vm, rt->node_index, VLIB_NODE_STATE_DISABLED);
84 
85  /* add node index to the freelist */
87 }
88 
89 static const char
90  *http_response = "HTTP/1.1 200 OK\r\n"
91  "Content-Type: text/html\r\n"
92  "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
93  "Connection: close\r\n"
94  "Pragma: no-cache\r\n" "Content-Length: %d\r\n\r\n%s";
95 
96 static const char
97  *http_error_template = "HTTP/1.1 %s\r\n"
98  "Content-Type: text/html\r\n"
99  "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
100  "Connection: close\r\n" "Pragma: no-cache\r\n" "Content-Length: 0\r\n\r\n";
101 
102 /* Header, including incantation to suppress favicon.ico requests */
103 static const char
104  *html_header_template = "<html><head><title>%v</title>"
105  "</head><link rel=\"icon\" href=\"data:,\"><body><pre>";
106 
107 static const char *html_footer = "</pre></body></html>\r\n";
108 
109 static const char
110  *html_header_static = "<html><head><title>static reply</title></head>"
111  "<link rel=\"icon\" href=\"data:,\"><body><pre>hello</pre></body>"
112  "</html>\r\n";
113 
114 static u8 *static_http;
115 
116 static void
117 http_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
118 {
119  u8 **output_vecp = (u8 **) arg;
120  u8 *output_vec;
121  u32 offset;
122 
123  output_vec = *output_vecp;
124 
125  offset = vec_len (output_vec);
126  vec_validate (output_vec, offset + buffer_bytes - 1);
127  clib_memcpy (output_vec + offset, buffer, buffer_bytes);
128 
129  *output_vecp = output_vec;
130 }
131 
132 void
134 {
135  session_fifo_event_t evt;
136  u32 offset, bytes_to_send;
137  f64 delay = 10e-3;
139  vlib_main_t *vm = hsm->vlib_main;
140  f64 last_sent_timer = vlib_time_now (vm);
141 
142  bytes_to_send = vec_len (data);
143  offset = 0;
144 
145  while (bytes_to_send > 0)
146  {
147  int actual_transfer;
148 
149  actual_transfer = svm_fifo_enqueue_nowait
150  (s->server_tx_fifo, bytes_to_send, data + offset);
151 
152  /* Made any progress? */
153  if (actual_transfer <= 0)
154  {
155  vlib_process_suspend (vm, delay);
156  /* 10s deadman timer */
157  if (vlib_time_now (vm) > last_sent_timer + 10.0)
158  {
159  /* $$$$ FC: reset transport session here? */
160  break;
161  }
162  /* Exponential backoff, within reason */
163  if (delay < 1.0)
164  delay = delay * 2.0;
165  }
166  else
167  {
168  last_sent_timer = vlib_time_now (vm);
169  offset += actual_transfer;
170  bytes_to_send -= actual_transfer;
171 
172  if (svm_fifo_set_event (s->server_tx_fifo))
173  {
174  /* Fabricate TX event, send to vpp */
175  evt.fifo = s->server_tx_fifo;
176  evt.event_type = FIFO_EVENT_APP_TX;
177 
178  unix_shared_memory_queue_add (hsm->vpp_queue[s->thread_index],
179  (u8 *) & evt,
180  0 /* do wait for mutex */ );
181  }
182  delay = 10e-3;
183  }
184  }
185 }
186 
187 static void
188 send_error (stream_session_t * s, char *str)
189 {
190  u8 *data;
191 
192  data = format (0, http_error_template, str);
193  send_data (s, data);
194  vec_free (data);
195 }
196 
197 static uword
200 {
202  u8 *request = 0, *reply = 0;
203  builtin_http_server_args **save_args;
205  stream_session_t *s;
206  unformat_input_t input;
207  int i;
208  u8 *http = 0, *html = 0;
209 
210  save_args = vlib_node_get_runtime_data (hsm->vlib_main, rt->node_index);
211  args = *save_args;
213  ASSERT (s);
214 
215  request = (u8 *) (void *) (args->data);
216  if (vec_len (request) < 7)
217  {
218  send_error (s, "400 Bad Request");
219  goto out;
220  }
221 
222  for (i = 0; i < vec_len (request) - 4; i++)
223  {
224  if (request[i] == 'G' &&
225  request[i + 1] == 'E' &&
226  request[i + 2] == 'T' && request[i + 3] == ' ')
227  goto found;
228  }
229 bad_request:
230  send_error (s, "400 Bad Request");
231  goto out;
232 
233 found:
234  /* Lose "GET " */
235  vec_delete (request, i + 5, 0);
236 
237  /* Replace slashes with spaces, stop at the end of the path */
238  i = 0;
239  while (1)
240  {
241  if (request[i] == '/')
242  request[i] = ' ';
243  else if (request[i] == ' ')
244  {
245  /* vlib_cli_input is vector-based, no need for a NULL */
246  _vec_len (request) = i;
247  break;
248  }
249  i++;
250  /* Should never happen */
251  if (i == vec_len (request))
252  goto bad_request;
253  }
254 
255  /* Generate the html header */
256  html = format (0, html_header_template, request /* title */ );
257 
258  /* Run the command */
259  unformat_init_vector (&input, request);
260  vlib_cli_input (vm, &input, http_cli_output, (uword) & reply);
261  unformat_free (&input);
262  request = 0;
263 
264  /* Generate the html page */
265  html = format (html, "%v", reply);
266  html = format (html, html_footer);
267  /* And the http reply */
268  http = format (0, http_response, vec_len (html), html);
269 
270  /* Send it */
271  send_data (s, http);
272 
273 out:
274  /* Cleanup */
275  vec_free (request);
276  vec_free (reply);
277  vec_free (html);
278  vec_free (http);
279 
280  free_http_process (args);
281  return (0);
282 }
283 
284 static void
286 {
287  char *name;
288  vlib_node_t *n;
290  vlib_main_t *vm = hsm->vlib_main;
292  builtin_http_server_args **save_args;
293 
295  {
297  vlib_node_set_state (vm, n->index, VLIB_NODE_STATE_POLLING);
298  _vec_len (hsm->free_http_cli_process_node_indices) = l - 1;
299  }
300  else
301  {
302  static vlib_node_registration_t r = {
303  .function = http_cli_process,
304  .type = VLIB_NODE_TYPE_PROCESS,
305  .process_log2_n_stack_bytes = 16,
306  .runtime_data_bytes = sizeof (void *),
307  };
308 
309  name = (char *) format (0, "http-cli-%d", l);
310  r.name = name;
311  vlib_register_node (vm, &r);
312  vec_free (name);
313 
314  n = vlib_get_node (vm, r.index);
315  }
316 
317  /* Save the node index in the args. It won't be zero. */
318  args->node_index = n->index;
319 
320  /* Save the args (pointer) in the node runtime */
321  save_args = vlib_node_get_runtime_data (vm, n->index);
322  *save_args = args;
323 
325 }
326 
327 static void
329 {
331 }
332 
333 static int
335 {
337  svm_fifo_t *rx_fifo;
338  u32 max_dequeue;
339  int actual_transfer;
340 
341  rx_fifo = s->server_rx_fifo;
342  max_dequeue = svm_fifo_max_dequeue (rx_fifo);
343  svm_fifo_unset_event (rx_fifo);
344  if (PREDICT_FALSE (max_dequeue == 0))
345  return -1;
346 
347  vec_validate (hsm->rx_buf[s->thread_index], max_dequeue - 1);
348  _vec_len (hsm->rx_buf[s->thread_index]) = max_dequeue;
349 
350  actual_transfer = svm_fifo_dequeue_nowait (rx_fifo, max_dequeue,
351  hsm->rx_buf[s->thread_index]);
352  ASSERT (actual_transfer > 0);
353  _vec_len (hsm->rx_buf[s->thread_index]) = actual_transfer;
354  return 0;
355 }
356 
357 static int
359 {
362  int rv;
363 
364  rv = session_rx_request (s);
365  if (rv)
366  return rv;
367 
368  /* send the command to a new/recycled vlib process */
369  args = clib_mem_alloc (sizeof (*args));
370  args->data = vec_dup (hsm->rx_buf[s->thread_index]);
371  args->session_handle = session_handle (s);
372 
373  /* Send an RPC request via the thread-0 input node */
374  if (vlib_get_thread_index () != 0)
375  {
376  session_fifo_event_t evt;
377  evt.rpc_args.fp = alloc_http_process_callback;
378  evt.rpc_args.arg = args;
379  evt.event_type = FIFO_EVENT_RPC;
381  (session_manager_get_vpp_event_queue (0 /* main thread */ ),
382  (u8 *) & evt, 0 /* do wait for mutex */ );
383  }
384  else
385  alloc_http_process (args);
386  return 0;
387 }
388 
389 static int
391 {
393  u8 *request = 0;
394  int i;
395  int rv;
396 
397  rv = session_rx_request (s);
398  if (rv)
399  return rv;
400 
401  request = hsm->rx_buf[s->thread_index];
402  if (vec_len (request) < 7)
403  {
404  send_error (s, "400 Bad Request");
405  goto out;
406  }
407 
408  for (i = 0; i < vec_len (request) - 4; i++)
409  {
410  if (request[i] == 'G' &&
411  request[i + 1] == 'E' &&
412  request[i + 2] == 'T' && request[i + 3] == ' ')
413  goto found;
414  }
415  send_error (s, "400 Bad Request");
416  goto out;
417 
418 found:
419 
420  /* Send it */
421  send_data (s, static_http);
422 
423 out:
424  /* Cleanup */
425  vec_free (request);
426  hsm->rx_buf[s->thread_index] = request;
427  return 0;
428 }
429 
430 static int
432 {
434 
435  bsm->vpp_queue[s->thread_index] =
436  session_manager_get_vpp_event_queue (s->thread_index);
437  s->session_state = SESSION_STATE_READY;
438  bsm->byte_index = 0;
439  return 0;
440 }
441 
442 static void
444 {
446  vnet_disconnect_args_t _a, *a = &_a;
447 
448  a->handle = session_handle (s);
449  a->app_index = bsm->app_index;
451 }
452 
453 static void
455 {
456  clib_warning ("called.. ");
457 
459 }
460 
461 static int
463  stream_session_t * s, u8 is_fail)
464 {
465  clib_warning ("called...");
466  return -1;
467 }
468 
469 static int
471  const u8 * seg_name, u32 seg_size)
472 {
473  clib_warning ("called...");
474  return -1;
475 }
476 
477 static int
478 builtin_redirect_connect_callback (u32 client_index, void *mp)
479 {
480  clib_warning ("called...");
481  return -1;
482 }
483 
485  .session_accept_callback = builtin_session_accept_callback,
486  .session_disconnect_callback = builtin_session_disconnect_callback,
487  .session_connected_callback = builtin_session_connected_callback,
488  .add_segment_callback = builtin_add_segment_callback,
489  .redirect_connect_callback = builtin_redirect_connect_callback,
490  .builtin_server_rx_callback = http_server_rx_callback,
491  .session_reset_callback = builtin_session_reset_callback
492 };
493 
494 /* Abuse VPP's input queue */
495 static int
497 {
499  api_main_t *am = &api_main;
501 
502  shmem_hdr = am->shmem_hdr;
503  hsm->vl_input_queue = shmem_hdr->vl_input_queue;
504  hsm->my_client_index =
505  vl_api_memclnt_create_internal ("test_http_server", hsm->vl_input_queue);
506  return 0;
507 }
508 
509 static int
511 {
513  u8 segment_name[128];
514  u64 options[APP_OPTIONS_N_OPTIONS];
515  vnet_app_attach_args_t _a, *a = &_a;
516  u32 segment_size = 128 << 20;
517 
518  memset (a, 0, sizeof (*a));
519  memset (options, 0, sizeof (options));
520 
521  if (hsm->private_segment_size)
522  segment_size = hsm->private_segment_size;
523 
524  a->api_client_index = hsm->my_client_index;
525  a->session_cb_vft = &builtin_session_cb_vft;
526  a->options = options;
527  a->options[APP_OPTIONS_SEGMENT_SIZE] = segment_size;
528  a->options[APP_OPTIONS_RX_FIFO_SIZE] =
529  hsm->fifo_size ? hsm->fifo_size : 8 << 10;
530  a->options[APP_OPTIONS_TX_FIFO_SIZE] =
531  hsm->fifo_size ? hsm->fifo_size : 32 << 10;
532  a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
534  a->segment_name = segment_name;
535  a->segment_name_length = ARRAY_LEN (segment_name);
536 
537  if (vnet_application_attach (a))
538  {
539  clib_warning ("failed to attach server");
540  return -1;
541  }
542  hsm->app_index = a->app_index;
543  return 0;
544 }
545 
546 static int
548 {
550  vnet_bind_args_t _a, *a = &_a;
551  memset (a, 0, sizeof (*a));
552  a->app_index = hsm->app_index;
553  a->uri = "tcp://0.0.0.0/80";
554  return vnet_bind_uri (a);
555 }
556 
557 static int
559 {
561  u32 num_threads;
563 
564  ASSERT (hsm->my_client_index == (u32) ~ 0);
565  if (create_api_loopback (vm))
566  return -1;
567 
568  num_threads = 1 /* main thread */ + vtm->n_threads;
569  vec_validate (http_server_main.vpp_queue, num_threads - 1);
570 
571  if (server_attach ())
572  {
573  clib_warning ("failed to attach server");
574  return -1;
575  }
576  if (server_listen ())
577  {
578  clib_warning ("failed to start listening");
579  return -1;
580  }
581  return 0;
582 }
583 
584 static clib_error_t *
586  unformat_input_t * input, vlib_cli_command_t * cmd)
587 {
589  int rv, is_static = 0;
590  u64 seg_size;
591  u8 *html;
592 
593  hsm->prealloc_fifos = 0;
594  hsm->private_segment_size = 0;
595  hsm->fifo_size = 0;
597  {
598  if (unformat (input, "static"))
599  is_static = 1;
600  else if (unformat (input, "prealloc-fifos %d", &hsm->prealloc_fifos))
601  ;
602  else if (unformat (input, "private-segment-size %U",
603  unformat_memory_size, &seg_size))
604  {
605  if (seg_size >= 0x100000000ULL)
606  {
607  vlib_cli_output (vm, "private segment size %llu, too large",
608  seg_size);
609  return 0;
610  }
611  hsm->private_segment_size = seg_size;
612  }
613  else if (unformat (input, "fifo-size %d", &hsm->fifo_size))
614  hsm->fifo_size <<= 10;
615  else
616  return clib_error_return (0, "unknown input `%U'",
617  format_unformat_error, input);
618  }
619  if (hsm->my_client_index != (u32) ~ 0)
620  return clib_error_return (0, "test http server is already running");
621 
622  vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */ );
623 
624  if (is_static)
625  {
626  builtin_session_cb_vft.builtin_server_rx_callback =
628  html = format (0, html_header_static);
629  static_http = format (0, http_response, vec_len (html), html);
630  }
631  rv = server_create (vm);
632  switch (rv)
633  {
634  case 0:
635  break;
636  default:
637  return clib_error_return (0, "server_create returned %d", rv);
638  }
639  return 0;
640 }
641 
642 /* *INDENT-OFF* */
643 VLIB_CLI_COMMAND (server_create_command, static) =
644 {
645  .path = "test http server",
646  .short_help = "test http server",
647  .function = server_create_command_fn,
648 };
649 /* *INDENT-ON* */
650 
651 static clib_error_t *
653 {
656  u32 num_threads;
657 
658  hsm->my_client_index = ~0;
659  hsm->vlib_main = vm;
660  num_threads = 1 /* main thread */ + vtm->n_threads;
661  vec_validate (hsm->rx_buf, num_threads - 1);
662  return 0;
663 }
664 
666 
667 /*
668 * fd.io coding-style-patch-verification: ON
669 *
670 * Local Variables:
671 * eval: (c-set-style "gnu")
672 * End:
673 */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:432
static void http_cli_output(uword arg, u8 *buffer, uword buffer_bytes)
vlib_main_t vlib_global_main
Definition: main.c:1637
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
static u8 * static_http
a
Definition: bitmap.h:516
void vlib_cli_input(vlib_main_t *vm, unformat_input_t *input, vlib_cli_output_function_t *function, uword function_arg)
Definition: cli.c:643
int vnet_bind_uri(vnet_bind_args_t *a)
void send_data(stream_session_t *s, u8 *data)
static int session_rx_request(stream_session_t *s)
unix_shared_memory_queue_t * vl_input_queue
Definition: api_common.h:68
static const char * http_error_template
static void alloc_http_process_callback(void *cb_args)
u32 index
Definition: node.h:237
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:224
static int http_server_rx_callback(stream_session_t *s)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:518
struct _vlib_node_registration vlib_node_registration_t
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static void free_http_process(builtin_http_server_args *args)
static int builtin_add_segment_callback(u32 client_index, const u8 *seg_name, u32 seg_size)
static const char * http_response
static int server_attach()
struct _svm_fifo svm_fifo_t
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:448
unix_shared_memory_queue_t ** vpp_queue
static clib_error_t * server_create_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static void alloc_http_process(builtin_http_server_args *args)
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
struct _vnet_disconnect_args_t vnet_disconnect_args_t
static const char * html_header_static
static u32 svm_fifo_max_dequeue(svm_fifo_t *f)
Definition: svm_fifo.h:100
static int builtin_session_connected_callback(u32 app_index, u32 api_context, stream_session_t *s, u8 is_fail)
struct _stream_session_cb_vft session_cb_vft_t
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned long u64
Definition: types.h:89
struct vl_shmem_hdr_ * shmem_hdr
Binary API shared-memory segment header pointer.
Definition: api_common.h:261
static int server_listen()
void stream_session_cleanup(stream_session_t *s)
Cleanup transport and session state.
Definition: session.c:948
struct _stream_session_t stream_session_t
static const char * html_header_template
struct _vnet_app_attach_args_t vnet_app_attach_args_t
http_server_main_t http_server_main
vl_shmem_hdr_t * shmem_hdr
int unix_shared_memory_queue_add(unix_shared_memory_queue_t *q, u8 *elem, int nowait)
struct _unformat_input_t unformat_input_t
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:370
static void * vlib_node_get_runtime_data(vlib_main_t *vm, u32 node_index)
Get node runtime private data by node index.
Definition: node_funcs.h:110
#define PREDICT_FALSE(x)
Definition: clib.h:105
static void svm_fifo_unset_event(svm_fifo_t *f)
Unsets fifo event flag.
Definition: svm_fifo.h:133
u32 node_index
Node index.
Definition: node.h:437
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: session.c:1171
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:198
void unformat_init_vector(unformat_input_t *input, u8 *vector_string)
Definition: unformat.c:1031
static u8 svm_fifo_set_event(svm_fifo_t *f)
Sets fifo event flag.
Definition: svm_fifo.h:123
static unix_shared_memory_queue_t * session_manager_get_vpp_event_queue(u32 thread_index)
Definition: session.h:459
api_main_t api_main
Definition: api_shared.c:35
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
u32 runtime_index
Definition: node.h:240
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:221
vlib_main_t * vm
Definition: buffer.c:283
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
#define clib_warning(format, args...)
Definition: error.h:59
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:89
static void send_error(stream_session_t *s, char *str)
#define clib_memcpy(a, b, c)
Definition: string.h:75
u32 vl_api_memclnt_create_internal(char *, unix_shared_memory_queue_t *)
Definition: memory_vlib.c:142
int vnet_disconnect_session(vnet_disconnect_args_t *a)
#define ARRAY_LEN(x)
Definition: clib.h:59
int svm_fifo_enqueue_nowait(svm_fifo_t *f, u32 max_bytes, u8 *copy_from_here)
Definition: svm_fifo.c:533
static int builtin_session_accept_callback(stream_session_t *s)
static int builtin_redirect_connect_callback(u32 client_index, void *mp)
unix_shared_memory_queue_t * vl_input_queue
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:781
u32 vlib_register_node(vlib_main_t *vm, vlib_node_registration_t *r)
Definition: node.c:498
static void clib_mem_free(void *p)
Definition: mem.h:179
static int http_server_rx_callback_static(stream_session_t *s)
static void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
Set node dispatch state.
Definition: node_funcs.h:147
static int app_index
static void * clib_mem_alloc(uword size)
Definition: mem.h:112
u64 uword
Definition: types.h:112
static stream_session_t * session_get_from_handle(u64 handle)
Definition: session.h:274
static u64 session_handle(stream_session_t *s)
Definition: session.h:249
static clib_error_t * builtin_http_server_main_init(vlib_main_t *vm)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
clib_error_t * vnet_application_attach(vnet_app_attach_args_t *a)
Attach application to vpp.
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
static int create_api_loopback(vlib_main_t *vm)
static int server_create(vlib_main_t *vm)
static uword http_cli_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
unformat_function_t unformat_memory_size
Definition: format.h:294
struct clib_bihash_value offset
template key/value backing page structure
static const char * html_footer
vhost_user_req_t request
Definition: vhost-user.h:76
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
static vlib_node_t * vlib_get_node(vlib_main_t *vm, u32 i)
Get vlib node by index.
Definition: node_funcs.h:59
http_process_event_t
void vlib_start_process(vlib_main_t *vm, uword process_index)
Definition: main.c:1344
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
int svm_fifo_dequeue_nowait(svm_fifo_t *f, u32 max_bytes, u8 *copy_here)
Definition: svm_fifo.c:690
struct _vnet_bind_args_t vnet_bind_args_t
static void builtin_session_disconnect_callback(stream_session_t *s)
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static session_cb_vft_t builtin_session_cb_vft
static void builtin_session_reset_callback(stream_session_t *s)
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
u32 * free_http_cli_process_node_indices
struct _unix_shared_memory_queue unix_shared_memory_queue_t