FD.io VPP  v21.01.1
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/ip/ip_types_api.h>
26 
27 #include <vnet/vnet_msg_enum.h>
28 
29 #define vl_typedefs /* define message structures */
30 #include <vnet/vnet_all_api_h.h>
31 #undef vl_typedefs
32 
33 #define vl_endianfun /* define message structures */
34 #include <vnet/vnet_all_api_h.h>
35 #undef vl_endianfun
36 
37 /* instantiate all the print functions we know about */
38 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
39 #define vl_printfun
40 #include <vnet/vnet_all_api_h.h>
41 #undef vl_printfun
42 
44 
45 #define foreach_session_api_msg \
46 _(APP_ATTACH, app_attach) \
47 _(APPLICATION_DETACH, application_detach) \
48 _(SESSION_ENABLE_DISABLE, session_enable_disable) \
49 _(APP_NAMESPACE_ADD_DEL, app_namespace_add_del) \
50 _(SESSION_RULE_ADD_DEL, session_rule_add_del) \
51 _(SESSION_RULES_DUMP, session_rules_dump) \
52 _(APPLICATION_TLS_CERT_ADD, application_tls_cert_add) \
53 _(APPLICATION_TLS_KEY_ADD, application_tls_key_add) \
54 _(APP_ADD_CERT_KEY_PAIR, app_add_cert_key_pair) \
55 _(APP_DEL_CERT_KEY_PAIR, app_del_cert_key_pair) \
56 _(APP_WORKER_ADD_DEL, app_worker_add_del) \
57 
58 static transport_proto_t
59 api_session_transport_proto_decode (const vl_api_transport_proto_t * api_tp)
60 {
61  switch (*api_tp)
62  {
64  return TRANSPORT_PROTO_TCP;
66  return TRANSPORT_PROTO_UDP;
68  return TRANSPORT_PROTO_TLS;
70  return TRANSPORT_PROTO_QUIC;
71  default:
72  return TRANSPORT_PROTO_NONE;
73  }
74 }
75 
76 static vl_api_transport_proto_t
78 {
79  switch (tp)
80  {
81  case TRANSPORT_PROTO_TCP:
83  case TRANSPORT_PROTO_UDP:
85  case TRANSPORT_PROTO_TLS:
87  case TRANSPORT_PROTO_QUIC:
89  default:
91  }
92 }
93 
94 static int
95 session_send_fds (vl_api_registration_t * reg, int fds[], int n_fds)
96 {
99  return SESSION_E_BAPI_NO_FD;
100  error = vl_api_send_fd_msg (reg, fds, n_fds);
101  if (error)
102  {
103  clib_error_report (error);
104  return SESSION_E_BAPI_SEND_FD;
105  }
106  return 0;
107 }
108 
109 static int
111 {
112  int rv;
113  u8 try = 0;
114  while (try < 100)
115  {
118  SVM_Q_NOWAIT, msg);
119  if (!rv)
120  return 0;
121  try++;
122  usleep (1);
123  }
124  clib_warning ("failed to alloc msg");
125  return -1;
126 }
127 
128 static int
130 {
131  app_worker_t *app_wrk = app_worker_get (s->app_wrk_index);
132  svm_msg_q_msg_t _msg, *msg = &_msg;
133  svm_msg_q_t *vpp_queue, *app_mq;
136  session_event_t *evt;
137  application_t *app;
138 
139  app = application_get (app_wrk->app_index);
140  app_mq = app_wrk->event_queue;
141  if (mq_try_lock_and_alloc_msg (app_mq, msg))
142  return SESSION_E_MQ_MSG_ALLOC;
143 
144  evt = svm_msg_q_msg_data (app_mq, msg);
145  clib_memset (evt, 0, sizeof (*evt));
146  evt->event_type = SESSION_CTRL_EVT_ACCEPTED;
147  mp = (session_accepted_msg_t *) evt->data;
148  clib_memset (mp, 0, sizeof (*mp));
149  mp->context = app->app_index;
153  mp->flags = s->flags;
154 
155  if (session_has_transport (s))
156  {
159  if (application_is_proxy (app))
160  {
161  listener =
164  if (listener)
166  }
168  mp->vpp_event_queue_address = pointer_to_uword (vpp_queue);
169  mp->handle = session_handle (s);
170 
171  session_get_endpoint (s, &mp->rmt, 0 /* is_lcl */ );
172  }
173  else
174  {
175  ct_connection_t *ct;
176 
180  mp->rmt.is_ip4 = session_type_is_ip4 (listener->session_type);
181  mp->rmt.port = ct->c_rmt_port;
182  mp->handle = session_handle (s);
184  mp->vpp_event_queue_address = pointer_to_uword (vpp_queue);
185  }
186  svm_msg_q_add_and_unlock (app_mq, msg);
187 
188  return 0;
189 }
190 
191 static inline void
193  session_evt_type_t evt_type)
194 {
195  svm_msg_q_msg_t _msg, *msg = &_msg;
197  svm_msg_q_t *app_mq;
198  session_event_t *evt;
199 
200  app_mq = app_wrk->event_queue;
201  if (mq_try_lock_and_alloc_msg (app_mq, msg))
202  return;
203  evt = svm_msg_q_msg_data (app_mq, msg);
204  clib_memset (evt, 0, sizeof (*evt));
205  evt->event_type = evt_type;
206  mp = (session_disconnected_msg_t *) evt->data;
207  mp->handle = sh;
208  mp->context = app_wrk->api_client_index;
209  svm_msg_q_add_and_unlock (app_mq, msg);
210 }
211 
212 static inline void
214  svm_fifo_t * f, session_evt_type_t evt_type)
215 {
216  app_worker_t *app_wrk;
217  application_t *app;
218  int i;
219 
220  app = application_get (app_index);
221  if (!app)
222  return;
223 
224  for (i = 0; i < f->n_subscribers; i++)
225  {
226  if (!(app_wrk = application_get_worker (app, f->subscribers[i])))
227  continue;
229  }
230 }
231 
232 static void
234 {
235  app_worker_t *app_wrk = app_worker_get (s->app_wrk_index);
237 
240 
244 }
245 
246 static void
248 {
249  app_worker_t *app_wrk = app_worker_get (s->app_wrk_index);
251 
253 
257 }
258 
259 int
260 mq_send_session_connected_cb (u32 app_wrk_index, u32 api_context,
261  session_t * s, session_error_t err)
262 {
263  svm_msg_q_msg_t _msg, *msg = &_msg;
265  svm_msg_q_t *vpp_mq, *app_mq;
267  app_worker_t *app_wrk;
268  session_event_t *evt;
269 
270  app_wrk = app_worker_get (app_wrk_index);
271  app_mq = app_wrk->event_queue;
272  if (!app_mq)
273  {
274  clib_warning ("app %u with api index: %u not attached",
275  app_wrk->app_index, app_wrk->api_client_index);
276  return -1;
277  }
278 
279  if (mq_try_lock_and_alloc_msg (app_mq, msg))
280  return SESSION_E_MQ_MSG_ALLOC;
281 
282  evt = svm_msg_q_msg_data (app_mq, msg);
283  clib_memset (evt, 0, sizeof (*evt));
284  evt->event_type = SESSION_CTRL_EVT_CONNECTED;
285  mp = (session_connected_msg_t *) evt->data;
286  clib_memset (mp, 0, sizeof (*mp));
287  mp->context = api_context;
288 
289  if (err)
290  goto done;
291 
292  if (session_has_transport (s))
293  {
294  tc = session_get_transport (s);
295  if (!tc)
296  {
297  clib_warning ("failed to retrieve transport!");
298  err = SESSION_E_REFUSED;
299  goto done;
300  }
301 
303  mp->handle = session_handle (s);
305 
306  session_get_endpoint (s, &mp->lcl, 1 /* is_lcl */ );
307 
311  }
312  else
313  {
314  ct_connection_t *cct;
315  session_t *ss;
316 
318  mp->handle = session_handle (s);
319  mp->lcl.port = cct->c_lcl_port;
320  mp->lcl.is_ip4 = cct->c_is_ip4;
326  ss = ct_session_get_peer (s);
327  mp->ct_rx_fifo = pointer_to_uword (ss->tx_fifo);
328  mp->ct_tx_fifo = pointer_to_uword (ss->rx_fifo);
330  }
331 
332 done:
333  mp->retval = err;
334 
335  svm_msg_q_add_and_unlock (app_mq, msg);
336  return 0;
337 }
338 
339 int
340 mq_send_session_bound_cb (u32 app_wrk_index, u32 api_context,
341  session_handle_t handle, int rv)
342 {
343  svm_msg_q_msg_t _msg, *msg = &_msg;
344  svm_msg_q_t *app_mq, *vpp_evt_q;
347  app_worker_t *app_wrk;
348  session_event_t *evt;
349  app_listener_t *al;
350  session_t *ls = 0;
351  app_wrk = app_worker_get (app_wrk_index);
352  app_mq = app_wrk->event_queue;
353  if (!app_mq)
354  {
355  clib_warning ("app %u with api index: %u not attached",
356  app_wrk->app_index, app_wrk->api_client_index);
357  return -1;
358  }
359 
360  if (mq_try_lock_and_alloc_msg (app_mq, msg))
361  return SESSION_E_MQ_MSG_ALLOC;
362 
363  evt = svm_msg_q_msg_data (app_mq, msg);
364  clib_memset (evt, 0, sizeof (*evt));
365  evt->event_type = SESSION_CTRL_EVT_BOUND;
366  mp = (session_bound_msg_t *) evt->data;
367  mp->context = api_context;
368 
369  if (rv)
370  goto done;
371 
372  mp->handle = handle;
373  al = app_listener_get_w_handle (handle);
375  ls = app_listener_get_session (al);
376  else
378 
379  session_get_endpoint (ls, &tep, 1 /* is_lcl */ );
380  mp->lcl_port = tep.port;
381  mp->lcl_is_ip4 = tep.is_ip4;
382  clib_memcpy_fast (mp->lcl_ip, &tep.ip, sizeof (tep.ip));
383 
384  vpp_evt_q = session_main_get_vpp_event_queue (0);
385  mp->vpp_evt_q = pointer_to_uword (vpp_evt_q);
386 
388  {
389  mp->rx_fifo = pointer_to_uword (ls->rx_fifo);
390  mp->tx_fifo = pointer_to_uword (ls->tx_fifo);
391  }
392 
393 done:
394  mp->retval = rv;
395  svm_msg_q_add_and_unlock (app_mq, msg);
396  return 0;
397 }
398 
399 void
401  u32 context, int rv)
402 {
403  svm_msg_q_msg_t _msg, *msg = &_msg;
405  svm_msg_q_t *app_mq;
406  session_event_t *evt;
407 
408  app_mq = app_wrk->event_queue;
409  if (mq_try_lock_and_alloc_msg (app_mq, msg))
410  return;
411 
412  evt = svm_msg_q_msg_data (app_mq, msg);
413  clib_memset (evt, 0, sizeof (*evt));
414  evt->event_type = SESSION_CTRL_EVT_UNLISTEN_REPLY;
415  ump = (session_unlisten_reply_msg_t *) evt->data;
416  ump->context = context;
417  ump->handle = sh;
418  ump->retval = rv;
419  svm_msg_q_add_and_unlock (app_mq, msg);
420 }
421 
422 static void
424 {
425  svm_msg_q_msg_t _msg, *msg = &_msg;
427  svm_msg_q_t *vpp_evt_q;
428  app_worker_t *app_wrk;
429  session_event_t *evt;
430  svm_msg_q_t *app_mq;
431 
432  app_wrk = app_worker_get (s->app_wrk_index);
433  app_mq = app_wrk->event_queue;
434  if (mq_try_lock_and_alloc_msg (app_mq, msg))
435  return;
436 
437  evt = svm_msg_q_msg_data (app_mq, msg);
438  clib_memset (evt, 0, sizeof (*evt));
439  evt->event_type = SESSION_CTRL_EVT_MIGRATED;
440  mp = (session_migrated_msg_t *) evt->data;
441  mp->handle = session_handle (s);
442  mp->new_handle = new_sh;
445  mp->vpp_evt_q = pointer_to_uword (vpp_evt_q);
446  svm_msg_q_add_and_unlock (app_mq, msg);
447 }
448 
449 static int
450 mq_send_add_segment_cb (u32 app_wrk_index, u64 segment_handle)
451 {
452  int fds[SESSION_N_FD_TYPE], n_fds = 0;
453  svm_msg_q_msg_t _msg, *msg = &_msg;
456  app_worker_t *app_wrk;
457  session_event_t *evt;
458  svm_msg_q_t *app_mq;
459  fifo_segment_t *fs;
460  ssvm_private_t *sp;
461  u8 fd_flags = 0;
462 
463  app_wrk = app_worker_get (app_wrk_index);
464 
466  if (!reg)
467  {
468  clib_warning ("no api registration for client: %u",
469  app_wrk->api_client_index);
470  return -1;
471  }
472 
473  fs = segment_manager_get_segment_w_handle (segment_handle);
474  sp = &fs->ssvm;
475  if (ssvm_type (sp) == SSVM_SEGMENT_MEMFD)
476  {
478  {
479  clib_warning ("can't send memfd fd");
480  return -1;
481  }
482 
483  fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
484  fds[n_fds] = sp->fd;
485  n_fds += 1;
486  }
487 
488  app_mq = app_wrk->event_queue;
489  if (mq_try_lock_and_alloc_msg (app_mq, msg))
490  return -1;
491 
492  if (n_fds)
493  session_send_fds (reg, fds, n_fds);
494 
495  evt = svm_msg_q_msg_data (app_mq, msg);
496  clib_memset (evt, 0, sizeof (*evt));
497  evt->event_type = SESSION_CTRL_EVT_APP_ADD_SEGMENT;
498  mp = (session_app_add_segment_msg_t *) evt->data;
499  clib_memset (mp, 0, sizeof (*mp));
500  mp->segment_size = sp->ssvm_size;
501  mp->fd_flags = fd_flags;
502  mp->segment_handle = segment_handle;
503  strncpy ((char *) mp->segment_name, (char *) sp->name,
504  sizeof (mp->segment_name) - 1);
505 
506  svm_msg_q_add_and_unlock (app_mq, msg);
507 
508  return 0;
509 }
510 
511 static int
512 mq_send_del_segment_cb (u32 app_wrk_index, u64 segment_handle)
513 {
514  svm_msg_q_msg_t _msg, *msg = &_msg;
517  app_worker_t *app_wrk;
518  session_event_t *evt;
519  svm_msg_q_t *app_mq;
520 
521  app_wrk = app_worker_get (app_wrk_index);
523  if (!reg)
524  {
525  clib_warning ("no registration: %u", app_wrk->api_client_index);
526  return -1;
527  }
528 
529  app_mq = app_wrk->event_queue;
530  if (mq_try_lock_and_alloc_msg (app_mq, msg))
531  return -1;
532 
533  evt = svm_msg_q_msg_data (app_mq, msg);
534  clib_memset (evt, 0, sizeof (*evt));
535  evt->event_type = SESSION_CTRL_EVT_APP_DEL_SEGMENT;
536  mp = (session_app_del_segment_msg_t *) evt->data;
537  clib_memset (mp, 0, sizeof (*mp));
538  mp->segment_handle = segment_handle;
539  svm_msg_q_add_and_unlock (app_mq, msg);
540 
541  return 0;
542 }
543 
544 static void
546 {
547  svm_msg_q_msg_t _msg, *msg = &_msg;
549  svm_msg_q_t *app_mq;
550  session_event_t *evt;
551  app_worker_t *app_wrk;
552 
553  /* Propagate transport cleanup notifications only if app didn't close */
554  if (ntf == SESSION_CLEANUP_TRANSPORT
555  && s->session_state != SESSION_STATE_TRANSPORT_DELETED)
556  return;
557 
558  app_wrk = app_worker_get_if_valid (s->app_wrk_index);
559  if (!app_wrk)
560  return;
561 
562  app_mq = app_wrk->event_queue;
563  if (mq_try_lock_and_alloc_msg (app_mq, msg))
564  return;
565 
566  evt = svm_msg_q_msg_data (app_mq, msg);
567  clib_memset (evt, 0, sizeof (*evt));
568  evt->event_type = SESSION_CTRL_EVT_CLEANUP;
569  mp = (session_cleanup_msg_t *) evt->data;
570  mp->handle = session_handle (s);
571  mp->type = ntf;
572  svm_msg_q_add_and_unlock (app_mq, msg);
573 }
574 
575 static session_cb_vft_t session_mq_cb_vft = {
577  .session_disconnect_callback = mq_send_session_disconnected_cb,
578  .session_connected_callback = mq_send_session_connected_cb,
579  .session_reset_callback = mq_send_session_reset_cb,
580  .session_migrate_callback = mq_send_session_migrate_cb,
581  .session_cleanup_callback = mq_send_session_cleanup_cb,
582  .add_segment_callback = mq_send_add_segment_cb,
583  .del_segment_callback = mq_send_del_segment_cb,
584 };
585 
586 static void
588 {
589  vl_api_session_enable_disable_reply_t *rmp;
591  int rv = 0;
592 
594  REPLY_MACRO (VL_API_SESSION_ENABLE_DISABLE_REPLY);
595 }
596 
597 static void
599 {
600  int rv = 0, fds[SESSION_N_FD_TYPE], n_fds = 0;
602  ssvm_private_t *segp, *evt_q_segment;
603  vnet_app_attach_args_t _a, *a = &_a;
604  u8 fd_flags = 0, ctrl_thread;
606  svm_msg_q_t *ctrl_mq;
607 
609  if (!reg)
610  return;
611 
613  {
614  rv = VNET_API_ERROR_FEATURE_DISABLED;
615  goto done;
616  }
617  /* Only support binary api with socket transport */
619  {
620  rv = VNET_API_ERROR_APP_UNSUPPORTED_CFG;
621  goto done;
622  }
623 
625  sizeof (mp->options),
626  "Out of options, fix api message definition");
627 
628  clib_memset (a, 0, sizeof (*a));
629  a->api_client_index = mp->client_index;
630  a->options = mp->options;
631  a->session_cb_vft = &session_mq_cb_vft;
632  a->namespace_id = vl_api_from_api_to_new_vec (mp, &mp->namespace_id);
633 
634  if ((rv = vnet_application_attach (a)))
635  {
636  clib_warning ("attach returned: %d", rv);
637  vec_free (a->namespace_id);
638  goto done;
639  }
640  vec_free (a->namespace_id);
641 
642  /* Send event queues segment */
643  if ((evt_q_segment = session_main_get_evt_q_segment ()))
644  {
645  fd_flags |= SESSION_FD_F_VPP_MQ_SEGMENT;
646  fds[n_fds] = evt_q_segment->fd;
647  n_fds += 1;
648  }
649  /* Send fifo segment fd if needed */
650  if (ssvm_type (a->segment) == SSVM_SEGMENT_MEMFD)
651  {
652  fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
653  fds[n_fds] = a->segment->fd;
654  n_fds += 1;
655  }
656  if (a->options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD)
657  {
658  fd_flags |= SESSION_FD_F_MQ_EVENTFD;
659  fds[n_fds] = svm_msg_q_get_producer_eventfd (a->app_evt_q);
660  n_fds += 1;
661  }
662 
663 done:
664  /* *INDENT-OFF* */
665  REPLY_MACRO2 (VL_API_APP_ATTACH_REPLY, ({
666  if (!rv)
667  {
668  ctrl_thread = vlib_num_workers () ? 1 : 0;
669  ctrl_mq = session_main_get_vpp_event_queue (ctrl_thread);
670  segp = a->segment;
671  rmp->app_index = clib_host_to_net_u32 (a->app_index);
672  rmp->app_mq = pointer_to_uword (a->app_evt_q);
673  rmp->vpp_ctrl_mq = pointer_to_uword (ctrl_mq);
674  rmp->vpp_ctrl_mq_thread = ctrl_thread;
675  rmp->n_fds = n_fds;
676  rmp->fd_flags = fd_flags;
677  if (vec_len (segp->name))
678  {
680  }
681  rmp->segment_size = segp->ssvm_size;
682  rmp->segment_handle = clib_host_to_net_u64 (a->segment_handle);
683  }
684  }));
685  /* *INDENT-ON* */
686 
687  if (n_fds)
688  session_send_fds (reg, fds, n_fds);
689 }
690 
691 static void
693 {
694  int rv = 0, fds[SESSION_N_FD_TYPE], n_fds = 0;
697  application_t *app;
698  u8 fd_flags = 0;
699 
701  {
702  rv = VNET_API_ERROR_FEATURE_DISABLED;
703  goto done;
704  }
705 
707  if (!reg)
708  return;
709 
710  app = application_get_if_valid (clib_net_to_host_u32 (mp->app_index));
711  if (!app)
712  {
713  rv = VNET_API_ERROR_INVALID_VALUE;
714  goto done;
715  }
716 
718  .app_index = app->app_index,
719  .wrk_map_index = clib_net_to_host_u32 (mp->wrk_index),
720  .api_client_index = mp->client_index,
721  .is_add = mp->is_add
722  };
723  rv = vnet_app_worker_add_del (&args);
724  if (rv)
725  {
726  clib_warning ("app worker add/del returned: %d", rv);
727  goto done;
728  }
729 
730  if (!mp->is_add)
731  goto done;
732 
733  /* Send fifo segment fd if needed */
734  if (ssvm_type (args.segment) == SSVM_SEGMENT_MEMFD)
735  {
736  fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
737  fds[n_fds] = args.segment->fd;
738  n_fds += 1;
739  }
740  if (application_segment_manager_properties (app)->use_mq_eventfd)
741  {
742  fd_flags |= SESSION_FD_F_MQ_EVENTFD;
743  fds[n_fds] = svm_msg_q_get_producer_eventfd (args.evt_q);
744  n_fds += 1;
745  }
746 
747  /* *INDENT-OFF* */
748 done:
749  REPLY_MACRO2 (VL_API_APP_WORKER_ADD_DEL_REPLY, ({
750  rmp->is_add = mp->is_add;
751  rmp->wrk_index = clib_host_to_net_u32 (args.wrk_map_index);
752  rmp->segment_handle = clib_host_to_net_u64 (args.segment_handle);
753  if (!rv && mp->is_add)
754  {
755  if (vec_len (args.segment->name))
756  {
757  vl_api_vec_to_api_string (args.segment->name, &rmp->segment_name);
758  }
759  rmp->app_event_queue_address = pointer_to_uword (args.evt_q);
760  rmp->n_fds = n_fds;
761  rmp->fd_flags = fd_flags;
762  }
763  }));
764  /* *INDENT-ON* */
765 
766  if (n_fds)
767  session_send_fds (reg, fds, n_fds);
768 }
769 
770 static void
772 {
773  vl_api_application_detach_reply_t *rmp;
774  int rv = VNET_API_ERROR_INVALID_VALUE_2;
775  vnet_app_detach_args_t _a, *a = &_a;
776  application_t *app;
777 
779  {
780  rv = VNET_API_ERROR_FEATURE_DISABLED;
781  goto done;
782  }
783 
784  app = application_lookup (mp->client_index);
785  if (app)
786  {
787  a->app_index = app->app_index;
788  a->api_client_index = mp->client_index;
789  rv = vnet_application_detach (a);
790  }
791 
792 done:
793  REPLY_MACRO (VL_API_APPLICATION_DETACH_REPLY);
794 }
795 
796 static void
798 {
800  u32 appns_index = 0;
801  u8 *ns_id = 0;
802  int rv = 0;
803  if (session_main_is_enabled () == 0)
804  {
805  rv = VNET_API_ERROR_FEATURE_DISABLED;
806  goto done;
807  }
808 
809  ns_id = vl_api_from_api_to_new_vec (mp, &mp->namespace_id);
810 
812  .ns_id = ns_id,
813  .secret = clib_net_to_host_u64 (mp->secret),
814  .sw_if_index = clib_net_to_host_u32 (mp->sw_if_index),
815  .ip4_fib_id = clib_net_to_host_u32 (mp->ip4_fib_id),
816  .ip6_fib_id = clib_net_to_host_u32 (mp->ip6_fib_id),
817  .is_add = 1
818  };
819  rv = vnet_app_namespace_add_del (&args);
820  if (!rv)
821  {
822  appns_index = app_namespace_index_from_id (ns_id);
823  if (appns_index == APP_NAMESPACE_INVALID_INDEX)
824  {
825  clib_warning ("app ns lookup failed");
826  rv = VNET_API_ERROR_UNSPECIFIED;
827  }
828  }
829  vec_free (ns_id);
830 
831  /* *INDENT-OFF* */
832 done:
833  REPLY_MACRO2 (VL_API_APP_NAMESPACE_ADD_DEL_REPLY, ({
834  if (!rv)
835  rmp->appns_index = clib_host_to_net_u32 (appns_index);
836  }));
837  /* *INDENT-ON* */
838 }
839 
840 static void
842 {
843  vl_api_session_rule_add_del_reply_t *rmp;
845  session_rule_table_add_del_args_t *table_args = &args.table_args;
846  int rv = 0;
847 
848  clib_memset (&args, 0, sizeof (args));
849 
850  ip_prefix_decode (&mp->lcl, &table_args->lcl);
851  ip_prefix_decode (&mp->rmt, &table_args->rmt);
852 
853  table_args->lcl_port = mp->lcl_port;
854  table_args->rmt_port = mp->rmt_port;
855  table_args->action_index = clib_net_to_host_u32 (mp->action_index);
856  table_args->is_add = mp->is_add;
857  mp->tag[sizeof (mp->tag) - 1] = 0;
858  table_args->tag = format (0, "%s", mp->tag);
859  args.appns_index = clib_net_to_host_u32 (mp->appns_index);
860  args.scope = mp->scope;
861  args.transport_proto =
863  TRANSPORT_PROTO_UDP ? 1 : 0;
864 
865  rv = vnet_session_rule_add_del (&args);
866  if (rv)
867  clib_warning ("rule add del returned: %d", rv);
868  vec_free (table_args->tag);
869  REPLY_MACRO (VL_API_SESSION_RULE_ADD_DEL_REPLY);
870 }
871 
872 static void
873 send_session_rule_details4 (mma_rule_16_t * rule, u8 is_local,
874  u8 transport_proto, u32 appns_index, u8 * tag,
875  vl_api_registration_t * reg, u32 context)
876 {
878  session_mask_or_match_4_t *match =
879  (session_mask_or_match_4_t *) & rule->match;
880  session_mask_or_match_4_t *mask =
881  (session_mask_or_match_4_t *) & rule->mask;
882  fib_prefix_t lcl, rmt;
883 
884  rmp = vl_msg_api_alloc (sizeof (*rmp));
885  clib_memset (rmp, 0, sizeof (*rmp));
886  rmp->_vl_msg_id = ntohs (VL_API_SESSION_RULES_DETAILS);
887  rmp->context = context;
888 
889  clib_memset (&lcl, 0, sizeof (lcl));
890  clib_memset (&rmt, 0, sizeof (rmt));
891  ip_set (&lcl.fp_addr, &match->lcl_ip, 1);
892  ip_set (&rmt.fp_addr, &match->rmt_ip, 1);
893  lcl.fp_len = ip4_mask_to_preflen (&mask->lcl_ip);
894  rmt.fp_len = ip4_mask_to_preflen (&mask->rmt_ip);
895 
896  ip_prefix_encode (&lcl, &rmp->lcl);
897  ip_prefix_encode (&rmt, &rmp->rmt);
898  rmp->lcl_port = match->lcl_port;
899  rmp->rmt_port = match->rmt_port;
900  rmp->action_index = clib_host_to_net_u32 (rule->action_index);
901  rmp->scope =
903  rmp->transport_proto = api_session_transport_proto_encode (transport_proto);
904  rmp->appns_index = clib_host_to_net_u32 (appns_index);
905  if (tag)
906  {
907  clib_memcpy_fast (rmp->tag, tag, vec_len (tag));
908  rmp->tag[vec_len (tag)] = 0;
909  }
910 
911  vl_api_send_msg (reg, (u8 *) rmp);
912 }
913 
914 static void
915 send_session_rule_details6 (mma_rule_40_t * rule, u8 is_local,
916  u8 transport_proto, u32 appns_index, u8 * tag,
917  vl_api_registration_t * reg, u32 context)
918 {
920  session_mask_or_match_6_t *match =
921  (session_mask_or_match_6_t *) & rule->match;
922  session_mask_or_match_6_t *mask =
923  (session_mask_or_match_6_t *) & rule->mask;
924  fib_prefix_t lcl, rmt;
925 
926  rmp = vl_msg_api_alloc (sizeof (*rmp));
927  clib_memset (rmp, 0, sizeof (*rmp));
928  rmp->_vl_msg_id = ntohs (VL_API_SESSION_RULES_DETAILS);
929  rmp->context = context;
930 
931  clib_memset (&lcl, 0, sizeof (lcl));
932  clib_memset (&rmt, 0, sizeof (rmt));
933  ip_set (&lcl.fp_addr, &match->lcl_ip, 0);
934  ip_set (&rmt.fp_addr, &match->rmt_ip, 0);
935  lcl.fp_len = ip6_mask_to_preflen (&mask->lcl_ip);
936  rmt.fp_len = ip6_mask_to_preflen (&mask->rmt_ip);
937 
938  ip_prefix_encode (&lcl, &rmp->lcl);
939  ip_prefix_encode (&rmt, &rmp->rmt);
940  rmp->lcl_port = match->lcl_port;
941  rmp->rmt_port = match->rmt_port;
942  rmp->action_index = clib_host_to_net_u32 (rule->action_index);
943  rmp->scope =
945  rmp->transport_proto = api_session_transport_proto_encode (transport_proto);
946  rmp->appns_index = clib_host_to_net_u32 (appns_index);
947  if (tag)
948  {
949  clib_memcpy_fast (rmp->tag, tag, vec_len (tag));
950  rmp->tag[vec_len (tag)] = 0;
951  }
952 
953  vl_api_send_msg (reg, (u8 *) rmp);
954 }
955 
956 static void
958  u8 tp, u8 is_local, u32 appns_index,
959  vl_api_registration_t * reg, u32 context)
960 {
961  mma_rule_16_t *rule16;
962  mma_rule_40_t *rule40;
963  mma_rules_table_16_t *srt16;
964  mma_rules_table_40_t *srt40;
965  u32 ri;
966 
967  if (is_local || fib_proto == FIB_PROTOCOL_IP4)
968  {
969  u8 *tag = 0;
970  /* *INDENT-OFF* */
971  srt16 = &srt->session_rules_tables_16;
972  pool_foreach (rule16, srt16->rules) {
973  ri = mma_rules_table_rule_index_16 (srt16, rule16);
974  tag = session_rules_table_rule_tag (srt, ri, 1);
975  send_session_rule_details4 (rule16, is_local, tp, appns_index, tag,
976  reg, context);
977  }
978  /* *INDENT-ON* */
979  }
980  if (is_local || fib_proto == FIB_PROTOCOL_IP6)
981  {
982  u8 *tag = 0;
983  /* *INDENT-OFF* */
984  srt40 = &srt->session_rules_tables_40;
985  pool_foreach (rule40, srt40->rules) {
986  ri = mma_rules_table_rule_index_40 (srt40, rule40);
987  tag = session_rules_table_rule_tag (srt, ri, 1);
988  send_session_rule_details6 (rule40, is_local, tp, appns_index, tag,
989  reg, context);
990  }
991  /* *INDENT-ON* */
992  }
993 }
994 
995 static void
997 {
999  session_table_t *st;
1000  u8 tp;
1001 
1003  if (!reg)
1004  return;
1005 
1006  /* *INDENT-OFF* */
1007  session_table_foreach (st, ({
1008  for (tp = 0; tp < TRANSPORT_N_PROTOS; tp++)
1009  {
1010  send_session_rules_table_details (&st->session_rules[tp],
1011  st->active_fib_proto, tp,
1012  st->is_local, st->appns_index, reg,
1013  mp->context);
1014  }
1015  }));
1016  /* *INDENT-ON* */
1017 }
1018 
1019 static void
1021 {
1024  u32 certkey_len, key_len, cert_len;
1025  int rv = 0;
1026  if (session_main_is_enabled () == 0)
1027  {
1028  rv = VNET_API_ERROR_FEATURE_DISABLED;
1029  goto done;
1030  }
1031 
1032  cert_len = clib_net_to_host_u16 (mp->cert_len);
1033  if (cert_len > 10000)
1034  {
1035  rv = VNET_API_ERROR_INVALID_VALUE;
1036  goto done;
1037  }
1038 
1039  certkey_len = clib_net_to_host_u16 (mp->certkey_len);
1040  if (certkey_len < cert_len)
1041  {
1042  rv = VNET_API_ERROR_INVALID_VALUE;
1043  goto done;
1044  }
1045 
1046  key_len = certkey_len - cert_len;
1047  if (key_len > 10000)
1048  {
1049  rv = VNET_API_ERROR_INVALID_VALUE;
1050  goto done;
1051  }
1052 
1053  clib_memset (a, 0, sizeof (*a));
1054  vec_validate (a->cert, cert_len);
1055  vec_validate (a->key, key_len);
1056  clib_memcpy_fast (a->cert, mp->certkey, cert_len);
1057  clib_memcpy_fast (a->key, mp->certkey + cert_len, key_len);
1058  rv = vnet_app_add_cert_key_pair (a);
1059  vec_free (a->cert);
1060  vec_free (a->key);
1061 
1062 done:
1063  /* *INDENT-OFF* */
1064  REPLY_MACRO2 (VL_API_APP_ADD_CERT_KEY_PAIR_REPLY, ({
1065  if (!rv)
1066  rmp->index = clib_host_to_net_u32 (a->index);
1067  }));
1068  /* *INDENT-ON* */
1069 }
1070 
1071 static void
1073 {
1074  vl_api_app_del_cert_key_pair_reply_t *rmp;
1075  u32 ckpair_index;
1076  int rv = 0;
1077  if (session_main_is_enabled () == 0)
1078  {
1079  rv = VNET_API_ERROR_FEATURE_DISABLED;
1080  goto done;
1081  }
1082  ckpair_index = clib_net_to_host_u32 (mp->index);
1083  rv = vnet_app_del_cert_key_pair (ckpair_index);
1084 
1085 done:
1086  REPLY_MACRO (VL_API_APP_DEL_CERT_KEY_PAIR_REPLY);
1087 }
1088 
1089 /* ### WILL BE DEPRECATED POST 20.01 ### */
1090 static void
1092  mp)
1093 {
1094  vl_api_application_tls_cert_add_reply_t *rmp;
1095  app_cert_key_pair_t *ckpair;
1096  application_t *app;
1097  u32 cert_len;
1098  int rv = 0;
1099  if (session_main_is_enabled () == 0)
1100  {
1101  rv = VNET_API_ERROR_FEATURE_DISABLED;
1102  goto done;
1103  }
1104  if (!(app = application_lookup (mp->client_index)))
1105  {
1106  rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
1107  goto done;
1108  }
1109  cert_len = clib_net_to_host_u16 (mp->cert_len);
1110  if (cert_len > 10000)
1111  {
1112  rv = VNET_API_ERROR_INVALID_VALUE;
1113  goto done;
1114  }
1115  ckpair = app_cert_key_pair_get_default ();
1116  vec_validate (ckpair->cert, cert_len);
1117  clib_memcpy_fast (ckpair->cert, mp->cert, cert_len);
1118 
1119 done:
1120  REPLY_MACRO (VL_API_APPLICATION_TLS_CERT_ADD_REPLY);
1121 }
1122 
1123 /* ### WILL BE DEPRECATED POST 20.01 ### */
1124 static void
1126  mp)
1127 {
1128  vl_api_application_tls_key_add_reply_t *rmp;
1129  app_cert_key_pair_t *ckpair;
1130  application_t *app;
1131  u32 key_len;
1132  int rv = 0;
1133  if (session_main_is_enabled () == 0)
1134  {
1135  rv = VNET_API_ERROR_FEATURE_DISABLED;
1136  goto done;
1137  }
1138  if (!(app = application_lookup (mp->client_index)))
1139  {
1140  rv = VNET_API_ERROR_APPLICATION_NOT_ATTACHED;
1141  goto done;
1142  }
1143  key_len = clib_net_to_host_u16 (mp->key_len);
1144  if (key_len > 10000)
1145  {
1146  rv = VNET_API_ERROR_INVALID_VALUE;
1147  goto done;
1148  }
1149  ckpair = app_cert_key_pair_get_default ();
1150  vec_validate (ckpair->key, key_len);
1151  clib_memcpy_fast (ckpair->key, mp->key, key_len);
1152 done:
1153  REPLY_MACRO (VL_API_APPLICATION_TLS_KEY_ADD_REPLY);
1154 }
1155 
1156 static clib_error_t *
1158 {
1159  application_t *app = application_lookup (client_index);
1160  vnet_app_detach_args_t _a, *a = &_a;
1161  if (app)
1162  {
1163  a->app_index = app->app_index;
1164  a->api_client_index = client_index;
1166  }
1167  return 0;
1168 }
1169 
1171 
1172 #define vl_msg_name_crc_list
1173 #include <vnet/vnet_all_api_h.h>
1174 #undef vl_msg_name_crc_list
1175 
1176 static void
1178 {
1179 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1180  foreach_vl_msg_name_crc_session;
1181 #undef _
1182 }
1183 
1184 /*
1185  * session_api_hookup
1186  * Add uri's API message handlers to the table.
1187  * vlib has already mapped shared memory and
1188  * added the client registration handlers.
1189  * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
1190  */
1191 static clib_error_t *
1193 {
1194  api_main_t *am = vlibapi_get_main ();
1195 
1196 #define _(N,n) \
1197  vl_msg_api_set_handlers(VL_API_##N, #n, \
1198  vl_api_##n##_t_handler, \
1199  vl_noop_handler, \
1200  vl_api_##n##_t_endian, \
1201  vl_api_##n##_t_print, \
1202  sizeof(vl_api_##n##_t), 1);
1204 #undef _
1205 
1206  /*
1207  * Set up the (msg_name, crc, message-id) table
1208  */
1210 
1211  return 0;
1212 }
1213 
1215 
1216 /*
1217  * Socket api functions
1218  */
1219 
1220 static void
1221 sapi_send_fds (app_worker_t * app_wrk, int *fds, int n_fds)
1222 {
1223  app_sapi_msg_t smsg = { 0 };
1224  app_namespace_t *app_ns;
1225  application_t *app;
1226  clib_socket_t *cs;
1227  u32 cs_index;
1228 
1229  app = application_get (app_wrk->app_index);
1230  app_ns = app_namespace_get (app->ns_index);
1231  cs_index = appns_sapi_handle_sock_index (app_wrk->api_client_index);
1232  cs = appns_sapi_get_socket (app_ns, cs_index);
1233  if (PREDICT_FALSE (!cs))
1234  return;
1235 
1236  /* There's no payload for the message only the type */
1238  clib_socket_sendmsg (cs, &smsg, sizeof (smsg), fds, n_fds);
1239 }
1240 
1241 static int
1242 mq_send_add_segment_sapi_cb (u32 app_wrk_index, u64 segment_handle)
1243 {
1244  int fds[SESSION_N_FD_TYPE], n_fds = 0;
1245  svm_msg_q_msg_t _msg, *msg = &_msg;
1247  app_worker_t *app_wrk;
1248  session_event_t *evt;
1249  svm_msg_q_t *app_mq;
1250  fifo_segment_t *fs;
1251  ssvm_private_t *sp;
1252  u8 fd_flags = 0;
1253 
1254  app_wrk = app_worker_get (app_wrk_index);
1255 
1256  fs = segment_manager_get_segment_w_handle (segment_handle);
1257  sp = &fs->ssvm;
1259 
1260  fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
1261  fds[n_fds] = sp->fd;
1262  n_fds += 1;
1263 
1264  app_mq = app_wrk->event_queue;
1265  if (mq_try_lock_and_alloc_msg (app_mq, msg))
1266  return -1;
1267 
1268  /*
1269  * Send the fd over api socket
1270  */
1271  sapi_send_fds (app_wrk, fds, n_fds);
1272 
1273  /*
1274  * Send the actual message over mq
1275  */
1276  evt = svm_msg_q_msg_data (app_mq, msg);
1277  clib_memset (evt, 0, sizeof (*evt));
1278  evt->event_type = SESSION_CTRL_EVT_APP_ADD_SEGMENT;
1279  mp = (session_app_add_segment_msg_t *) evt->data;
1280  clib_memset (mp, 0, sizeof (*mp));
1281  mp->segment_size = sp->ssvm_size;
1282  mp->fd_flags = fd_flags;
1283  mp->segment_handle = segment_handle;
1284  strncpy ((char *) mp->segment_name, (char *) sp->name,
1285  sizeof (mp->segment_name) - 1);
1286 
1287  svm_msg_q_add_and_unlock (app_mq, msg);
1288 
1289  return 0;
1290 }
1291 
1292 static int
1293 mq_send_del_segment_sapi_cb (u32 app_wrk_index, u64 segment_handle)
1294 {
1295  svm_msg_q_msg_t _msg, *msg = &_msg;
1297  app_worker_t *app_wrk;
1298  session_event_t *evt;
1299  svm_msg_q_t *app_mq;
1300 
1301  app_wrk = app_worker_get (app_wrk_index);
1302 
1303  app_mq = app_wrk->event_queue;
1304  if (mq_try_lock_and_alloc_msg (app_mq, msg))
1305  return -1;
1306 
1307  evt = svm_msg_q_msg_data (app_mq, msg);
1308  clib_memset (evt, 0, sizeof (*evt));
1309  evt->event_type = SESSION_CTRL_EVT_APP_DEL_SEGMENT;
1310  mp = (session_app_del_segment_msg_t *) evt->data;
1311  clib_memset (mp, 0, sizeof (*mp));
1312  mp->segment_handle = segment_handle;
1313  svm_msg_q_add_and_unlock (app_mq, msg);
1314 
1315  return 0;
1316 }
1317 
1318 static session_cb_vft_t session_mq_sapi_cb_vft = {
1320  .session_disconnect_callback = mq_send_session_disconnected_cb,
1321  .session_connected_callback = mq_send_session_connected_cb,
1322  .session_reset_callback = mq_send_session_reset_cb,
1323  .session_migrate_callback = mq_send_session_migrate_cb,
1324  .session_cleanup_callback = mq_send_session_cleanup_cb,
1325  .add_segment_callback = mq_send_add_segment_sapi_cb,
1326  .del_segment_callback = mq_send_del_segment_sapi_cb,
1327 };
1328 
1329 static void
1331  app_sapi_attach_msg_t * mp)
1332 {
1333  int rv = 0, fds[SESSION_N_FD_TYPE], n_fds = 0;
1334  vnet_app_attach_args_t _a, *a = &_a;
1336  ssvm_private_t *evt_q_segment;
1337  u8 fd_flags = 0, ctrl_thread;
1338  app_ns_api_handle_t *handle;
1339  app_sapi_msg_t msg = { 0 };
1340  app_worker_t *app_wrk;
1341  svm_msg_q_t *ctrl_mq;
1342  application_t *app;
1343 
1344  /* Make sure name is null terminated */
1345  mp->name[63] = 0;
1346 
1347  clib_memset (a, 0, sizeof (*a));
1348  a->api_client_index = appns_sapi_socket_handle (app_ns, cs);
1349  a->name = format (0, "%s", (char *) mp->name);
1350  a->options = mp->options;
1351  a->session_cb_vft = &session_mq_sapi_cb_vft;
1352  a->use_sock_api = 1;
1353  a->options[APP_OPTIONS_NAMESPACE] = app_namespace_index (app_ns);
1354 
1355  if ((rv = vnet_application_attach (a)))
1356  {
1357  clib_warning ("attach returned: %d", rv);
1358  goto done;
1359  }
1360 
1361  /* Send event queues segment */
1362  if ((evt_q_segment = session_main_get_evt_q_segment ()))
1363  {
1364  fd_flags |= SESSION_FD_F_VPP_MQ_SEGMENT;
1365  fds[n_fds] = evt_q_segment->fd;
1366  n_fds += 1;
1367  }
1368  /* Send fifo segment fd if needed */
1369  if (ssvm_type (a->segment) == SSVM_SEGMENT_MEMFD)
1370  {
1371  fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
1372  fds[n_fds] = a->segment->fd;
1373  n_fds += 1;
1374  }
1375  if (a->options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD)
1376  {
1377  fd_flags |= SESSION_FD_F_MQ_EVENTFD;
1378  fds[n_fds] = svm_msg_q_get_producer_eventfd (a->app_evt_q);
1379  n_fds += 1;
1380  }
1381 
1382 done:
1383 
1385  rmp = &msg.attach_reply;
1386  rmp->retval = rv;
1387  if (!rv)
1388  {
1389  ctrl_thread = vlib_num_workers ()? 1 : 0;
1390  ctrl_mq = session_main_get_vpp_event_queue (ctrl_thread);
1391  rmp->app_index = a->app_index;
1392  rmp->app_mq = pointer_to_uword (a->app_evt_q);
1393  rmp->vpp_ctrl_mq = pointer_to_uword (ctrl_mq);
1394  rmp->vpp_ctrl_mq_thread = ctrl_thread;
1395  rmp->n_fds = n_fds;
1396  rmp->fd_flags = fd_flags;
1397  /* No segment name and size since we only support memfds
1398  * in this configuration */
1399  rmp->segment_handle = a->segment_handle;
1400  rmp->api_client_handle = a->api_client_index;
1401 
1402  /* Update app index for socket */
1403  handle = (app_ns_api_handle_t *) & cs->private_data;
1404  app = application_get (a->app_index);
1405  app_wrk = application_get_worker (app, 0);
1406  handle->aah_app_wrk_index = app_wrk->wrk_index;
1407  }
1408 
1409  clib_socket_sendmsg (cs, &msg, sizeof (msg), fds, n_fds);
1410  vec_free (a->name);
1411 }
1412 
1413 static void
1415 {
1416  app_namespace_t *app_ns = app_namespace_get (api_handle >> 16);
1417  u16 sock_index = api_handle & 0xffff;
1418  app_ns_api_handle_t *handle;
1419  clib_socket_t *cs;
1420  clib_file_t *cf;
1421 
1422  cs = appns_sapi_get_socket (app_ns, sock_index);
1423  if (!cs)
1424  return;
1425 
1426  handle = (app_ns_api_handle_t *) & cs->private_data;
1427  cf = clib_file_get (&file_main, handle->aah_file_index);
1428  clib_file_del (&file_main, cf);
1429 
1430  clib_socket_close (cs);
1431  appns_sapi_free_socket (app_ns, cs);
1432 }
1433 
1434 static void
1436  clib_socket_t * cs,
1438 {
1439  int rv = 0, fds[SESSION_N_FD_TYPE], n_fds = 0;
1441  app_ns_api_handle_t *handle;
1442  app_sapi_msg_t msg = { 0 };
1443  app_worker_t *app_wrk;
1444  u32 sapi_handle = -1;
1445  application_t *app;
1446  u8 fd_flags = 0;
1447 
1448  app = application_get_if_valid (mp->app_index);
1449  if (!app)
1450  {
1451  rv = VNET_API_ERROR_INVALID_VALUE;
1452  goto done;
1453  }
1454 
1455  sapi_handle = appns_sapi_socket_handle (app_ns, cs);
1456 
1458  .app_index = app->app_index,
1459  .wrk_map_index = mp->wrk_index,
1460  .api_client_index = sapi_handle,
1461  .is_add = mp->is_add
1462  };
1463  rv = vnet_app_worker_add_del (&args);
1464  if (rv)
1465  {
1466  clib_warning ("app worker add/del returned: %d", rv);
1467  goto done;
1468  }
1469 
1470  if (!mp->is_add)
1471  {
1472  sapi_socket_close_w_handle (sapi_handle);
1473  goto done;
1474  }
1475 
1476  /* Send fifo segment fd if needed */
1477  if (ssvm_type (args.segment) == SSVM_SEGMENT_MEMFD)
1478  {
1479  fd_flags |= SESSION_FD_F_MEMFD_SEGMENT;
1480  fds[n_fds] = args.segment->fd;
1481  n_fds += 1;
1482  }
1483  if (application_segment_manager_properties (app)->use_mq_eventfd)
1484  {
1485  fd_flags |= SESSION_FD_F_MQ_EVENTFD;
1486  fds[n_fds] = svm_msg_q_get_producer_eventfd (args.evt_q);
1487  n_fds += 1;
1488  }
1489 
1490 done:
1491 
1493  rmp = &msg.worker_add_del_reply;
1494  rmp->retval = rv;
1495  rmp->is_add = mp->is_add;
1496  rmp->api_client_handle = sapi_handle;
1497  rmp->wrk_index = args.wrk_map_index;
1498  rmp->segment_handle = args.segment_handle;
1499  if (!rv && mp->is_add)
1500  {
1501  /* No segment name and size. This supports only memfds */
1502  rmp->app_event_queue_address = pointer_to_uword (args.evt_q);
1503  rmp->n_fds = n_fds;
1504  rmp->fd_flags = fd_flags;
1505 
1506  /* Update app index for socket */
1507  handle = (app_ns_api_handle_t *) & cs->private_data;
1508  app_wrk = application_get_worker (app, args.wrk_map_index);
1509  handle->aah_app_wrk_index = app_wrk->wrk_index;
1510  }
1511 
1512  clib_socket_sendmsg (cs, &msg, sizeof (msg), fds, n_fds);
1513 }
1514 
1515 static void
1517 {
1518  app_ns_api_handle_t *handle;
1519  app_worker_t *app_wrk;
1520  u32 api_client_handle;
1521 
1522  api_client_handle = appns_sapi_socket_handle (app_ns, cs);
1523  sapi_socket_close_w_handle (api_client_handle);
1524 
1525  /* Cleanup everything because app worker closed socket or crashed */
1526  handle = (app_ns_api_handle_t *) & cs->private_data;
1527  app_wrk = app_worker_get (handle->aah_app_wrk_index);
1528 
1530  .app_index = app_wrk->app_index,
1531  .wrk_map_index = app_wrk->wrk_map_index,
1532  .api_client_index = api_client_handle,
1533  .is_add = 0
1534  };
1535  /* Send rpc to main thread for worker barrier */
1537  sizeof (args));
1538 }
1539 
1540 static clib_error_t *
1542 {
1545  app_sapi_msg_t msg = { 0 };
1546  app_namespace_t *app_ns;
1547  clib_error_t *err = 0;
1548  clib_socket_t *cs;
1549 
1550  app_ns = app_namespace_get (handle->aah_app_ns_index);
1551  cs = appns_sapi_get_socket (app_ns, handle->aah_sock_index);
1552  if (!cs)
1553  goto error;
1554 
1555  err = clib_socket_recvmsg (cs, &msg, sizeof (msg), 0, 0);
1556  if (err)
1557  {
1558  clib_error_free (err);
1559  sapi_socket_detach (app_ns, cs);
1560  goto error;
1561  }
1562 
1563  handle = (app_ns_api_handle_t *) & cs->private_data;
1564 
1566 
1567  switch (msg.type)
1568  {
1570  session_api_attach_handler (app_ns, cs, &msg.attach);
1571  break;
1573  sapi_add_del_worker_handler (app_ns, cs, &msg.worker_add_del);
1574  break;
1575  default:
1576  clib_warning ("app wrk %u unknown message type: %u",
1577  handle->aah_app_wrk_index, msg.type);
1578  break;
1579  }
1580 
1582 
1583 error:
1584  return 0;
1585 }
1586 
1587 static clib_error_t *
1589 {
1591  clib_warning ("called for app ns %u", handle->aah_app_ns_index);
1592  return 0;
1593 }
1594 
1595 static clib_error_t *
1597 {
1599  app_namespace_t *app_ns;
1600  clib_socket_t *cs;
1601 
1602  app_ns = app_namespace_get (handle->aah_app_ns_index);
1603  cs = appns_sapi_get_socket (app_ns, handle->aah_sock_index);
1604  if (!cs)
1605  return 0;
1606 
1607  sapi_socket_detach (app_ns, cs);
1608  return 0;
1609 }
1610 
1611 static clib_error_t *
1613 {
1615  app_namespace_t *app_ns;
1616  clib_file_t cf = { 0 };
1617  clib_error_t *err = 0;
1618  clib_socket_t *ccs, *scs;
1619 
1620  /* Listener files point to namespace */
1621  app_ns = app_namespace_get (handle.aah_app_ns_index);
1622 
1623  /*
1624  * Initialize client socket
1625  */
1626  ccs = appns_sapi_alloc_socket (app_ns);
1627 
1628  /* Grab server socket after client is initialized */
1629  scs = appns_sapi_get_socket (app_ns, handle.aah_sock_index);
1630  if (!scs)
1631  goto error;
1632 
1633  err = clib_socket_accept (scs, ccs);
1634  if (err)
1635  {
1636  clib_error_report (err);
1637  goto error;
1638  }
1639 
1640  cf.read_function = sapi_sock_read_ready;
1641  cf.write_function = sapi_sock_write_ready;
1642  cf.error_function = sapi_sock_error;
1643  cf.file_descriptor = ccs->fd;
1644  /* File points to app namespace and socket */
1645  handle.aah_sock_index = appns_sapi_socket_index (app_ns, ccs);
1646  cf.private_data = handle.as_u64;
1647  cf.description = format (0, "app sock conn fd: %d", ccs->fd);
1648 
1649  /* Poll until we get an attach message. Socket points to file and
1650  * application that owns the socket */
1651  handle.aah_app_wrk_index = APP_INVALID_INDEX;
1652  handle.aah_file_index = clib_file_add (&file_main, &cf);
1653  ccs->private_data = handle.as_u64;
1654 
1655  return err;
1656 
1657 error:
1658  appns_sapi_free_socket (app_ns, ccs);
1659  return err;
1660 }
1661 
1662 int
1664 {
1665  char *subdir = "/app_ns_sockets/";
1666  app_ns_api_handle_t *handle;
1667  clib_file_t cf = { 0 };
1668  struct stat file_stat;
1669  clib_error_t *err;
1670  clib_socket_t *cs;
1671  u8 *dir = 0;
1672  int rv = 0;
1673 
1675  strlen (vlib_unix_get_runtime_dir ()));
1676  vec_add (dir, (u8 *) subdir, strlen (subdir));
1677 
1678  err = vlib_unix_recursive_mkdir ((char *) dir);
1679  if (err)
1680  {
1681  clib_error_report (err);
1682  rv = -1;
1683  goto error;
1684  }
1685 
1686  app_ns->sock_name = format (0, "%v%v%c", dir, app_ns->ns_id, 0);
1687 
1688  /*
1689  * Create and initialize socket to listen on
1690  */
1691  cs = appns_sapi_alloc_socket (app_ns);
1692  cs->config = (char *) app_ns->sock_name;
1693  cs->flags = CLIB_SOCKET_F_IS_SERVER |
1696 
1697  if ((err = clib_socket_init (cs)))
1698  {
1699  clib_error_report (err);
1700  rv = -1;
1701  goto error;
1702  }
1703 
1704  if (stat ((char *) app_ns->sock_name, &file_stat) == -1)
1705  {
1706  rv = -1;
1707  goto error;
1708  }
1709 
1710  /*
1711  * Start polling it
1712  */
1714  cf.file_descriptor = cs->fd;
1715  /* File points to namespace */
1716  handle = (app_ns_api_handle_t *) & cf.private_data;
1717  handle->aah_app_ns_index = app_namespace_index (app_ns);
1718  handle->aah_sock_index = appns_sapi_socket_index (app_ns, cs);
1719  cf.description = format (0, "app sock listener: %s", app_ns->sock_name);
1720 
1721  /* Socket points to clib file index */
1722  handle = (app_ns_api_handle_t *) & cs->private_data;
1723  handle->aah_file_index = clib_file_add (&file_main, &cf);
1724  handle->aah_app_wrk_index = APP_INVALID_INDEX;
1725 
1726 error:
1727  vec_free (dir);
1728  return rv;
1729 }
1730 
1731 /*
1732  * fd.io coding-style-patch-verification: ON
1733  *
1734  * Local Variables:
1735  * eval: (c-set-style "gnu")
1736  * End:
1737  */
static void session_api_attach_handler(app_namespace_t *app_ns, clib_socket_t *cs, app_sapi_attach_msg_t *mp)
Definition: session_api.c:1330
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
struct _vnet_app_worker_add_del_args vnet_app_worker_add_del_args_t
app_sapi_attach_reply_msg_t attach_reply
string namespace_id[]
Definition: session.api:41
#define APP_NAMESPACE_INVALID_INDEX
static clib_error_t * session_api_hookup(vlib_main_t *vm)
Definition: session_api.c:1192
static void clib_file_del(clib_file_main_t *um, clib_file_t *f)
Definition: file.h:109
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 void vl_api_app_del_cert_key_pair_t_handler(vl_api_app_del_cert_key_pair_t *mp)
Definition: session_api.c:1072
app_cert_key_pair_t * app_cert_key_pair_get_default()
Definition: application.c:1699
void mq_send_unlisten_reply(app_worker_t *app_wrk, session_handle_t sh, u32 context, int rv)
Definition: session_api.c:400
int vnet_app_add_cert_key_pair(vnet_app_add_cert_key_pair_args_t *a)
Definition: application.c:1706
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:213
Add certificate and key.
Definition: session.api:103
transport_endpoint_t rmt
a
Definition: bitmap.h:544
VL_MSG_API_REAPER_FUNCTION(application_reaper_cb)
#define TRANSPORT_N_PROTOS
Definition: session.h:216
uword ssvm_size
Definition: ssvm.h:84
void ip_prefix_decode(const vl_api_prefix_t *in, fib_prefix_t *out)
Definition: ip_types_api.c:259
transport_proto
Definition: session.api:22
svm_fifo_t * tx_fifo
struct _session_rules_table_t session_rules_table_t
#define ntohs(x)
Definition: af_xdp.bpf.c:29
u32 ns_index
Namespace the application belongs to.
Definition: application.h:116
vl_api_transport_proto_t transport_proto
Definition: session.api:310
Application add TLS key WILL BE DEPRECATED POST 20.01
Definition: session.api:142
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:527
static void sapi_send_fds(app_worker_t *app_wrk, int *fds, int n_fds)
Definition: session_api.c:1221
static void vl_api_app_namespace_add_del_t_handler(vl_api_app_namespace_add_del_t *mp)
Definition: session_api.c:797
int vnet_app_namespace_add_del(vnet_app_namespace_add_del_args_t *a)
u32 app_namespace_index(app_namespace_t *app_ns)
unsigned long u64
Definition: types.h:89
static svm_msg_q_t * session_main_get_vpp_event_queue(u32 thread_index)
Definition: session.h:645
vl_api_transport_proto_t transport_proto
Definition: session.api:268
void ip_set(ip46_address_t *dst, void *src, u8 is_ip4)
Definition: ip.c:93
#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:192
#define REPLY_MACRO2(t, body)
u8 * session_rules_table_rule_tag(session_rules_table_t *srt, u32 ri, u8 is_ip4)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static clib_socket_t * appns_sapi_alloc_socket(app_namespace_t *app_ns)
transport_connection_t * session_get_transport(session_t *s)
Definition: session.c:1631
app_sapi_worker_add_del_msg_t worker_add_del
add/del session rule
Definition: session.api:265
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:35
vl_api_session_rule_scope_t scope
Definition: session.api:276
u64 private_data
Definition: file.h:64
u32 ip4_mask_to_preflen(ip4_address_t *mask)
Definition: ip_types.c:501
fifo_segment_t * segment_manager_get_segment_w_handle(u64 segment_handle)
Session rules details.
Definition: session.api:307
static u32 appns_sapi_socket_index(app_namespace_t *app_ns, clib_socket_t *cs)
static session_t * listen_session_get_from_handle(session_handle_t handle)
Definition: session.h:583
int vnet_app_del_cert_key_pair(u32 index)
Definition: application.c:1727
u32 file_descriptor
Definition: file.h:54
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
application_t * application_lookup(u32 api_client_index)
Definition: application.c:394
static int mq_send_del_segment_cb(u32 app_wrk_index, u64 segment_handle)
Definition: session_api.c:512
u32 wrk_map_index
Worker index in app&#39;s map pool.
Definition: application.h:40
u16 key_len
Definition: ikev2_types.api:95
app_sapi_msg_type_e type
vlib_main_t * vm
Definition: in2out_ed.c:1580
#define foreach_session_api_msg
Definition: session_api.c:45
static clib_socket_t * appns_sapi_get_socket(app_namespace_t *app_ns, u32 sock_index)
u32 flags
Session flags.
u16 mask
Definition: flow_types.api:52
void * vl_msg_api_alloc(int nbytes)
unsigned char u8
Definition: types.h:56
app_worker_t * application_get_worker(application_t *app, u32 wrk_map_index)
Definition: application.c:652
static void sapi_socket_detach(app_namespace_t *app_ns, clib_socket_t *cs)
Definition: session_api.c:1516
application_t * application_get_if_valid(u32 app_index)
Definition: application.c:434
__clib_export clib_error_t * clib_socket_init(clib_socket_t *s)
Definition: socket.c:384
segment_manager_props_t * application_segment_manager_properties(application_t *app)
Definition: application.c:1311
clib_file_function_t * read_function
Definition: file.h:67
#define vlib_worker_thread_barrier_sync(X)
Definition: threads.h:205
static session_handle_t session_handle(session_t *s)
void session_get_endpoint(session_t *s, transport_endpoint_t *tep, u8 is_lcl)
Definition: session.c:1642
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:668
#define CLIB_SOCKET_F_IS_SERVER
Definition: socket.h:58
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:179
app_sapi_worker_add_del_reply_msg_t worker_add_del_reply
int application_is_proxy(application_t *app)
Definition: application.c:1141
static void mq_send_session_reset_cb(session_t *s)
Definition: session_api.c:247
static clib_file_t * clib_file_get(clib_file_main_t *fm, u32 file_index)
Definition: file.h:152
static void vl_api_session_enable_disable_t_handler(vl_api_session_enable_disable_t *mp)
Definition: session_api.c:587
static char * vlib_unix_get_runtime_dir(void)
Definition: unix.h:143
Application attach reply.
Definition: session.api:59
u32 session_index
global listening session index
Definition: application.h:89
static clib_error_t * clib_socket_sendmsg(clib_socket_t *s, void *msg, int msglen, int fds[], int num_fds)
Definition: socket.h:151
vl_api_registration_t * vl_mem_api_client_index_to_registration(u32 handle)
Definition: memory_api.c:765
description fragment has unexpected format
Definition: map.api:433
static clib_error_t * sapi_sock_write_ready(clib_file_t *cf)
Definition: session_api.c:1588
add/del application namespace
Definition: session.api:217
Aggregate type for a prefix.
Definition: fib_types.h:202
static void vl_api_application_tls_cert_add_t_handler(vl_api_application_tls_cert_add_t *mp)
Definition: session_api.c:1091
static u32 appns_sapi_socket_handle(app_namespace_t *app_ns, clib_socket_t *cs)
clib_file_main_t file_main
Definition: main.c:63
static clib_error_t * clib_socket_recvmsg(clib_socket_t *s, void *msg, int msglen, int fds[], int num_fds)
Definition: socket.h:158
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:873
u32 app_namespace_index_from_id(const u8 *ns_id)
u16 fp_len
The mask length.
Definition: fib_types.h:206
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:692
static void appns_sapi_free_socket(app_namespace_t *app_ns, clib_socket_t *cs)
Definition: cJSON.c:84
static void mq_send_session_cleanup_cb(session_t *s, session_cleanup_ntf_t ntf)
Definition: session_api.c:545
u8 * description
Definition: file.h:70
static void sapi_add_del_worker_handler(app_namespace_t *app_ns, clib_socket_t *cs, app_sapi_worker_add_del_msg_t *mp)
Definition: session_api.c:1435
session_t * app_listener_get_local_session(app_listener_t *al)
Definition: application.c:289
#define VL_API_INVALID_FI
Definition: api_common.h:78
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:225
session_t * app_listener_get_session(app_listener_t *al)
Definition: application.c:280
bool is_add[default=true]
Definition: session.api:274
struct _session_rule_add_del_args session_rule_add_del_args_t
static clib_error_t * clib_socket_close(clib_socket_t *sock)
Definition: socket.h:175
unsigned short u16
Definition: types.h:57
static int session_send_fds(vl_api_registration_t *reg, int fds[], int n_fds)
Definition: session_api.c:95
#define APP_INVALID_INDEX
Definition: application.h:178
static void vl_api_session_rules_dump_t_handler(vl_api_session_rules_dump_t *mp)
Definition: session_api.c:996
int vnet_session_rule_add_del(session_rule_add_del_args_t *args)
#define PREDICT_FALSE(x)
Definition: clib.h:121
#define REPLY_MACRO(t)
app_namespace_t * app_namespace_get(u32 index)
static clib_error_t * application_reaper_cb(u32 client_index)
Definition: session_api.c:1157
u32 wrk_index
Worker index in global worker pool.
Definition: application.h:37
app_worker_t * app_worker_get_if_valid(u32 wrk_index)
#define SESSION_INVALID_INDEX
Definition: session_types.h:22
static void sapi_socket_close_w_handle(u32 api_handle)
Definition: session_api.c:1414
u64 session_segment_handle(session_t *s)
Definition: session.c:1561
clib_error_t * vnet_session_enable_disable(vlib_main_t *vm, u8 is_en)
Definition: session.c:1793
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:575
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:227
int vnet_application_attach(vnet_app_attach_args_t *a)
Attach application to vpp.
Definition: application.c:816
bool is_local
Definition: ikev2_types.api:33
static int mq_try_lock_and_alloc_msg(svm_msg_q_t *app_mq, svm_msg_q_msg_t *msg)
Definition: session_api.c:110
An API client registration, only in vpp/vlib.
Definition: api_common.h:47
Add certificate and key.
Definition: session.api:90
static clib_error_t * sapi_sock_read_ready(clib_file_t *cf)
Definition: session_api.c:1541
ssvm_private_t ssvm
ssvm segment data
Definition: fifo_segment.h:68
session_handle_t listener_handle
Parent listener session index if the result of an accept.
session_t * app_worker_first_listener(app_worker_t *app, u8 fib_proto, u8 transport_proto)
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
__clib_export clib_error_t * clib_socket_accept(clib_socket_t *server, clib_socket_t *client)
Definition: socket.c:526
static clib_error_t * sapi_sock_accept_ready(clib_file_t *scf)
Definition: session_api.c:1612
#define clib_warning(format, args...)
Definition: error.h:59
static int mq_send_del_segment_sapi_cb(u32 app_wrk_index, u64 segment_handle)
Definition: session_api.c:1293
struct _transport_connection transport_connection_t
static void mq_send_session_disconnected_cb(session_t *s)
Definition: session_api.c:233
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:957
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:79
static clib_error_t * vl_api_send_fd_msg(vl_api_registration_t *reg, int fds[], int n_fds)
Definition: api.h:107
static u32 vl_api_registration_file_index(vl_api_registration_t *reg)
Definition: api.h:87
struct _app_namespace app_namespace_t
application_t * application_get(u32 app_index)
Definition: application.c:426
vl_api_interface_index_t sw_if_index[default=0xffffffff]
Definition: session.api:221
static u32 session_thread_from_handle(session_handle_t handle)
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:915
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
#define ASSERT(truth)
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:198
bool is_enable[default=true]
Definition: session.api:201
session_t * ct_session_get_peer(session_t *s)
Reply for app namespace add/del.
Definition: session.api:232
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
Definition: file.h:96
Application detach from session layer.
Definition: session.api:77
app_sapi_attach_msg_t attach
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:423
static u32 appns_sapi_handle_sock_index(u32 sapi_sock_handle)
int vnet_application_detach(vnet_app_detach_args_t *a)
Detach application from vpp.
Definition: application.c:886
int appns_sapi_add_ns_socket(app_namespace_t *app_ns)
Definition: session_api.c:1663
enum _transport_proto transport_proto_t
#define clib_error_report(e)
Definition: error.h:113
struct _vnet_app_add_cert_key_pair_args_ vnet_app_add_cert_key_pair_args_t
struct _socket_t clib_socket_t
static int mq_send_session_accepted_cb(session_t *s)
Definition: session_api.c:129
vl_api_session_rule_scope_t scope
Definition: session.api:317
static void vl_api_app_attach_t_handler(vl_api_app_attach_t *mp)
Definition: session_api.c:598
u32 ip6_mask_to_preflen(ip6_address_t *mask)
Definition: ip_types.c:563
struct _vnet_app_detach_args_t vnet_app_detach_args_t
static uword pointer_to_uword(const void *p)
Definition: types.h:131
#define CLIB_SOCKET_F_SEQPACKET
Definition: socket.h:63
static void vl_api_app_add_cert_key_pair_t_handler(vl_api_app_add_cert_key_pair_t *mp)
Definition: session_api.c:1020
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 transport_proto_t api_session_transport_proto_decode(const vl_api_transport_proto_t *api_tp)
Definition: session_api.c:59
void ip_prefix_encode(const fib_prefix_t *in, vl_api_prefix_t *out)
Definition: ip_types_api.c:287
static void setup_message_id_table(api_main_t *am)
Definition: session_api.c:1177
u32 app_index
App index in app pool.
Definition: application.h:98
static u8 session_type_is_ip4(session_type_t st)
static session_cb_vft_t session_mq_cb_vft
Definition: session_api.c:575
add/del application worker
Definition: session.api:158
clib_error_t * vlib_unix_recursive_mkdir(char *path)
Definition: util.c:103
int mq_send_session_connected_cb(u32 app_wrk_index, u32 api_context, session_t *s, session_error_t err)
Definition: session_api.c:260
app_worker_t * app_worker_get(u32 wrk_index)
u64 session_handle_t
static clib_error_t * sapi_sock_error(clib_file_t *cf)
Definition: session_api.c:1596
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void vlib_rpc_call_main_thread(void *callback, u8 *args, u32 arg_size)
Definition: threads.c:1945
volatile u8 session_state
State in session layer state machine.
#define STATIC_ASSERT(truth,...)
#define CLIB_SOCKET_F_PASSCRED
Definition: socket.h:64
static void vl_api_application_tls_key_add_t_handler(vl_api_application_tls_key_add_t *mp)
Definition: session_api.c:1125
ssvm_private_t * session_main_get_evt_q_segment(void)
Definition: session.c:1555
connectionless service
static vl_api_transport_proto_t api_session_transport_proto_encode(const transport_proto_t tp)
Definition: session_api.c:77
VLIB_API_INIT_FUNCTION(session_api_hookup)
#define clib_error_free(e)
Definition: error.h:86
session_cleanup_ntf_t
struct _session_lookup_table session_table_t
int vnet_app_worker_add_del(vnet_app_worker_add_del_args_t *a)
Definition: application.c:724
static void vl_api_application_detach_t_handler(vl_api_application_detach_t *mp)
Definition: session_api.c:771
static u8 session_has_transport(session_t *s)
struct _session_rules_table_add_del_args session_rule_table_add_del_args_t
u8 appns_sapi_enabled(void)
u32 app_index
Index of owning app.
Definition: application.h:43
static api_main_t * vlibapi_get_main(void)
Definition: api_common.h:389
static u8 svm_fifo_n_subscribers(svm_fifo_t *f)
Fifo number of subscribers getter.
Definition: svm_fifo.h:644
#define session_table_foreach(VAR, BODY)
Definition: session_table.h:74
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
Definition: threads.c:1561
Application add TLS certificate WILL BE DEPRECATED POST 20.01
Definition: session.api:127
static u32 vlib_num_workers()
Definition: threads.h:377
static session_cb_vft_t session_mq_sapi_cb_vft
Definition: session_api.c:1318
enum session_error_ session_error_t
transport_endpoint_t lcl
u32 app_wrk_index
Index of the app worker that owns the session.
Dump session rules.
Definition: session.api:284
Definition: file.h:51
static void vl_api_session_rule_add_del_t_handler(vl_api_session_rule_add_del_t *mp)
Definition: session_api.c:841
int(* session_accept_callback)(session_t *new_session)
Notify server of newly accepted session.
u32 api_client_index
API index for the worker.
Definition: application.h:63
int mq_send_session_bound_cb(u32 app_wrk_index, u32 api_context, session_handle_t handle, int rv)
Definition: session_api.c:340
#define CLIB_SOCKET_F_ALLOW_GROUP_WRITE
Definition: socket.h:62
static int mq_send_add_segment_sapi_cb(u32 app_wrk_index, u64 segment_handle)
Definition: session_api.c:1242
svm_msg_q_t * event_queue
Application listens for events on this svm queue.
Definition: application.h:46
static transport_service_type_t session_transport_service_type(session_t *s)
struct _svm_fifo svm_fifo_t
Application attach to session layer.
Definition: session.api:37
u8 * vl_api_from_api_to_new_vec(void *mp, vl_api_string_t *astr)
Definition: api_shared.c:1188
Delete certificate and key.
Definition: session.api:114
int vl_api_vec_to_api_string(const u8 *vec, vl_api_string_t *str)
Definition: api_shared.c:1161
static int mq_send_add_segment_cb(u32 app_wrk_index, u64 segment_handle)
Definition: session_api.c:450
non-blocking call - works with both condvar and eventfd signaling
Definition: queue.h:44
bool is_add[default=true]
Definition: session.api:164
static u8 session_main_is_enabled()
Definition: session.h:651
ssvm_segment_type_t ssvm_type(const ssvm_private_t *ssvm)
Definition: ssvm.c:451