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