LCOV - code coverage report
Current view: top level - vcl - vcl_bapi.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 214 398 53.8 %
Date: 2023-07-05 22:20:52 Functions: 20 30 66.7 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018-2019 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this
       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 <vcl/vcl_private.h>
      17             : #include <vlibmemory/api.h>
      18             : 
      19             : #include <vnet/format_fns.h>
      20             : #include <vnet/session/session.api_enum.h>
      21             : #include <vnet/session/session.api_types.h>
      22             : 
      23             : #define REPLY_MSG_ID_BASE msg_id_base
      24             : 
      25             : static u16 msg_id_base;
      26             : 
      27             : static u8 *
      28           0 : format_api_error (u8 * s, va_list * args)
      29             : {
      30           0 :   i32 error = va_arg (*args, u32);
      31             :   uword *p;
      32             : 
      33           0 :   p = hash_get (vcm->error_string_by_error_number, -error);
      34             : 
      35           0 :   if (p)
      36           0 :     s = format (s, "%s (%d)", p[0], error);
      37             :   else
      38           0 :     s = format (s, "%d", error);
      39           0 :   return s;
      40             : }
      41             : 
      42             : static void
      43          29 :   vl_api_session_enable_disable_reply_t_handler
      44             :   (vl_api_session_enable_disable_reply_t * mp)
      45             : {
      46          29 :   vcl_worker_t *wrk = vcl_worker_get (0);
      47             : 
      48          29 :   if (mp->retval)
      49             :     {
      50           0 :       clib_warning ("VCL<%d>: session_enable_disable failed: %U", getpid (),
      51             :                     format_api_error, ntohl (mp->retval));
      52             :     }
      53             :   else
      54          29 :     wrk->bapi_app_state = STATE_APP_ENABLED;
      55          29 : }
      56             : 
      57             : static void
      58          29 : vl_api_app_attach_reply_t_handler (vl_api_app_attach_reply_t * mp)
      59             : {
      60          29 :   vcl_worker_t *wrk = vcl_worker_get (0);
      61             :   u64 segment_handle;
      62          29 :   int *fds = 0, i, rv;
      63          29 :   u32 n_fds = 0;
      64          29 :   char *segment_name = 0;
      65             : 
      66          29 :   if (mp->retval)
      67             :     {
      68           0 :       VERR ("attach failed: %U", format_api_error, ntohl (mp->retval));
      69           0 :       goto failed;
      70             :     }
      71             : 
      72          29 :   vcl_set_worker_index (0);
      73             : 
      74          29 :   segment_handle = clib_net_to_host_u64 (mp->segment_handle);
      75          29 :   if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
      76             :     {
      77           0 :       VERR ("invalid segment handle");
      78           0 :       goto failed;
      79             :     }
      80             : 
      81          29 :   if (mp->n_fds)
      82             :     {
      83          29 :       vec_validate (fds, mp->n_fds);
      84          29 :       if (vl_socket_client_recv_fd_msg2 (&wrk->bapi_sock_ctx, fds, mp->n_fds,
      85             :                                          5))
      86           0 :         goto failed;
      87             : 
      88          29 :       if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
      89          29 :         if (vcl_segment_attach (vcl_vpp_worker_segment_handle (0),
      90             :                                 "vpp-mq-seg", SSVM_SEGMENT_MEMFD,
      91          29 :                                 fds[n_fds++]))
      92           0 :           goto failed;
      93             : 
      94          29 :       if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
      95             :         {
      96          29 :           segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name);
      97             :           rv =
      98          29 :             vcl_segment_attach (segment_handle, segment_name,
      99          29 :                                 SSVM_SEGMENT_MEMFD, fds[n_fds++]);
     100          29 :           vec_free (segment_name);
     101          29 :           if (rv != 0)
     102           0 :             goto failed;
     103             :         }
     104             : 
     105          29 :       vcl_segment_attach_mq (segment_handle, mp->app_mq, 0,
     106             :                              &wrk->app_event_queue);
     107             : 
     108          29 :       if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
     109             :         {
     110           0 :           svm_msg_q_set_eventfd (wrk->app_event_queue, fds[n_fds]);
     111           0 :           vcl_mq_epoll_add_evfd (wrk, wrk->app_event_queue);
     112           0 :           n_fds++;
     113             :         }
     114             : 
     115          29 :       vcl_segment_discover_mqs (vcl_vpp_worker_segment_handle (0), fds + n_fds,
     116          29 :                                 mp->n_fds - n_fds);
     117          29 :       vcl_segment_attach_mq (vcl_vpp_worker_segment_handle (0),
     118          29 :                              mp->vpp_ctrl_mq, mp->vpp_ctrl_mq_thread,
     119             :                              &wrk->ctrl_mq);
     120          29 :       vcm->ctrl_mq = wrk->ctrl_mq;
     121             : 
     122          29 :       vec_free (fds);
     123             :     }
     124             :   else
     125             :     {
     126           0 :       segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name);
     127             :       rv =
     128           0 :         vcl_segment_attach (segment_handle, segment_name, SSVM_SEGMENT_SHM,
     129             :                             -1);
     130           0 :       vec_free (segment_name);
     131           0 :       if (rv != 0)
     132           0 :         goto failed;
     133             :     }
     134             : 
     135          29 :   vcm->app_index = clib_net_to_host_u32 (mp->app_index);
     136          29 :   wrk->bapi_app_state = STATE_APP_ATTACHED;
     137          29 :   return;
     138             : 
     139           0 : failed:
     140           0 :   wrk->bapi_app_state = STATE_APP_FAILED;
     141           0 :   for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++)
     142           0 :     close (fds[i]);
     143           0 :   vec_free (fds);
     144             : }
     145             : 
     146             : static void
     147          11 : vl_api_app_worker_add_del_reply_t_handler (vl_api_app_worker_add_del_reply_t *
     148             :                                            mp)
     149             : {
     150          11 :   int n_fds = 0, *fds = 0, i, rv;
     151             :   u64 segment_handle;
     152             :   vcl_worker_t *wrk;
     153             :   u32 wrk_index;
     154          11 :   char *segment_name = 0;
     155             : 
     156          11 :   if (!mp->is_add)
     157          11 :     return;
     158             : 
     159           0 :   wrk_index = mp->context;
     160           0 :   wrk = vcl_worker_get_if_valid (wrk_index);
     161           0 :   if (!wrk)
     162           0 :     return;
     163             : 
     164           0 :   if (mp->retval)
     165             :     {
     166           0 :       clib_warning ("VCL<%d>: add/del worker failed: %U", getpid (),
     167             :                     format_api_error, ntohl (mp->retval));
     168           0 :       goto failed;
     169             :     }
     170             : 
     171           0 :   vcl_set_worker_index (wrk_index);
     172           0 :   wrk->vpp_wrk_index = clib_net_to_host_u32 (mp->wrk_index);
     173           0 :   wrk->ctrl_mq = vcm->ctrl_mq;
     174             : 
     175           0 :   segment_handle = clib_net_to_host_u64 (mp->segment_handle);
     176           0 :   if (segment_handle == VCL_INVALID_SEGMENT_HANDLE)
     177             :     {
     178           0 :       clib_warning ("invalid segment handle");
     179           0 :       goto failed;
     180             :     }
     181             : 
     182           0 :   if (mp->n_fds)
     183             :     {
     184           0 :       vec_validate (fds, mp->n_fds);
     185           0 :       if (vl_socket_client_recv_fd_msg2 (&wrk->bapi_sock_ctx, fds, mp->n_fds,
     186             :                                          5))
     187           0 :         goto failed;
     188             : 
     189           0 :       if (mp->fd_flags & SESSION_FD_F_VPP_MQ_SEGMENT)
     190           0 :         if (vcl_segment_attach (vcl_vpp_worker_segment_handle (wrk_index),
     191             :                                 "vpp-worker-seg", SSVM_SEGMENT_MEMFD,
     192           0 :                                 fds[n_fds++]))
     193           0 :           goto failed;
     194             : 
     195           0 :       if (mp->fd_flags & SESSION_FD_F_MEMFD_SEGMENT)
     196             :         {
     197           0 :           segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name);
     198             :           rv =
     199           0 :             vcl_segment_attach (segment_handle, segment_name,
     200           0 :                                 SSVM_SEGMENT_MEMFD, fds[n_fds++]);
     201           0 :           vec_free (segment_name);
     202           0 :           if (rv != 0)
     203           0 :             goto failed;
     204             :         }
     205             : 
     206           0 :       vcl_segment_attach_mq (segment_handle, mp->app_event_queue_address, 0,
     207             :                              &wrk->app_event_queue);
     208             : 
     209           0 :       if (mp->fd_flags & SESSION_FD_F_MQ_EVENTFD)
     210             :         {
     211           0 :           svm_msg_q_set_eventfd (wrk->app_event_queue, fds[n_fds]);
     212           0 :           vcl_mq_epoll_add_evfd (wrk, wrk->app_event_queue);
     213           0 :           n_fds++;
     214             :         }
     215             : 
     216           0 :       vec_free (fds);
     217             :     }
     218             :   else
     219             :     {
     220           0 :       segment_name = vl_api_from_api_to_new_c_string (&mp->segment_name);
     221             :       rv =
     222           0 :         vcl_segment_attach (segment_handle, segment_name, SSVM_SEGMENT_SHM,
     223             :                             -1);
     224           0 :       vec_free (segment_name);
     225           0 :       if (rv != 0)
     226           0 :         goto failed;
     227             :     }
     228           0 :   wrk->bapi_app_state = STATE_APP_READY;
     229           0 :   VDBG (0, "worker %u vpp-worker %u added", wrk_index, wrk->vpp_wrk_index);
     230           0 :   return;
     231             : 
     232           0 : failed:
     233           0 :   wrk->bapi_app_state = STATE_APP_FAILED;
     234           0 :   for (i = clib_max (n_fds - 1, 0); i < vec_len (fds); i++)
     235           0 :     close (fds[i]);
     236           0 :   vec_free (fds);
     237             : }
     238             : 
     239             : static void
     240           2 : vl_api_app_add_cert_key_pair_reply_t_handler (
     241             :   vl_api_app_add_cert_key_pair_reply_t *mp)
     242             : {
     243           2 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     244             : 
     245           2 :   if (mp->retval)
     246             :     {
     247           0 :       VDBG (0, "Adding cert and key failed: %U", format_api_error,
     248             :             ntohl (mp->retval));
     249           0 :       return;
     250             :     }
     251           2 :   wrk->bapi_return = clib_net_to_host_u32 (mp->index);
     252           2 :   wrk->bapi_app_state = STATE_APP_READY;
     253             : }
     254             : 
     255             : static void
     256           0 : vl_api_app_del_cert_key_pair_reply_t_handler (
     257             :   vl_api_app_del_cert_key_pair_reply_t *mp)
     258             : {
     259           0 :   if (mp->retval)
     260             :     {
     261           0 :       VDBG (0, "Deleting cert and key failed: %U", format_api_error,
     262             :             ntohl (mp->retval));
     263           0 :       return;
     264             :     }
     265             : }
     266             : 
     267             : #define foreach_sock_msg                                                      \
     268             :   _ (SESSION_ENABLE_DISABLE_REPLY, session_enable_disable_reply)              \
     269             :   _ (APP_ATTACH_REPLY, app_attach_reply)                                      \
     270             :   _ (APP_ADD_CERT_KEY_PAIR_REPLY, app_add_cert_key_pair_reply)                \
     271             :   _ (APP_DEL_CERT_KEY_PAIR_REPLY, app_del_cert_key_pair_reply)                \
     272             :   _ (APP_WORKER_ADD_DEL_REPLY, app_worker_add_del_reply)
     273             : 
     274             : #define vl_endianfun          /* define message structures */
     275             : #include <vnet/session/session.api.h>
     276             : #undef vl_endianfun
     277             : 
     278             : #define vl_calcsizefun
     279             : #include <vnet/session/session.api.h>
     280             : #undef vl_calcsizefun
     281             : 
     282             : /* instantiate all the print functions we know about */
     283             : #define vl_printfun
     284             : #include <vnet/session/session.api.h>
     285             : #undef vl_printfun
     286             : 
     287             : #define vl_api_version(n, v) static u32 api_version = v;
     288             : #include <vnet/session/session.api.h>
     289             : #undef vl_api_version
     290             : 
     291             : static void
     292          29 : vcl_bapi_hookup (void)
     293             : {
     294          29 :   u8 *msg_base_lookup_name = format (0, "session_%08x%c", api_version, 0);
     295             : 
     296          29 :   REPLY_MSG_ID_BASE =
     297          29 :     vl_client_get_first_plugin_msg_id ((char *) msg_base_lookup_name);
     298             : 
     299          29 :   vec_free (msg_base_lookup_name);
     300             : 
     301          29 :   if (REPLY_MSG_ID_BASE == (u16) ~0)
     302           0 :     return;
     303             : 
     304             : #define _(N, n)                                                               \
     305             :   vl_msg_api_config (&(vl_msg_api_msg_config_t){                              \
     306             :     .id = REPLY_MSG_ID_BASE + VL_API_##N,                                     \
     307             :     .name = #n,                                                               \
     308             :     .handler = vl_api_##n##_t_handler,                                        \
     309             :     .endian = vl_api_##n##_t_endian,                                          \
     310             :     .format_fn = vl_api_##n##_t_format,                                       \
     311             :     .size = sizeof (vl_api_##n##_t),                                          \
     312             :     .traced = 1,                                                              \
     313             :     .tojson = vl_api_##n##_t_tojson,                                          \
     314             :     .fromjson = vl_api_##n##_t_fromjson,                                      \
     315             :     .calc_size = vl_api_##n##_t_calc_size,                                    \
     316             :   });
     317          29 :   foreach_sock_msg;
     318             : #undef _
     319             : }
     320             : 
     321             : /*
     322             :  * VPP-API message functions
     323             :  */
     324             : static void
     325          29 : vcl_bapi_send_session_enable_disable (u8 is_enable)
     326             : {
     327          29 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     328             :   vl_api_session_enable_disable_t *bmp;
     329          29 :   bmp = vl_msg_api_alloc (sizeof (*bmp));
     330          29 :   memset (bmp, 0, sizeof (*bmp));
     331             : 
     332          29 :   bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_SESSION_ENABLE_DISABLE);
     333          29 :   bmp->client_index = wrk->api_client_handle;
     334          29 :   bmp->context = htonl (0xfeedface);
     335          29 :   bmp->is_enable = is_enable;
     336          29 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & bmp);
     337          29 : }
     338             : 
     339             : void
     340          29 : vcl_bapi_send_attach (void)
     341             : {
     342          29 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     343          29 :   u8 tls_engine = CRYPTO_ENGINE_OPENSSL;
     344             :   vl_api_app_attach_t *bmp;
     345          29 :   u8 nsid_len = vec_len (vcm->cfg.namespace_id);
     346          58 :   u8 app_is_proxy = (vcm->cfg.app_proxy_transport_tcp ||
     347          29 :                      vcm->cfg.app_proxy_transport_udp);
     348             : 
     349          29 :   tls_engine = vcm->cfg.tls_engine ? vcm->cfg.tls_engine : tls_engine;
     350             : 
     351          29 :   bmp = vl_msg_api_alloc (sizeof (*bmp));
     352          29 :   memset (bmp, 0, sizeof (*bmp));
     353             : 
     354          29 :   bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_ATTACH);
     355          29 :   bmp->client_index = wrk->api_client_handle;
     356          29 :   bmp->context = htonl (0xfeedface);
     357          29 :   bmp->options[APP_OPTIONS_FLAGS] =
     358          29 :     APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT |
     359          29 :     (vcm->cfg.app_scope_local ? APP_OPTIONS_FLAGS_USE_LOCAL_SCOPE : 0) |
     360          29 :     (vcm->cfg.app_scope_global ? APP_OPTIONS_FLAGS_USE_GLOBAL_SCOPE : 0) |
     361          29 :     (app_is_proxy ? APP_OPTIONS_FLAGS_IS_PROXY : 0) |
     362          29 :     (vcm->cfg.use_mq_eventfd ? APP_OPTIONS_FLAGS_EVT_MQ_USE_EVENTFD : 0) |
     363          29 :     (vcm->cfg.huge_page ? APP_OPTIONS_FLAGS_USE_HUGE_PAGE : 0);
     364          29 :   bmp->options[APP_OPTIONS_PROXY_TRANSPORT] =
     365          58 :     (u64) ((vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) |
     366          29 :            (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0));
     367          29 :   bmp->options[APP_OPTIONS_SEGMENT_SIZE] = vcm->cfg.segment_size;
     368          29 :   bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = vcm->cfg.add_segment_size;
     369          29 :   bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = vcm->cfg.rx_fifo_size;
     370          29 :   bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = vcm->cfg.tx_fifo_size;
     371          29 :   bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
     372          29 :     vcm->cfg.preallocated_fifo_pairs;
     373          29 :   bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = vcm->cfg.event_queue_size;
     374          29 :   bmp->options[APP_OPTIONS_TLS_ENGINE] = tls_engine;
     375          29 :   if (nsid_len)
     376             :     {
     377          19 :       vl_api_vec_to_api_string (vcm->cfg.namespace_id, &bmp->namespace_id);
     378          19 :       bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = vcm->cfg.namespace_secret;
     379             :     }
     380          29 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & bmp);
     381          29 : }
     382             : 
     383             : void
     384           0 : vcl_bapi_send_detach (void)
     385             : {
     386           0 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     387             :   vl_api_application_detach_t *bmp;
     388           0 :   bmp = vl_msg_api_alloc (sizeof (*bmp));
     389           0 :   memset (bmp, 0, sizeof (*bmp));
     390             : 
     391           0 :   bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APPLICATION_DETACH);
     392           0 :   bmp->client_index = wrk->api_client_handle;
     393           0 :   bmp->context = htonl (0xfeedface);
     394           0 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & bmp);
     395           0 : }
     396             : 
     397             : static void
     398          11 : vcl_bapi_send_app_worker_add_del (u8 is_add)
     399             : {
     400          11 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     401             :   vl_api_app_worker_add_del_t *mp;
     402             : 
     403          11 :   mp = vl_msg_api_alloc (sizeof (*mp));
     404          11 :   memset (mp, 0, sizeof (*mp));
     405             : 
     406          11 :   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_WORKER_ADD_DEL);
     407          11 :   mp->client_index = wrk->api_client_handle;
     408          11 :   mp->app_index = clib_host_to_net_u32 (vcm->app_index);
     409          11 :   mp->context = wrk->wrk_index;
     410          11 :   mp->is_add = is_add;
     411          11 :   if (!is_add)
     412          11 :     mp->wrk_index = clib_host_to_net_u32 (wrk->vpp_wrk_index);
     413             : 
     414          11 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & mp);
     415          11 : }
     416             : 
     417             : static void
     418           0 : vcl_bapi_send_child_worker_del (vcl_worker_t * child_wrk)
     419             : {
     420           0 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     421             :   vl_api_app_worker_add_del_t *mp;
     422             : 
     423           0 :   mp = vl_msg_api_alloc (sizeof (*mp));
     424           0 :   memset (mp, 0, sizeof (*mp));
     425             : 
     426           0 :   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_WORKER_ADD_DEL);
     427           0 :   mp->client_index = wrk->api_client_handle;
     428           0 :   mp->app_index = clib_host_to_net_u32 (vcm->app_index);
     429           0 :   mp->context = wrk->wrk_index;
     430           0 :   mp->is_add = 0;
     431           0 :   mp->wrk_index = clib_host_to_net_u32 (child_wrk->vpp_wrk_index);
     432             : 
     433           0 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & mp);
     434           0 : }
     435             : 
     436             : static void
     437           2 : vcl_bapi_send_app_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
     438             : {
     439           2 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     440           2 :   u32 cert_len = ckpair->cert_len;
     441           2 :   u32 key_len = ckpair->key_len;
     442             :   vl_api_app_add_cert_key_pair_t *bmp;
     443             : 
     444           2 :   bmp = vl_msg_api_alloc (sizeof (*bmp) + cert_len + key_len);
     445           2 :   clib_memset (bmp, 0, sizeof (*bmp) + cert_len + key_len);
     446             : 
     447           2 :   bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_ADD_CERT_KEY_PAIR);
     448           2 :   bmp->client_index = wrk->api_client_handle;
     449           2 :   bmp->context = wrk->wrk_index;
     450           2 :   bmp->cert_len = clib_host_to_net_u16 (cert_len);
     451           2 :   bmp->certkey_len = clib_host_to_net_u16 (key_len + cert_len);
     452           2 :   clib_memcpy_fast (bmp->certkey, ckpair->cert, cert_len);
     453           2 :   clib_memcpy_fast (bmp->certkey + cert_len, ckpair->key, key_len);
     454             : 
     455           2 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp);
     456           2 : }
     457             : 
     458             : static void
     459           0 : vcl_bapi_send_app_del_cert_key_pair (u32 ckpair_index)
     460             : {
     461           0 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     462             :   vl_api_app_del_cert_key_pair_t *bmp;
     463           0 :   bmp = vl_msg_api_alloc (sizeof (*bmp));
     464           0 :   clib_memset (bmp, 0, sizeof (*bmp));
     465             : 
     466           0 :   bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_DEL_CERT_KEY_PAIR);
     467           0 :   bmp->client_index = wrk->api_client_handle;
     468           0 :   bmp->context = wrk->wrk_index;
     469           0 :   bmp->index = clib_host_to_net_u32 (ckpair_index);
     470           0 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp);
     471           0 : }
     472             : 
     473             : u32
     474           0 : vcl_bapi_max_nsid_len (void)
     475             : {
     476             :   vl_api_app_attach_t *mp;
     477           0 :   return (sizeof (mp->namespace_id) - 1);
     478             : }
     479             : 
     480             : static void
     481          29 : vcl_bapi_init_error_string_table (void)
     482             : {
     483          29 :   vcm->error_string_by_error_number = hash_create (0, sizeof (uword));
     484             : 
     485             : #define _(n, v, s) hash_set (vcm->error_string_by_error_number, -v, s);
     486          29 :   foreach_vnet_api_error;
     487             : #undef _
     488             : 
     489          29 :   hash_set (vcm->error_string_by_error_number, 99, "Misc");
     490          29 : }
     491             : 
     492             : static void
     493          29 : vcl_bapi_cleanup (void)
     494             : {
     495          29 :   socket_client_main_t *scm = &socket_client_main;
     496          29 :   api_main_t *am = vlibapi_get_main ();
     497             : 
     498          29 :   am->my_client_index = ~0;
     499          29 :   am->my_registration = 0;
     500          29 :   am->vl_input_queue = 0;
     501          29 :   am->msg_index_by_name_and_crc = 0;
     502          29 :   scm->socket_fd = 0;
     503             : 
     504          29 :   vl_client_api_unmap ();
     505          29 : }
     506             : 
     507             : static int
     508          29 : vcl_bapi_connect_to_vpp (void)
     509             : {
     510          29 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     511          29 :   vppcom_cfg_t *vcl_cfg = &vcm->cfg;
     512          29 :   int rv = VPPCOM_OK;
     513             :   api_main_t *am;
     514             :   u8 *wrk_name;
     515             : 
     516          29 :   wrk_name = format (0, "%v-wrk-%u%c", vcm->app_name, wrk->wrk_index, 0);
     517             : 
     518             :   /* Make sure api is cleaned up in case this is a connect from a
     519             :    * forked worker */
     520          29 :   vcl_bapi_cleanup ();
     521             : 
     522          29 :   vlibapi_set_main (&wrk->bapi_api_ctx);
     523          29 :   vlibapi_set_memory_client_main (&wrk->bapi_mem_ctx);
     524             : 
     525          29 :   if (!vcl_cfg->vpp_bapi_socket_name)
     526             :     {
     527           0 :       rv = VPPCOM_EINVAL;
     528           0 :       goto error;
     529             :     }
     530             : 
     531          29 :   if (vl_socket_client_connect2 (&wrk->bapi_sock_ctx,
     532          29 :                                  (char *) vcl_cfg->vpp_bapi_socket_name,
     533             :                                  (char *) wrk_name,
     534             :                                  0 /* default rx/tx buffer */ ))
     535             :     {
     536           0 :       VERR ("app (%s) socket connect failed!", wrk_name);
     537           0 :       rv = VPPCOM_ECONNREFUSED;
     538           0 :       goto error;
     539             :     }
     540             : 
     541          29 :   if (vl_socket_client_init_shm2 (&wrk->bapi_sock_ctx, 0,
     542             :                                   1 /* want_pthread */ ))
     543             :     {
     544           0 :       VERR ("app (%s) init shm failed!", wrk_name);
     545           0 :       rv = VPPCOM_ECONNREFUSED;
     546           0 :       goto error;
     547             :     }
     548          29 :   vcl_bapi_hookup ();
     549             : 
     550          29 :   am = vlibapi_get_main ();
     551          29 :   wrk->vl_input_queue = am->shmem_hdr->vl_input_queue;
     552          29 :   wrk->api_client_handle = (u32) am->my_client_index;
     553             : 
     554          29 :   VDBG (0, "app (%s) is connected to VPP!", wrk_name);
     555             :   vcl_evt (VCL_EVT_INIT, vcm);
     556             : 
     557           0 : error:
     558          29 :   vec_free (wrk_name);
     559          29 :   return rv;
     560             : }
     561             : 
     562             : void
     563          29 : vcl_bapi_disconnect_from_vpp (void)
     564             : {
     565          29 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     566          29 :   vppcom_cfg_t *vcl_cfg = &vcm->cfg;
     567             : 
     568          29 :   if (vcl_cfg->vpp_bapi_socket_name)
     569          29 :     vl_socket_client_disconnect2 (&wrk->bapi_sock_ctx);
     570             :   else
     571           0 :     vl_client_disconnect_from_vlib ();
     572          29 : }
     573             : 
     574             : static const char *
     575           0 : vcl_bapi_app_state_str (vcl_bapi_app_state_t state)
     576             : {
     577             :   char *st;
     578             : 
     579           0 :   switch (state)
     580             :     {
     581           0 :     case STATE_APP_START:
     582           0 :       st = "STATE_APP_START";
     583           0 :       break;
     584             : 
     585           0 :     case STATE_APP_CONN_VPP:
     586           0 :       st = "STATE_APP_CONN_VPP";
     587           0 :       break;
     588             : 
     589           0 :     case STATE_APP_ENABLED:
     590           0 :       st = "STATE_APP_ENABLED";
     591           0 :       break;
     592             : 
     593           0 :     case STATE_APP_ATTACHED:
     594           0 :       st = "STATE_APP_ATTACHED";
     595           0 :       break;
     596             : 
     597           0 :     default:
     598           0 :       st = "UNKNOWN_APP_STATE";
     599           0 :       break;
     600             :     }
     601             : 
     602           0 :   return st;
     603             : }
     604             : 
     605             : static int
     606          60 : vcl_bapi_wait_for_wrk_state_change (vcl_bapi_app_state_t app_state)
     607             : {
     608          60 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     609          60 :   f64 timeout = clib_time_now (&wrk->clib_time) + vcm->cfg.app_timeout;
     610             : 
     611      621052 :   while (clib_time_now (&wrk->clib_time) < timeout)
     612             :     {
     613      621052 :       if (wrk->bapi_app_state == app_state)
     614          60 :         return VPPCOM_OK;
     615      620992 :       if (wrk->bapi_app_state == STATE_APP_FAILED)
     616           0 :         return VPPCOM_ECONNABORTED;
     617             :     }
     618           0 :   VDBG (0, "timeout waiting for state %s, current state %d",
     619             :         vcl_bapi_app_state_str (app_state), wrk->bapi_app_state);
     620             :   vcl_evt (VCL_EVT_SESSION_TIMEOUT, vcm, bapi_app_state);
     621             : 
     622           0 :   return VPPCOM_ETIMEDOUT;
     623             : }
     624             : 
     625             : static int
     626          29 : vcl_bapi_session_enable (void)
     627             : {
     628          29 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     629             :   int rv;
     630             : 
     631          29 :   if (wrk->bapi_app_state != STATE_APP_ENABLED)
     632             :     {
     633          29 :       vcl_bapi_send_session_enable_disable (1 /* is_enabled == TRUE */ );
     634          29 :       rv = vcl_bapi_wait_for_wrk_state_change (STATE_APP_ENABLED);
     635          29 :       if (PREDICT_FALSE (rv))
     636             :         {
     637           0 :           VDBG (0, "application session enable timed out! returning %d (%s)",
     638             :                 rv, vppcom_retval_str (rv));
     639           0 :           return rv;
     640             :         }
     641             :     }
     642          29 :   return VPPCOM_OK;
     643             : }
     644             : 
     645             : static int
     646          29 : vcl_bapi_init (void)
     647             : {
     648          29 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     649             :   int rv;
     650             : 
     651          29 :   wrk->bapi_app_state = STATE_APP_START;
     652          29 :   vcl_bapi_init_error_string_table ();
     653          29 :   rv = vcl_bapi_connect_to_vpp ();
     654          29 :   if (rv)
     655             :     {
     656           0 :       VERR ("couldn't connect to VPP!");
     657           0 :       return rv;
     658             :     }
     659          29 :   VDBG (0, "sending session enable");
     660          29 :   rv = vcl_bapi_session_enable ();
     661          29 :   if (rv)
     662             :     {
     663           0 :       VERR ("vppcom_app_session_enable() failed!");
     664           0 :       return rv;
     665             :     }
     666             : 
     667          29 :   return 0;
     668             : }
     669             : 
     670             : int
     671          29 : vcl_bapi_attach (void)
     672             : {
     673             :   int rv;
     674             : 
     675             :   /* API hookup and connect to VPP */
     676          29 :   if ((rv = vcl_bapi_init ()))
     677           0 :     return rv;
     678             : 
     679          29 :   vcl_bapi_send_attach ();
     680          29 :   rv = vcl_bapi_wait_for_wrk_state_change (STATE_APP_ATTACHED);
     681          29 :   if (PREDICT_FALSE (rv))
     682             :     {
     683           0 :       VDBG (0, "application attach timed out! returning %d (%s)", rv,
     684             :             vppcom_retval_str (rv));
     685           0 :       return rv;
     686             :     }
     687             : 
     688          29 :   return 0;
     689             : }
     690             : 
     691             : int
     692           0 : vcl_bapi_app_worker_add (void)
     693             : {
     694           0 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     695             : 
     696           0 :   if (vcl_bapi_connect_to_vpp ())
     697           0 :     return -1;
     698             : 
     699           0 :   wrk->bapi_app_state = STATE_APP_ADDING_WORKER;
     700           0 :   vcl_bapi_send_app_worker_add_del (1 /* is_add */ );
     701           0 :   if (vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY))
     702           0 :     return -1;
     703           0 :   return 0;
     704             : }
     705             : 
     706             : void
     707          11 : vcl_bapi_app_worker_del (vcl_worker_t * wrk)
     708             : {
     709             :   /* Notify vpp that the worker is going away */
     710          11 :   if (wrk->wrk_index == vcl_get_worker_index ())
     711          11 :     vcl_bapi_send_app_worker_add_del (0 /* is_add */ );
     712             :   else
     713           0 :     vcl_bapi_send_child_worker_del (wrk);
     714             : 
     715             :   /* Disconnect the binary api */
     716          11 :   if (vec_len (vcm->workers) == 1)
     717          11 :     vcl_bapi_disconnect_from_vpp ();
     718             :   else
     719           0 :     vl_client_send_disconnect (1 /* vpp should cleanup */ );
     720          11 : }
     721             : 
     722             : int
     723          30 : vcl_bapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds)
     724             : {
     725             :   clib_error_t *err;
     726             : 
     727          30 :   if ((err = vl_socket_client_recv_fd_msg2 (&wrk->bapi_sock_ctx, fds, n_fds,
     728             :                                             5)))
     729             :     {
     730           0 :       clib_error_report (err);
     731           0 :       return -1;
     732             :     }
     733             : 
     734          30 :   return 0;
     735             : }
     736             : 
     737             : int
     738           2 : vcl_bapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
     739             : {
     740           2 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     741             : 
     742           2 :   if (ckpair->key_len == 0 || ckpair->key_len == ~0)
     743           0 :     return VPPCOM_EINVAL;
     744             : 
     745           2 :   vcl_bapi_send_app_add_cert_key_pair (ckpair);
     746           2 :   wrk->bapi_app_state = STATE_APP_ADDING_TLS_DATA;
     747           2 :   vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY);
     748           2 :   if (wrk->bapi_app_state == STATE_APP_READY)
     749           2 :     return wrk->bapi_return;
     750           0 :   return VPPCOM_EFAULT;
     751             : }
     752             : 
     753             : int
     754           0 : vcl_bapi_del_cert_key_pair (u32 ckpair_index)
     755             : {
     756             :   /* Don't wait for reply */
     757           0 :   vcl_bapi_send_app_del_cert_key_pair (ckpair_index);
     758           0 :   return 0;
     759             : }
     760             : 
     761             : int
     762           0 : vcl_bapi_worker_set (void)
     763             : {
     764           0 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     765             :   int i;
     766             : 
     767             :   /* Find the first worker with the same pid */
     768           0 :   for (i = 0; i < vec_len (vcm->workers); i++)
     769             :     {
     770           0 :       if (i == wrk->wrk_index)
     771           0 :         continue;
     772           0 :       if (vcm->workers[i].current_pid == wrk->current_pid)
     773             :         {
     774           0 :           wrk->vl_input_queue = vcm->workers[i].vl_input_queue;
     775           0 :           wrk->api_client_handle = vcm->workers[i].api_client_handle;
     776           0 :           return 0;
     777             :         }
     778             :     }
     779           0 :   return -1;
     780             : }
     781             : 
     782             : /*
     783             :  * fd.io coding-style-patch-verification: ON
     784             :  *
     785             :  * Local Variables:
     786             :  * eval: (c-set-style "gnu")
     787             :  * End:
     788             :  */

Generated by: LCOV version 1.14