LCOV - code coverage report
Current view: top level - vnet/ip - punt_api.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 129 149 86.6 %
Date: 2023-10-26 01:39:38 Functions: 20 20 100.0 %

          Line data    Source code
       1             : /*
       2             :  *------------------------------------------------------------------
       3             :  * punt_api.c - Punt api
       4             :  *
       5             :  * Copyright (c) 2016 Cisco and/or its affiliates.
       6             :  * Licensed under the Apache License, Version 2.0 (the "License");
       7             :  * you may not use this file except in compliance with the License.
       8             :  * You may obtain a copy of the License at:
       9             :  *
      10             :  *     http://www.apache.org/licenses/LICENSE-2.0
      11             :  *
      12             :  * Unless required by applicable law or agreed to in writing, software
      13             :  * distributed under the License is distributed on an "AS IS" BASIS,
      14             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      15             :  * See the License for the specific language governing permissions and
      16             :  * limitations under the License.
      17             :  *------------------------------------------------------------------
      18             :  */
      19             : 
      20             : #include <vnet/vnet.h>
      21             : #include <vlibmemory/api.h>
      22             : #include <vnet/ip/punt.h>
      23             : #include <vnet/ip/ip_types_api.h>
      24             : 
      25             : #include <vnet/format_fns.h>
      26             : #include <vnet/ip/punt.api_enum.h>
      27             : #include <vnet/ip/punt.api_types.h>
      28             : 
      29             : #define REPLY_MSG_ID_BASE punt_main.msg_id_base
      30             : #include <vlibapi/api_helper_macros.h>
      31             : 
      32             : static int
      33         118 : vl_api_punt_type_decode (vl_api_punt_type_t in, punt_type_t * out)
      34             : {
      35         118 :   in = clib_net_to_host_u32 (in);
      36             : 
      37         118 :   switch (in)
      38             :     {
      39             : #define _(v, s)                                 \
      40             :       case PUNT_API_TYPE_##v:                   \
      41             :         *out = PUNT_TYPE_##v;                   \
      42             :         return (0);
      43         118 :       foreach_punt_type
      44             : #undef _
      45             :     }
      46             : 
      47           0 :   return (-1);
      48             : }
      49             : 
      50             : static vl_api_punt_type_t
      51          33 : vl_api_punt_type_encode (punt_type_t in)
      52             : {
      53          33 :   vl_api_punt_type_t pt = PUNT_API_TYPE_L4;
      54             : 
      55          33 :   switch (in)
      56             :     {
      57             : #define _(v, s)                                   \
      58             :       case PUNT_TYPE_##v:                         \
      59             :         pt = PUNT_API_TYPE_##v;                   \
      60             :         break;
      61          33 :       foreach_punt_type
      62             : #undef _
      63             :     }
      64             : 
      65          33 :   return (clib_host_to_net_u32 (pt));
      66             : }
      67             : 
      68             : static int
      69          67 : vl_api_punt_l4_decode (const vl_api_punt_l4_t * in, punt_l4_t * out)
      70             : {
      71             :   int rv;
      72             : 
      73          67 :   rv = ip_address_family_decode (in->af, &out->af);
      74          67 :   if (rv < 0)
      75           0 :     return (rv);
      76          67 :   rv = ip_proto_decode (in->protocol, &out->protocol);
      77          67 :   if (rv < 0)
      78           0 :     return (rv);
      79          67 :   out->port = clib_net_to_host_u16 (in->port);
      80             : 
      81          67 :   return (rv);
      82             : }
      83             : 
      84             : static int
      85           8 : vl_api_punt_ip_proto_decode (const vl_api_punt_ip_proto_t * in,
      86             :                              punt_ip_proto_t * out)
      87             : {
      88             :   int rv;
      89             : 
      90           8 :   rv = ip_address_family_decode (in->af, &out->af);
      91           8 :   if (rv < 0)
      92           0 :     return (rv);
      93           8 :   rv = ip_proto_decode (in->protocol, &out->protocol);
      94             : 
      95           8 :   return (rv);
      96             : }
      97             : 
      98             : static int
      99          10 : vl_api_punt_exception_decode (const vl_api_punt_exception_t * in,
     100             :                               punt_exception_t * out)
     101             : {
     102             :   int rv;
     103             : 
     104          10 :   out->reason = clib_net_to_host_u32 (in->id);
     105          10 :   rv = vlib_punt_reason_validate (out->reason);
     106             : 
     107          10 :   return (rv);
     108             : }
     109             : 
     110             : static int
     111          85 : vl_api_punt_decode (const vl_api_punt_t * in, punt_reg_t * out)
     112             : {
     113             :   int rv;
     114             : 
     115          85 :   rv = vl_api_punt_type_decode (in->type, &out->type);
     116             : 
     117          85 :   if (rv)
     118           0 :     return (rv);
     119             : 
     120          85 :   switch (out->type)
     121             :     {
     122          67 :     case PUNT_TYPE_L4:
     123          67 :       return (vl_api_punt_l4_decode (&in->punt.l4, &out->punt.l4));
     124          10 :     case PUNT_TYPE_EXCEPTION:
     125          10 :       return (vl_api_punt_exception_decode (&in->punt.exception,
     126             :                                             &out->punt.exception));
     127           8 :     case PUNT_TYPE_IP_PROTO:
     128           8 :       return (vl_api_punt_ip_proto_decode (&in->punt.ip_proto,
     129             :                                            &out->punt.ip_proto));
     130             :     }
     131             : 
     132           0 :   return (-1);
     133             : }
     134             : 
     135             : static void
     136          22 : vl_api_punt_l4_encode (const punt_l4_t * in, vl_api_punt_l4_t * out)
     137             : {
     138          22 :   out->af = ip_address_family_encode (in->af);
     139          22 :   out->protocol = ip_proto_encode (in->protocol);
     140          22 :   out->port = clib_net_to_host_u16 (in->port);
     141          22 : }
     142             : 
     143             : static void
     144           5 : vl_api_punt_ip_proto_encode (const punt_ip_proto_t * in,
     145             :                              vl_api_punt_ip_proto_t * out)
     146             : {
     147           5 :   out->af = ip_address_family_encode (in->af);
     148           5 :   out->protocol = ip_proto_encode (in->protocol);
     149           5 : }
     150             : 
     151             : static void
     152           6 : vl_api_punt_exception_encode (const punt_exception_t * in,
     153             :                               vl_api_punt_exception_t * out)
     154             : {
     155           6 :   out->id = clib_host_to_net_u32 (in->reason);
     156           6 : }
     157             : 
     158             : static void
     159          33 : vl_api_punt_encode (const punt_reg_t * in, vl_api_punt_t * out)
     160             : {
     161          33 :   out->type = vl_api_punt_type_encode (in->type);
     162             : 
     163          33 :   switch (in->type)
     164             :     {
     165          22 :     case PUNT_TYPE_L4:
     166          22 :       vl_api_punt_l4_encode (&in->punt.l4, &out->punt.l4);
     167          22 :       break;
     168           5 :     case PUNT_TYPE_IP_PROTO:
     169           5 :       vl_api_punt_ip_proto_encode (&in->punt.ip_proto, &out->punt.ip_proto);
     170           5 :       break;
     171           6 :     case PUNT_TYPE_EXCEPTION:
     172           6 :       vl_api_punt_exception_encode (&in->punt.exception,
     173             :                                     &out->punt.exception);
     174           6 :       break;
     175             :     }
     176          33 : }
     177             : 
     178             : static void
     179          14 : vl_api_set_punt_t_handler (vl_api_set_punt_t * mp)
     180             : {
     181             :   vl_api_set_punt_reply_t *rmp;
     182          14 :   vlib_main_t *vm = vlib_get_main ();
     183             :   clib_error_t *error;
     184             :   punt_reg_t pr;
     185             :   int rv;
     186             : 
     187          14 :   rv = vl_api_punt_decode (&mp->punt, &pr);
     188             : 
     189          14 :   if (rv)
     190           0 :     goto out;
     191             : 
     192          14 :   error = vnet_punt_add_del (vm, &pr, mp->is_add);
     193          14 :   if (error)
     194             :     {
     195           0 :       rv = -1;
     196           0 :       clib_error_report (error);
     197             :     }
     198             : 
     199          14 : out:
     200          14 :   REPLY_MACRO (VL_API_SET_PUNT_REPLY);
     201             : }
     202             : 
     203             : static void
     204          35 : vl_api_punt_socket_register_t_handler (vl_api_punt_socket_register_t * mp)
     205             : {
     206             :   vl_api_punt_socket_register_reply_t *rmp;
     207          35 :   vlib_main_t *vm = vlib_get_main ();
     208             :   clib_error_t *error;
     209             :   punt_reg_t pr;
     210             :   int rv;
     211             : 
     212          35 :   rv = vl_api_punt_decode (&mp->punt, &pr);
     213             : 
     214          35 :   if (rv)
     215           0 :     return;
     216             : 
     217          35 :   error = vnet_punt_socket_add (vm, ntohl (mp->header_version),
     218          35 :                                 &pr, (char *) mp->pathname);
     219          35 :   if (error)
     220             :     {
     221           0 :       rv = -1;
     222           0 :       clib_error_report (error);
     223             :     }
     224             : 
     225          35 :   char *p = vnet_punt_get_server_pathname ();
     226             : 
     227             :   /* *INDENT-OFF* */
     228          35 :   REPLY_MACRO2 (VL_API_PUNT_SOCKET_REGISTER_REPLY,
     229             :   ({
     230             :     memcpy ((char *) rmp->pathname, p, sizeof (rmp->pathname));
     231             :   }));
     232             :   /* *INDENT-ON* */
     233             : }
     234             : 
     235             : typedef struct punt_socket_send_ctx_t_
     236             : {
     237             :   vl_api_registration_t *reg;
     238             :   u32 context;
     239             : } punt_socket_send_ctx_t;
     240             : 
     241             : static walk_rc_t
     242          33 : vl_api_punt_socket_send_details (const punt_client_t * pc, void *args)
     243             : {
     244          33 :   punt_socket_send_ctx_t *ctx = args;
     245             :   vl_api_punt_socket_details_t *mp;
     246             : 
     247          33 :   mp = vl_msg_api_alloc (sizeof (*mp));
     248          33 :   if (!mp)
     249           0 :     return (WALK_STOP);
     250             : 
     251          33 :   clib_memset (mp, 0, sizeof (*mp));
     252          33 :   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_PUNT_SOCKET_DETAILS);
     253          33 :   mp->context = ctx->context;
     254          33 :   vl_api_punt_encode (&pc->reg, &mp->punt);
     255          33 :   memcpy (mp->pathname, pc->caddr.sun_path, sizeof (pc->caddr.sun_path));
     256             : 
     257          33 :   vl_api_send_msg (ctx->reg, (u8 *) mp);
     258             : 
     259          33 :   return (WALK_CONTINUE);
     260             : }
     261             : 
     262             : static void
     263          33 : vl_api_punt_socket_dump_t_handler (vl_api_punt_socket_dump_t * mp)
     264             : {
     265             :   vl_api_registration_t *reg;
     266             :   punt_type_t pt;
     267             : 
     268          33 :   if (0 != vl_api_punt_type_decode (mp->type, &pt))
     269           0 :     return;
     270             : 
     271          33 :   reg = vl_api_client_index_to_registration (mp->client_index);
     272          33 :   if (!reg)
     273           0 :     return;
     274             : 
     275          33 :   punt_socket_send_ctx_t ctx = {
     276             :     .reg = reg,
     277          33 :     .context = mp->context,
     278             :   };
     279             : 
     280          33 :   punt_client_walk (pt, vl_api_punt_socket_send_details, &ctx);
     281             : }
     282             : 
     283             : static void
     284          36 : vl_api_punt_socket_deregister_t_handler (vl_api_punt_socket_deregister_t * mp)
     285             : {
     286             :   vl_api_punt_socket_deregister_reply_t *rmp;
     287          36 :   vlib_main_t *vm = vlib_get_main ();
     288             :   clib_error_t *error;
     289             :   punt_reg_t pr;
     290             :   int rv;
     291             : 
     292          36 :   rv = vl_api_punt_decode (&mp->punt, &pr);
     293             : 
     294          36 :   if (rv)
     295           0 :     goto out;
     296             : 
     297          36 :   error = vnet_punt_socket_del (vm, &pr);
     298          36 :   if (error)
     299             :     {
     300           0 :       rv = -1;
     301           0 :       clib_error_report (error);
     302             :     }
     303             : 
     304          36 : out:
     305          36 :   REPLY_MACRO (VL_API_PUNT_SOCKET_DEREGISTER_REPLY);
     306             : }
     307             : 
     308             : typedef struct punt_reason_dump_walk_ctx_t_
     309             : {
     310             :   vl_api_registration_t *reg;
     311             :   u32 context;
     312             :   u8 *name;
     313             : } punt_reason_dump_walk_ctx_t;
     314             : 
     315             : static int
     316          20 : punt_reason_dump_walk_cb (vlib_punt_reason_t id, const u8 * name, void *args)
     317             : {
     318          20 :   punt_reason_dump_walk_ctx_t *ctx = args;
     319             :   vl_api_punt_reason_details_t *mp;
     320             : 
     321          20 :   if (ctx->name)
     322             :     {
     323             :       /* user requested a specific punt-reason */
     324          46 :       if (vec_cmp (name, ctx->name))
     325             :         /* not the reasonn we're lookgin for */
     326          10 :         return 1;
     327             :     }
     328             : 
     329          10 :   mp = vl_msg_api_alloc (sizeof (*mp) + vec_len (name));
     330          10 :   if (!mp)
     331           0 :     return (0);
     332             : 
     333          10 :   clib_memset (mp, 0, sizeof (*mp));
     334          10 :   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_PUNT_REASON_DETAILS);
     335             : 
     336          10 :   mp->context = ctx->context;
     337          10 :   mp->reason.id = clib_host_to_net_u32 (id);
     338          10 :   vl_api_vec_to_api_string (name, &mp->reason.name);
     339             : 
     340          10 :   vl_api_send_msg (ctx->reg, (u8 *) mp);
     341             : 
     342          10 :   return (1);
     343             : }
     344             : 
     345             : static void
     346           4 : vl_api_punt_reason_dump_t_handler (vl_api_punt_reason_dump_t * mp)
     347             : {
     348             :   vl_api_registration_t *reg;
     349             : 
     350           4 :   reg = vl_api_client_index_to_registration (mp->client_index);
     351           4 :   if (!reg)
     352           0 :     return;
     353             : 
     354           8 :   punt_reason_dump_walk_ctx_t ctx = {
     355             :     .reg = reg,
     356           4 :     .context = mp->context,
     357           4 :     .name = vl_api_from_api_to_new_vec (mp, &mp->reason.name),
     358             :   };
     359             : 
     360           4 :   punt_reason_walk (punt_reason_dump_walk_cb, &ctx);
     361             : 
     362           4 :   vec_free (ctx.name);
     363             : }
     364             : 
     365             : #include <vnet/ip/punt.api.c>
     366             : 
     367             : static clib_error_t *
     368         575 : punt_api_hookup (vlib_main_t * vm)
     369             : {
     370             :   /*
     371             :    * Set up the (msg_name, crc, message-id) table
     372             :    */
     373         575 :   REPLY_MSG_ID_BASE = setup_message_id_table ();
     374             : 
     375         575 :   return 0;
     376             : }
     377             : 
     378        5759 : VLIB_API_INIT_FUNCTION (punt_api_hookup);
     379             : 
     380             : 
     381             : /*
     382             :  * fd.io coding-style-patch-verification: ON
     383             :  *
     384             :  * Local Variables:
     385             :  * eval: (c-set-style "gnu")
     386             :  * End:
     387             :  */

Generated by: LCOV version 1.14