FD.io VPP  v18.01-8-g0eacf49
Vector Packet Processing
application.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 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 
19 #include <vnet/session/session.h>
20 
21 /**
22  * Pool from which we allocate all applications
23  */
25 
26 /**
27  * Hash table of apps by api client index
28  */
30 
31 /**
32  * Default application event queue size
33  */
35 
36 static u8 *
38 {
39  u8 *app_name;
40 
42  regp = vl_api_client_index_to_registration (app->api_client_index);
43  if (!regp)
44  app_name = format (0, "builtin-%d%c", app->index, 0);
45  else
46  app_name = format (0, "%s%c", regp->name, 0);
47 
48  return app_name;
49 }
50 
51 u32
53 {
54  app_namespace_t *app_ns;
55  app_ns = app_namespace_get (app->ns_index);
57  return APP_INVALID_INDEX;
58  if (fib_proto == FIB_PROTOCOL_IP4)
59  return session_lookup_get_index_for_fib (fib_proto,
60  app_ns->ip4_fib_index);
61  else
62  return session_lookup_get_index_for_fib (fib_proto,
63  app_ns->ip6_fib_index);
64 }
65 
66 u32
68 {
69  app_namespace_t *app_ns;
70  if (!application_has_local_scope (app))
71  return APP_INVALID_INDEX;
72  app_ns = app_namespace_get (app->ns_index);
73  return app_ns->local_table_index;
74 }
75 
76 int
78 {
80 
81  /* builtin servers are always OK */
82  if (app->api_client_index == ~0)
83  return 0;
84 
85  q = vl_api_client_index_to_input_queue (app->api_client_index);
86  if (!q)
87  return 1;
88 
89  if (q->cursize == q->maxsize)
90  return 1;
91  return 0;
92 }
93 
94 /**
95  * Returns app name
96  *
97  * Since the name is not stored per app, we generate it on the fly. It is
98  * the caller's responsibility to free the vector
99  */
100 u8 *
102 {
103  application_t *app = application_get (app_index);
104  if (!app)
105  return 0;
106  return app_get_name_from_reg_index (app);
107 }
108 
109 static void
111 {
112  hash_set (app_by_api_client_index, app->api_client_index, app->index);
113 }
114 
115 static void
117 {
118  hash_unset (app_by_api_client_index, app->api_client_index);
119 }
120 
122 application_lookup (u32 api_client_index)
123 {
124  uword *p;
125  p = hash_get (app_by_api_client_index, api_client_index);
126  if (p)
127  return application_get (p[0]);
128 
129  return 0;
130 }
131 
134 {
135  application_t *app;
136  pool_get (app_pool, app);
137  memset (app, 0, sizeof (*app));
138  app->index = application_get_index (app);
139  app->connects_seg_manager = APP_INVALID_SEGMENT_MANAGER_INDEX;
140  app->first_segment_manager = APP_INVALID_SEGMENT_MANAGER_INDEX;
141  if (CLIB_DEBUG > 1)
142  clib_warning ("[%d] New app (%d)", getpid (), app->index);
143  return app;
144 }
145 
146 void
148 {
150  vnet_unbind_args_t _a, *a = &_a;
151  segment_manager_t *sm;
152  u64 handle, *handles = 0;
153  u32 index;
154  int i;
155 
156  /*
157  * The app event queue allocated in first segment is cleared with
158  * the segment manager. No need to explicitly free it.
159  */
160  if (CLIB_DEBUG > 1)
161  clib_warning ("[%d] Delete app (%d)", getpid (), app->index);
162 
163  if (application_is_proxy (app))
165 
166  /*
167  * Listener cleanup
168  */
169 
170  /* *INDENT-OFF* */
171  hash_foreach (handle, index, app->listeners_table,
172  ({
173  vec_add1 (handles, handle);
174  sm = segment_manager_get (index);
175  sm->app_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
176  }));
177  /* *INDENT-ON* */
178 
179  for (i = 0; i < vec_len (handles); i++)
180  {
181  a->app_index = app->index;
182  a->handle = handles[i];
183  /* seg manager is removed when unbind completes */
184  vnet_unbind (a);
185  }
186 
187  /*
188  * Connects segment manager cleanup
189  */
190 
191  if (app->connects_seg_manager != APP_INVALID_SEGMENT_MANAGER_INDEX)
192  {
193  sm = segment_manager_get (app->connects_seg_manager);
194  sm->app_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
196  }
197 
198  /* If first segment manager is used by a listener */
199  if (app->first_segment_manager != APP_INVALID_SEGMENT_MANAGER_INDEX
200  && app->first_segment_manager != app->connects_seg_manager)
201  {
202  sm = segment_manager_get (app->first_segment_manager);
203  /* .. and has no fifos, e.g. it might be used for redirected sessions,
204  * remove it */
205  if (!segment_manager_has_fifos (sm))
206  {
207  sm->app_index = SEGMENT_MANAGER_INVALID_APP_INDEX;
208  segment_manager_del (sm);
209  }
210  }
211  props = segment_manager_properties_get (app->sm_properties);
213  application_table_del (app);
214  pool_put (app_pool, app);
215 }
216 
217 static void
219 {
220  if (cb_fns->session_accept_callback == 0)
221  clib_warning ("No accept callback function provided");
222  if (cb_fns->session_connected_callback == 0)
223  clib_warning ("No session connected callback function provided");
224  if (cb_fns->session_disconnect_callback == 0)
225  clib_warning ("No session disconnect callback function provided");
226  if (cb_fns->session_reset_callback == 0)
227  clib_warning ("No session reset callback function provided");
228 }
229 
230 int
231 application_init (application_t * app, u32 api_client_index, u64 * options,
232  session_cb_vft_t * cb_fns)
233 {
234  segment_manager_t *sm;
236  u32 app_evt_queue_size, first_seg_size;
237  u32 default_rx_fifo_size = 16 << 10, default_tx_fifo_size = 16 << 10;
238  int rv;
239 
240  app_evt_queue_size = options[APP_OPTIONS_EVT_QUEUE_SIZE] > 0 ?
242 
243  /*
244  * Setup segment manager
245  */
246  sm = segment_manager_new ();
247  sm->app_index = app->index;
249  app->sm_properties = segment_manager_properties_index (props);
250  props->add_segment_size = options[APP_OPTIONS_ADD_SEGMENT_SIZE];
251  props->rx_fifo_size = options[APP_OPTIONS_RX_FIFO_SIZE];
252  props->rx_fifo_size =
253  props->rx_fifo_size ? props->rx_fifo_size : default_rx_fifo_size;
254  props->tx_fifo_size = options[APP_OPTIONS_TX_FIFO_SIZE];
255  props->tx_fifo_size =
256  props->tx_fifo_size ? props->tx_fifo_size : default_tx_fifo_size;
257  props->add_segment = props->add_segment_size != 0;
258  props->preallocated_fifo_pairs = options[APP_OPTIONS_PREALLOC_FIFO_PAIRS];
259  props->use_private_segment = options[APP_OPTIONS_FLAGS]
260  & APP_OPTIONS_FLAGS_IS_BUILTIN;
261  props->private_segment_count = options[APP_OPTIONS_PRIVATE_SEGMENT_COUNT];
262 
263  first_seg_size = options[APP_OPTIONS_SEGMENT_SIZE];
264  if ((rv = segment_manager_init (sm, app->sm_properties, first_seg_size)))
265  return rv;
266  sm->first_is_protected = 1;
267 
268  /*
269  * Setup application
270  */
271  app->first_segment_manager = segment_manager_index (sm);
272  app->api_client_index = api_client_index;
273  app->flags = options[APP_OPTIONS_FLAGS];
274  app->cb_fns = *cb_fns;
275  app->ns_index = options[APP_OPTIONS_NAMESPACE];
276  app->listeners_table = hash_create (0, sizeof (u64));
277  app->proxied_transports = options[APP_OPTIONS_PROXY_TRANSPORT];
278 
279  /* If no scope enabled, default to global */
281  && !application_has_local_scope (app))
282  app->flags |= APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
283 
284  /* Allocate app event queue in the first shared-memory segment */
285  app->event_queue = segment_manager_alloc_queue (sm, app_evt_queue_size);
286 
287  /* Check that the obvious things are properly set up */
288  application_verify_cb_fns (cb_fns);
289 
290  /* Add app to lookup by api_client_index table */
291  application_table_add (app);
292 
293  return 0;
294 }
295 
298 {
299  if (index == APP_INVALID_INDEX)
300  return 0;
301  return pool_elt_at_index (app_pool, index);
302 }
303 
306 {
307  if (pool_is_free_index (app_pool, index))
308  return 0;
309 
310  return pool_elt_at_index (app_pool, index);
311 }
312 
313 u32
315 {
316  return app - app_pool;
317 }
318 
319 static segment_manager_t *
321 {
322  segment_manager_t *sm = 0;
323 
324  /* If the first segment manager is not in use, don't allocate a new one */
325  if (app->first_segment_manager != APP_INVALID_SEGMENT_MANAGER_INDEX
326  && app->first_segment_manager_in_use == 0)
327  {
328  sm = segment_manager_get (app->first_segment_manager);
329  app->first_segment_manager_in_use = 1;
330  return sm;
331  }
332 
333  sm = segment_manager_new ();
334  sm->properties_index = app->sm_properties;
335 
336  return sm;
337 }
338 
339 /**
340  * Start listening local transport endpoint for requested transport.
341  *
342  * Creates a 'dummy' stream session with state LISTENING to be used in session
343  * lookups, prior to establishing connection. Requests transport to build
344  * it's own specific listening connection.
345  */
346 int
348  u64 * res)
349 {
350  segment_manager_t *sm;
351  stream_session_t *s;
352  u64 handle;
353  session_type_t sst;
354 
355  sst = session_type_from_proto_and_ip (sep->transport_proto, sep->is_ip4);
356  s = listen_session_new (sst);
357  s->app_index = srv->index;
358 
359  if (stream_session_listen (s, sep))
360  goto err;
361 
362  /* Allocate segment manager. All sessions derived out of a listen session
363  * have fifos allocated by the same segment manager. */
365  if (sm == 0)
366  goto err;
367 
368  /* Add to app's listener table. Useful to find all child listeners
369  * when app goes down, although, just for unbinding this is not needed */
370  handle = listen_session_get_handle (s);
371  hash_set (srv->listeners_table, handle, segment_manager_index (sm));
372 
373  *res = handle;
374  return 0;
375 
376 err:
377  listen_session_del (s);
378  return -1;
379 }
380 
381 /**
382  * Stop listening on session associated to handle
383  */
384 int
386 {
387  stream_session_t *listener;
388  uword *indexp;
389  segment_manager_t *sm;
390 
391  if (srv && hash_get (srv->listeners_table, handle) == 0)
392  {
393  clib_warning ("app doesn't own handle %llu!", handle);
394  return -1;
395  }
396 
397  listener = listen_session_get_from_handle (handle);
398  stream_session_stop_listen (listener);
399 
400  indexp = hash_get (srv->listeners_table, handle);
401  ASSERT (indexp);
402 
403  sm = segment_manager_get (*indexp);
404  if (srv->first_segment_manager == *indexp)
405  {
406  /* Delete sessions but don't remove segment manager */
407  srv->first_segment_manager_in_use = 0;
409  }
410  else
411  {
413  }
414  hash_unset (srv->listeners_table, handle);
415  listen_session_del (listener);
416 
417  return 0;
418 }
419 
420 int
422  u32 api_context)
423 {
424  segment_manager_t *sm;
425  int rv;
426 
427  /* Make sure we have a segment manager for connects */
428  if (app->connects_seg_manager == APP_INVALID_SEGMENT_MANAGER_INDEX)
429  {
431  if (sm == 0)
432  return -1;
433  app->connects_seg_manager = segment_manager_index (sm);
434  }
435 
436  if ((rv = session_open (app->index, sep, api_context)))
437  return rv;
438 
439  return 0;
440 }
441 
444 {
445  ASSERT (app->connects_seg_manager != (u32) ~ 0);
446  return segment_manager_get (app->connects_seg_manager);
447 }
448 
451  stream_session_t * s)
452 {
453  uword *smp;
454  smp = hash_get (app->listeners_table, listen_session_get_handle (s));
455  ASSERT (smp != 0);
456  return segment_manager_get (*smp);
457 }
458 
459 int
461 {
462  return (app->flags & APP_OPTIONS_FLAGS_IS_PROXY);
463 }
464 
465 int
467 {
468  return (app->flags & APP_OPTIONS_FLAGS_IS_BUILTIN);
469 }
470 
471 int
473 {
474  return (application_is_proxy (app) && application_is_builtin (app));
475 }
476 
477 int
479 {
480  application_t *app = application_get (app_index);
481  u32 seg_size = 0;
482  u8 *seg_name;
483 
484  /* Send an API message to the external app, to map new segment */
485  ASSERT (app->cb_fns.add_segment_callback);
486 
487  segment_manager_get_segment_info (fifo_segment_index, &seg_name, &seg_size);
488  return app->cb_fns.add_segment_callback (app->api_client_index, seg_name,
489  seg_size);
490 }
491 
492 u8
494 {
495  return app->flags & APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE;
496 }
497 
498 u8
500 {
501  return app->flags & APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE;
502 }
503 
504 u32
506 {
507  return hash_elts (app->listeners_table);
508 }
509 
512  u8 transport_proto)
513 {
514  stream_session_t *listener;
515  u64 handle;
516  u32 sm_index;
517  u8 sst;
518 
519  sst = session_type_from_proto_and_ip (transport_proto,
520  fib_proto == FIB_PROTOCOL_IP4);
521 
522  /* *INDENT-OFF* */
523  hash_foreach (handle, sm_index, app->listeners_table, ({
524  listener = listen_session_get_from_handle (handle);
525  if (listener->session_type == sst
526  && listener->listener_index != SESSION_PROXY_LISTENER_INDEX)
527  return listener;
528  }));
529  /* *INDENT-ON* */
530 
531  return 0;
532 }
533 
536  u8 transport_proto)
537 {
538  stream_session_t *listener;
539  u64 handle;
540  u32 sm_index;
541  u8 sst;
542 
543  sst = session_type_from_proto_and_ip (transport_proto,
544  fib_proto == FIB_PROTOCOL_IP4);
545 
546  /* *INDENT-OFF* */
547  hash_foreach (handle, sm_index, app->listeners_table, ({
548  listener = listen_session_get_from_handle (handle);
549  if (listener->session_type == sst
550  && listener->listener_index == SESSION_PROXY_LISTENER_INDEX)
551  return listener;
552  }));
553  /* *INDENT-ON* */
554 
555  return 0;
556 }
557 
558 static clib_error_t *
560  u8 transport_proto, u8 is_start)
561 {
562  app_namespace_t *app_ns = app_namespace_get (app->ns_index);
563  u8 is_ip4 = (fib_proto == FIB_PROTOCOL_IP4);
566  stream_session_t *s;
567  u64 handle;
568 
569  if (is_start)
570  {
571  s = application_first_listener (app, fib_proto, transport_proto);
572  if (!s)
573  {
574  sep.is_ip4 = is_ip4;
575  sep.fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
576  sep.sw_if_index = app_ns->sw_if_index;
577  sep.transport_proto = transport_proto;
578  application_start_listen (app, &sep, &handle);
579  s = listen_session_get_from_handle (handle);
580  s->listener_index = SESSION_PROXY_LISTENER_INDEX;
581  }
582  }
583  else
584  {
585  s = application_proxy_listener (app, fib_proto, transport_proto);
586  ASSERT (s);
587  }
588 
590 
591  if (!ip_is_zero (&tc->lcl_ip, 1))
592  {
593  u32 sti;
594  sep.is_ip4 = is_ip4;
595  sep.fib_index = app_namespace_get_fib_index (app_ns, fib_proto);
596  sep.transport_proto = transport_proto;
597  sep.port = 0;
598  sti = session_lookup_get_index_for_fib (fib_proto, sep.fib_index);
599  if (is_start)
600  session_lookup_add_session_endpoint (sti, &sep, s->session_index);
601  else
603  }
604 
605  return 0;
606 }
607 
608 static void
610  u8 transport_proto, u8 is_start)
611 {
613  app_namespace_t *app_ns;
614  app_ns = app_namespace_get (app->ns_index);
615  sep.is_ip4 = 1;
616  sep.transport_proto = transport_proto;
617  sep.port = 0;
618 
619  if (is_start)
620  {
621  session_lookup_add_session_endpoint (app_ns->local_table_index, &sep,
622  app->index);
623  sep.is_ip4 = 0;
624  session_lookup_add_session_endpoint (app_ns->local_table_index, &sep,
625  app->index);
626  }
627  else
628  {
629  session_lookup_del_session_endpoint (app_ns->local_table_index, &sep);
630  sep.is_ip4 = 0;
631  session_lookup_del_session_endpoint (app_ns->local_table_index, &sep);
632  }
633 }
634 
635 void
637  transport_proto_t transport_proto, u8 is_start)
638 {
639  if (application_has_local_scope (app))
640  application_start_stop_proxy_local_scope (app, transport_proto, is_start);
641 
643  {
645  transport_proto, is_start);
647  transport_proto, is_start);
648  }
649 }
650 
651 void
653 {
654  u16 transports = app->proxied_transports;
656 
658  if (application_is_builtin (app))
659  return;
660 
661  /* *INDENT-OFF* */
663  if (transports & (1 << tp))
664  application_start_stop_proxy (app, tp, 1);
665  }));
666  /* *INDENT-ON* */
667 }
668 
669 void
671 {
672  u16 transports = app->proxied_transports;
674 
676 
677  /* *INDENT-OFF* */
679  if (transports & (1 << tp))
680  application_start_stop_proxy (app, tp, 0);
681  }));
682  /* *INDENT-ON* */
683 }
684 
685 u8 *
686 format_application_listener (u8 * s, va_list * args)
687 {
688  application_t *app = va_arg (*args, application_t *);
689  u64 handle = va_arg (*args, u64);
690  u32 index = va_arg (*args, u32);
691  int verbose = va_arg (*args, int);
692  stream_session_t *listener;
693  u8 *app_name, *str;
694 
695  if (app == 0)
696  {
697  if (verbose)
698  s = format (s, "%-40s%-20s%-15s%-15s%-10s", "Connection", "App",
699  "API Client", "ListenerID", "SegManager");
700  else
701  s = format (s, "%-40s%-20s", "Connection", "App");
702 
703  return s;
704  }
705 
706  app_name = app_get_name_from_reg_index (app);
707  listener = listen_session_get_from_handle (handle);
708  str = format (0, "%U", format_stream_session, listener, verbose);
709 
710  if (verbose)
711  {
712  s = format (s, "%-40s%-20s%-15u%-15u%-10u", str, app_name,
713  app->api_client_index, handle, index);
714  }
715  else
716  s = format (s, "%-40s%-20s", str, app_name);
717 
718  vec_free (app_name);
719  return s;
720 }
721 
722 void
724 {
726  segment_manager_t *sm;
727  u8 *app_name, *s = 0;
728  int j;
729 
730  /* Header */
731  if (app == 0)
732  {
733  if (verbose)
734  vlib_cli_output (vm, "%-40s%-20s%-15s%-10s", "Connection", "App",
735  "API Client", "SegManager");
736  else
737  vlib_cli_output (vm, "%-40s%-20s", "Connection", "App");
738  return;
739  }
740 
741  /* make sure */
742  if (app->connects_seg_manager == (u32) ~ 0)
743  return;
744 
745  app_name = app_get_name_from_reg_index (app);
746 
747  /* Across all fifo segments */
748  sm = segment_manager_get (app->connects_seg_manager);
749  for (j = 0; j < vec_len (sm->segment_indices); j++)
750  {
751  svm_fifo_segment_private_t *fifo_segment;
752  svm_fifo_t *fifo;
753  u8 *str;
754 
755  fifo_segment = svm_fifo_segment_get_segment (sm->segment_indices[j]);
756  fifo = svm_fifo_segment_get_fifo_list (fifo_segment);
757  while (fifo)
758  {
759  u32 session_index, thread_index;
760  stream_session_t *session;
761 
762  session_index = fifo->master_session_index;
763  thread_index = fifo->master_thread_index;
764 
765  session = session_get (session_index, thread_index);
766  str = format (0, "%U", format_stream_session, session, verbose);
767 
768  if (verbose)
769  s = format (s, "%-40s%-20s%-15u%-10u", str, app_name,
770  app->api_client_index, app->connects_seg_manager);
771  else
772  s = format (s, "%-40s%-20s", str, app_name);
773 
774  vlib_cli_output (vm, "%v", s);
775  vec_reset_length (s);
776  vec_free (str);
777 
778  fifo = fifo->next;
779  }
780  vec_free (s);
781  }
782 
783  vec_free (app_name);
784 }
785 
786 u8 *
787 format_application (u8 * s, va_list * args)
788 {
789  application_t *app = va_arg (*args, application_t *);
790  CLIB_UNUSED (int verbose) = va_arg (*args, int);
792  const u8 *app_ns_name;
793  u8 *app_name;
794 
795  if (app == 0)
796  {
797  if (verbose)
798  s = format (s, "%-10s%-20s%-15s%-15s%-15s%-15s%-15s", "Index", "Name",
799  "API Client", "Namespace", "Add seg size", "Rx fifo size",
800  "Tx fifo size");
801  else
802  s =
803  format (s, "%-10s%-20s%-15s%-40s", "Index", "Name", "API Client",
804  "Namespace");
805  return s;
806  }
807 
808  app_name = app_get_name_from_reg_index (app);
809  app_ns_name = app_namespace_id_from_index (app->ns_index);
810  props = segment_manager_properties_get (app->sm_properties);
811  if (verbose)
812  s =
813  format (s, "%-10d%-20s%-15d%-15d%-15d%-15d%-15d", app->index, app_name,
814  app->api_client_index, app->ns_index,
815  props->add_segment_size,
816  props->rx_fifo_size, props->tx_fifo_size);
817  else
818  s = format (s, "%-10d%-20s%-15d%-40s", app->index, app_name,
819  app->api_client_index, app_ns_name);
820  return s;
821 }
822 
823 static clib_error_t *
825  vlib_cli_command_t * cmd)
826 {
827  application_t *app;
828  int do_server = 0;
829  int do_client = 0;
830  int verbose = 0;
831 
833 
835  {
836  if (unformat (input, "server"))
837  do_server = 1;
838  else if (unformat (input, "client"))
839  do_client = 1;
840  else if (unformat (input, "verbose"))
841  verbose = 1;
842  else
843  break;
844  }
845 
846  if (do_server)
847  {
848  u64 handle;
849  u32 index;
850  if (pool_elts (app_pool))
851  {
853  0 /* header */ , 0, 0,
854  verbose);
855  /* *INDENT-OFF* */
856  pool_foreach (app, app_pool,
857  ({
858  /* App's listener sessions */
859  if (hash_elts (app->listeners_table) == 0)
860  continue;
861  hash_foreach (handle, index, app->listeners_table,
862  ({
863  vlib_cli_output (vm, "%U", format_application_listener, app,
864  handle, index, verbose);
865  }));
866  }));
867  /* *INDENT-ON* */
868  }
869  else
870  vlib_cli_output (vm, "No active server bindings");
871  }
872 
873  if (do_client)
874  {
875  if (pool_elts (app_pool))
876  {
877  application_format_connects (0, verbose);
878 
879  /* *INDENT-OFF* */
880  pool_foreach (app, app_pool,
881  ({
882  if (app->connects_seg_manager == (u32)~0)
883  continue;
884  application_format_connects (app, verbose);
885  }));
886  /* *INDENT-ON* */
887  }
888  else
889  vlib_cli_output (vm, "No active client bindings");
890  }
891 
892  /* Print app related info */
893  if (!do_server && !do_client)
894  {
895  vlib_cli_output (vm, "%U", format_application, 0, verbose);
896  /* *INDENT-OFF* */
897  pool_foreach (app, app_pool, ({
898  vlib_cli_output (vm, "%U", format_application, app, verbose);
899  }));
900  /* *INDENT-ON* */
901  }
902 
903  return 0;
904 }
905 
906 /* *INDENT-OFF* */
907 VLIB_CLI_COMMAND (show_app_command, static) =
908 {
909  .path = "show app",
910  .short_help = "show app [server|client] [verbose]",
911  .function = show_app_command_fn,
912 };
913 /* *INDENT-ON* */
914 
915 /*
916  * fd.io coding-style-patch-verification: ON
917  *
918  * Local Variables:
919  * eval: (c-set-style "gnu")
920  * End:
921  */
int application_open_session(application_t *app, session_endpoint_t *sep, u32 api_context)
Definition: application.c:421
static void application_table_add(application_t *app)
Definition: application.c:110
int application_stop_listen(application_t *srv, u64 handle)
Stop listening on session associated to handle.
Definition: application.c:385
u8 * name
Client name.
Definition: api_common.h:51
#define hash_set(h, key, value)
Definition: hash.h:254
static u32 default_app_evt_queue_size
Default application event queue size.
Definition: application.c:34
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
static stream_session_t * listen_session_get_from_handle(u64 handle)
Definition: session.h:474
int application_add_segment_notify(u32 app_index, u32 fifo_segment_index)
Definition: application.c:478
u32 application_n_listeners(application_t *app)
Definition: application.c:505
#define CLIB_UNUSED(x)
Definition: clib.h:79
u32 segment_manager_properties_index(segment_manager_properties_t *p)
#define hash_unset(h, key)
Definition: hash.h:260
a
Definition: bitmap.h:516
u8 application_has_global_scope(application_t *app)
Definition: application.c:499
struct _transport_connection transport_connection_t
struct _segment_manager_properties segment_manager_properties_t
#define session_cli_return_if_not_enabled()
Definition: session.h:550
static clib_error_t * show_app_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: application.c:824
clib_error_t * vnet_unbind(vnet_unbind_args_t *a)
#define SESSION_PROXY_LISTENER_INDEX
Definition: session.h:27
application_t * application_new()
Definition: application.c:133
u32 session_lookup_get_index_for_fib(u32 fib_proto, u32 fib_index)
application_t * application_lookup(u32 api_client_index)
Definition: application.c:122
static stream_session_t * listen_session_new(session_type_t type)
Definition: session.h:491
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:225
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define SESSION_ENDPOINT_NULL
struct _svm_fifo svm_fifo_t
void segment_manager_get_segment_info(u32 index, u8 **name, u32 *size)
segment_manager_t * application_get_listen_segment_manager(application_t *app, stream_session_t *s)
Definition: application.c:450
int application_is_proxy(application_t *app)
Definition: application.c:460
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:438
static void application_table_del(application_t *app)
Definition: application.c:116
struct _stream_session_cb_vft session_cb_vft_t
struct _vnet_unbind_args_t vnet_unbind_args_t
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:441
#define transport_proto_foreach(VAR, BODY)
unix_shared_memory_queue_t * segment_manager_alloc_queue(segment_manager_t *sm, u32 queue_size)
Allocates shm queue in the first segment.
unsigned long u64
Definition: types.h:89
static u8 * app_get_name_from_reg_index(application_t *app)
Definition: application.c:37
struct _stream_session_t stream_session_t
segment_manager_t * segment_manager_new()
static void application_verify_cb_fns(session_cb_vft_t *cb_fns)
Definition: application.c:218
int session_open(u32 app_index, session_endpoint_t *rmt, u32 opaque)
Ask transport to open connection to remote transport endpoint.
Definition: session.c:807
static void listen_session_del(stream_session_t *s)
Definition: session.h:513
int application_is_builtin(application_t *app)
Definition: application.c:466
#define hash_get(h, key)
Definition: hash.h:248
u32 app_namespace_get_fib_index(app_namespace_t *app_ns, u8 fib_proto)
static svm_fifo_t * svm_fifo_segment_get_fifo_list(svm_fifo_segment_private_t *fifo_segment)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:459
struct _session_endpoint session_endpoint_t
stream_session_t * application_proxy_listener(application_t *app, u8 fib_proto, u8 transport_proto)
Definition: application.c:535
struct _unformat_input_t unformat_input_t
static application_t * app_pool
Pool from which we allocate all applications.
Definition: application.c:24
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:271
#define APP_INVALID_INDEX
Definition: application.h:105
u8 segment_manager_has_fifos(segment_manager_t *sm)
void segment_manager_properties_free(segment_manager_properties_t *props)
stream_session_t * application_first_listener(application_t *app, u8 fib_proto, u8 transport_proto)
Definition: application.c:511
int application_start_listen(application_t *srv, session_endpoint_t *sep, u64 *res)
Start listening local transport endpoint for requested transport.
Definition: application.c:347
app_namespace_t * app_namespace_get(u32 index)
u32 application_session_table(application_t *app, u8 fib_proto)
Definition: application.c:52
u8 * application_name_from_index(u32 app_index)
Returns app name.
Definition: application.c:101
static stream_session_t * session_get(u32 si, u32 thread_index)
Definition: session.h:229
#define SEGMENT_MANAGER_INVALID_APP_INDEX
An API client registration, only in vpp/vlib.
Definition: api_common.h:44
u32 application_local_session_table(application_t *app)
Definition: application.c:67
segment_manager_properties_t * segment_manager_properties_alloc(void)
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static session_type_t session_type_from_proto_and_ip(transport_proto_t proto, u8 is_ip4)
Definition: session.h:289
vlib_main_t * vm
Definition: buffer.c:283
u8 * format_stream_session(u8 *s, va_list *args)
Format stream session as per the following format.
Definition: session_cli.c:52
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
segment_manager_t * application_get_connect_segment_manager(application_t *app)
Definition: application.c:443
int session_lookup_del_session_endpoint(u32 table_index, session_endpoint_t *sep)
#define clib_warning(format, args...)
Definition: error.h:59
unix_shared_memory_queue_t * vl_api_client_index_to_input_queue(u32 index)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:268
struct _application application_t
const u8 * app_namespace_id_from_index(u32 index)
static uword * app_by_api_client_index
Hash table of apps by api client index.
Definition: application.c:29
int session_lookup_add_session_endpoint(u32 table_index, session_endpoint_t *sep, u64 value)
static svm_fifo_segment_private_t * svm_fifo_segment_get_segment(u32 segment_index)
struct _app_namespace app_namespace_t
static u32 segment_manager_index(segment_manager_t *sm)
static segment_manager_t * application_alloc_segment_manager(application_t *app)
Definition: application.c:320
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define hash_create(elts, value_bytes)
Definition: hash.h:681
void segment_manager_init_del(segment_manager_t *sm)
static uword hash_elts(void *v)
Definition: hash.h:117
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u8 session_type_t
int application_init(application_t *app, u32 api_client_index, u64 *options, session_cb_vft_t *cb_fns)
Definition: application.c:231
void application_remove_proxy(application_t *app)
Definition: application.c:670
void application_del(application_t *app)
Definition: application.c:147
u32 application_get_index(application_t *app)
Definition: application.c:314
static int app_index
int stream_session_stop_listen(stream_session_t *s)
Ask transport to stop listening on local transport endpoint.
Definition: session.c:904
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u64 uword
Definition: types.h:112
u8 ip_is_zero(ip46_address_t *ip46_address, u8 is_ip4)
Definition: ip.c:20
void segment_manager_del(segment_manager_t *sm)
Removes segment manager.
unsigned short u16
Definition: types.h:57
u8 * format_application_listener(u8 *s, va_list *args)
Definition: application.c:686
enum _transport_proto transport_proto_t
transport_connection_t * listen_session_get_transport(stream_session_t *s)
Definition: session.c:1039
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
u8 * format_application(u8 *s, va_list *args)
Definition: application.c:787
application_t * application_get(u32 index)
Definition: application.c:297
int segment_manager_init(segment_manager_t *sm, u32 props_index, u32 first_seg_size)
Initializes segment manager based on options provided.
void segment_manager_del_sessions(segment_manager_t *sm)
Initiate disconnects for all sessions &#39;owned&#39; by a segment manager.
struct _segment_manager segment_manager_t
static clib_error_t * application_start_stop_proxy_fib_proto(application_t *app, u8 fib_proto, u8 transport_proto, u8 is_start)
Definition: application.c:559
static void application_start_stop_proxy_local_scope(application_t *app, u8 transport_proto, u8 is_start)
Definition: application.c:609
vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
void application_setup_proxy(application_t *app)
Definition: application.c:652
int application_is_builtin_proxy(application_t *app)
Definition: application.c:472
void application_start_stop_proxy(application_t *app, transport_proto_t transport_proto, u8 is_start)
Definition: application.c:636
int application_api_queue_is_full(application_t *app)
Definition: application.c:77
#define APP_INVALID_SEGMENT_MANAGER_INDEX
Definition: application.h:108
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
static segment_manager_t * segment_manager_get(u32 index)
static u64 listen_session_get_handle(stream_session_t *s)
Definition: session.h:467
application_t * application_get_if_valid(u32 index)
Definition: application.c:305
void application_format_connects(application_t *app, int verbose)
Definition: application.c:723
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
struct _unix_shared_memory_queue unix_shared_memory_queue_t
segment_manager_properties_t * segment_manager_properties_get(u32 smp_index)
int stream_session_listen(stream_session_t *s, session_endpoint_t *sep)
Ask transport to listen on local transport endpoint.
Definition: session.c:872
u8 application_has_local_scope(application_t *app)
Definition: application.c:493
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128