FD.io VPP  v18.10-34-gcce845e
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 /* *INDENT-OFF* */
91 static const char *http_response =
92  "HTTP/1.1 200 OK\r\n"
93  "Content-Type: text/html\r\n"
94  "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
95  "Connection: keep-alive \r\n"
96  "Pragma: no-cache\r\n"
97  "Content-Length: %d\r\n\r\n%s";
98 
99 static const char *http_error_template =
100  "HTTP/1.1 %s\r\n"
101  "Content-Type: text/html\r\n"
102  "Expires: Mon, 11 Jan 1970 10:10:10 GMT\r\n"
103  "Connection: close\r\n"
104  "Pragma: no-cache\r\n"
105  "Content-Length: 0\r\n\r\n";
106 
107 /* Header, including incantation to suppress favicon.ico requests */
108 static const char *html_header_template =
109  "<html><head><title>%v</title></head>"
110  "<link rel=\"icon\" href=\"data:,\">"
111  "<body><pre>";
112 
113 static const char *html_footer =
114  "</pre></body></html>\r\n";
115 
116 static const char *html_header_static =
117  "<html><head><title>static reply</title></head>"
118  "<link rel=\"icon\" href=\"data:,\">"
119  "<body><pre>hello</pre></body></html>\r\n";
120 /* *INDENT-ON* */
121 
122 static u8 *static_http;
123 
124 static void
125 http_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
126 {
127  u8 **output_vecp = (u8 **) arg;
128  u8 *output_vec;
129  u32 offset;
130 
131  output_vec = *output_vecp;
132 
133  offset = vec_len (output_vec);
134  vec_validate (output_vec, offset + buffer_bytes - 1);
135  clib_memcpy (output_vec + offset, buffer, buffer_bytes);
136 
137  *output_vecp = output_vec;
138 }
139 
140 void
142 {
143  u32 offset, bytes_to_send;
144  f64 delay = 10e-3;
146  vlib_main_t *vm = hsm->vlib_main;
147  f64 last_sent_timer = vlib_time_now (vm);
148 
149  bytes_to_send = vec_len (data);
150  offset = 0;
151 
152  while (bytes_to_send > 0)
153  {
154  int actual_transfer;
155 
156  actual_transfer = svm_fifo_enqueue_nowait
157  (s->server_tx_fifo, bytes_to_send, data + offset);
158 
159  /* Made any progress? */
160  if (actual_transfer <= 0)
161  {
162  vlib_process_suspend (vm, delay);
163  /* 10s deadman timer */
164  if (vlib_time_now (vm) > last_sent_timer + 10.0)
165  {
166  /* $$$$ FC: reset transport session here? */
167  break;
168  }
169  /* Exponential backoff, within reason */
170  if (delay < 1.0)
171  delay = delay * 2.0;
172  }
173  else
174  {
175  last_sent_timer = vlib_time_now (vm);
176  offset += actual_transfer;
177  bytes_to_send -= actual_transfer;
178 
179  if (svm_fifo_set_event (s->server_tx_fifo))
180  session_send_io_evt_to_thread (s->server_tx_fifo,
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)
376  else
377  alloc_http_process (args);
378  return 0;
379 }
380 
381 static int
383 {
385  u8 *request = 0;
386  int i;
387  int rv;
388 
389  rv = session_rx_request (s);
390  if (rv)
391  return rv;
392 
393  request = hsm->rx_buf[s->thread_index];
394  if (vec_len (request) < 7)
395  {
396  send_error (s, "400 Bad Request");
397  goto out;
398  }
399 
400  for (i = 0; i < vec_len (request) - 4; i++)
401  {
402  if (request[i] == 'G' &&
403  request[i + 1] == 'E' &&
404  request[i + 2] == 'T' && request[i + 3] == ' ')
405  goto found;
406  }
407  send_error (s, "400 Bad Request");
408  goto out;
409 
410 found:
411 
412  /* Send it */
413  send_data (s, static_http);
414 
415 out:
416  /* Cleanup */
417  vec_free (request);
418  hsm->rx_buf[s->thread_index] = request;
419  return 0;
420 }
421 
422 static int
424 {
426 
427  bsm->vpp_queue[s->thread_index] =
428  session_manager_get_vpp_event_queue (s->thread_index);
429  s->session_state = SESSION_STATE_READY;
430  bsm->byte_index = 0;
431  return 0;
432 }
433 
434 static void
436 {
438  vnet_disconnect_args_t _a, *a = &_a;
439 
440  a->handle = session_handle (s);
441  a->app_index = bsm->app_index;
443 }
444 
445 static void
447 {
448  clib_warning ("called.. ");
450 }
451 
452 static int
454  stream_session_t * s, u8 is_fail)
455 {
456  clib_warning ("called...");
457  return -1;
458 }
459 
460 static int
462 {
463  clib_warning ("called...");
464  return -1;
465 }
466 
468  .session_accept_callback = http_server_session_accept_callback,
469  .session_disconnect_callback = http_server_session_disconnect_callback,
470  .session_connected_callback = http_server_session_connected_callback,
471  .add_segment_callback = http_server_add_segment_callback,
472  .builtin_app_rx_callback = http_server_rx_callback,
473  .session_reset_callback = http_server_session_reset_callback
474 };
475 
476 /* Abuse VPP's input queue */
477 static int
479 {
481  api_main_t *am = &api_main;
483 
484  shmem_hdr = am->shmem_hdr;
485  hsm->vl_input_queue = shmem_hdr->vl_input_queue;
486  hsm->my_client_index =
487  vl_api_memclnt_create_internal ("http_server", hsm->vl_input_queue);
488  return 0;
489 }
490 
491 static int
493 {
494  vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert;
495  vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key;
497  u64 options[APP_OPTIONS_N_OPTIONS];
498  vnet_app_attach_args_t _a, *a = &_a;
499  u32 segment_size = 128 << 20;
500 
501  memset (a, 0, sizeof (*a));
502  memset (options, 0, sizeof (options));
503 
504  if (hsm->private_segment_size)
505  segment_size = hsm->private_segment_size;
506 
507  a->api_client_index = hsm->my_client_index;
508  a->session_cb_vft = &http_server_session_cb_vft;
509  a->options = options;
510  a->options[APP_OPTIONS_SEGMENT_SIZE] = segment_size;
511  a->options[APP_OPTIONS_RX_FIFO_SIZE] =
512  hsm->fifo_size ? hsm->fifo_size : 8 << 10;
513  a->options[APP_OPTIONS_TX_FIFO_SIZE] =
514  hsm->fifo_size ? hsm->fifo_size : 32 << 10;
515  a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
517 
518  if (vnet_application_attach (a))
519  {
520  clib_warning ("failed to attach server");
521  return -1;
522  }
523  hsm->app_index = a->app_index;
524 
525  memset (a_cert, 0, sizeof (*a_cert));
526  a_cert->app_index = a->app_index;
527  vec_validate (a_cert->cert, test_srv_crt_rsa_len);
529  vnet_app_add_tls_cert (a_cert);
530 
531  memset (a_key, 0, sizeof (*a_key));
532  a_key->app_index = a->app_index;
533  vec_validate (a_key->key, test_srv_key_rsa_len);
535  vnet_app_add_tls_key (a_key);
536 
537  return 0;
538 }
539 
540 static int
542 {
544  vnet_bind_args_t _a, *a = &_a;
545  memset (a, 0, sizeof (*a));
546  a->app_index = hsm->app_index;
547  a->uri = "tcp://0.0.0.0/80";
548  if (hsm->uri)
549  a->uri = (char *) hsm->uri;
550  return vnet_bind_uri (a);
551 }
552 
553 static int
555 {
557  u32 num_threads;
559 
560  ASSERT (hsm->my_client_index == (u32) ~ 0);
561  if (create_api_loopback (vm))
562  return -1;
563 
564  num_threads = 1 /* main thread */ + vtm->n_threads;
565  vec_validate (http_server_main.vpp_queue, num_threads - 1);
566 
567  if (server_attach ())
568  {
569  clib_warning ("failed to attach server");
570  return -1;
571  }
572  if (http_server_listen ())
573  {
574  clib_warning ("failed to start listening");
575  return -1;
576  }
577  return 0;
578 }
579 
580 static clib_error_t *
582  unformat_input_t * input,
583  vlib_cli_command_t * cmd)
584 {
586  int rv, is_static = 0;
587  u64 seg_size;
588  u8 *html;
589 
590  hsm->prealloc_fifos = 0;
591  hsm->private_segment_size = 0;
592  hsm->fifo_size = 0;
594  {
595  if (unformat (input, "static"))
596  is_static = 1;
597  else if (unformat (input, "prealloc-fifos %d", &hsm->prealloc_fifos))
598  ;
599  else if (unformat (input, "private-segment-size %U",
600  unformat_memory_size, &seg_size))
601  {
602  if (seg_size >= 0x100000000ULL)
603  {
604  vlib_cli_output (vm, "private segment size %llu, too large",
605  seg_size);
606  return 0;
607  }
608  hsm->private_segment_size = seg_size;
609  }
610  else if (unformat (input, "fifo-size %d", &hsm->fifo_size))
611  hsm->fifo_size <<= 10;
612  else if (unformat (input, "uri %s", &hsm->uri))
613  ;
614  else
615  return clib_error_return (0, "unknown input `%U'",
616  format_unformat_error, input);
617  }
618  if (hsm->my_client_index != (u32) ~ 0)
619  return clib_error_return (0, "test http server is already running");
620 
621  vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */ );
622 
623  if (is_static)
624  {
625  http_server_session_cb_vft.builtin_app_rx_callback =
627  html = format (0, html_header_static);
628  static_http = format (0, http_response, vec_len (html), html);
629  }
630  rv = http_server_create (vm);
631  switch (rv)
632  {
633  case 0:
634  break;
635  default:
636  return clib_error_return (0, "server_create returned %d", rv);
637  }
638  return 0;
639 }
640 
641 /* *INDENT-OFF* */
642 VLIB_CLI_COMMAND (http_server_create_command, static) =
643 {
644  .path = "test http server",
645  .short_help = "test http server",
646  .function = http_server_create_command_fn,
647 };
648 /* *INDENT-ON* */
649 
650 static clib_error_t *
652 {
655  u32 num_threads;
656 
657  hsm->my_client_index = ~0;
658  hsm->vlib_main = vm;
659  num_threads = 1 /* main thread */ + vtm->n_threads;
660  vec_validate (hsm->rx_buf, num_threads - 1);
661  return 0;
662 }
663 
665 
666 /*
667 * fd.io coding-style-patch-verification: ON
668 *
669 * Local Variables:
670 * eval: (c-set-style "gnu")
671 * End:
672 */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
static void http_server_session_disconnect_callback(stream_session_t *s)
Definition: http_server.c:435
vlib_main_t vlib_global_main
Definition: main.c:1638
static int http_server_create(vlib_main_t *vm)
Definition: http_server.c:554
u32 vl_api_memclnt_create_internal(char *name, svm_queue_t *q)
Definition: memory_api.c:112
a
Definition: bitmap.h:538
const u32 test_srv_crt_rsa_len
static const char * html_header_template
Definition: http_server.c:108
void vlib_cli_input(vlib_main_t *vm, unformat_input_t *input, vlib_cli_output_function_t *function, uword function_arg)
Definition: cli.c:688
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
unsigned long u64
Definition: types.h:89
u32 index
Definition: node.h:288
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:523
void session_send_rpc_evt_to_thread(u32 thread_index, void *fp, void *rpc_args)
Definition: session.c:110
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:423
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:360
clib_error_t * vnet_app_add_tls_cert(vnet_app_add_tls_cert_args_t *a)
Definition: application.c:1887
unsigned char u8
Definition: types.h:56
static void alloc_http_process_callback(void *cb_args)
Definition: http_server.c:328
double f64
Definition: types.h:142
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
memset(h->entries, 0, sizeof(h->entries[0])*entries)
static svm_msg_q_t * session_manager_get_vpp_event_queue(u32 thread_index)
Definition: session.h:590
static int http_server_rx_callback_static(stream_session_t *s)
Definition: http_server.c:382
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
struct _vnet_disconnect_args_t vnet_disconnect_args_t
static u32 svm_fifo_max_dequeue(svm_fifo_t *f)
Definition: svm_fifo.h:114
struct _stream_session_cb_vft session_cb_vft_t
static int http_server_listen()
Definition: http_server.c:541
#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:523
svm_msg_q_t ** vpp_queue
Definition: http_server.c:35
struct vl_shmem_hdr_ * shmem_hdr
Binary API shared-memory segment header pointer.
Definition: api_common.h:264
void stream_session_cleanup(stream_session_t *s)
Cleanup transport and session state.
Definition: session.c:1127
unsigned int u32
Definition: types.h:88
struct _stream_session_t stream_session_t
int session_send_io_evt_to_thread(svm_fifo_t *f, session_evt_type_t evt_type)
Definition: session.c:87
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:467
clib_error_t * vnet_app_add_tls_key(vnet_app_add_tls_key_args_t *a)
Definition: application.c:1899
static void http_server_session_reset_callback(stream_session_t *s)
Definition: http_server.c:446
static const char * html_header_static
Definition: http_server.c:116
static u8 * static_http
Definition: http_server.c:122
struct _unformat_input_t unformat_input_t
static session_handle_t session_handle(stream_session_t *s)
Definition: session.h:334
#define vec_dup(V)
Return copy of vector (no header, no alignment)
Definition: vec.h:373
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:107
static void svm_fifo_unset_event(svm_fifo_t *f)
Unsets fifo event flag.
Definition: svm_fifo.h:170
static void free_http_process(http_server_args *args)
Definition: http_server.c:63
static const char * html_footer
Definition: http_server.c:113
u32 node_index
Node index.
Definition: node.h:494
const char test_srv_crt_rsa[]
u8 name[64]
Definition: memclnt.api:151
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: session.c:1461
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:201
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:157
static int http_server_add_segment_callback(u32 client_index, const ssvm_private_t *sp)
Definition: http_server.c:461
vlib_main_t * vlib_main
Definition: http_server.c:57
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
u32 runtime_index
Definition: node.h:291
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:211
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:453
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
#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:141
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
#define ASSERT(truth)
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:786
u32 vlib_register_node(vlib_main_t *vm, vlib_node_registration_t *r)
Definition: node.c:519
static void clib_mem_free(void *p)
Definition: mem.h:205
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:132
uword * handler_by_get_request
Definition: http_server.c:38
struct _vlib_node_registration vlib_node_registration_t
static clib_error_t * http_server_main_init(vlib_main_t *vm)
Definition: http_server.c:651
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)
static int server_attach()
Definition: http_server.c:492
clib_error_t * vnet_application_attach(vnet_app_attach_args_t *a)
Attach application to vpp.
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:162
static int create_api_loopback(vlib_main_t *vm)
Definition: http_server.c:478
vhost_user_req_t request
Definition: vhost_user.h:114
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:581
struct _svm_queue svm_queue_t
static const char * http_error_template
Definition: http_server.c:99
static int http_server_rx_callback(stream_session_t *s)
Definition: http_server.c:358
unformat_function_t unformat_memory_size
Definition: format.h:295
struct clib_bihash_value offset
template key/value backing page structure
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:1347
api_main_t api_main
Definition: api_shared.c:35
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
int svm_fifo_dequeue_nowait(svm_fifo_t *f, u32 max_bytes, u8 *copy_here)
Definition: svm_fifo.c:670
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:125
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:170
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