FD.io VPP  v18.04-17-g3a0d853
Vector Packet Processing
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 
56  u8 *uri;
59 
61 
62 static void
64 {
68  vlib_node_t *n;
69  u32 node_index;
70  http_server_args **save_args;
71 
72  node_index = args->node_index;
73  ASSERT (node_index != 0);
74 
75  n = vlib_get_node (vm, node_index);
76  rt = vlib_node_get_runtime (vm, n->index);
77  save_args = vlib_node_get_runtime_data (vm, n->index);
78 
79  /* Reset process session pointer */
80  clib_mem_free (*save_args);
81  *save_args = 0;
82 
83  /* Turn off the process node */
84  vlib_node_set_state (vm, rt->node_index, VLIB_NODE_STATE_DISABLED);
85 
86  /* add node index to the freelist */
88 }
89 
90 static const char
91  *http_response = "HTTP/1.1 200 OK\r\n"
92  "Content-Type: text/html\r\n"
93  "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
94  "Connection: close\r\n"
95  "Pragma: no-cache\r\n" "Content-Length: %d\r\n\r\n%s";
96 
97 static const char
98  *http_error_template = "HTTP/1.1 %s\r\n"
99  "Content-Type: text/html\r\n"
100  "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
101  "Connection: close\r\n" "Pragma: no-cache\r\n" "Content-Length: 0\r\n\r\n";
102 
103 /* Header, including incantation to suppress favicon.ico requests */
104 static const char
105  *html_header_template = "<html><head><title>%v</title>"
106  "</head><link rel=\"icon\" href=\"data:,\"><body><pre>";
107 
108 static const char *html_footer = "</pre></body></html>\r\n";
109 
110 static const char
111  *html_header_static = "<html><head><title>static reply</title></head>"
112  "<link rel=\"icon\" href=\"data:,\"><body><pre>hello</pre></body>"
113  "</html>\r\n";
114 
115 static u8 *static_http;
116 
117 static void
118 http_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
119 {
120  u8 **output_vecp = (u8 **) arg;
121  u8 *output_vec;
122  u32 offset;
123 
124  output_vec = *output_vecp;
125 
126  offset = vec_len (output_vec);
127  vec_validate (output_vec, offset + buffer_bytes - 1);
128  clib_memcpy (output_vec + offset, buffer, buffer_bytes);
129 
130  *output_vecp = output_vec;
131 }
132 
133 void
135 {
136  session_fifo_event_t evt;
137  u32 offset, bytes_to_send;
138  f64 delay = 10e-3;
140  vlib_main_t *vm = hsm->vlib_main;
141  f64 last_sent_timer = vlib_time_now (vm);
142 
143  bytes_to_send = vec_len (data);
144  offset = 0;
145 
146  while (bytes_to_send > 0)
147  {
148  int actual_transfer;
149 
150  actual_transfer = svm_fifo_enqueue_nowait
151  (s->server_tx_fifo, bytes_to_send, data + offset);
152 
153  /* Made any progress? */
154  if (actual_transfer <= 0)
155  {
156  vlib_process_suspend (vm, delay);
157  /* 10s deadman timer */
158  if (vlib_time_now (vm) > last_sent_timer + 10.0)
159  {
160  /* $$$$ FC: reset transport session here? */
161  break;
162  }
163  /* Exponential backoff, within reason */
164  if (delay < 1.0)
165  delay = delay * 2.0;
166  }
167  else
168  {
169  last_sent_timer = vlib_time_now (vm);
170  offset += actual_transfer;
171  bytes_to_send -= actual_transfer;
172 
173  if (svm_fifo_set_event (s->server_tx_fifo))
174  {
175  /* Fabricate TX event, send to vpp */
176  evt.fifo = s->server_tx_fifo;
177  evt.event_type = FIFO_EVENT_APP_TX;
178 
179  svm_queue_add (hsm->vpp_queue[s->thread_index],
180  (u8 *) & evt, 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  http_server_args **save_args;
204  http_server_args *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  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 {
330  alloc_http_process ((http_server_args *) cb_args);
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 {
361  http_server_args *args;
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.. ");
458 }
459 
460 static int
462  stream_session_t * s, u8 is_fail)
463 {
464  clib_warning ("called...");
465  return -1;
466 }
467 
468 static int
470 {
471  clib_warning ("called...");
472  return -1;
473 }
474 
476  .session_accept_callback = http_server_session_accept_callback,
477  .session_disconnect_callback = http_server_session_disconnect_callback,
478  .session_connected_callback = http_server_session_connected_callback,
479  .add_segment_callback = http_server_add_segment_callback,
480  .builtin_app_rx_callback = http_server_rx_callback,
481  .session_reset_callback = http_server_session_reset_callback
482 };
483 
484 /* Abuse VPP's input queue */
485 static int
487 {
489  api_main_t *am = &api_main;
491 
492  shmem_hdr = am->shmem_hdr;
493  hsm->vl_input_queue = shmem_hdr->vl_input_queue;
494  hsm->my_client_index =
495  vl_api_memclnt_create_internal ("http_server", hsm->vl_input_queue);
496  return 0;
497 }
498 
499 static int
501 {
502  vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert;
503  vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key;
505  u64 options[APP_OPTIONS_N_OPTIONS];
506  vnet_app_attach_args_t _a, *a = &_a;
507  u32 segment_size = 128 << 20;
508 
509  memset (a, 0, sizeof (*a));
510  memset (options, 0, sizeof (options));
511 
512  if (hsm->private_segment_size)
513  segment_size = hsm->private_segment_size;
514 
515  a->api_client_index = hsm->my_client_index;
516  a->session_cb_vft = &http_server_session_cb_vft;
517  a->options = options;
518  a->options[APP_OPTIONS_SEGMENT_SIZE] = segment_size;
519  a->options[APP_OPTIONS_RX_FIFO_SIZE] =
520  hsm->fifo_size ? hsm->fifo_size : 8 << 10;
521  a->options[APP_OPTIONS_TX_FIFO_SIZE] =
522  hsm->fifo_size ? hsm->fifo_size : 32 << 10;
523  a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
525 
526  if (vnet_application_attach (a))
527  {
528  clib_warning ("failed to attach server");
529  return -1;
530  }
531  hsm->app_index = a->app_index;
532 
533  memset (a_cert, 0, sizeof (*a_cert));
534  a_cert->app_index = a->app_index;
535  vec_validate (a_cert->cert, test_srv_crt_rsa_len);
537  vnet_app_add_tls_cert (a_cert);
538 
539  memset (a_key, 0, sizeof (*a_key));
540  a_key->app_index = a->app_index;
541  vec_validate (a_key->key, test_srv_key_rsa_len);
543  vnet_app_add_tls_key (a_key);
544 
545  return 0;
546 }
547 
548 static int
550 {
552  vnet_bind_args_t _a, *a = &_a;
553  memset (a, 0, sizeof (*a));
554  a->app_index = hsm->app_index;
555  a->uri = "tcp://0.0.0.0/80";
556  if (hsm->uri)
557  a->uri = (char *) hsm->uri;
558  return vnet_bind_uri (a);
559 }
560 
561 static int
563 {
565  u32 num_threads;
567 
568  ASSERT (hsm->my_client_index == (u32) ~ 0);
569  if (create_api_loopback (vm))
570  return -1;
571 
572  num_threads = 1 /* main thread */ + vtm->n_threads;
573  vec_validate (http_server_main.vpp_queue, num_threads - 1);
574 
575  if (server_attach ())
576  {
577  clib_warning ("failed to attach server");
578  return -1;
579  }
580  if (http_server_listen ())
581  {
582  clib_warning ("failed to start listening");
583  return -1;
584  }
585  return 0;
586 }
587 
588 static clib_error_t *
590  unformat_input_t * input,
591  vlib_cli_command_t * cmd)
592 {
594  int rv, is_static = 0;
595  u64 seg_size;
596  u8 *html;
597 
598  hsm->prealloc_fifos = 0;
599  hsm->private_segment_size = 0;
600  hsm->fifo_size = 0;
602  {
603  if (unformat (input, "static"))
604  is_static = 1;
605  else if (unformat (input, "prealloc-fifos %d", &hsm->prealloc_fifos))
606  ;
607  else if (unformat (input, "private-segment-size %U",
608  unformat_memory_size, &seg_size))
609  {
610  if (seg_size >= 0x100000000ULL)
611  {
612  vlib_cli_output (vm, "private segment size %llu, too large",
613  seg_size);
614  return 0;
615  }
616  hsm->private_segment_size = seg_size;
617  }
618  else if (unformat (input, "fifo-size %d", &hsm->fifo_size))
619  hsm->fifo_size <<= 10;
620  else if (unformat (input, "uri %s", &hsm->uri))
621  ;
622  else
623  return clib_error_return (0, "unknown input `%U'",
624  format_unformat_error, input);
625  }
626  if (hsm->my_client_index != (u32) ~ 0)
627  return clib_error_return (0, "test http server is already running");
628 
629  vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */ );
630 
631  if (is_static)
632  {
633  http_server_session_cb_vft.builtin_app_rx_callback =
635  html = format (0, html_header_static);
636  static_http = format (0, http_response, vec_len (html), html);
637  }
638  rv = http_server_create (vm);
639  switch (rv)
640  {
641  case 0:
642  break;
643  default:
644  return clib_error_return (0, "server_create returned %d", rv);
645  }
646  return 0;
647 }
648 
649 /* *INDENT-OFF* */
650 VLIB_CLI_COMMAND (http_server_create_command, static) =
651 {
652  .path = "test http server",
653  .short_help = "test http server",
654  .function = http_server_create_command_fn,
655 };
656 /* *INDENT-ON* */
657 
658 static clib_error_t *
660 {
663  u32 num_threads;
664 
665  hsm->my_client_index = ~0;
666  hsm->vlib_main = vm;
667  num_threads = 1 /* main thread */ + vtm->n_threads;
668  vec_validate (hsm->rx_buf, num_threads - 1);
669  return 0;
670 }
671 
673 
674 /*
675 * fd.io coding-style-patch-verification: ON
676 *
677 * Local Variables:
678 * eval: (c-set-style "gnu")
679 * End:
680 */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:434
static svm_queue_t * session_manager_get_vpp_event_queue(u32 thread_index)
Definition: session.h:505
static void http_server_session_disconnect_callback(stream_session_t *s)
Definition: http_server.c:443
vlib_main_t vlib_global_main
Definition: main.c:1642
int svm_queue_add(svm_queue_t *q, u8 *elem, int nowait)
Definition: queue.c:184
static int http_server_create(vlib_main_t *vm)
Definition: http_server.c:562
u32 vl_api_memclnt_create_internal(char *name, svm_queue_t *q)
Definition: memory_api.c:112
a
Definition: bitmap.h:516
const u32 test_srv_crt_rsa_len
static const char * html_header_template
Definition: http_server.c:105
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
svm_queue_t * vl_input_queue
Definition: http_server.c:43
static const char * http_response
Definition: http_server.c:91
int vnet_bind_uri(vnet_bind_args_t *a)
const u32 test_srv_key_rsa_len
u32 index
Definition: node.h:237
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:227
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:520
int i
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static int http_server_session_accept_callback(stream_session_t *s)
Definition: http_server.c:431
struct _vnet_application_add_tls_cert_args_t vnet_app_add_tls_cert_args_t
static stream_session_t * session_get_from_handle(session_handle_t handle)
Definition: session.h:287
clib_error_t * vnet_app_add_tls_cert(vnet_app_add_tls_cert_args_t *a)
Definition: application.c:1231
static void alloc_http_process_callback(void *cb_args)
Definition: http_server.c:328
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
static void send_error(stream_session_t *s, char *str)
Definition: http_server.c:188
static int http_server_rx_callback_static(stream_session_t *s)
Definition: http_server.c:390
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
struct _vnet_disconnect_args_t vnet_disconnect_args_t
static u32 svm_fifo_max_dequeue(svm_fifo_t *f)
Definition: svm_fifo.h:100
struct _stream_session_cb_vft session_cb_vft_t
static int http_server_listen()
Definition: http_server.c:549
#define clib_error_return(e, args...)
Definition: error.h:99
int svm_fifo_enqueue_nowait(svm_fifo_t *f, u32 max_bytes, const u8 *copy_from_here)
Definition: svm_fifo.c:534
unsigned long u64
Definition: types.h:89
struct vl_shmem_hdr_ * shmem_hdr
Binary API shared-memory segment header pointer.
Definition: api_common.h:262
void stream_session_cleanup(stream_session_t *s)
Cleanup transport and session state.
Definition: session.c:1049
struct _stream_session_t stream_session_t
struct _vnet_app_attach_args_t vnet_app_attach_args_t
vl_shmem_hdr_t * shmem_hdr
static session_cb_vft_t http_server_session_cb_vft
Definition: http_server.c:475
clib_error_t * vnet_app_add_tls_key(vnet_app_add_tls_key_args_t *a)
Definition: application.c:1243
static void http_server_session_reset_callback(stream_session_t *s)
Definition: http_server.c:454
static const char * html_header_static
Definition: http_server.c:111
static u8 * static_http
Definition: http_server.c:115
struct _unformat_input_t unformat_input_t
static session_handle_t session_handle(stream_session_t *s)
Definition: session.h:261
#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
static void free_http_process(http_server_args *args)
Definition: http_server.c:63
static const char * html_footer
Definition: http_server.c:108
u32 node_index
Node index.
Definition: node.h:437
const char test_srv_crt_rsa[]
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: session.c:1312
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:199
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 int http_server_add_segment_callback(u32 client_index, const ssvm_private_t *sp)
Definition: http_server.c:469
vlib_main_t * vlib_main
Definition: http_server.c:57
#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:294
static int http_server_session_connected_callback(u32 app_index, u32 api_context, stream_session_t *s, u8 is_fail)
Definition: http_server.c:461
#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
#define clib_memcpy(a, b, c)
Definition: string.h:75
int vnet_disconnect_session(vnet_disconnect_args_t *a)
svm_queue_t * vl_input_queue
Definition: memory_shared.h:84
void send_data(stream_session_t *s, u8 *data)
Definition: http_server.c:134
#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:783
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
struct _vnet_application_add_tls_key_args_t vnet_app_add_tls_key_args_t
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 void * clib_mem_alloc(uword size)
Definition: mem.h:112
u64 uword
Definition: types.h:112
uword * handler_by_get_request
Definition: http_server.c:38
struct _vlib_node_registration vlib_node_registration_t
svm_queue_t ** vpp_queue
Definition: http_server.c:35
static clib_error_t * http_server_main_init(vlib_main_t *vm)
Definition: http_server.c:659
http_server_main_t http_server_main
Definition: http_server.c:60
static void alloc_http_process(http_server_args *args)
Definition: http_server.c:285
#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
static int server_attach()
Definition: http_server.c:500
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)
Definition: http_server.c:486
static clib_error_t * http_server_create_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: http_server.c:589
struct _svm_queue svm_queue_t
static const char * http_error_template
Definition: http_server.c:98
static int http_server_rx_callback(stream_session_t *s)
Definition: http_server.c:358
unformat_function_t unformat_memory_size
Definition: format.h:294
struct clib_bihash_value offset
template key/value backing page structure
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
Definition: http_server.c:20
void vlib_start_process(vlib_main_t *vm, uword process_index)
Definition: main.c:1344
api_main_t api_main
Definition: api_shared.c:35
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:692
struct _vnet_bind_args_t vnet_bind_args_t
static void http_cli_output(uword arg, u8 *buffer, uword buffer_bytes)
Definition: http_server.c:118
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:169
const char test_srv_key_rsa[]
u32 * free_http_cli_process_node_indices
Definition: http_server.c:40
static uword http_cli_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: http_server.c:198
static int session_rx_request(stream_session_t *s)
Definition: http_server.c:334