FD.io VPP  v19.01.2-3-gf61a1a8
Vector Packet Processing
proxy.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>
17 #include <vlibmemory/api.h>
21 
23 
24 typedef struct
25 {
26  char uri[128];
30 
31 static void
32 proxy_cb_fn (void *data, u32 data_len)
33 {
36 
37  memset (&a, 0, sizeof (a));
38  a.api_context = pa->api_context;
39  a.app_index = pa->app_index;
40  a.uri = pa->uri;
41  vnet_connect_uri (&a);
42 }
43 
44 static void
46 {
47  if (vlib_get_thread_index () == 0)
48  {
49  vnet_connect_uri (a);
50  }
51  else
52  {
54  args.api_context = a->api_context;
55  args.app_index = a->app_index;
56  clib_memcpy (args.uri, a->uri, vec_len (a->uri));
57  vl_api_rpc_call_main_thread (proxy_cb_fn, (u8 *) & args, sizeof (args));
58  }
59 }
60 
61 static void
62 delete_proxy_session (stream_session_t * s, int is_active_open)
63 {
64  proxy_main_t *pm = &proxy_main;
65  proxy_session_t *ps = 0;
66  vnet_disconnect_args_t _a, *a = &_a;
67  stream_session_t *active_open_session = 0;
68  stream_session_t *server_session = 0;
69  uword *p;
70  u64 handle;
71 
72  handle = session_handle (s);
73 
75  if (is_active_open)
76  {
77  active_open_session = s;
78 
80  if (p == 0)
81  {
82  clib_warning ("proxy session for %s handle %lld (%llx) AWOL",
83  is_active_open ? "active open" : "server",
84  handle, handle);
85  }
86  else if (!pool_is_free_index (pm->sessions, p[0]))
87  {
88  ps = pool_elt_at_index (pm->sessions, p[0]);
89  if (ps->vpp_server_handle != ~0)
90  server_session = session_get_from_handle (ps->vpp_server_handle);
91  else
92  server_session = 0;
93  }
94  }
95  else
96  {
97  server_session = s;
98 
99  p = hash_get (pm->proxy_session_by_server_handle, handle);
100  if (p == 0)
101  {
102  clib_warning ("proxy session for %s handle %lld (%llx) AWOL",
103  is_active_open ? "active open" : "server",
104  handle, handle);
105  }
106  else if (!pool_is_free_index (pm->sessions, p[0]))
107  {
108  ps = pool_elt_at_index (pm->sessions, p[0]);
109  if (ps->vpp_active_open_handle != ~0)
110  active_open_session = session_get_from_handle
112  else
113  active_open_session = 0;
114  }
115  }
116 
117  if (ps)
118  {
119  if (CLIB_DEBUG > 0)
120  clib_memset (ps, 0xFE, sizeof (*ps));
121  pool_put (pm->sessions, ps);
122  }
123 
125 
126  if (active_open_session)
127  {
128  a->handle = session_handle (active_open_session);
129  a->app_index = pm->active_open_app_index;
131  session_handle (active_open_session));
133  }
134 
135  if (server_session)
136  {
137  a->handle = session_handle (server_session);
138  a->app_index = pm->server_app_index;
140  session_handle (server_session));
142  }
143 }
144 
145 static int
147 {
148  proxy_main_t *pm = &proxy_main;
149 
150  s->session_state = SESSION_STATE_READY;
151 
153 
154  return 0;
155 }
156 
157 static void
159 {
160  delete_proxy_session (s, 0 /* is_active_open */ );
161 }
162 
163 static void
165 {
166  clib_warning ("Reset session %U", format_stream_session, s, 2);
167  delete_proxy_session (s, 0 /* is_active_open */ );
168 }
169 
170 static int
171 proxy_connected_callback (u32 app_index, u32 api_context,
172  stream_session_t * s, u8 is_fail)
173 {
174  clib_warning ("called...");
175  return -1;
176 }
177 
178 static int
179 proxy_add_segment_callback (u32 client_index, u64 segment_handle)
180 {
181  clib_warning ("called...");
182  return -1;
183 }
184 
185 static int
187 {
188  u32 max_dequeue;
189  int actual_transfer __attribute__ ((unused));
190  svm_fifo_t *tx_fifo, *rx_fifo;
191  proxy_main_t *pm = &proxy_main;
192  u32 thread_index = vlib_get_thread_index ();
193  vnet_connect_args_t _a, *a = &_a;
194  proxy_session_t *ps;
195  int proxy_index;
196  uword *p;
197  svm_fifo_t *active_open_tx_fifo;
198 
199  ASSERT (s->thread_index == thread_index);
200 
203 
204  if (PREDICT_TRUE (p != 0))
205  {
207  active_open_tx_fifo = s->server_rx_fifo;
208 
209  /*
210  * Send event for active open tx fifo
211  */
212  if (svm_fifo_set_event (active_open_tx_fifo))
213  {
214  u32 ao_thread_index = active_open_tx_fifo->master_thread_index;
215  if (session_send_io_evt_to_thread_custom (active_open_tx_fifo,
216  ao_thread_index,
218  clib_warning ("failed to enqueue tx evt");
219  }
220  }
221  else
222  {
223  rx_fifo = s->server_rx_fifo;
224  tx_fifo = s->server_tx_fifo;
225 
226  ASSERT (rx_fifo->master_thread_index == thread_index);
227  ASSERT (tx_fifo->master_thread_index == thread_index);
228 
229  max_dequeue = svm_fifo_max_dequeue (s->server_rx_fifo);
230 
231  if (PREDICT_FALSE (max_dequeue == 0))
232  return 0;
233 
234  actual_transfer = svm_fifo_peek (rx_fifo, 0 /* relative_offset */ ,
235  max_dequeue, pm->rx_buf[thread_index]);
236 
237  /* $$$ your message in this space: parse url, etc. */
238 
239  clib_memset (a, 0, sizeof (*a));
240 
242  pool_get (pm->sessions, ps);
243  clib_memset (ps, 0, sizeof (*ps));
244  ps->server_rx_fifo = rx_fifo;
245  ps->server_tx_fifo = tx_fifo;
247 
248  proxy_index = ps - pm->sessions;
249 
251  proxy_index);
252 
254 
255  a->uri = (char *) pm->client_uri;
256  a->api_context = proxy_index;
257  a->app_index = pm->active_open_app_index;
259  }
260 
261  return 0;
262 }
263 
265  .session_accept_callback = proxy_accept_callback,
266  .session_disconnect_callback = proxy_disconnect_callback,
267  .session_connected_callback = proxy_connected_callback,
268  .add_segment_callback = proxy_add_segment_callback,
269  .builtin_app_rx_callback = proxy_rx_callback,
270  .session_reset_callback = proxy_reset_callback
271 };
272 
273 static int
275  stream_session_t * s, u8 is_fail)
276 {
277  proxy_main_t *pm = &proxy_main;
278  proxy_session_t *ps;
279  u8 thread_index = vlib_get_thread_index ();
280 
281  if (is_fail)
282  {
283  clib_warning ("connection %d failed!", opaque);
284  return 0;
285  }
286 
287  /*
288  * Setup proxy session handle.
289  */
291 
292  ps = pool_elt_at_index (pm->sessions, opaque);
294 
295  s->server_tx_fifo = ps->server_rx_fifo;
296  s->server_rx_fifo = ps->server_tx_fifo;
297 
298  /*
299  * Reset the active-open tx-fifo master indices so the active-open session
300  * will receive data, etc.
301  */
302  s->server_tx_fifo->master_session_index = s->session_index;
303  s->server_tx_fifo->master_thread_index = s->thread_index;
304 
305  /*
306  * Account for the active-open session's use of the fifos
307  * so they won't disappear until the last session which uses
308  * them disappears
309  */
310  s->server_tx_fifo->refcnt++;
311  s->server_rx_fifo->refcnt++;
312 
314  ps->vpp_active_open_handle, opaque);
315 
317 
318  /*
319  * Send event for active open tx fifo
320  */
321  ASSERT (s->thread_index == thread_index);
322  if (svm_fifo_set_event (s->server_tx_fifo))
324 
325  return 0;
326 }
327 
328 static void
330 {
331  delete_proxy_session (s, 1 /* is_active_open */ );
332 }
333 
334 static int
336 {
337  return 0;
338 }
339 
340 static void
342 {
343  delete_proxy_session (s, 1 /* is_active_open */ );
344 }
345 
346 static int
348 {
349  svm_fifo_t *proxy_tx_fifo;
350 
351  proxy_tx_fifo = s->server_rx_fifo;
352 
353  /*
354  * Send event for server tx fifo
355  */
356  if (svm_fifo_set_event (proxy_tx_fifo))
357  {
358  u8 thread_index = proxy_tx_fifo->master_thread_index;
359  return session_send_io_evt_to_thread_custom (proxy_tx_fifo,
360  thread_index,
362  }
363 
364  return 0;
365 }
366 
367 /* *INDENT-OFF* */
369  .session_reset_callback = active_open_reset_callback,
370  .session_connected_callback = active_open_connected_callback,
371  .session_accept_callback = active_open_create_callback,
372  .session_disconnect_callback = active_open_disconnect_callback,
373  .builtin_app_rx_callback = active_open_rx_callback
374 };
375 /* *INDENT-ON* */
376 
377 
378 static void
380 {
381  proxy_main_t *pm = &proxy_main;
382  api_main_t *am = &api_main;
383  vl_shmem_hdr_t *shmem_hdr;
384 
385  shmem_hdr = am->shmem_hdr;
386  pm->vl_input_queue = shmem_hdr->vl_input_queue;
387  pm->server_client_index =
388  vl_api_memclnt_create_internal ("proxy_server", pm->vl_input_queue);
390  vl_api_memclnt_create_internal ("proxy_active_open", pm->vl_input_queue);
391 }
392 
393 static int
395 {
396  proxy_main_t *pm = &proxy_main;
397  u64 options[APP_OPTIONS_N_OPTIONS];
398  vnet_app_attach_args_t _a, *a = &_a;
399  u32 segment_size = 512 << 20;
400 
401  clib_memset (a, 0, sizeof (*a));
402  clib_memset (options, 0, sizeof (options));
403 
404  if (pm->private_segment_size)
405  segment_size = pm->private_segment_size;
406  a->api_client_index = pm->server_client_index;
407  a->session_cb_vft = &proxy_session_cb_vft;
408  a->options = options;
409  a->options[APP_OPTIONS_SEGMENT_SIZE] = segment_size;
410  a->options[APP_OPTIONS_RX_FIFO_SIZE] = pm->fifo_size;
411  a->options[APP_OPTIONS_TX_FIFO_SIZE] = pm->fifo_size;
413  a->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
414  pm->prealloc_fifos ? pm->prealloc_fifos : 0;
415 
416  a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN;
417 
418  if (vnet_application_attach (a))
419  {
420  clib_warning ("failed to attach server");
421  return -1;
422  }
423  pm->server_app_index = a->app_index;
424 
425  return 0;
426 }
427 
428 static int
430 {
431  proxy_main_t *pm = &proxy_main;
432  vnet_app_attach_args_t _a, *a = &_a;
433  u64 options[16];
434 
435  clib_memset (a, 0, sizeof (*a));
436  clib_memset (options, 0, sizeof (options));
437 
438  a->api_client_index = pm->active_open_client_index;
439  a->session_cb_vft = &active_open_clients;
440 
441  options[APP_OPTIONS_ACCEPT_COOKIE] = 0x12345678;
442  options[APP_OPTIONS_SEGMENT_SIZE] = 512 << 20;
443  options[APP_OPTIONS_RX_FIFO_SIZE] = pm->fifo_size;
444  options[APP_OPTIONS_TX_FIFO_SIZE] = pm->fifo_size;
447  pm->prealloc_fifos ? pm->prealloc_fifos : 0;
448 
449  options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN
450  | APP_OPTIONS_FLAGS_IS_PROXY;
451 
452  a->options = options;
453 
454  if (vnet_application_attach (a))
455  return -1;
456 
457  pm->active_open_app_index = a->app_index;
458 
459  return 0;
460 }
461 
462 static int
464 {
465  proxy_main_t *pm = &proxy_main;
466  vnet_bind_args_t _a, *a = &_a;
467  clib_memset (a, 0, sizeof (*a));
468  a->app_index = pm->server_app_index;
469  a->uri = (char *) pm->server_uri;
470  return vnet_bind_uri (a);
471 }
472 
473 static int
475 {
476  proxy_main_t *pm = &proxy_main;
478  u32 num_threads;
479  int i;
480 
481  if (pm->server_client_index == (u32) ~ 0)
483 
484  num_threads = 1 /* main thread */ + vtm->n_threads;
485  vec_validate (proxy_main.server_event_queue, num_threads - 1);
486  vec_validate (proxy_main.active_open_event_queue, num_threads - 1);
487  vec_validate (pm->rx_buf, num_threads - 1);
488 
489  for (i = 0; i < num_threads; i++)
490  vec_validate (pm->rx_buf[i], pm->rcv_buffer_size);
491 
492  if (proxy_server_attach ())
493  {
494  clib_warning ("failed to attach server app");
495  return -1;
496  }
497  if (proxy_server_listen ())
498  {
499  clib_warning ("failed to start listening");
500  return -1;
501  }
502  if (active_open_attach ())
503  {
504  clib_warning ("failed to attach active open app");
505  return -1;
506  }
507 
508  for (i = 0; i < num_threads; i++)
509  {
512 
514 
516  }
517 
518  return 0;
519 }
520 
521 static clib_error_t *
523  vlib_cli_command_t * cmd)
524 {
525  proxy_main_t *pm = &proxy_main;
526  char *default_server_uri = "tcp://0.0.0.0/23";
527  char *default_client_uri = "tcp://6.0.2.2/23";
528  int rv;
529  u64 tmp;
530 
531  pm->fifo_size = 64 << 10;
532  pm->rcv_buffer_size = 1024;
533  pm->prealloc_fifos = 0;
534  pm->private_segment_count = 0;
535  pm->private_segment_size = 0;
536  pm->server_uri = 0;
537 
539  {
540  if (unformat (input, "fifo-size %d", &pm->fifo_size))
541  pm->fifo_size <<= 10;
542  else if (unformat (input, "rcv-buf-size %d", &pm->rcv_buffer_size))
543  ;
544  else if (unformat (input, "prealloc-fifos %d", &pm->prealloc_fifos))
545  ;
546  else if (unformat (input, "private-segment-count %d",
547  &pm->private_segment_count))
548  ;
549  else if (unformat (input, "private-segment-size %U",
550  unformat_memory_size, &tmp))
551  {
552  if (tmp >= 0x100000000ULL)
553  return clib_error_return
554  (0, "private segment size %lld (%llu) too large", tmp, tmp);
555  pm->private_segment_size = tmp;
556  }
557  else if (unformat (input, "server-uri %s", &pm->server_uri))
558  ;
559  else if (unformat (input, "client-uri %s", &pm->client_uri))
560  pm->client_uri = format (0, "%s%c", pm->client_uri, 0);
561  else
562  return clib_error_return (0, "unknown input `%U'",
563  format_unformat_error, input);
564  }
565 
566  if (!pm->server_uri)
567  {
568  clib_warning ("No server-uri provided, Using default: %s",
569  default_server_uri);
570  pm->server_uri = format (0, "%s%c", default_server_uri, 0);
571  }
572  if (!pm->client_uri)
573  {
574  clib_warning ("No client-uri provided, Using default: %s",
575  default_client_uri);
576  pm->client_uri = format (0, "%s%c", default_client_uri, 0);
577  }
578 
579  vnet_session_enable_disable (vm, 1 /* turn on session and transport */ );
580 
581  rv = proxy_server_create (vm);
582  switch (rv)
583  {
584  case 0:
585  break;
586  default:
587  return clib_error_return (0, "server_create returned %d", rv);
588  }
589 
590  return 0;
591 }
592 
593 /* *INDENT-OFF* */
594 VLIB_CLI_COMMAND (proxy_create_command, static) =
595 {
596  .path = "test proxy server",
597  .short_help = "test proxy server [server-uri <tcp://ip/port>]"
598  "[client-uri <tcp://ip/port>][fifo-size <nn>][rcv-buf-size <nn>]"
599  "[prealloc-fifos <nn>][private-segment-size <mem>]"
600  "[private-segment-count <nn>]",
601  .function = proxy_server_create_command_fn,
602 };
603 /* *INDENT-ON* */
604 
605 clib_error_t *
607 {
608  proxy_main_t *pm = &proxy_main;
609  pm->server_client_index = ~0;
610  pm->active_open_client_index = ~0;
613 
614  return 0;
615 }
616 
618 
619 /*
620 * fd.io coding-style-patch-verification: ON
621 *
622 * Local Variables:
623 * eval: (c-set-style "gnu")
624 * End:
625 */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
u64 vpp_active_open_handle
Definition: proxy.h:36
#define hash_set(h, key, value)
Definition: hash.h:255
u32 private_segment_count
Number of private fifo segs.
Definition: proxy.h:62
u32 vl_api_memclnt_create_internal(char *name, svm_queue_t *q)
Definition: memory_api.c:120
#define hash_unset(h, key)
Definition: hash.h:261
a
Definition: bitmap.h:538
static void proxy_reset_callback(stream_session_t *s)
Definition: proxy.c:164
char uri[128]
Definition: proxy.c:26
svm_queue_t * vl_input_queue
vpe input queue
Definition: proxy.h:41
struct _vnet_connect_args vnet_connect_args_t
int vnet_bind_uri(vnet_bind_args_t *a)
#define PREDICT_TRUE(x)
Definition: clib.h:112
unsigned long u64
Definition: types.h:89
static int proxy_connected_callback(u32 app_index, u32 api_context, stream_session_t *s, u8 is_fail)
Definition: proxy.c:171
static_always_inline void clib_spinlock_unlock_if_init(clib_spinlock_t *p)
Definition: lock.h:98
static clib_error_t * proxy_server_create_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: proxy.c:522
int i
static void create_api_loopbacks(vlib_main_t *vm)
Definition: proxy.c:379
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
uword * proxy_session_by_server_handle
Definition: proxy.h:53
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static stream_session_t * session_get_from_handle(session_handle_t handle)
Definition: session.h:390
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:236
unsigned char u8
Definition: types.h:56
svm_fifo_t * server_rx_fifo
Definition: proxy.h:32
struct _svm_fifo svm_fifo_t
#define clib_memcpy(d, s, n)
Definition: string.h:180
static svm_msg_q_t * session_manager_get_vpp_event_queue(u32 thread_index)
Definition: session.h:656
u8 prealloc_fifos
Request fifo preallocation.
Definition: proxy.h:80
u32 fifo_size
Definition: proxy.h:61
#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:124
struct _stream_session_cb_vft session_cb_vft_t
static session_cb_vft_t proxy_session_cb_vft
Definition: proxy.c:264
#define clib_error_return(e, args...)
Definition: error.h:99
void vl_api_rpc_call_main_thread(void *fp, u8 *data, u32 data_length)
Definition: vlib_api.c:623
struct vl_shmem_hdr_ * shmem_hdr
Binary API shared-memory segment header pointer.
Definition: api_common.h:265
unsigned int u32
Definition: types.h:88
int rcv_buffer_size
Definition: proxy.h:64
u32 server_app_index
server app index
Definition: proxy.h:49
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:88
struct _vnet_app_attach_args_t vnet_app_attach_args_t
clib_error_t * proxy_main_init(vlib_main_t *vm)
Definition: proxy.c:606
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:511
proxy_session_t * sessions
Session pool, shared.
Definition: proxy.h:71
static int active_open_connected_callback(u32 app_index, u32 opaque, stream_session_t *s, u8 is_fail)
Definition: proxy.c:274
struct _unformat_input_t unformat_input_t
static void proxy_cb_fn(void *data, u32 data_len)
Definition: proxy.c:32
static session_handle_t session_handle(stream_session_t *s)
Definition: session.h:364
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
#define PREDICT_FALSE(x)
Definition: clib.h:111
proxy_main_t proxy_main
Definition: proxy.c:22
static int proxy_server_create(vlib_main_t *vm)
Definition: proxy.c:474
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: session.c:1529
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:202
u64 vpp_server_handle
Definition: proxy.h:35
static u8 svm_fifo_set_event(svm_fifo_t *f)
Sets fifo event flag.
Definition: svm_fifo.h:167
svm_msg_q_t ** active_open_event_queue
Definition: proxy.h:44
static void active_open_reset_callback(stream_session_t *s)
Definition: proxy.c:329
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
u32 active_open_client_index
active open API client handle
Definition: proxy.h:50
static int proxy_accept_callback(stream_session_t *s)
Definition: proxy.c:146
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:212
vlib_main_t * vm
Definition: buffer.c:301
u8 * format_stream_session(u8 *s, va_list *args)
Format stream session as per the following format.
Definition: session_cli.c:57
#define clib_warning(format, args...)
Definition: error.h:59
u32 server_client_index
server API client handle
Definition: proxy.h:48
static void proxy_call_main_thread(vnet_connect_args_t *a)
Definition: proxy.c:45
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:283
u8 * server_uri
Definition: proxy.h:65
static void delete_proxy_session(stream_session_t *s, int is_active_open)
Definition: proxy.c:62
int vnet_disconnect_session(vnet_disconnect_args_t *a)
svm_queue_t * vl_input_queue
Definition: memory_shared.h:84
svm_msg_q_t ** server_event_queue
per-thread vectors
Definition: proxy.h:43
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
u32 active_open_app_index
active open index after attach
Definition: proxy.h:51
#define hash_create(elts, value_bytes)
Definition: hash.h:696
#define ASSERT(truth)
static int proxy_server_attach()
Definition: proxy.c:394
static int active_open_create_callback(stream_session_t *s)
Definition: proxy.c:335
static void proxy_disconnect_callback(stream_session_t *s)
Definition: proxy.c:158
uword * proxy_session_by_active_open_handle
Definition: proxy.h:54
u8 ** rx_buf
intermediate rx buffers
Definition: proxy.h:45
clib_spinlock_t sessions_lock
Definition: proxy.h:72
u32 private_segment_size
size of private fifo segs
Definition: proxy.h:63
static int active_open_attach(void)
Definition: proxy.c:429
static int proxy_rx_callback(stream_session_t *s)
Definition: proxy.c:186
svm_fifo_t * server_tx_fifo
Definition: proxy.h:33
clib_error_t * vnet_connect_uri(vnet_connect_args_t *a)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
clib_error_t * vnet_application_attach(vnet_app_attach_args_t *a)
Attach application to vpp.
u64 uword
Definition: types.h:112
int session_send_io_evt_to_thread_custom(void *data, u32 thread_index, session_evt_type_t evt_type)
Definition: session.c:94
static void active_open_disconnect_callback(stream_session_t *s)
Definition: proxy.c:341
unformat_function_t unformat_memory_size
Definition: format.h:295
static int proxy_add_segment_callback(u32 client_index, u64 segment_handle)
Definition: proxy.c:179
static int proxy_server_listen()
Definition: proxy.c:463
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 int active_open_rx_callback(stream_session_t *s)
Definition: proxy.c:347
static session_cb_vft_t active_open_clients
Definition: proxy.c:368
int svm_fifo_peek(svm_fifo_t *f, u32 relative_offset, u32 max_bytes, u8 *copy_here)
Definition: svm_fifo.c:726
api_main_t api_main
Definition: api_shared.c:35
static_always_inline void clib_spinlock_lock_if_init(clib_spinlock_t *p)
Definition: lock.h:82
struct _vnet_bind_args_t vnet_bind_args_t
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
u8 * client_uri
Definition: proxy.h:66
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170