FD.io VPP  v18.07.1-19-g511ce25
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  session_fifo_event_t evt;
144  u32 offset, bytes_to_send;
145  f64 delay = 10e-3;
147  vlib_main_t *vm = hsm->vlib_main;
148  f64 last_sent_timer = vlib_time_now (vm);
149 
150  bytes_to_send = vec_len (data);
151  offset = 0;
152 
153  while (bytes_to_send > 0)
154  {
155  int actual_transfer;
156 
157  actual_transfer = svm_fifo_enqueue_nowait
158  (s->server_tx_fifo, bytes_to_send, data + offset);
159 
160  /* Made any progress? */
161  if (actual_transfer <= 0)
162  {
163  vlib_process_suspend (vm, delay);
164  /* 10s deadman timer */
165  if (vlib_time_now (vm) > last_sent_timer + 10.0)
166  {
167  /* $$$$ FC: reset transport session here? */
168  break;
169  }
170  /* Exponential backoff, within reason */
171  if (delay < 1.0)
172  delay = delay * 2.0;
173  }
174  else
175  {
176  last_sent_timer = vlib_time_now (vm);
177  offset += actual_transfer;
178  bytes_to_send -= actual_transfer;
179 
180  if (svm_fifo_set_event (s->server_tx_fifo))
181  {
182  /* Fabricate TX event, send to vpp */
183  evt.fifo = s->server_tx_fifo;
184  evt.event_type = FIFO_EVENT_APP_TX;
185 
186  svm_queue_add (hsm->vpp_queue[s->thread_index],
187  (u8 *) & evt, 0 /* do wait for mutex */ );
188  }
189  delay = 10e-3;
190  }
191  }
192 }
193 
194 static void
195 send_error (stream_session_t * s, char *str)
196 {
197  u8 *data;
198 
199  data = format (0, http_error_template, str);
200  send_data (s, data);
201  vec_free (data);
202 }
203 
204 static uword
207 {
209  u8 *request = 0, *reply = 0;
210  http_server_args **save_args;
211  http_server_args *args;
212  stream_session_t *s;
213  unformat_input_t input;
214  int i;
215  u8 *http = 0, *html = 0;
216 
217  save_args = vlib_node_get_runtime_data (hsm->vlib_main, rt->node_index);
218  args = *save_args;
220  ASSERT (s);
221 
222  request = (u8 *) (void *) (args->data);
223  if (vec_len (request) < 7)
224  {
225  send_error (s, "400 Bad Request");
226  goto out;
227  }
228 
229  for (i = 0; i < vec_len (request) - 4; i++)
230  {
231  if (request[i] == 'G' &&
232  request[i + 1] == 'E' &&
233  request[i + 2] == 'T' && request[i + 3] == ' ')
234  goto found;
235  }
236 bad_request:
237  send_error (s, "400 Bad Request");
238  goto out;
239 
240 found:
241  /* Lose "GET " */
242  vec_delete (request, i + 5, 0);
243 
244  /* Replace slashes with spaces, stop at the end of the path */
245  i = 0;
246  while (1)
247  {
248  if (request[i] == '/')
249  request[i] = ' ';
250  else if (request[i] == ' ')
251  {
252  /* vlib_cli_input is vector-based, no need for a NULL */
253  _vec_len (request) = i;
254  break;
255  }
256  i++;
257  /* Should never happen */
258  if (i == vec_len (request))
259  goto bad_request;
260  }
261 
262  /* Generate the html header */
263  html = format (0, html_header_template, request /* title */ );
264 
265  /* Run the command */
266  unformat_init_vector (&input, request);
267  vlib_cli_input (vm, &input, http_cli_output, (uword) & reply);
268  unformat_free (&input);
269  request = 0;
270 
271  /* Generate the html page */
272  html = format (html, "%v", reply);
273  html = format (html, html_footer);
274  /* And the http reply */
275  http = format (0, http_response, vec_len (html), html);
276 
277  /* Send it */
278  send_data (s, http);
279 
280 out:
281  /* Cleanup */
282  vec_free (request);
283  vec_free (reply);
284  vec_free (html);
285  vec_free (http);
286 
287  free_http_process (args);
288  return (0);
289 }
290 
291 static void
293 {
294  char *name;
295  vlib_node_t *n;
297  vlib_main_t *vm = hsm->vlib_main;
299  http_server_args **save_args;
300 
302  {
304  vlib_node_set_state (vm, n->index, VLIB_NODE_STATE_POLLING);
305  _vec_len (hsm->free_http_cli_process_node_indices) = l - 1;
306  }
307  else
308  {
309  static vlib_node_registration_t r = {
310  .function = http_cli_process,
311  .type = VLIB_NODE_TYPE_PROCESS,
312  .process_log2_n_stack_bytes = 16,
313  .runtime_data_bytes = sizeof (void *),
314  };
315 
316  name = (char *) format (0, "http-cli-%d", l);
317  r.name = name;
318  vlib_register_node (vm, &r);
319  vec_free (name);
320 
321  n = vlib_get_node (vm, r.index);
322  }
323 
324  /* Save the node index in the args. It won't be zero. */
325  args->node_index = n->index;
326 
327  /* Save the args (pointer) in the node runtime */
328  save_args = vlib_node_get_runtime_data (vm, n->index);
329  *save_args = args;
330 
332 }
333 
334 static void
336 {
337  alloc_http_process ((http_server_args *) cb_args);
338 }
339 
340 static int
342 {
344  svm_fifo_t *rx_fifo;
345  u32 max_dequeue;
346  int actual_transfer;
347 
348  rx_fifo = s->server_rx_fifo;
349  max_dequeue = svm_fifo_max_dequeue (rx_fifo);
350  svm_fifo_unset_event (rx_fifo);
351  if (PREDICT_FALSE (max_dequeue == 0))
352  return -1;
353 
354  vec_validate (hsm->rx_buf[s->thread_index], max_dequeue - 1);
355  _vec_len (hsm->rx_buf[s->thread_index]) = max_dequeue;
356 
357  actual_transfer = svm_fifo_dequeue_nowait (rx_fifo, max_dequeue,
358  hsm->rx_buf[s->thread_index]);
359  ASSERT (actual_transfer > 0);
360  _vec_len (hsm->rx_buf[s->thread_index]) = actual_transfer;
361  return 0;
362 }
363 
364 static int
366 {
368  http_server_args *args;
369  int rv;
370 
371  rv = session_rx_request (s);
372  if (rv)
373  return rv;
374 
375  /* send the command to a new/recycled vlib process */
376  args = clib_mem_alloc (sizeof (*args));
377  args->data = vec_dup (hsm->rx_buf[s->thread_index]);
378  args->session_handle = session_handle (s);
379 
380  /* Send an RPC request via the thread-0 input node */
381  if (vlib_get_thread_index () != 0)
382  {
383  session_fifo_event_t evt;
384  evt.rpc_args.fp = alloc_http_process_callback;
385  evt.rpc_args.arg = args;
386  evt.event_type = FIFO_EVENT_RPC;
388  (session_manager_get_vpp_event_queue (0 /* main thread */ ),
389  (u8 *) & evt, 0 /* do wait for mutex */ );
390  }
391  else
392  alloc_http_process (args);
393  return 0;
394 }
395 
396 static int
398 {
400  u8 *request = 0;
401  int i;
402  int rv;
403 
404  rv = session_rx_request (s);
405  if (rv)
406  return rv;
407 
408  request = hsm->rx_buf[s->thread_index];
409  if (vec_len (request) < 7)
410  {
411  send_error (s, "400 Bad Request");
412  goto out;
413  }
414 
415  for (i = 0; i < vec_len (request) - 4; i++)
416  {
417  if (request[i] == 'G' &&
418  request[i + 1] == 'E' &&
419  request[i + 2] == 'T' && request[i + 3] == ' ')
420  goto found;
421  }
422  send_error (s, "400 Bad Request");
423  goto out;
424 
425 found:
426 
427  /* Send it */
428  send_data (s, static_http);
429 
430 out:
431  /* Cleanup */
432  vec_free (request);
433  hsm->rx_buf[s->thread_index] = request;
434  return 0;
435 }
436 
437 static int
439 {
441 
442  bsm->vpp_queue[s->thread_index] =
443  session_manager_get_vpp_event_queue (s->thread_index);
444  s->session_state = SESSION_STATE_READY;
445  bsm->byte_index = 0;
446  return 0;
447 }
448 
449 static void
451 {
453  vnet_disconnect_args_t _a, *a = &_a;
454 
455  a->handle = session_handle (s);
456  a->app_index = bsm->app_index;
458 }
459 
460 static void
462 {
463  clib_warning ("called.. ");
465 }
466 
467 static int
469  stream_session_t * s, u8 is_fail)
470 {
471  clib_warning ("called...");
472  return -1;
473 }
474 
475 static int
477 {
478  clib_warning ("called...");
479  return -1;
480 }
481 
483  .session_accept_callback = http_server_session_accept_callback,
484  .session_disconnect_callback = http_server_session_disconnect_callback,
485  .session_connected_callback = http_server_session_connected_callback,
486  .add_segment_callback = http_server_add_segment_callback,
487  .builtin_app_rx_callback = http_server_rx_callback,
488  .session_reset_callback = http_server_session_reset_callback
489 };
490 
491 /* Abuse VPP's input queue */
492 static int
494 {
496  api_main_t *am = &api_main;
498 
499  shmem_hdr = am->shmem_hdr;
500  hsm->vl_input_queue = shmem_hdr->vl_input_queue;
501  hsm->my_client_index =
502  vl_api_memclnt_create_internal ("http_server", hsm->vl_input_queue);
503  return 0;
504 }
505 
506 static int
508 {
509  vnet_app_add_tls_cert_args_t _a_cert, *a_cert = &_a_cert;
510  vnet_app_add_tls_key_args_t _a_key, *a_key = &_a_key;
512  u64 options[APP_OPTIONS_N_OPTIONS];
513  vnet_app_attach_args_t _a, *a = &_a;
514  u32 segment_size = 128 << 20;
515 
516  memset (a, 0, sizeof (*a));
517  memset (options, 0, sizeof (options));
518 
519  if (hsm->private_segment_size)
520  segment_size = hsm->private_segment_size;
521 
522  a->api_client_index = hsm->my_client_index;
523  a->session_cb_vft = &http_server_session_cb_vft;
524  a->options = options;
525  a->options[APP_OPTIONS_SEGMENT_SIZE] = segment_size;
526  a->options[APP_OPTIONS_RX_FIFO_SIZE] =
527  hsm->fifo_size ? hsm->fifo_size : 8 << 10;
528  a->options[APP_OPTIONS_TX_FIFO_SIZE] =
529  hsm->fifo_size ? hsm->fifo_size : 32 << 10;
530  a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
532 
533  if (vnet_application_attach (a))
534  {
535  clib_warning ("failed to attach server");
536  return -1;
537  }
538  hsm->app_index = a->app_index;
539 
540  memset (a_cert, 0, sizeof (*a_cert));
541  a_cert->app_index = a->app_index;
542  vec_validate (a_cert->cert, test_srv_crt_rsa_len);
544  vnet_app_add_tls_cert (a_cert);
545 
546  memset (a_key, 0, sizeof (*a_key));
547  a_key->app_index = a->app_index;
548  vec_validate (a_key->key, test_srv_key_rsa_len);
550  vnet_app_add_tls_key (a_key);
551 
552  return 0;
553 }
554 
555 static int
557 {
559  vnet_bind_args_t _a, *a = &_a;
560  memset (a, 0, sizeof (*a));
561  a->app_index = hsm->app_index;
562  a->uri = "tcp://0.0.0.0/80";
563  if (hsm->uri)
564  a->uri = (char *) hsm->uri;
565  return vnet_bind_uri (a);
566 }
567 
568 static int
570 {
572  u32 num_threads;
574 
575  ASSERT (hsm->my_client_index == (u32) ~ 0);
576  if (create_api_loopback (vm))
577  return -1;
578 
579  num_threads = 1 /* main thread */ + vtm->n_threads;
580  vec_validate (http_server_main.vpp_queue, num_threads - 1);
581 
582  if (server_attach ())
583  {
584  clib_warning ("failed to attach server");
585  return -1;
586  }
587  if (http_server_listen ())
588  {
589  clib_warning ("failed to start listening");
590  return -1;
591  }
592  return 0;
593 }
594 
595 static clib_error_t *
597  unformat_input_t * input,
598  vlib_cli_command_t * cmd)
599 {
601  int rv, is_static = 0;
602  u64 seg_size;
603  u8 *html;
604 
605  hsm->prealloc_fifos = 0;
606  hsm->private_segment_size = 0;
607  hsm->fifo_size = 0;
609  {
610  if (unformat (input, "static"))
611  is_static = 1;
612  else if (unformat (input, "prealloc-fifos %d", &hsm->prealloc_fifos))
613  ;
614  else if (unformat (input, "private-segment-size %U",
615  unformat_memory_size, &seg_size))
616  {
617  if (seg_size >= 0x100000000ULL)
618  {
619  vlib_cli_output (vm, "private segment size %llu, too large",
620  seg_size);
621  return 0;
622  }
623  hsm->private_segment_size = seg_size;
624  }
625  else if (unformat (input, "fifo-size %d", &hsm->fifo_size))
626  hsm->fifo_size <<= 10;
627  else if (unformat (input, "uri %s", &hsm->uri))
628  ;
629  else
630  return clib_error_return (0, "unknown input `%U'",
631  format_unformat_error, input);
632  }
633  if (hsm->my_client_index != (u32) ~ 0)
634  return clib_error_return (0, "test http server is already running");
635 
636  vnet_session_enable_disable (vm, 1 /* turn on TCP, etc. */ );
637 
638  if (is_static)
639  {
640  http_server_session_cb_vft.builtin_app_rx_callback =
642  html = format (0, html_header_static);
643  static_http = format (0, http_response, vec_len (html), html);
644  }
645  rv = http_server_create (vm);
646  switch (rv)
647  {
648  case 0:
649  break;
650  default:
651  return clib_error_return (0, "server_create returned %d", rv);
652  }
653  return 0;
654 }
655 
656 /* *INDENT-OFF* */
657 VLIB_CLI_COMMAND (http_server_create_command, static) =
658 {
659  .path = "test http server",
660  .short_help = "test http server",
661  .function = http_server_create_command_fn,
662 };
663 /* *INDENT-ON* */
664 
665 static clib_error_t *
667 {
670  u32 num_threads;
671 
672  hsm->my_client_index = ~0;
673  hsm->vlib_main = vm;
674  num_threads = 1 /* main thread */ + vtm->n_threads;
675  vec_validate (hsm->rx_buf, num_threads - 1);
676  return 0;
677 }
678 
680 
681 /*
682 * fd.io coding-style-patch-verification: ON
683 *
684 * Local Variables:
685 * eval: (c-set-style "gnu")
686 * End:
687 */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
static svm_queue_t * session_manager_get_vpp_event_queue(u32 thread_index)
Definition: session.h:553
static void http_server_session_disconnect_callback(stream_session_t *s)
Definition: http_server.c:450
vlib_main_t vlib_global_main
Definition: main.c:1644
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:569
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:644
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:273
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:228
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
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:438
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:336
clib_error_t * vnet_app_add_tls_cert(vnet_app_add_tls_cert_args_t *a)
Definition: application.c:1233
unsigned char u8
Definition: types.h:56
static void alloc_http_process_callback(void *cb_args)
Definition: http_server.c:335
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:195
static int http_server_rx_callback_static(stream_session_t *s)
Definition: http_server.c:397
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:156
struct _vnet_disconnect_args_t vnet_disconnect_args_t
static u32 svm_fifo_max_dequeue(svm_fifo_t *f)
Definition: svm_fifo.h:105
struct _stream_session_cb_vft session_cb_vft_t
static int http_server_listen()
Definition: http_server.c:556
#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:538
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:1149
unsigned int u32
Definition: types.h:88
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:482
clib_error_t * vnet_app_add_tls_key(vnet_app_add_tls_key_args_t *a)
Definition: application.c:1245
static void http_server_session_reset_callback(stream_session_t *s)
Definition: http_server.c:461
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:310
#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:105
static void svm_fifo_unset_event(svm_fifo_t *f)
Unsets fifo event flag.
Definition: svm_fifo.h:144
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:473
const char test_srv_crt_rsa[]
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: session.c:1470
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:134
static int http_server_add_segment_callback(u32 client_index, const ssvm_private_t *sp)
Definition: http_server.c:476
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:276
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:468
#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:154
#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:518
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
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:666
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:292
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static int server_attach()
Definition: http_server.c:507
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:493
vhost_user_req_t request
Definition: vhost_user.h:109
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:596
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:365
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:1346
api_main_t api_main
Definition: api_shared.c:35
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:681
int svm_fifo_dequeue_nowait(svm_fifo_t *f, u32 max_bytes, u8 *copy_here)
Definition: svm_fifo.c:710
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:205
static int session_rx_request(stream_session_t *s)
Definition: http_server.c:341