LCOV - code coverage report
Current view: top level - vcl - vcl_bapi.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 215 399 53.9 %
Date: 2023-10-26 01:39:38 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 :     (vcm->cfg.app_original_dst ? APP_OPTIONS_FLAGS_GET_ORIGINAL_DST : 0);
     365          29 :   bmp->options[APP_OPTIONS_PROXY_TRANSPORT] =
     366          58 :     (u64) ((vcm->cfg.app_proxy_transport_tcp ? 1 << TRANSPORT_PROTO_TCP : 0) |
     367          29 :            (vcm->cfg.app_proxy_transport_udp ? 1 << TRANSPORT_PROTO_UDP : 0));
     368          29 :   bmp->options[APP_OPTIONS_SEGMENT_SIZE] = vcm->cfg.segment_size;
     369          29 :   bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = vcm->cfg.add_segment_size;
     370          29 :   bmp->options[APP_OPTIONS_RX_FIFO_SIZE] = vcm->cfg.rx_fifo_size;
     371          29 :   bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = vcm->cfg.tx_fifo_size;
     372          29 :   bmp->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] =
     373          29 :     vcm->cfg.preallocated_fifo_pairs;
     374          29 :   bmp->options[APP_OPTIONS_EVT_QUEUE_SIZE] = vcm->cfg.event_queue_size;
     375          29 :   bmp->options[APP_OPTIONS_TLS_ENGINE] = tls_engine;
     376          29 :   if (nsid_len)
     377             :     {
     378          19 :       vl_api_vec_to_api_string (vcm->cfg.namespace_id, &bmp->namespace_id);
     379          19 :       bmp->options[APP_OPTIONS_NAMESPACE_SECRET] = vcm->cfg.namespace_secret;
     380             :     }
     381          29 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & bmp);
     382          29 : }
     383             : 
     384             : void
     385           0 : vcl_bapi_send_detach (void)
     386             : {
     387           0 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     388             :   vl_api_application_detach_t *bmp;
     389           0 :   bmp = vl_msg_api_alloc (sizeof (*bmp));
     390           0 :   memset (bmp, 0, sizeof (*bmp));
     391             : 
     392           0 :   bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APPLICATION_DETACH);
     393           0 :   bmp->client_index = wrk->api_client_handle;
     394           0 :   bmp->context = htonl (0xfeedface);
     395           0 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & bmp);
     396           0 : }
     397             : 
     398             : static void
     399          11 : vcl_bapi_send_app_worker_add_del (u8 is_add)
     400             : {
     401          11 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     402             :   vl_api_app_worker_add_del_t *mp;
     403             : 
     404          11 :   mp = vl_msg_api_alloc (sizeof (*mp));
     405          11 :   memset (mp, 0, sizeof (*mp));
     406             : 
     407          11 :   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_WORKER_ADD_DEL);
     408          11 :   mp->client_index = wrk->api_client_handle;
     409          11 :   mp->app_index = clib_host_to_net_u32 (vcm->app_index);
     410          11 :   mp->context = wrk->wrk_index;
     411          11 :   mp->is_add = is_add;
     412          11 :   if (!is_add)
     413          11 :     mp->wrk_index = clib_host_to_net_u32 (wrk->vpp_wrk_index);
     414             : 
     415          11 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & mp);
     416          11 : }
     417             : 
     418             : static void
     419           0 : vcl_bapi_send_child_worker_del (vcl_worker_t * child_wrk)
     420             : {
     421           0 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     422             :   vl_api_app_worker_add_del_t *mp;
     423             : 
     424           0 :   mp = vl_msg_api_alloc (sizeof (*mp));
     425           0 :   memset (mp, 0, sizeof (*mp));
     426             : 
     427           0 :   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_WORKER_ADD_DEL);
     428           0 :   mp->client_index = wrk->api_client_handle;
     429           0 :   mp->app_index = clib_host_to_net_u32 (vcm->app_index);
     430           0 :   mp->context = wrk->wrk_index;
     431           0 :   mp->is_add = 0;
     432           0 :   mp->wrk_index = clib_host_to_net_u32 (child_wrk->vpp_wrk_index);
     433             : 
     434           0 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) & mp);
     435           0 : }
     436             : 
     437             : static void
     438           2 : vcl_bapi_send_app_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
     439             : {
     440           2 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     441           2 :   u32 cert_len = ckpair->cert_len;
     442           2 :   u32 key_len = ckpair->key_len;
     443             :   vl_api_app_add_cert_key_pair_t *bmp;
     444             : 
     445           2 :   bmp = vl_msg_api_alloc (sizeof (*bmp) + cert_len + key_len);
     446           2 :   clib_memset (bmp, 0, sizeof (*bmp) + cert_len + key_len);
     447             : 
     448           2 :   bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_ADD_CERT_KEY_PAIR);
     449           2 :   bmp->client_index = wrk->api_client_handle;
     450           2 :   bmp->context = wrk->wrk_index;
     451           2 :   bmp->cert_len = clib_host_to_net_u16 (cert_len);
     452           2 :   bmp->certkey_len = clib_host_to_net_u16 (key_len + cert_len);
     453           2 :   clib_memcpy_fast (bmp->certkey, ckpair->cert, cert_len);
     454           2 :   clib_memcpy_fast (bmp->certkey + cert_len, ckpair->key, key_len);
     455             : 
     456           2 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp);
     457           2 : }
     458             : 
     459             : static void
     460           0 : vcl_bapi_send_app_del_cert_key_pair (u32 ckpair_index)
     461             : {
     462           0 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     463             :   vl_api_app_del_cert_key_pair_t *bmp;
     464           0 :   bmp = vl_msg_api_alloc (sizeof (*bmp));
     465           0 :   clib_memset (bmp, 0, sizeof (*bmp));
     466             : 
     467           0 :   bmp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_APP_DEL_CERT_KEY_PAIR);
     468           0 :   bmp->client_index = wrk->api_client_handle;
     469           0 :   bmp->context = wrk->wrk_index;
     470           0 :   bmp->index = clib_host_to_net_u32 (ckpair_index);
     471           0 :   vl_msg_api_send_shmem (wrk->vl_input_queue, (u8 *) &bmp);
     472           0 : }
     473             : 
     474             : u32
     475           0 : vcl_bapi_max_nsid_len (void)
     476             : {
     477             :   vl_api_app_attach_t *mp;
     478           0 :   return (sizeof (mp->namespace_id) - 1);
     479             : }
     480             : 
     481             : static void
     482          29 : vcl_bapi_init_error_string_table (void)
     483             : {
     484          29 :   vcm->error_string_by_error_number = hash_create (0, sizeof (uword));
     485             : 
     486             : #define _(n, v, s) hash_set (vcm->error_string_by_error_number, -v, s);
     487          29 :   foreach_vnet_api_error;
     488             : #undef _
     489             : 
     490          29 :   hash_set (vcm->error_string_by_error_number, 99, "Misc");
     491          29 : }
     492             : 
     493             : static void
     494          29 : vcl_bapi_cleanup (void)
     495             : {
     496          29 :   socket_client_main_t *scm = &socket_client_main;
     497          29 :   api_main_t *am = vlibapi_get_main ();
     498             : 
     499          29 :   am->my_client_index = ~0;
     500          29 :   am->my_registration = 0;
     501          29 :   am->vl_input_queue = 0;
     502          29 :   am->msg_index_by_name_and_crc = 0;
     503          29 :   scm->socket_fd = 0;
     504             : 
     505          29 :   vl_client_api_unmap ();
     506          29 : }
     507             : 
     508             : static int
     509          29 : vcl_bapi_connect_to_vpp (void)
     510             : {
     511          29 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     512          29 :   vppcom_cfg_t *vcl_cfg = &vcm->cfg;
     513          29 :   int rv = VPPCOM_OK;
     514             :   api_main_t *am;
     515             :   u8 *wrk_name;
     516             : 
     517          29 :   wrk_name = format (0, "%v-wrk-%u%c", vcm->app_name, wrk->wrk_index, 0);
     518             : 
     519             :   /* Make sure api is cleaned up in case this is a connect from a
     520             :    * forked worker */
     521          29 :   vcl_bapi_cleanup ();
     522             : 
     523          29 :   vlibapi_set_main (&wrk->bapi_api_ctx);
     524          29 :   vlibapi_set_memory_client_main (&wrk->bapi_mem_ctx);
     525             : 
     526          29 :   if (!vcl_cfg->vpp_bapi_socket_name)
     527             :     {
     528           0 :       rv = VPPCOM_EINVAL;
     529           0 :       goto error;
     530             :     }
     531             : 
     532          29 :   if (vl_socket_client_connect2 (&wrk->bapi_sock_ctx,
     533          29 :                                  (char *) vcl_cfg->vpp_bapi_socket_name,
     534             :                                  (char *) wrk_name,
     535             :                                  0 /* default rx/tx buffer */ ))
     536             :     {
     537           0 :       VERR ("app (%s) socket connect failed!", wrk_name);
     538           0 :       rv = VPPCOM_ECONNREFUSED;
     539           0 :       goto error;
     540             :     }
     541             : 
     542          29 :   if (vl_socket_client_init_shm2 (&wrk->bapi_sock_ctx, 0,
     543             :                                   1 /* want_pthread */ ))
     544             :     {
     545           0 :       VERR ("app (%s) init shm failed!", wrk_name);
     546           0 :       rv = VPPCOM_ECONNREFUSED;
     547           0 :       goto error;
     548             :     }
     549          29 :   vcl_bapi_hookup ();
     550             : 
     551          29 :   am = vlibapi_get_main ();
     552          29 :   wrk->vl_input_queue = am->shmem_hdr->vl_input_queue;
     553          29 :   wrk->api_client_handle = (u32) am->my_client_index;
     554             : 
     555          29 :   VDBG (0, "app (%s) is connected to VPP!", wrk_name);
     556             :   vcl_evt (VCL_EVT_INIT, vcm);
     557             : 
     558           0 : error:
     559          29 :   vec_free (wrk_name);
     560          29 :   return rv;
     561             : }
     562             : 
     563             : void
     564          29 : vcl_bapi_disconnect_from_vpp (void)
     565             : {
     566          29 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     567          29 :   vppcom_cfg_t *vcl_cfg = &vcm->cfg;
     568             : 
     569          29 :   if (vcl_cfg->vpp_bapi_socket_name)
     570          29 :     vl_socket_client_disconnect2 (&wrk->bapi_sock_ctx);
     571             :   else
     572           0 :     vl_client_disconnect_from_vlib ();
     573          29 : }
     574             : 
     575             : static const char *
     576           0 : vcl_bapi_app_state_str (vcl_bapi_app_state_t state)
     577             : {
     578             :   char *st;
     579             : 
     580           0 :   switch (state)
     581             :     {
     582           0 :     case STATE_APP_START:
     583           0 :       st = "STATE_APP_START";
     584           0 :       break;
     585             : 
     586           0 :     case STATE_APP_CONN_VPP:
     587           0 :       st = "STATE_APP_CONN_VPP";
     588           0 :       break;
     589             : 
     590           0 :     case STATE_APP_ENABLED:
     591           0 :       st = "STATE_APP_ENABLED";
     592           0 :       break;
     593             : 
     594           0 :     case STATE_APP_ATTACHED:
     595           0 :       st = "STATE_APP_ATTACHED";
     596           0 :       break;
     597             : 
     598           0 :     default:
     599           0 :       st = "UNKNOWN_APP_STATE";
     600           0 :       break;
     601             :     }
     602             : 
     603           0 :   return st;
     604             : }
     605             : 
     606             : static int
     607          60 : vcl_bapi_wait_for_wrk_state_change (vcl_bapi_app_state_t app_state)
     608             : {
     609          60 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     610          60 :   f64 timeout = clib_time_now (&wrk->clib_time) + vcm->cfg.app_timeout;
     611             : 
     612      577073 :   while (clib_time_now (&wrk->clib_time) < timeout)
     613             :     {
     614      577073 :       if (wrk->bapi_app_state == app_state)
     615          60 :         return VPPCOM_OK;
     616      577013 :       if (wrk->bapi_app_state == STATE_APP_FAILED)
     617           0 :         return VPPCOM_ECONNABORTED;
     618             :     }
     619           0 :   VDBG (0, "timeout waiting for state %s, current state %d",
     620             :         vcl_bapi_app_state_str (app_state), wrk->bapi_app_state);
     621             :   vcl_evt (VCL_EVT_SESSION_TIMEOUT, vcm, bapi_app_state);
     622             : 
     623           0 :   return VPPCOM_ETIMEDOUT;
     624             : }
     625             : 
     626             : static int
     627          29 : vcl_bapi_session_enable (void)
     628             : {
     629          29 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     630             :   int rv;
     631             : 
     632          29 :   if (wrk->bapi_app_state != STATE_APP_ENABLED)
     633             :     {
     634          29 :       vcl_bapi_send_session_enable_disable (1 /* is_enabled == TRUE */ );
     635          29 :       rv = vcl_bapi_wait_for_wrk_state_change (STATE_APP_ENABLED);
     636          29 :       if (PREDICT_FALSE (rv))
     637             :         {
     638           0 :           VDBG (0, "application session enable timed out! returning %d (%s)",
     639             :                 rv, vppcom_retval_str (rv));
     640           0 :           return rv;
     641             :         }
     642             :     }
     643          29 :   return VPPCOM_OK;
     644             : }
     645             : 
     646             : static int
     647          29 : vcl_bapi_init (void)
     648             : {
     649          29 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     650             :   int rv;
     651             : 
     652          29 :   wrk->bapi_app_state = STATE_APP_START;
     653          29 :   vcl_bapi_init_error_string_table ();
     654          29 :   rv = vcl_bapi_connect_to_vpp ();
     655          29 :   if (rv)
     656             :     {
     657           0 :       VERR ("couldn't connect to VPP!");
     658           0 :       return rv;
     659             :     }
     660          29 :   VDBG (0, "sending session enable");
     661          29 :   rv = vcl_bapi_session_enable ();
     662          29 :   if (rv)
     663             :     {
     664           0 :       VERR ("vppcom_app_session_enable() failed!");
     665           0 :       return rv;
     666             :     }
     667             : 
     668          29 :   return 0;
     669             : }
     670             : 
     671             : int
     672          29 : vcl_bapi_attach (void)
     673             : {
     674             :   int rv;
     675             : 
     676             :   /* API hookup and connect to VPP */
     677          29 :   if ((rv = vcl_bapi_init ()))
     678           0 :     return rv;
     679             : 
     680          29 :   vcl_bapi_send_attach ();
     681          29 :   rv = vcl_bapi_wait_for_wrk_state_change (STATE_APP_ATTACHED);
     682          29 :   if (PREDICT_FALSE (rv))
     683             :     {
     684           0 :       VDBG (0, "application attach timed out! returning %d (%s)", rv,
     685             :             vppcom_retval_str (rv));
     686           0 :       return rv;
     687             :     }
     688             : 
     689          29 :   return 0;
     690             : }
     691             : 
     692             : int
     693           0 : vcl_bapi_app_worker_add (void)
     694             : {
     695           0 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     696             : 
     697           0 :   if (vcl_bapi_connect_to_vpp ())
     698           0 :     return -1;
     699             : 
     700           0 :   wrk->bapi_app_state = STATE_APP_ADDING_WORKER;
     701           0 :   vcl_bapi_send_app_worker_add_del (1 /* is_add */ );
     702           0 :   if (vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY))
     703           0 :     return -1;
     704           0 :   return 0;
     705             : }
     706             : 
     707             : void
     708          11 : vcl_bapi_app_worker_del (vcl_worker_t * wrk)
     709             : {
     710             :   /* Notify vpp that the worker is going away */
     711          11 :   if (wrk->wrk_index == vcl_get_worker_index ())
     712          11 :     vcl_bapi_send_app_worker_add_del (0 /* is_add */ );
     713             :   else
     714           0 :     vcl_bapi_send_child_worker_del (wrk);
     715             : 
     716             :   /* Disconnect the binary api */
     717          11 :   if (vec_len (vcm->workers) == 1)
     718          11 :     vcl_bapi_disconnect_from_vpp ();
     719             :   else
     720           0 :     vl_client_send_disconnect (1 /* vpp should cleanup */ );
     721          11 : }
     722             : 
     723             : int
     724          30 : vcl_bapi_recv_fds (vcl_worker_t * wrk, int *fds, int n_fds)
     725             : {
     726             :   clib_error_t *err;
     727             : 
     728          30 :   if ((err = vl_socket_client_recv_fd_msg2 (&wrk->bapi_sock_ctx, fds, n_fds,
     729             :                                             5)))
     730             :     {
     731           0 :       clib_error_report (err);
     732           0 :       return -1;
     733             :     }
     734             : 
     735          30 :   return 0;
     736             : }
     737             : 
     738             : int
     739           2 : vcl_bapi_add_cert_key_pair (vppcom_cert_key_pair_t *ckpair)
     740             : {
     741           2 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     742             : 
     743           2 :   if (ckpair->key_len == 0 || ckpair->key_len == ~0)
     744           0 :     return VPPCOM_EINVAL;
     745             : 
     746           2 :   vcl_bapi_send_app_add_cert_key_pair (ckpair);
     747           2 :   wrk->bapi_app_state = STATE_APP_ADDING_TLS_DATA;
     748           2 :   vcl_bapi_wait_for_wrk_state_change (STATE_APP_READY);
     749           2 :   if (wrk->bapi_app_state == STATE_APP_READY)
     750           2 :     return wrk->bapi_return;
     751           0 :   return VPPCOM_EFAULT;
     752             : }
     753             : 
     754             : int
     755           0 : vcl_bapi_del_cert_key_pair (u32 ckpair_index)
     756             : {
     757             :   /* Don't wait for reply */
     758           0 :   vcl_bapi_send_app_del_cert_key_pair (ckpair_index);
     759           0 :   return 0;
     760             : }
     761             : 
     762             : int
     763           0 : vcl_bapi_worker_set (void)
     764             : {
     765           0 :   vcl_worker_t *wrk = vcl_worker_get_current ();
     766             :   int i;
     767             : 
     768             :   /* Find the first worker with the same pid */
     769           0 :   for (i = 0; i < vec_len (vcm->workers); i++)
     770             :     {
     771           0 :       if (i == wrk->wrk_index)
     772           0 :         continue;
     773           0 :       if (vcm->workers[i].current_pid == wrk->current_pid)
     774             :         {
     775           0 :           wrk->vl_input_queue = vcm->workers[i].vl_input_queue;
     776           0 :           wrk->api_client_handle = vcm->workers[i].api_client_handle;
     777           0 :           return 0;
     778             :         }
     779             :     }
     780           0 :   return -1;
     781             : }
     782             : 
     783             : /*
     784             :  * fd.io coding-style-patch-verification: ON
     785             :  *
     786             :  * Local Variables:
     787             :  * eval: (c-set-style "gnu")
     788             :  * End:
     789             :  */

Generated by: LCOV version 1.14