FD.io VPP  v19.08-27-gf4dcae4
Vector Packet Processing
session_api.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-2019 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>
23 #include <vnet/session/session.h>
24 
25 #include <vnet/vnet_msg_enum.h>
26 
27 #define vl_typedefs /* define message structures */
28 #include <vnet/vnet_all_api_h.h>
29 #undef vl_typedefs
30 
31 #define vl_endianfun /* define message structures */
32 #include <vnet/vnet_all_api_h.h>
33 #undef vl_endianfun
34 
35 /* instantiate all the print functions we know about */
36 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
37 #define vl_printfun
38 #include <vnet/vnet_all_api_h.h>
39 #undef vl_printfun
40 
42 
43 #define foreach_session_api_msg \
44 _(MAP_ANOTHER_SEGMENT_REPLY, map_another_segment_reply) \
45 _(APPLICATION_ATTACH, application_attach) \
46 _(APPLICATION_DETACH, application_detach) \
47 _(BIND_URI, bind_uri) \
48 _(UNBIND_URI, unbind_uri) \
49 _(CONNECT_URI, connect_uri) \
50 _(DISCONNECT_SESSION, disconnect_session) \
51 _(DISCONNECT_SESSION_REPLY, disconnect_session_reply) \
52 _(BIND_SOCK, bind_sock) \
53 _(UNBIND_SOCK, unbind_sock) \
54 _(CONNECT_SOCK, connect_sock) \
55 _(SESSION_ENABLE_DISABLE, session_enable_disable) \
56 _(APP_NAMESPACE_ADD_DEL, app_namespace_add_del) \
57 _(SESSION_RULE_ADD_DEL, session_rule_add_del) \
58 _(SESSION_RULES_DUMP, session_rules_dump) \
59 _(APPLICATION_TLS_CERT_ADD, application_tls_cert_add) \
60 _(APPLICATION_TLS_KEY_ADD, application_tls_key_add) \
61 _(APP_WORKER_ADD_DEL, app_worker_add_del) \
62 
63 static int
64 session_send_fds (vl_api_registration_t * reg, int fds[], int n_fds)
65 {
66  clib_error_t *error;
68  {
69  clib_warning ("can't send memfd fd");
70  return -1;
71  }
72  error = vl_api_send_fd_msg (reg, fds, n_fds);
73  if (error)
74  {
75  clib_error_report (error);
76  return -1;
77  }
78  return 0;
79 }
80 
81 static int
82 send_add_segment_callback (u32 api_client_index, u64 segment_handle)
83 {
84  int fds[SESSION_N_FD_TYPE], n_fds = 0;
87  fifo_segment_t *fs;
88  ssvm_private_t *sp;
89  u8 fd_flags = 0;
90 
91  reg = vl_mem_api_client_index_to_registration (api_client_index);
92  if (!reg)
93  {
94  clib_warning ("no api registration for client: %u", api_client_index);
95  return -1;
96  }
97 
98  fs = segment_manager_get_segment_w_handle (segment_handle);
99  sp = &fs->ssvm;
100  if (ssvm_type (sp) == SSVM_SEGMENT_MEMFD)
101  {
103  {
104  clib_warning ("can't send memfd fd");
105  return -1;
106  }
107 
108  fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
109  fds[n_fds] = sp->fd;
110  n_fds += 1;
111  }
112 
113  mp = vl_mem_api_alloc_as_if_client_w_reg (reg, sizeof (*mp));
114  clib_memset (mp, 0, sizeof (*mp));
115  mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_MAP_ANOTHER_SEGMENT);
116  mp->segment_size = sp->ssvm_size;
117  mp->fd_flags = fd_flags;
118  mp->segment_handle = clib_host_to_net_u64 (segment_handle);
119  strncpy ((char *) mp->segment_name, (char *) sp->name,
120  sizeof (mp->segment_name) - 1);
121 
122  vl_msg_api_send_shmem (reg->vl_input_queue, (u8 *) & mp);
123 
124  if (n_fds)
125  return session_send_fds (reg, fds, n_fds);
126 
127  return 0;
128 }
129 
130 static int
131 send_del_segment_callback (u32 api_client_index, u64 segment_handle)
132 {
135 
136  reg = vl_mem_api_client_index_to_registration (api_client_index);
137  if (!reg)
138  {
139  clib_warning ("no registration: %u", api_client_index);
140  return -1;
141  }
142 
143  mp = vl_mem_api_alloc_as_if_client_w_reg (reg, sizeof (*mp));
144  clib_memset (mp, 0, sizeof (*mp));
145  mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_UNMAP_SEGMENT);
146  mp->segment_handle = clib_host_to_net_u64 (segment_handle);
147  vl_msg_api_send_shmem (reg->vl_input_queue, (u8 *) & mp);
148 
149  return 0;
150 }
151 
152 static int
154 {
155  int rv;
156  u8 try = 0;
157  while (try < 100)
158  {
161  SVM_Q_NOWAIT, msg);
162  if (!rv)
163  return 0;
164  try++;
165  usleep (1);
166  }
167  clib_warning ("failed to alloc msg");
168  return -1;
169 }
170 
171 static int
173 {
174  app_worker_t *app_wrk = app_worker_get (s->app_wrk_index);
175  svm_msg_q_msg_t _msg, *msg = &_msg;
176  svm_msg_q_t *vpp_queue, *app_mq;
179  session_event_t *evt;
180  application_t *app;
181 
182  app = application_get (app_wrk->app_index);
183  app_mq = app_wrk->event_queue;
184  if (mq_try_lock_and_alloc_msg (app_mq, msg))
185  return -1;
186 
187  evt = svm_msg_q_msg_data (app_mq, msg);
188  clib_memset (evt, 0, sizeof (*evt));
189  evt->event_type = SESSION_CTRL_EVT_ACCEPTED;
190  mp = (session_accepted_msg_t *) evt->data;
191  clib_memset (mp, 0, sizeof (*mp));
192  mp->context = app->app_index;
196 
197  if (session_has_transport (s))
198  {
201  if (application_is_proxy (app))
202  {
203  listener =
206  if (listener)
208  }
210  mp->vpp_event_queue_address = pointer_to_uword (vpp_queue);
211  mp->handle = session_handle (s);
212 
213  session_get_endpoint (s, &mp->rmt, 0 /* is_lcl */ );
214  }
215  else
216  {
217  ct_connection_t *ct;
218 
222  mp->rmt.is_ip4 = session_type_is_ip4 (listener->session_type);
223  mp->rmt.port = ct->c_rmt_port;
224  mp->handle = session_handle (s);
225  vpp_queue = session_main_get_vpp_event_queue (0);
226  mp->vpp_event_queue_address = pointer_to_uword (vpp_queue);
227  }
228  svm_msg_q_add_and_unlock (app_mq, msg);
229 
230  return 0;
231 }
232 
233 static inline void
235  session_evt_type_t evt_type)
236 {
237  svm_msg_q_msg_t _msg, *msg = &_msg;
239  svm_msg_q_t *app_mq;
240  session_event_t *evt;
241 
242  app_mq = app_wrk->event_queue;
243  if (mq_try_lock_and_alloc_msg (app_mq, msg))
244  return;
245  evt = svm_msg_q_msg_data (app_mq, msg);
246  clib_memset (evt, 0, sizeof (*evt));
247  evt->event_type = evt_type;
248  mp = (session_disconnected_msg_t *) evt->data;
249  mp->handle = sh;
250  mp->context = app_wrk->api_client_index;
251  svm_msg_q_add_and_unlock (app_mq, msg);
252 }
253 
254 static inline void
256  svm_fifo_t * f, session_evt_type_t evt_type)
257 {
258  app_worker_t *app_wrk;
259  application_t *app;
260  int i;
261 
262  app = application_get (app_index);
263  if (!app)
264  return;
265 
266  for (i = 0; i < f->n_subscribers; i++)
267  {
268  if (!(app_wrk = application_get_worker (app, f->subscribers[i])))
269  continue;
271  }
272 }
273 
274 static void
276 {
277  app_worker_t *app_wrk = app_worker_get (s->app_wrk_index);
279 
282 
286 }
287 
288 static void
290 {
291  app_worker_t *app_wrk = app_worker_get (s->app_wrk_index);
293 
295 
299 }
300 
301 static int
302 mq_send_session_connected_cb (u32 app_wrk_index, u32 api_context,
303  session_t * s, u8 is_fail)
304 {
305  svm_msg_q_msg_t _msg, *msg = &_msg;
307  svm_msg_q_t *vpp_mq, *app_mq;
309  app_worker_t *app_wrk;
310  session_event_t *evt;
311 
312  app_wrk = app_worker_get (app_wrk_index);
313  app_mq = app_wrk->event_queue;
314  if (!app_mq)
315  {
316  clib_warning ("app %u with api index: %u not attached",
317  app_wrk->app_index, app_wrk->api_client_index);
318  return -1;
319  }
320 
321  if (mq_try_lock_and_alloc_msg (app_mq, msg))
322  return -1;
323 
324  evt = svm_msg_q_msg_data (app_mq, msg);
325  clib_memset (evt, 0, sizeof (*evt));
326  evt->event_type = SESSION_CTRL_EVT_CONNECTED;
327  mp = (session_connected_msg_t *) evt->data;
328  clib_memset (mp, 0, sizeof (*mp));
329  mp->context = api_context;
330 
331  if (is_fail)
332  goto done;
333 
334  if (session_has_transport (s))
335  {
336  tc = session_get_transport (s);
337  if (!tc)
338  {
339  is_fail = 1;
340  goto done;
341  }
342 
344  mp->handle = session_handle (s);
346 
347  session_get_endpoint (s, &mp->lcl, 1 /* is_lcl */ );
348 
352  }
353  else
354  {
355  ct_connection_t *cct;
356  session_t *ss;
357 
359  mp->handle = session_handle (s);
360  mp->lcl.port = cct->c_lcl_port;
361  mp->lcl.is_ip4 = cct->c_is_ip4;
367  ss = ct_session_get_peer (s);
368  mp->ct_rx_fifo = pointer_to_uword (ss->tx_fifo);
369  mp->ct_tx_fifo = pointer_to_uword (ss->rx_fifo);
371  }
372 
373 done:
374  mp->retval = is_fail ?
375  clib_host_to_net_u32 (VNET_API_ERROR_SESSION_CONNECT) : 0;
376 
377  svm_msg_q_add_and_unlock (app_mq, msg);
378  return 0;
379 }
380 
381 static int
382 mq_send_session_bound_cb (u32 app_wrk_index, u32 api_context,
383  session_handle_t handle, int rv)
384 {
385  svm_msg_q_msg_t _msg, *msg = &_msg;
386  svm_msg_q_t *app_mq, *vpp_evt_q;
389  app_worker_t *app_wrk;
390  session_event_t *evt;
391  app_listener_t *al;
392  session_t *ls = 0;
393  app_wrk = app_worker_get (app_wrk_index);
394  app_mq = app_wrk->event_queue;
395  if (!app_mq)
396  {
397  clib_warning ("app %u with api index: %u not attached",
398  app_wrk->app_index, app_wrk->api_client_index);
399  return -1;
400  }
401 
402  if (mq_try_lock_and_alloc_msg (app_mq, msg))
403  return -1;
404 
405  evt = svm_msg_q_msg_data (app_mq, msg);
406  clib_memset (evt, 0, sizeof (*evt));
407  evt->event_type = SESSION_CTRL_EVT_BOUND;
408  mp = (session_bound_msg_t *) evt->data;
409  mp->context = api_context;
410 
411  if (rv)
412  goto done;
413 
414  mp->handle = handle;
415  al = app_listener_get_w_handle (handle);
417  ls = app_listener_get_session (al);
418  else
420 
421  session_get_endpoint (ls, &tep, 1 /* is_lcl */ );
422  mp->lcl_port = tep.port;
423  mp->lcl_is_ip4 = tep.is_ip4;
424  clib_memcpy_fast (mp->lcl_ip, &tep.ip, sizeof (tep.ip));
425 
426  vpp_evt_q = session_main_get_vpp_event_queue (0);
427  mp->vpp_evt_q = pointer_to_uword (vpp_evt_q);
428 
430  {
431  mp->rx_fifo = pointer_to_uword (ls->rx_fifo);
432  mp->tx_fifo = pointer_to_uword (ls->tx_fifo);
433  }
434 
435 done:
436  mp->retval = rv;
437  svm_msg_q_add_and_unlock (app_mq, msg);
438  return 0;
439 }
440 
441 static void
443 {
444  clib_warning ("not supported");
445 }
446 
447 
449  .session_accept_callback = mq_send_session_accepted_cb,
450  .session_disconnect_callback = mq_send_session_disconnected_cb,
451  .session_connected_callback = mq_send_session_connected_cb,
452  .session_reset_callback = mq_send_session_reset_cb,
453  .session_migrate_callback = mq_send_session_migrate_cb,
454  .add_segment_callback = send_add_segment_callback,
455  .del_segment_callback = send_del_segment_callback,
456 };
457 
458 static void
460 {
461  vl_api_session_enable_disable_reply_t *rmp;
463  int rv = 0;
464 
466  REPLY_MACRO (VL_API_SESSION_ENABLE_DISABLE_REPLY);
467 }
468 
469 static void
471 {
472  int rv = 0, fds[SESSION_N_FD_TYPE], n_fds = 0;
474  ssvm_private_t *segp, *evt_q_segment;
475  vnet_app_attach_args_t _a, *a = &_a;
477  u8 fd_flags = 0;
478 
480  if (!reg)
481  return;
482 
483  if (session_main_is_enabled () == 0)
484  {
485  rv = VNET_API_ERROR_FEATURE_DISABLED;
486  goto done;
487  }
488 
490  sizeof (mp->options),
491  "Out of options, fix api message definition");
492 
493  clib_memset (a, 0, sizeof (*a));
494  a->api_client_index = mp->client_index;
495  a->options = mp->options;
496  a->session_cb_vft = &session_mq_cb_vft;
497  if (mp->namespace_id_len > 64)
498  {
499  rv = VNET_API_ERROR_INVALID_VALUE;
500  goto done;
501  }
502 
503  if (mp->namespace_id_len)
504  {
505  vec_validate (a->namespace_id, mp->namespace_id_len - 1);
506  clib_memcpy_fast (a->namespace_id, mp->namespace_id,
507  mp->namespace_id_len);
508  }
509 
510  if ((rv = vnet_application_attach (a)))
511  {
512  clib_warning ("attach returned: %d", rv);
513  vec_free (a->namespace_id);
514  goto done;
515  }
516  vec_free (a->namespace_id);
517 
518  /* Send event queues segment */
519  if ((evt_q_segment = session_main_get_evt_q_segment ()))
520  {
521  fd_flags |= SESSION_FD_F_VPP_MQ_SEGMENT;
522  fds[n_fds] = evt_q_segment->fd;
523  n_fds += 1;
524  }
525  /* Send fifo segment fd if needed */
526  if (ssvm_type (a->segment) == SSVM_SEGMENT_MEMFD)
527  {
528  fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
529  fds[n_fds] = a->segment->fd;
530  n_fds += 1;
531  }
532  if (a->options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD)
533  {
534  fd_flags |= SESSION_FD_F_MQ_EVENTFD;
535  fds[n_fds] = svm_msg_q_get_producer_eventfd (a->app_evt_q);
536  n_fds += 1;
537  }
538 
539 done:
540 
541  /* *INDENT-OFF* */
542  REPLY_MACRO2 (VL_API_APPLICATION_ATTACH_REPLY, ({
543  if (!rv)
544  {
545  segp = a->segment;
546  rmp->app_index = clib_host_to_net_u32 (a->app_index);
547  rmp->segment_name_length = 0;
548  rmp->segment_size = segp->ssvm_size;
549  if (vec_len (segp->name))
550  {
551  memcpy (rmp->segment_name, segp->name, vec_len (segp->name));
552  rmp->segment_name_length = vec_len (segp->name);
553  }
554  rmp->app_event_queue_address = pointer_to_uword (a->app_evt_q);
555  rmp->n_fds = n_fds;
556  rmp->fd_flags = fd_flags;
557  rmp->segment_handle = clib_host_to_net_u64 (a->segment_handle);
558  }
559  }));
560  /* *INDENT-ON* */
561 
562  if (n_fds)
563  session_send_fds (reg, fds, n_fds);
564 }
565 
566 static void
568 {
569  vl_api_application_detach_reply_t *rmp;
570  int rv = VNET_API_ERROR_INVALID_VALUE_2;
571  vnet_app_detach_args_t _a, *a = &_a;
572  application_t *app;
573 
574  if (session_main_is_enabled () == 0)
575  {
576  rv = VNET_API_ERROR_FEATURE_DISABLED;
577  goto done;
578  }
579 
580  app = application_lookup (mp->client_index);
581  if (app)
582  {
583  a->app_index = app->app_index;
584  a->api_client_index = mp->client_index;
585  rv = vnet_application_detach (a);
586  }
587 
588 done:
589  REPLY_MACRO (VL_API_APPLICATION_DETACH_REPLY);
590 }
591 
592 static void
594 {
595  vl_api_bind_uri_reply_t *rmp;
596  vnet_listen_args_t _a, *a = &_a;
597  application_t *app = 0;
598  app_worker_t *app_wrk;
599  int rv;
600 
601  if (session_main_is_enabled () == 0)
602  {
603  rv = VNET_API_ERROR_FEATURE_DISABLED;
604  goto done;
605  }
606 
607  app = application_lookup (mp->client_index);
608  if (app)
609  {
610  clib_memset (a, 0, sizeof (*a));
611  a->uri = (char *) mp->uri;
612  a->app_index = app->app_index;
613  rv = vnet_bind_uri (a);
614  }
615  else
616  {
617  rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
618  }
619 
620 done:
621 
622  REPLY_MACRO (VL_API_BIND_URI_REPLY);
623 
624  if (app)
625  {
626  app_wrk = application_get_worker (app, 0);
627  mq_send_session_bound_cb (app_wrk->wrk_index, mp->context, a->handle,
628  rv);
629  }
630 }
631 
632 static void
634 {
635  vl_api_unbind_uri_reply_t *rmp;
636  application_t *app;
637  vnet_unlisten_args_t _a, *a = &_a;
638  int rv;
639 
640  if (session_main_is_enabled () == 0)
641  {
642  rv = VNET_API_ERROR_FEATURE_DISABLED;
643  goto done;
644  }
645 
646  app = application_lookup (mp->client_index);
647  if (app)
648  {
649  a->uri = (char *) mp->uri;
650  a->app_index = app->app_index;
651  a->wrk_map_index = 0;
652  rv = vnet_unbind_uri (a);
653  }
654  else
655  {
656  rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
657  }
658 
659 done:
660  REPLY_MACRO (VL_API_UNBIND_URI_REPLY);
661 }
662 
663 static void
665 {
666  vl_api_connect_uri_reply_t *rmp;
667  vnet_connect_args_t _a, *a = &_a;
668  application_t *app;
669  int rv = 0;
670 
671  if (session_main_is_enabled () == 0)
672  {
673  rv = VNET_API_ERROR_FEATURE_DISABLED;
674  goto done;
675  }
676 
677  app = application_lookup (mp->client_index);
678  if (app)
679  {
680  clib_memset (a, 0, sizeof (*a));
681  a->uri = (char *) mp->uri;
682  a->api_context = mp->context;
683  a->app_index = app->app_index;
684  if ((rv = vnet_connect_uri (a)))
685  clib_warning ("connect_uri returned: %d", rv);
686  }
687  else
688  {
689  rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
690  }
691 
692  /*
693  * Don't reply to stream (tcp) connects. The reply will come once
694  * the connection is established. In case of the redirects, the reply
695  * will come from the server app.
696  */
697  if (rv == 0)
698  return;
699 
700 done:
701  REPLY_MACRO (VL_API_CONNECT_URI_REPLY);
702 }
703 
704 static void
706 {
708  vnet_disconnect_args_t _a, *a = &_a;
709  application_t *app;
710  int rv = 0;
711 
712  if (session_main_is_enabled () == 0)
713  {
714  rv = VNET_API_ERROR_FEATURE_DISABLED;
715  goto done;
716  }
717 
718  app = application_lookup (mp->client_index);
719  if (app)
720  {
721  a->handle = mp->handle;
722  a->app_index = app->app_index;
723  rv = vnet_disconnect_session (a);
724  }
725  else
726  {
727  rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
728  }
729 
730 done:
731  REPLY_MACRO2 (VL_API_DISCONNECT_SESSION_REPLY, rmp->handle = mp->handle);
732 }
733 
734 static void
736  mp)
737 {
738  vnet_disconnect_args_t _a, *a = &_a;
739  application_t *app;
740 
741  /* Client objected to disconnecting the session, log and continue */
742  if (mp->retval)
743  {
744  clib_warning ("client retval %d", mp->retval);
745  return;
746  }
747 
748  /* Disconnect has been confirmed. Confirm close to transport */
749  app = application_lookup (mp->context);
750  if (app)
751  {
752  a->handle = mp->handle;
753  a->app_index = app->app_index;
755  }
756 }
757 
758 static void
759 vl_api_map_another_segment_reply_t_handler (vl_api_map_another_segment_reply_t
760  * mp)
761 {
762  clib_warning ("not implemented");
763 }
764 
765 static void
767 {
768  vnet_listen_args_t _a, *a = &_a;
769  vl_api_bind_sock_reply_t *rmp;
770  application_t *app = 0;
771  app_worker_t *app_wrk;
772  ip46_address_t *ip46;
773  int rv = 0;
774 
775  if (session_main_is_enabled () == 0)
776  {
777  rv = VNET_API_ERROR_FEATURE_DISABLED;
778  goto done;
779  }
780 
781  app = application_lookup (mp->client_index);
782  if (!app)
783  {
784  rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
785  goto done;
786  }
787 
788  ip46 = (ip46_address_t *) mp->ip;
789  clib_memset (a, 0, sizeof (*a));
790  a->sep.is_ip4 = mp->is_ip4;
791  a->sep.ip = *ip46;
792  a->sep.port = mp->port;
793  a->sep.fib_index = mp->vrf;
794  a->sep.sw_if_index = ENDPOINT_INVALID_INDEX;
795  a->sep.transport_proto = mp->proto;
796  a->app_index = app->app_index;
797  a->wrk_map_index = mp->wrk_index;
798 
799  if ((rv = vnet_listen (a)))
800  clib_warning ("listen returned: %d", rv);
801 
802 done:
803  /* Actual reply sent only over mq */
804  REPLY_MACRO (VL_API_BIND_SOCK_REPLY);
805 
806  if (app)
807  {
808  app_wrk = application_get_worker (app, mp->wrk_index);
809  mq_send_session_bound_cb (app_wrk->wrk_index, mp->context, a->handle,
810  rv);
811  }
812 }
813 
814 static void
816 {
817  vl_api_unbind_sock_reply_t *rmp;
818  vnet_unlisten_args_t _a, *a = &_a;
819  app_worker_t *app_wrk;
820  application_t *app = 0;
821  int rv = 0;
822 
823  if (session_main_is_enabled () == 0)
824  {
825  rv = VNET_API_ERROR_FEATURE_DISABLED;
826  goto done;
827  }
828 
829  app = application_lookup (mp->client_index);
830  if (app)
831  {
832  a->app_index = app->app_index;
833  a->handle = mp->handle;
834  a->wrk_map_index = mp->wrk_index;
835  if ((rv = vnet_unlisten (a)))
836  clib_warning ("unlisten returned: %d", rv);
837  }
838 
839 done:
840  REPLY_MACRO (VL_API_UNBIND_SOCK_REPLY);
841 
842  /*
843  * Send reply over msg queue
844  */
845  svm_msg_q_msg_t _msg, *msg = &_msg;
847  svm_msg_q_t *app_mq;
848  session_event_t *evt;
849 
850  if (!app)
851  return;
852 
853  app_wrk = application_get_worker (app, a->wrk_map_index);
854  if (!app_wrk)
855  return;
856 
857  app_mq = app_wrk->event_queue;
858  if (mq_try_lock_and_alloc_msg (app_mq, msg))
859  return;
860 
861  evt = svm_msg_q_msg_data (app_mq, msg);
862  clib_memset (evt, 0, sizeof (*evt));
863  evt->event_type = SESSION_CTRL_EVT_UNLISTEN_REPLY;
864  ump = (session_unlisten_reply_msg_t *) evt->data;
865  ump->context = mp->context;
866  ump->handle = mp->handle;
867  ump->retval = rv;
868  svm_msg_q_add_and_unlock (app_mq, msg);
869 }
870 
871 static void
873 {
874  vl_api_connect_sock_reply_t *rmp;
875  vnet_connect_args_t _a, *a = &_a;
876  application_t *app = 0;
877  int rv = 0;
878 
879  if (session_main_is_enabled () == 0)
880  {
881  rv = VNET_API_ERROR_FEATURE_DISABLED;
882  goto done;
883  }
884 
885  app = application_lookup (mp->client_index);
886  if (app)
887  {
888  svm_queue_t *client_q;
889  ip46_address_t *ip46 = (ip46_address_t *) mp->ip;
890 
891  clib_memset (a, 0, sizeof (*a));
893  mp->client_queue_address = pointer_to_uword (client_q);
894  a->sep.is_ip4 = mp->is_ip4;
895  a->sep.ip = *ip46;
896  a->sep.port = mp->port;
897  a->sep.transport_proto = mp->proto;
898  a->sep.peer.fib_index = mp->vrf;
899  a->sep.peer.sw_if_index = ENDPOINT_INVALID_INDEX;
900  a->sep_ext.parent_handle = mp->parent_handle;
901  if (mp->hostname_len)
902  {
903  vec_validate (a->sep_ext.hostname, mp->hostname_len - 1);
904  clib_memcpy_fast (a->sep_ext.hostname, mp->hostname,
905  mp->hostname_len);
906  }
907  a->api_context = mp->context;
908  a->app_index = app->app_index;
909  a->wrk_map_index = mp->wrk_index;
910  if ((rv = vnet_connect (a)))
911  clib_warning ("connect returned: %U", format_vnet_api_errno, rv);
912  vec_free (a->sep_ext.hostname);
913  }
914  else
915  {
916  rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
917  }
918 
919  if (rv == 0)
920  return;
921 
922  /* Got some error, relay it */
923 
924 done:
925  REPLY_MACRO (VL_API_CONNECT_SOCK_REPLY);
926 
927  if (app)
928  {
929  app_worker_t *app_wrk = application_get_worker (app, mp->wrk_index);
930  mq_send_session_connected_cb (app_wrk->wrk_index, mp->context, 0, 1);
931  }
932 }
933 
934 static void
936 {
937  int rv = 0, fds[SESSION_N_FD_TYPE], n_fds = 0;
940  application_t *app;
941  u8 fd_flags = 0;
942 
943  if (!session_main_is_enabled ())
944  {
945  rv = VNET_API_ERROR_FEATURE_DISABLED;
946  goto done;
947  }
948 
950  if (!reg)
951  return;
952 
953  app = application_get_if_valid (clib_net_to_host_u32 (mp->app_index));
954  if (!app)
955  {
956  rv = VNET_API_ERROR_INVALID_VALUE;
957  goto done;
958  }
959 
961  .app_index = app->app_index,
962  .wrk_map_index = clib_net_to_host_u32 (mp->wrk_index),
963  .api_client_index = mp->client_index,
964  .is_add = mp->is_add
965  };
966  rv = vnet_app_worker_add_del (&args);
967  if (rv)
968  {
969  clib_warning ("app worker add/del returned: %d", rv);
970  goto done;
971  }
972 
973  if (!mp->is_add)
974  goto done;
975 
976  /* Send fifo segment fd if needed */
977  if (ssvm_type (args.segment) == SSVM_SEGMENT_MEMFD)
978  {
979  fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
980  fds[n_fds] = args.segment->fd;
981  n_fds += 1;
982  }
983  if (application_segment_manager_properties (app)->use_mq_eventfd)
984  {
985  fd_flags |= SESSION_FD_F_MQ_EVENTFD;
986  fds[n_fds] = svm_msg_q_get_producer_eventfd (args.evt_q);
987  n_fds += 1;
988  }
989 
990  /* *INDENT-OFF* */
991 done:
992  REPLY_MACRO2 (VL_API_APP_WORKER_ADD_DEL_REPLY, ({
993  rmp->is_add = mp->is_add;
994  rmp->wrk_index = clib_host_to_net_u32 (args.wrk_map_index);
995  rmp->segment_handle = clib_host_to_net_u64 (args.segment_handle);
996  if (!rv && mp->is_add)
997  {
998  if (vec_len (args.segment->name))
999  {
1000  memcpy (rmp->segment_name, args.segment->name,
1001  vec_len (args.segment->name));
1002  rmp->segment_name_length = vec_len (args.segment->name);
1003  }
1004  rmp->app_event_queue_address = pointer_to_uword (args.evt_q);
1005  rmp->n_fds = n_fds;
1006  rmp->fd_flags = fd_flags;
1007  }
1008  }));
1009  /* *INDENT-ON* */
1010 
1011  if (n_fds)
1012  session_send_fds (reg, fds, n_fds);
1013 }
1014 
1015 static void
1017 {
1019  u32 appns_index = 0;
1020  u8 *ns_id = 0;
1021  int rv = 0;
1022  if (!session_main_is_enabled ())
1023  {
1024  rv = VNET_API_ERROR_FEATURE_DISABLED;
1025  goto done;
1026  }
1027 
1028  if (mp->namespace_id_len > ARRAY_LEN (mp->namespace_id))
1029  {
1030  rv = VNET_API_ERROR_INVALID_VALUE;
1031  goto done;
1032  }
1033 
1034  vec_validate (ns_id, mp->namespace_id_len - 1);
1037  .ns_id = ns_id,
1038  .secret = clib_net_to_host_u64 (mp->secret),
1039  .sw_if_index = clib_net_to_host_u32 (mp->sw_if_index),
1040  .ip4_fib_id = clib_net_to_host_u32 (mp->ip4_fib_id),
1041  .ip6_fib_id = clib_net_to_host_u32 (mp->ip6_fib_id),
1042  .is_add = 1
1043  };
1044  rv = vnet_app_namespace_add_del (&args);
1045  if (!rv)
1046  {
1047  appns_index = app_namespace_index_from_id (ns_id);
1048  if (appns_index == APP_NAMESPACE_INVALID_INDEX)
1049  {
1050  clib_warning ("app ns lookup failed");
1051  rv = VNET_API_ERROR_UNSPECIFIED;
1052  }
1053  }
1054  vec_free (ns_id);
1055 
1056  /* *INDENT-OFF* */
1057 done:
1058  REPLY_MACRO2 (VL_API_APP_NAMESPACE_ADD_DEL_REPLY, ({
1059  if (!rv)
1060  rmp->appns_index = clib_host_to_net_u32 (appns_index);
1061  }));
1062  /* *INDENT-ON* */
1063 }
1064 
1065 static void
1067 {
1068  vl_api_session_rule_add_del_reply_t *rmp;
1070  session_rule_table_add_del_args_t *table_args = &args.table_args;
1071  u8 fib_proto;
1072  int rv = 0;
1073 
1074  clib_memset (&args, 0, sizeof (args));
1075  fib_proto = mp->is_ip4 ? FIB_PROTOCOL_IP4 : FIB_PROTOCOL_IP6;
1076 
1077  table_args->lcl.fp_len = mp->lcl_plen;
1078  table_args->lcl.fp_proto = fib_proto;
1079  table_args->rmt.fp_len = mp->rmt_plen;
1080  table_args->rmt.fp_proto = fib_proto;
1081  table_args->lcl_port = mp->lcl_port;
1082  table_args->rmt_port = mp->rmt_port;
1083  table_args->action_index = clib_net_to_host_u32 (mp->action_index);
1084  table_args->is_add = mp->is_add;
1085  mp->tag[sizeof (mp->tag) - 1] = 0;
1086  table_args->tag = format (0, "%s", mp->tag);
1087  args.appns_index = clib_net_to_host_u32 (mp->appns_index);
1088  args.scope = mp->scope;
1089  args.transport_proto = mp->transport_proto;
1090 
1091  clib_memset (&table_args->lcl.fp_addr, 0, sizeof (table_args->lcl.fp_addr));
1092  clib_memset (&table_args->rmt.fp_addr, 0, sizeof (table_args->rmt.fp_addr));
1093  ip_set (&table_args->lcl.fp_addr, mp->lcl_ip, mp->is_ip4);
1094  ip_set (&table_args->rmt.fp_addr, mp->rmt_ip, mp->is_ip4);
1095  rv = vnet_session_rule_add_del (&args);
1096  if (rv)
1097  clib_warning ("rule add del returned: %d", rv);
1098  vec_free (table_args->tag);
1099  REPLY_MACRO (VL_API_SESSION_RULE_ADD_DEL_REPLY);
1100 }
1101 
1102 static void
1103 send_session_rule_details4 (mma_rule_16_t * rule, u8 is_local,
1104  u8 transport_proto, u32 appns_index, u8 * tag,
1106 {
1108  session_mask_or_match_4_t *match =
1109  (session_mask_or_match_4_t *) & rule->match;
1110  session_mask_or_match_4_t *mask =
1111  (session_mask_or_match_4_t *) & rule->mask;
1112 
1113  rmp = vl_msg_api_alloc (sizeof (*rmp));
1114  clib_memset (rmp, 0, sizeof (*rmp));
1115  rmp->_vl_msg_id = ntohs (VL_API_SESSION_RULES_DETAILS);
1116  rmp->context = context;
1117 
1118  rmp->is_ip4 = 1;
1119  clib_memcpy_fast (rmp->lcl_ip, &match->lcl_ip, sizeof (match->lcl_ip));
1120  clib_memcpy_fast (rmp->rmt_ip, &match->rmt_ip, sizeof (match->rmt_ip));
1121  rmp->lcl_plen = ip4_mask_to_preflen (&mask->lcl_ip);
1122  rmp->rmt_plen = ip4_mask_to_preflen (&mask->rmt_ip);
1123  rmp->lcl_port = match->lcl_port;
1124  rmp->rmt_port = match->rmt_port;
1125  rmp->action_index = clib_host_to_net_u32 (rule->action_index);
1126  rmp->scope =
1128  rmp->transport_proto = transport_proto;
1129  rmp->appns_index = clib_host_to_net_u32 (appns_index);
1130  if (tag)
1131  {
1132  clib_memcpy_fast (rmp->tag, tag, vec_len (tag));
1133  rmp->tag[vec_len (tag)] = 0;
1134  }
1135 
1136  vl_api_send_msg (reg, (u8 *) rmp);
1137 }
1138 
1139 static void
1140 send_session_rule_details6 (mma_rule_40_t * rule, u8 is_local,
1141  u8 transport_proto, u32 appns_index, u8 * tag,
1143 {
1145  session_mask_or_match_6_t *match =
1146  (session_mask_or_match_6_t *) & rule->match;
1147  session_mask_or_match_6_t *mask =
1148  (session_mask_or_match_6_t *) & rule->mask;
1149 
1150  rmp = vl_msg_api_alloc (sizeof (*rmp));
1151  clib_memset (rmp, 0, sizeof (*rmp));
1152  rmp->_vl_msg_id = ntohs (VL_API_SESSION_RULES_DETAILS);
1153  rmp->context = context;
1154 
1155  rmp->is_ip4 = 0;
1156  clib_memcpy_fast (rmp->lcl_ip, &match->lcl_ip, sizeof (match->lcl_ip));
1157  clib_memcpy_fast (rmp->rmt_ip, &match->rmt_ip, sizeof (match->rmt_ip));
1158  rmp->lcl_plen = ip6_mask_to_preflen (&mask->lcl_ip);
1159  rmp->rmt_plen = ip6_mask_to_preflen (&mask->rmt_ip);
1160  rmp->lcl_port = match->lcl_port;
1161  rmp->rmt_port = match->rmt_port;
1162  rmp->action_index = clib_host_to_net_u32 (rule->action_index);
1163  rmp->scope =
1165  rmp->transport_proto = transport_proto;
1166  rmp->appns_index = clib_host_to_net_u32 (appns_index);
1167  if (tag)
1168  {
1169  clib_memcpy_fast (rmp->tag, tag, vec_len (tag));
1170  rmp->tag[vec_len (tag)] = 0;
1171  }
1172 
1173  vl_api_send_msg (reg, (u8 *) rmp);
1174 }
1175 
1176 static void
1178  u8 tp, u8 is_local, u32 appns_index,
1180 {
1181  mma_rule_16_t *rule16;
1182  mma_rule_40_t *rule40;
1183  mma_rules_table_16_t *srt16;
1184  mma_rules_table_40_t *srt40;
1185  u32 ri;
1186 
1187  if (is_local || fib_proto == FIB_PROTOCOL_IP4)
1188  {
1189  u8 *tag = 0;
1190  /* *INDENT-OFF* */
1191  srt16 = &srt->session_rules_tables_16;
1192  pool_foreach (rule16, srt16->rules, ({
1193  ri = mma_rules_table_rule_index_16 (srt16, rule16);
1194  tag = session_rules_table_rule_tag (srt, ri, 1);
1195  send_session_rule_details4 (rule16, is_local, tp, appns_index, tag,
1196  reg, context);
1197  }));
1198  /* *INDENT-ON* */
1199  }
1200  if (is_local || fib_proto == FIB_PROTOCOL_IP6)
1201  {
1202  u8 *tag = 0;
1203  /* *INDENT-OFF* */
1204  srt40 = &srt->session_rules_tables_40;
1205  pool_foreach (rule40, srt40->rules, ({
1206  ri = mma_rules_table_rule_index_40 (srt40, rule40);
1207  tag = session_rules_table_rule_tag (srt, ri, 1);
1208  send_session_rule_details6 (rule40, is_local, tp, appns_index, tag,
1209  reg, context);
1210  }));
1211  /* *INDENT-ON* */
1212  }
1213 }
1214 
1215 static void
1217 {
1218  vl_api_registration_t *reg;
1219  session_table_t *st;
1220  u8 tp;
1221 
1223  if (!reg)
1224  return;
1225 
1226  /* *INDENT-OFF* */
1227  session_table_foreach (st, ({
1228  for (tp = 0; tp < TRANSPORT_N_PROTO; tp++)
1229  {
1230  send_session_rules_table_details (&st->session_rules[tp],
1231  st->active_fib_proto, tp,
1232  st->is_local, st->appns_index, reg,
1233  mp->context);
1234  }
1235  }));
1236  /* *INDENT-ON* */
1237 }
1238 
1239 static void
1241  mp)
1242 {
1244  vnet_app_add_tls_cert_args_t _a, *a = &_a;
1245  clib_error_t *error;
1246  application_t *app;
1247  u32 cert_len;
1248  int rv = 0;
1249  if (!session_main_is_enabled ())
1250  {
1251  rv = VNET_API_ERROR_FEATURE_DISABLED;
1252  goto done;
1253  }
1254  if (!(app = application_lookup (mp->client_index)))
1255  {
1256  rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
1257  goto done;
1258  }
1259  clib_memset (a, 0, sizeof (*a));
1260  a->app_index = app->app_index;
1261  cert_len = clib_net_to_host_u16 (mp->cert_len);
1262  if (cert_len > 10000)
1263  {
1264  rv = VNET_API_ERROR_INVALID_VALUE;
1265  goto done;
1266  }
1267  vec_validate (a->cert, cert_len);
1268  clib_memcpy_fast (a->cert, mp->cert, cert_len);
1269  if ((error = vnet_app_add_tls_cert (a)))
1270  {
1271  rv = clib_error_get_code (error);
1272  clib_error_report (error);
1273  }
1274  vec_free (a->cert);
1275 done:
1276  REPLY_MACRO (VL_API_APPLICATION_TLS_CERT_ADD_REPLY);
1277 }
1278 
1279 static void
1281  mp)
1282 {
1284  vnet_app_add_tls_key_args_t _a, *a = &_a;
1285  clib_error_t *error;
1286  application_t *app;
1287  u32 key_len;
1288  int rv = 0;
1289  if (!session_main_is_enabled ())
1290  {
1291  rv = VNET_API_ERROR_FEATURE_DISABLED;
1292  goto done;
1293  }
1294  if (!(app = application_lookup (mp->client_index)))
1295  {
1296  rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
1297  goto done;
1298  }
1299  clib_memset (a, 0, sizeof (*a));
1300  a->app_index = app->app_index;
1301  key_len = clib_net_to_host_u16 (mp->key_len);
1302  if (key_len > 10000)
1303  {
1304  rv = VNET_API_ERROR_INVALID_VALUE;
1305  goto done;
1306  }
1307  vec_validate (a->key, key_len);
1308  clib_memcpy_fast (a->key, mp->key, key_len);
1309  if ((error = vnet_app_add_tls_key (a)))
1310  {
1311  rv = clib_error_get_code (error);
1312  clib_error_report (error);
1313  }
1314  vec_free (a->key);
1315 done:
1316  REPLY_MACRO (VL_API_APPLICATION_TLS_KEY_ADD_REPLY);
1317 }
1318 
1319 static clib_error_t *
1321 {
1322  application_t *app = application_lookup (client_index);
1323  vnet_app_detach_args_t _a, *a = &_a;
1324  if (app)
1325  {
1326  a->app_index = app->app_index;
1327  a->api_client_index = client_index;
1329  }
1330  return 0;
1331 }
1332 
1334 
1335 #define vl_msg_name_crc_list
1336 #include <vnet/vnet_all_api_h.h>
1337 #undef vl_msg_name_crc_list
1338 
1339 static void
1341 {
1342 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1343  foreach_vl_msg_name_crc_session;
1344 #undef _
1345 }
1346 
1347 /*
1348  * session_api_hookup
1349  * Add uri's API message handlers to the table.
1350  * vlib has already mapped shared memory and
1351  * added the client registration handlers.
1352  * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
1353  */
1354 static clib_error_t *
1356 {
1357  api_main_t *am = &api_main;
1358 
1359 #define _(N,n) \
1360  vl_msg_api_set_handlers(VL_API_##N, #n, \
1361  vl_api_##n##_t_handler, \
1362  vl_noop_handler, \
1363  vl_api_##n##_t_endian, \
1364  vl_api_##n##_t_print, \
1365  sizeof(vl_api_##n##_t), 1);
1367 #undef _
1368 
1369  /*
1370  * Messages which bounce off the data-plane to
1371  * an API client. Simply tells the message handling infra not
1372  * to free the message.
1373  *
1374  * Bounced message handlers MUST NOT block the data plane
1375  */
1376  am->message_bounce[VL_API_CONNECT_URI] = 1;
1377  am->message_bounce[VL_API_CONNECT_SOCK] = 1;
1378 
1379  /*
1380  * Set up the (msg_name, crc, message-id) table
1381  */
1383 
1384  return 0;
1385 }
1386 
1388 
1389 /*
1390  * fd.io coding-style-patch-verification: ON
1391  *
1392  * Local Variables:
1393  * eval: (c-set-style "gnu")
1394  * End:
1395  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
static void vl_api_disconnect_session_reply_t_handler(vl_api_disconnect_session_reply_t *mp)
Definition: session_api.c:735
u64 ssvm_size
Definition: ssvm.h:85
struct _vnet_app_worker_add_del_args vnet_app_worker_add_del_args_t
#define ENDPOINT_INVALID_INDEX
#define APP_NAMESPACE_INVALID_INDEX
static clib_error_t * session_api_hookup(vlib_main_t *vm)
Definition: session_api.c:1355
void * svm_msg_q_msg_data(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Get data for message in queue.
session_type_t session_type
Type built from transport and network protocol types.
static int send_del_segment_callback(u32 api_client_index, u64 segment_handle)
Definition: session_api.c:131
static void mq_notify_close_subscribers(u32 app_index, session_handle_t sh, svm_fifo_t *f, session_evt_type_t evt_type)
Definition: session_api.c:255
transport_endpoint_t rmt
a
Definition: bitmap.h:538
VL_MSG_API_REAPER_FUNCTION(application_reaper_cb)
svm_fifo_t * tx_fifo
struct _session_rules_table_t session_rules_table_t
struct _vnet_connect_args vnet_connect_args_t
Application add TLS key.
Definition: session.api:83
struct _vnet_unlisten_args_t vnet_unlisten_args_t
static void vl_api_app_namespace_add_del_t_handler(vl_api_app_namespace_add_del_t *mp)
Definition: session_api.c:1016
int vnet_app_namespace_add_del(vnet_app_namespace_add_del_args_t *a)
unsigned long u64
Definition: types.h:89
static svm_msg_q_t * session_main_get_vpp_event_queue(u32 thread_index)
Definition: session.h:554
void ip_set(ip46_address_t *dst, void *src, u8 is_ip4)
Definition: ip.c:90
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
static void mq_send_session_close_evt(app_worker_t *app_wrk, session_handle_t sh, session_evt_type_t evt_type)
Definition: session_api.c:234
#define REPLY_MACRO2(t, body)
transport_connection_t * session_get_transport(session_t *s)
Definition: session.c:1398
add/del session rule
Definition: session.api:404
svm_fifo_t * rx_fifo
Pointers to rx/tx buffers.
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:34
u8 * message_bounce
Don&#39;t automatically free message buffer vetor.
Definition: api_common.h:223
fifo_segment_t * segment_manager_get_segment_w_handle(u64 segment_handle)
Session rules details.
Definition: session.api:448
static session_t * listen_session_get_from_handle(session_handle_t handle)
Definition: session.h:501
static void vl_api_map_another_segment_reply_t_handler(vl_api_map_another_segment_reply_t *mp)
Definition: session_api.c:759
Bind to an ip:port pair for a given transport protocol.
Definition: session.api:213
static int svm_msg_q_get_producer_eventfd(svm_msg_q_t *mq)
session_evt_type_t
static transport_proto_t session_get_transport_proto(session_t *s)
struct _vnet_app_namespace_add_del_args vnet_app_namespace_add_del_args_t
static int mq_send_session_bound_cb(u32 app_wrk_index, u32 api_context, session_handle_t handle, int rv)
Definition: session_api.c:382
application_t * application_lookup(u32 api_client_index)
Definition: application.c:386
int i
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
Request for map server summary status.
Definition: one.api:883
static void vl_api_unbind_sock_t_handler(vl_api_unbind_sock_t *mp)
Definition: session_api.c:815
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
int vnet_unlisten(vnet_unlisten_args_t *a)
Definition: application.c:1035
#define foreach_session_api_msg
Definition: session_api.c:43
struct _vnet_application_add_tls_cert_args_t vnet_app_add_tls_cert_args_t
void * vl_msg_api_alloc(int nbytes)
clib_error_t * vnet_app_add_tls_cert(vnet_app_add_tls_cert_args_t *a)
Definition: application.c:1300
unsigned char u8
Definition: types.h:56
app_worker_t * application_get_worker(application_t *app, u32 wrk_map_index)
Definition: application.c:644
application_t * application_get_if_valid(u32 app_index)
Definition: application.c:426
struct _vnet_bind_args_t vnet_listen_args_t
segment_manager_props_t * application_segment_manager_properties(application_t *app)
Definition: application.c:1287
static session_handle_t session_handle(session_t *s)
struct _svm_fifo svm_fifo_t
void session_get_endpoint(session_t *s, transport_endpoint_t *tep, u8 is_lcl)
Definition: session.c:1409
int svm_msg_q_lock_and_alloc_msg_w_ring(svm_msg_q_t *mq, u32 ring_index, u8 noblock, svm_msg_q_msg_t *msg)
Lock message queue and allocate message buffer on ring.
Reply for app worker add/del.
Definition: session.api:322
int application_is_proxy(application_t *app)
Definition: application.c:1117
static void vl_api_connect_uri_t_handler(vl_api_connect_uri_t *mp)
Definition: session_api.c:664
static void mq_send_session_reset_cb(session_t *s)
Definition: session_api.c:289
static void vl_api_session_enable_disable_t_handler(vl_api_session_enable_disable_t *mp)
Definition: session_api.c:459
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
struct _vnet_disconnect_args_t vnet_disconnect_args_t
u32 session_index
global listening session index
Definition: application.h:80
vl_api_registration_t * vl_mem_api_client_index_to_registration(u32 handle)
Definition: memory_api.c:793
add/del application namespace
Definition: session.api:362
static void vl_api_application_tls_cert_add_t_handler(vl_api_application_tls_cert_add_t *mp)
Definition: session_api.c:1240
unsigned int u32
Definition: types.h:88
static void send_session_rule_details4(mma_rule_16_t *rule, u8 is_local, u8 transport_proto, u32 appns_index, u8 *tag, vl_api_registration_t *reg, u32 context)
Definition: session_api.c:1103
u32 app_namespace_index_from_id(const u8 *ns_id)
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
struct _vnet_app_attach_args_t vnet_app_attach_args_t
static void vl_api_app_worker_add_del_t_handler(vl_api_app_worker_add_del_t *mp)
Definition: session_api.c:935
vpp->client unmap shared memory segment
Definition: session.api:125
static void vl_api_session_rules_dump_t_handler(vl_api_one_map_server_dump_t *mp)
Definition: session_api.c:1216
clib_error_t * vnet_app_add_tls_key(vnet_app_add_tls_key_args_t *a)
Definition: application.c:1312
session_t * app_listener_get_local_session(app_listener_t *al)
Definition: application.c:281
#define VL_API_INVALID_FI
Definition: api_common.h:77
svm_queue_t * vl_input_queue
shared memory only: pointer to client input queue
Definition: api_common.h:61
session_t * app_listener_get_session(app_listener_t *al)
Definition: application.c:272
struct _session_rule_add_del_args session_rule_add_del_args_t
client->vpp, attach application to session layer
Definition: session.api:27
u8 hostname[hostname_len]
Definition: session.api:268
static void vl_api_disconnect_session_t_handler(vl_api_disconnect_session_t *mp)
Definition: session_api.c:705
static int session_send_fds(vl_api_registration_t *reg, int fds[], int n_fds)
Definition: session_api.c:64
int vnet_session_rule_add_del(session_rule_add_del_args_t *args)
#define REPLY_MACRO(t)
static clib_error_t * application_reaper_cb(u32 client_index)
Definition: session_api.c:1320
Unbind a given URI.
Definition: session.api:153
u32 wrk_index
Worker index in global worker pool.
Definition: application.h:37
#define SESSION_INVALID_INDEX
Definition: session_types.h:22
static u8 * format_vnet_api_errno(u8 *s, va_list *args)
Definition: api_errno.h:164
u64 session_segment_handle(session_t *s)
Definition: session.c:1340
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: session.c:1543
session_handle_t app_listen_session_handle(session_t *ls)
Get app listener handle for listening session.
Definition: application.c:78
static u64 listen_session_get_handle(session_t *s)
Definition: session.h:493
u32 ip6_mask_to_preflen(ip6_address_t *mask)
Definition: ip.c:268
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:203
int vnet_application_attach(vnet_app_attach_args_t *a)
Attach application to vpp.
Definition: application.c:809
static int mq_try_lock_and_alloc_msg(svm_msg_q_t *app_mq, svm_msg_q_msg_t *msg)
Definition: session_api.c:153
An API client registration, only in vpp/vlib.
Definition: api_common.h:46
ssvm_private_t ssvm
ssvm segment data
Definition: fifo_segment.h:52
session_handle_t listener_handle
Parent listener session index if the result of an accept.
vlib_main_t * vm
Definition: buffer.c:312
session_t * app_worker_first_listener(app_worker_t *app, u8 fib_proto, u8 transport_proto)
svm_queue_t * vl_api_client_index_to_input_queue(u32 index)
Definition: memory_api.c:822
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
#define clib_warning(format, args...)
Definition: error.h:59
struct _stream_session_cb_vft session_cb_vft_t
struct _transport_connection transport_connection_t
static void mq_send_session_disconnected_cb(session_t *s)
Definition: session_api.c:275
u32 ip4_mask_to_preflen(ip4_address_t *mask)
Definition: ip.c:206
static void send_session_rules_table_details(session_rules_table_t *srt, u8 fib_proto, u8 tp, u8 is_local, u32 appns_index, vl_api_registration_t *reg, u32 context)
Definition: session_api.c:1177
#define ARRAY_LEN(x)
Definition: clib.h:62
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:56
Application attach reply.
Definition: session.api:50
static clib_error_t * vl_api_send_fd_msg(vl_api_registration_t *reg, int fds[], int n_fds)
Definition: api.h:84
static u32 vl_api_registration_file_index(vl_api_registration_t *reg)
Definition: api.h:64
application_t * application_get(u32 app_index)
Definition: application.c:418
int vnet_unbind_uri(vnet_unlisten_args_t *a)
static void send_session_rule_details6(mma_rule_40_t *rule, u8 is_local, u8 transport_proto, u32 appns_index, u8 *tag, vl_api_registration_t *reg, u32 context)
Definition: session_api.c:1140
int fd
memfd segments
Definition: ssvm.h:93
app_listener_t * app_listener_get_w_handle(session_handle_t handle)
Get app listener for listener session handle.
Definition: application.c:88
void svm_msg_q_add_and_unlock(svm_msg_q_t *mq, svm_msg_q_msg_t *msg)
Producer enqueue one message to queue with mutex held.
enable/disable session layer
Definition: session.api:342
static void vl_api_connect_sock_t_handler(vl_api_connect_sock_t *mp)
Definition: session_api.c:872
session_t * ct_session_get_peer(session_t *s)
Reply for app namespace add/del.
Definition: session.api:378
client->vpp, attach application to session layer
Definition: session.api:95
int vnet_listen(vnet_listen_args_t *a)
Definition: application.c:947
static fib_protocol_t session_get_fib_proto(session_t *s)
static void mq_send_session_migrate_cb(session_t *s, session_handle_t new_sh)
Definition: session_api.c:442
int vnet_application_detach(vnet_app_detach_args_t *a)
Detach application from vpp.
Definition: application.c:869
struct _vnet_application_add_tls_key_args_t vnet_app_add_tls_key_args_t
static void vl_api_bind_sock_t_handler(vl_api_bind_sock_t *mp)
Definition: session_api.c:766
vpp->client, please map an additional shared memory segment
Definition: session.api:110
#define clib_error_report(e)
Definition: error.h:113
static int mq_send_session_accepted_cb(session_t *s)
Definition: session_api.c:172
struct _vnet_app_detach_args_t vnet_app_detach_args_t
static uword pointer_to_uword(const void *p)
Definition: types.h:131
int vnet_connect(vnet_connect_args_t *a)
Definition: application.c:999
Connect to a remote peer.
Definition: session.api:255
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u8 * name
Definition: ssvm.h:87
u8 thread_index
Index of the thread that allocated the session.
static void vl_api_application_attach_t_handler(vl_api_application_attach_t *mp)
Definition: session_api.c:470
static void setup_message_id_table(api_main_t *am)
Definition: session_api.c:1340
u32 app_index
App index in app pool.
Definition: application.h:89
static u8 session_type_is_ip4(session_type_t st)
bidirectional disconnect API
Definition: session.api:183
static session_cb_vft_t session_mq_cb_vft
Definition: session_api.c:448
add/del application worker
Definition: session.api:301
app_worker_t * app_worker_get(u32 wrk_index)
u64 session_handle_t
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Bind to a given URI.
Definition: session.api:139
#define STATIC_ASSERT(truth,...)
static void vl_api_application_tls_key_add_t_handler(vl_api_application_tls_key_add_t *mp)
Definition: session_api.c:1280
int vnet_bind_uri(vnet_listen_args_t *a)
ssvm_private_t * session_main_get_evt_q_segment(void)
Definition: session.c:1331
connectionless service
#define clib_error_get_code(err)
Definition: error.h:77
int vnet_disconnect_session(vnet_disconnect_args_t *a)
Definition: application.c:1064
VLIB_API_INIT_FUNCTION(session_api_hookup)
struct _session_lookup_table session_table_t
int vnet_app_worker_add_del(vnet_app_worker_add_del_args_t *a)
Definition: application.c:717
struct _svm_queue svm_queue_t
void * vl_mem_api_alloc_as_if_client_w_reg(vl_api_registration_t *reg, int nbytes)
static void vl_api_application_detach_t_handler(vl_api_application_detach_t *mp)
Definition: session_api.c:567
static u8 session_has_transport(session_t *s)
struct _session_rules_table_add_del_args session_rule_table_add_del_args_t
u32 app_index
Index of owning app.
Definition: application.h:43
static u8 svm_fifo_n_subscribers(svm_fifo_t *f)
Definition: svm_fifo.h:671
#define session_table_foreach(VAR, BODY)
Definition: session_table.h:75
Application add TLS certificate.
Definition: session.api:69
static int send_add_segment_callback(u32 api_client_index, u64 segment_handle)
Definition: session_api.c:82
transport_endpoint_t lcl
u32 app_wrk_index
Index of the app worker that owns the session.
Connect to a given URI.
Definition: session.api:169
static void vl_api_session_rule_add_del_t_handler(vl_api_session_rule_add_del_t *mp)
Definition: session_api.c:1066
bidirectional disconnect reply API
Definition: session.api:196
u32 api_client_index
API index for the worker.
Definition: application.h:63
int vnet_connect_uri(vnet_connect_args_t *a)
svm_msg_q_t * event_queue
Application listens for events on this svm queue.
Definition: application.h:46
u32 context
Definition: gre.api:45
static transport_service_type_t session_transport_service_type(session_t *s)
api_main_t api_main
Definition: api_shared.c:35
static int mq_send_session_connected_cb(u32 app_wrk_index, u32 api_context, session_t *s, u8 is_fail)
Definition: session_api.c:302
static void vl_api_bind_uri_t_handler(vl_api_bind_uri_t *mp)
Definition: session_api.c:593
non-blocking call - works with both condvar and eventfd signaling
Definition: queue.h:44
static u8 session_main_is_enabled()
Definition: session.h:560
static void vl_api_unbind_uri_t_handler(vl_api_unbind_uri_t *mp)
Definition: session_api.c:633
ssvm_segment_type_t ssvm_type(const ssvm_private_t *ssvm)
Definition: ssvm.c:438