LCOV - code coverage report
Current view: top level - vlibmemory - vlib_api.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 49 152 32.2 %
Date: 2023-07-05 22:20:52 Functions: 8 15 53.3 %

          Line data    Source code
       1             : /*
       2             :  * vlib_api.c VLIB API implementation
       3             :  *
       4             :  * Copyright (c) 2021 Cisco and/or its affiliates.
       5             :  * Licensed under the Apache License, Version 2.0 (the "License");
       6             :  * you may not use this file except in compliance with the License.
       7             :  * You may obtain a copy of the License at:
       8             :  *
       9             :  *     http://www.apache.org/licenses/LICENSE-2.0
      10             :  *
      11             :  * Unless required by applicable law or agreed to in writing, software
      12             :  * distributed under the License is distributed on an "AS IS" BASIS,
      13             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      14             :  * See the License for the specific language governing permissions and
      15             :  * limitations under the License.
      16             :  */
      17             : 
      18             : #include <vlibapi/api.h>
      19             : #include <vlibmemory/api.h>
      20             : #include <vnet/api_errno.h>
      21             : 
      22             : #include <vlibmemory/vlib.api_enum.h>
      23             : #include <vlibmemory/vlib.api_types.h>
      24             : 
      25             : static u16 msg_id_base;
      26             : #define REPLY_MSG_ID_BASE msg_id_base
      27             : #include <vlibapi/api_helper_macros.h>
      28             : 
      29             : static void
      30           0 : shmem_cli_output (uword arg, u8 *buffer, uword buffer_bytes)
      31             : {
      32           0 :   u8 **shmem_vecp = (u8 **) arg;
      33             :   u8 *shmem_vec;
      34             :   void *oldheap;
      35             :   u32 offset;
      36             : 
      37           0 :   shmem_vec = *shmem_vecp;
      38             : 
      39           0 :   offset = vec_len (shmem_vec);
      40             : 
      41           0 :   oldheap = vl_msg_push_heap ();
      42             : 
      43           0 :   vec_validate (shmem_vec, offset + buffer_bytes - 1);
      44             : 
      45           0 :   clib_memcpy (shmem_vec + offset, buffer, buffer_bytes);
      46             : 
      47           0 :   vl_msg_pop_heap (oldheap);
      48             : 
      49           0 :   *shmem_vecp = shmem_vec;
      50           0 : }
      51             : 
      52             : static void
      53           0 : vl_api_cli_t_handler (vl_api_cli_t *mp)
      54             : {
      55             :   vl_api_cli_reply_t *rp;
      56             :   vl_api_registration_t *reg;
      57           0 :   vlib_main_t *vm = vlib_get_main ();
      58             :   unformat_input_t input;
      59           0 :   u8 *shmem_vec = 0;
      60             :   void *oldheap;
      61             : 
      62           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
      63           0 :   if (!reg)
      64           0 :     return;
      65             :   ;
      66             : 
      67           0 :   rp = vl_msg_api_alloc (sizeof (*rp));
      68           0 :   rp->_vl_msg_id = ntohs (VL_API_CLI_REPLY + REPLY_MSG_ID_BASE);
      69           0 :   rp->context = mp->context;
      70             : 
      71           0 :   unformat_init_vector (&input, (u8 *) (uword) mp->cmd_in_shmem);
      72             : 
      73           0 :   vlib_cli_input (vm, &input, shmem_cli_output, (uword) &shmem_vec);
      74             : 
      75           0 :   oldheap = vl_msg_push_heap ();
      76           0 :   vec_add1 (shmem_vec, 0);
      77           0 :   vl_msg_pop_heap (oldheap);
      78             : 
      79           0 :   rp->reply_in_shmem = (uword) shmem_vec;
      80             : 
      81           0 :   vl_api_send_msg (reg, (u8 *) rp);
      82             : }
      83             : 
      84             : static void
      85      769631 : inband_cli_output (uword arg, u8 *buffer, uword buffer_bytes)
      86             : {
      87      769631 :   u8 **mem_vecp = (u8 **) arg;
      88      769631 :   u8 *mem_vec = *mem_vecp;
      89      769631 :   u32 offset = vec_len (mem_vec);
      90             : 
      91      769631 :   vec_validate (mem_vec, offset + buffer_bytes - 1);
      92      769631 :   clib_memcpy (mem_vec + offset, buffer, buffer_bytes);
      93      769631 :   *mem_vecp = mem_vec;
      94      769631 : }
      95             : 
      96             : static void
      97      250758 : vl_api_cli_inband_t_handler (vl_api_cli_inband_t *mp)
      98             : {
      99             :   vl_api_cli_inband_reply_t *rmp;
     100      250758 :   int rv = 0;
     101      250758 :   vlib_main_t *vm = vlib_get_main ();
     102             :   unformat_input_t input;
     103      250758 :   u8 *out_vec = 0;
     104      250758 :   u8 *cmd_vec = 0;
     105             : 
     106      250758 :   if (vl_msg_api_get_msg_length (mp) <
     107      250758 :       vl_api_string_len (&mp->cmd) + sizeof (*mp))
     108             :     {
     109           0 :       rv = -1;
     110           0 :       goto error;
     111             :     }
     112             : 
     113      250758 :   cmd_vec = vl_api_from_api_to_new_vec (mp, &mp->cmd);
     114             : 
     115      250758 :   unformat_init_string (&input, (char *) cmd_vec,
     116      250758 :                         vl_api_string_len (&mp->cmd));
     117      250758 :   rv = vlib_cli_input (vm, &input, inband_cli_output, (uword) &out_vec);
     118      250758 :   unformat_free (&input);
     119             : 
     120      250758 : error:
     121      250758 :   REPLY_MACRO3 (VL_API_CLI_INBAND_REPLY, vec_len (out_vec),
     122             :                 ({ vl_api_vec_to_api_string (out_vec, &rmp->reply); }));
     123      250758 :   vec_free (out_vec);
     124      250758 :   vec_free (cmd_vec);
     125             : }
     126             : 
     127             : static void
     128           0 : vl_api_get_node_index_t_handler (vl_api_get_node_index_t *mp)
     129             : {
     130           0 :   vlib_main_t *vm = vlib_get_main ();
     131             :   vl_api_get_node_index_reply_t *rmp;
     132             :   vlib_node_t *n;
     133           0 :   int rv = 0;
     134           0 :   u32 node_index = ~0;
     135             : 
     136           0 :   n = vlib_get_node_by_name (vm, mp->node_name);
     137             : 
     138           0 :   if (n == 0)
     139           0 :     rv = VNET_API_ERROR_NO_SUCH_NODE;
     140             :   else
     141           0 :     node_index = n->index;
     142             : 
     143           0 :   REPLY_MACRO2 (VL_API_GET_NODE_INDEX_REPLY,
     144             :                 ({ rmp->node_index = htonl (node_index); }));
     145             : }
     146             : 
     147             : static void
     148           1 : vl_api_add_node_next_t_handler (vl_api_add_node_next_t *mp)
     149             : {
     150           1 :   vlib_main_t *vm = vlib_get_main ();
     151             :   vl_api_add_node_next_reply_t *rmp;
     152             :   vlib_node_t *n, *next;
     153           1 :   int rv = 0;
     154           1 :   u32 next_index = ~0;
     155             : 
     156           1 :   n = vlib_get_node_by_name (vm, mp->node_name);
     157             : 
     158           1 :   if (n == 0)
     159             :     {
     160           0 :       rv = VNET_API_ERROR_NO_SUCH_NODE;
     161           0 :       goto out;
     162             :     }
     163             : 
     164           1 :   next = vlib_get_node_by_name (vm, mp->next_name);
     165             : 
     166           1 :   if (next == 0)
     167           0 :     rv = VNET_API_ERROR_NO_SUCH_NODE2;
     168             :   else
     169           1 :     next_index = vlib_node_add_next (vm, n->index, next->index);
     170             : 
     171           1 : out:
     172           1 :   REPLY_MACRO2 (VL_API_ADD_NODE_NEXT_REPLY,
     173             :                 ({ rmp->next_index = htonl (next_index); }));
     174             : }
     175             : 
     176             : static void
     177           0 : get_thread_data (vl_api_thread_data_t *td, int index)
     178             : {
     179           0 :   vlib_worker_thread_t *w = vlib_worker_threads + index;
     180           0 :   td->id = htonl (index);
     181           0 :   if (w->name)
     182           0 :     strncpy ((char *) td->name, (char *) w->name, ARRAY_LEN (td->name) - 1);
     183           0 :   if (w->registration)
     184           0 :     strncpy ((char *) td->type, (char *) w->registration->name,
     185             :              ARRAY_LEN (td->type) - 1);
     186           0 :   td->pid = htonl (w->lwp);
     187           0 :   td->cpu_id = htonl (w->cpu_id);
     188           0 :   td->core = htonl (w->core_id);
     189           0 :   td->cpu_socket = htonl (w->numa_id);
     190           0 : }
     191             : 
     192             : static void
     193           0 : vl_api_show_threads_t_handler (vl_api_show_threads_t *mp)
     194             : {
     195           0 :   int count = 0;
     196             : 
     197             : #if !defined(__powerpc64__)
     198             :   vl_api_registration_t *reg;
     199             :   vl_api_show_threads_reply_t *rmp;
     200             :   vl_api_thread_data_t *td;
     201           0 :   int i, msg_size = 0;
     202           0 :   count = vec_len (vlib_worker_threads);
     203           0 :   if (!count)
     204           0 :     return;
     205             : 
     206           0 :   msg_size = sizeof (*rmp) + sizeof (rmp->thread_data[0]) * count;
     207           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
     208           0 :   if (!reg)
     209           0 :     return;
     210             : 
     211           0 :   rmp = vl_msg_api_alloc (msg_size);
     212           0 :   clib_memset (rmp, 0, msg_size);
     213           0 :   rmp->_vl_msg_id = htons (VL_API_SHOW_THREADS_REPLY + REPLY_MSG_ID_BASE);
     214           0 :   rmp->context = mp->context;
     215           0 :   rmp->count = htonl (count);
     216           0 :   td = rmp->thread_data;
     217             : 
     218           0 :   for (i = 0; i < count; i++)
     219             :     {
     220           0 :       get_thread_data (&td[i], i);
     221             :     }
     222             : 
     223           0 :   vl_api_send_msg (reg, (u8 *) rmp);
     224             : #else
     225             : 
     226             :   /* unimplemented support */
     227             :   rv = -9;
     228             :   clib_warning ("power pc does not support show threads api");
     229             :   REPLY_MACRO2 (VL_API_SHOW_THREADS_REPLY, ({ rmp->count = htonl (count); }));
     230             : #endif
     231             : }
     232             : 
     233             : static void
     234           0 : vl_api_get_node_graph_t_handler (vl_api_get_node_graph_t *mp)
     235             : {
     236           0 :   int rv = 0;
     237           0 :   u8 *vector = 0;
     238           0 :   vlib_main_t *vm = vlib_get_main ();
     239             :   void *oldheap;
     240             :   vl_api_get_node_graph_reply_t *rmp;
     241             :   static vlib_node_t ***node_dups;
     242             :   static vlib_main_t **stat_vms;
     243             : 
     244           0 :   oldheap = vl_msg_push_heap ();
     245             : 
     246             :   /*
     247             :    * Keep the number of memcpy ops to a minimum (e.g. 1).
     248             :    */
     249           0 :   vec_validate (vector, 16384);
     250           0 :   vec_reset_length (vector);
     251             : 
     252           0 :   vlib_node_get_nodes (vm, 0 /* main threads */, 0 /* include stats */,
     253             :                        1 /* barrier sync */, &node_dups, &stat_vms);
     254           0 :   vector = vlib_node_serialize (vm, node_dups, vector, 1 /* include nexts */,
     255             :                                 1 /* include stats */);
     256             : 
     257           0 :   vl_msg_pop_heap (oldheap);
     258             : 
     259           0 :   REPLY_MACRO2 (VL_API_GET_NODE_GRAPH_REPLY,
     260             :                 ({ rmp->reply_in_shmem = (uword) vector; }));
     261             : }
     262             : 
     263             : static void
     264           0 : vl_api_get_next_index_t_handler (vl_api_get_next_index_t *mp)
     265             : {
     266           0 :   vlib_main_t *vm = vlib_get_main ();
     267             :   vl_api_get_next_index_reply_t *rmp;
     268             :   vlib_node_t *node, *next_node;
     269           0 :   int rv = 0;
     270           0 :   u32 next_node_index = ~0, next_index = ~0;
     271             :   uword *p;
     272             : 
     273           0 :   node = vlib_get_node_by_name (vm, mp->node_name);
     274             : 
     275           0 :   if (node == 0)
     276             :     {
     277           0 :       rv = VNET_API_ERROR_NO_SUCH_NODE;
     278           0 :       goto out;
     279             :     }
     280             : 
     281           0 :   next_node = vlib_get_node_by_name (vm, mp->next_name);
     282             : 
     283           0 :   if (next_node == 0)
     284             :     {
     285           0 :       rv = VNET_API_ERROR_NO_SUCH_NODE2;
     286           0 :       goto out;
     287             :     }
     288             :   else
     289           0 :     next_node_index = next_node->index;
     290             : 
     291           0 :   p = hash_get (node->next_slot_by_node, next_node_index);
     292             : 
     293           0 :   if (p == 0)
     294             :     {
     295           0 :       rv = VNET_API_ERROR_NO_SUCH_ENTRY;
     296           0 :       goto out;
     297             :     }
     298             :   else
     299           0 :     next_index = p[0];
     300             : 
     301           0 : out:
     302           0 :   REPLY_MACRO2 (VL_API_GET_NEXT_INDEX_REPLY,
     303             :                 ({ rmp->next_index = htonl (next_index); }));
     304             : }
     305             : 
     306             : static void
     307           1 : vl_api_get_f64_endian_value_t_handler (vl_api_get_f64_endian_value_t *mp)
     308             : {
     309           1 :   int rv = 0;
     310           1 :   f64 one = 1.0;
     311             :   vl_api_get_f64_endian_value_reply_t *rmp;
     312           1 :   if (1.0 != clib_net_to_host_f64 (mp->f64_one))
     313           0 :     rv = VNET_API_ERROR_API_ENDIAN_FAILED;
     314             : 
     315           1 :   REPLY_MACRO2 (VL_API_GET_F64_ENDIAN_VALUE_REPLY,
     316             :                 ({ rmp->f64_one_result = clib_host_to_net_f64 (one); }));
     317             : }
     318             : 
     319             : static void
     320           1 : vl_api_get_f64_increment_by_one_t_handler (
     321             :   vl_api_get_f64_increment_by_one_t *mp)
     322             : {
     323           1 :   int rv = 0;
     324             :   vl_api_get_f64_increment_by_one_reply_t *rmp;
     325             : 
     326           1 :   REPLY_MACRO2 (VL_API_GET_F64_INCREMENT_BY_ONE_REPLY, ({
     327             :                   rmp->f64_value = clib_host_to_net_f64 (
     328             :                     clib_net_to_host_f64 (mp->f64_value) + 1.0);
     329             :                 }));
     330             : }
     331             : 
     332             : #include <vlibmemory/vlib.api.c>
     333             : static clib_error_t *
     334         559 : vlib_apis_hookup (vlib_main_t *vm)
     335             : {
     336         559 :   api_main_t *am = vlibapi_get_main ();
     337             : 
     338             :   /*
     339             :    * Set up the (msg_name, crc, message-id) table
     340             :    */
     341         559 :   msg_id_base = setup_message_id_table ();
     342             : 
     343         559 :   vl_api_set_msg_thread_safe (am, VL_API_GET_NODE_GRAPH, 1);
     344         559 :   return 0;
     345             : }
     346             : 
     347       21279 : VLIB_API_INIT_FUNCTION (vlib_apis_hookup);
     348             : 
     349             : /*
     350             :  * fd.io coding-style-patch-verification: ON
     351             :  *
     352             :  * Local Variables:
     353             :  * eval: (c-set-style "gnu")
     354             :  * End:
     355             :  */

Generated by: LCOV version 1.14