LCOV - code coverage report
Current view: top level - plugins/af_packet - af_packet_api.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 57 104 54.8 %
Date: 2023-07-05 22:20:52 Functions: 7 10 70.0 %

          Line data    Source code
       1             : /*
       2             :  *------------------------------------------------------------------
       3             :  * af_packet_api.c - af-packet 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             : 
      23             : #include <vnet/interface.h>
      24             : #include <vnet/api_errno.h>
      25             : #include <af_packet/af_packet.h>
      26             : 
      27             : #include <vnet/format_fns.h>
      28             : #include <af_packet/af_packet.api_enum.h>
      29             : #include <af_packet/af_packet.api_types.h>
      30             : 
      31             : #define REPLY_MSG_ID_BASE msg_id_base
      32             : #include <vlibapi/api_helper_macros.h>
      33             : 
      34             : static u16 msg_id_base;
      35             : 
      36             : static void
      37           0 : vl_api_af_packet_create_t_handler (vl_api_af_packet_create_t * mp)
      38             : {
      39           0 :   af_packet_create_if_arg_t _arg, *arg = &_arg;
      40             :   vl_api_af_packet_create_reply_t *rmp;
      41           0 :   int rv = 0;
      42             : 
      43           0 :   clib_memset (arg, 0, sizeof (*arg));
      44             : 
      45           0 :   arg->host_if_name = format (0, "%s", mp->host_if_name);
      46           0 :   vec_add1 (arg->host_if_name, 0);
      47             : 
      48           0 :   arg->hw_addr = mp->use_random_hw_addr ? 0 : mp->hw_addr;
      49           0 :   arg->mode = AF_PACKET_IF_MODE_ETHERNET;
      50             :   // Default flags
      51           0 :   arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS | AF_PACKET_IF_FLAGS_CKSUM_GSO;
      52           0 :   rv = af_packet_create_if (arg);
      53             : 
      54           0 :   vec_free (arg->host_if_name);
      55             : 
      56           0 :   REPLY_MACRO2 (VL_API_AF_PACKET_CREATE_REPLY, ({
      57             :                   rmp->sw_if_index = clib_host_to_net_u32 (arg->sw_if_index);
      58             :                 }));
      59             : }
      60             : 
      61             : static void
      62           0 : vl_api_af_packet_create_v2_t_handler (vl_api_af_packet_create_v2_t *mp)
      63             : {
      64           0 :   af_packet_create_if_arg_t _arg, *arg = &_arg;
      65             :   vl_api_af_packet_create_v2_reply_t *rmp;
      66           0 :   int rv = 0;
      67             : 
      68           0 :   clib_memset (arg, 0, sizeof (*arg));
      69             : 
      70           0 :   arg->host_if_name = format (0, "%s", mp->host_if_name);
      71           0 :   vec_add1 (arg->host_if_name, 0);
      72             : 
      73             :   // Default number of rx/tx queue(s)
      74           0 :   arg->num_rxqs = 1;
      75           0 :   arg->num_txqs = 1;
      76           0 :   arg->rx_frame_size = clib_net_to_host_u32 (mp->rx_frame_size);
      77           0 :   arg->tx_frame_size = clib_net_to_host_u32 (mp->tx_frame_size);
      78           0 :   arg->rx_frames_per_block = clib_net_to_host_u32 (mp->rx_frames_per_block);
      79           0 :   arg->tx_frames_per_block = clib_net_to_host_u32 (mp->tx_frames_per_block);
      80           0 :   arg->hw_addr = mp->use_random_hw_addr ? 0 : mp->hw_addr;
      81           0 :   arg->mode = AF_PACKET_IF_MODE_ETHERNET;
      82             :   // Default flags
      83           0 :   arg->flags = AF_PACKET_IF_FLAGS_QDISC_BYPASS | AF_PACKET_IF_FLAGS_CKSUM_GSO;
      84             : 
      85           0 :   if (mp->num_rx_queues > 1)
      86           0 :     arg->num_rxqs = clib_net_to_host_u16 (mp->num_rx_queues);
      87             : 
      88           0 :   rv = af_packet_create_if (arg);
      89             : 
      90           0 :   vec_free (arg->host_if_name);
      91           0 :   REPLY_MACRO2 (VL_API_AF_PACKET_CREATE_V2_REPLY, ({
      92             :                   rmp->sw_if_index = clib_host_to_net_u32 (arg->sw_if_index);
      93             :                 }));
      94             : }
      95             : 
      96             : static void
      97         252 : vl_api_af_packet_create_v3_t_handler (vl_api_af_packet_create_v3_t *mp)
      98             : {
      99         252 :   af_packet_create_if_arg_t _arg, *arg = &_arg;
     100             :   vl_api_af_packet_create_v3_reply_t *rmp;
     101         252 :   int rv = 0;
     102             : 
     103         252 :   clib_memset (arg, 0, sizeof (*arg));
     104             : 
     105         252 :   arg->host_if_name = format (0, "%s", mp->host_if_name);
     106         252 :   vec_add1 (arg->host_if_name, 0);
     107             : 
     108             :   // Default number of rx/tx queue(s)
     109         252 :   arg->num_rxqs = 1;
     110         252 :   arg->num_txqs = 1;
     111         252 :   arg->rx_frame_size = clib_net_to_host_u32 (mp->rx_frame_size);
     112         252 :   arg->tx_frame_size = clib_net_to_host_u32 (mp->tx_frame_size);
     113         252 :   arg->rx_frames_per_block = clib_net_to_host_u32 (mp->rx_frames_per_block);
     114         252 :   arg->tx_frames_per_block = clib_net_to_host_u32 (mp->tx_frames_per_block);
     115         252 :   arg->hw_addr = mp->use_random_hw_addr ? 0 : mp->hw_addr;
     116             : 
     117         252 :   switch (clib_net_to_host_u32 (mp->mode))
     118             :     {
     119         252 :     case AF_PACKET_API_MODE_ETHERNET:
     120         252 :       arg->mode = AF_PACKET_IF_MODE_ETHERNET;
     121         252 :       break;
     122           0 :     case AF_PACKET_API_MODE_IP:
     123           0 :       arg->mode = AF_PACKET_IF_MODE_IP;
     124           0 :       break;
     125           0 :     default:
     126           0 :       arg->sw_if_index = ~0;
     127           0 :       rv = VNET_ERR_INVALID_VALUE;
     128           0 :       goto error;
     129             :     }
     130             : 
     131             :   STATIC_ASSERT (((int) AF_PACKET_API_FLAG_QDISC_BYPASS ==
     132             :                   (int) AF_PACKET_IF_FLAGS_QDISC_BYPASS),
     133             :                  "af-packet qdisc-bypass api flag mismatch");
     134             :   STATIC_ASSERT (
     135             :     ((int) AF_PACKET_API_FLAG_CKSUM_GSO == (int) AF_PACKET_IF_FLAGS_CKSUM_GSO),
     136             :     "af-packet checksum/gso offload api flag mismatch");
     137             : 
     138             :   STATIC_ASSERT (
     139             :     ((int) AF_PACKET_API_FLAG_VERSION_2 == (int) AF_PACKET_IF_FLAGS_VERSION_2),
     140             :     "af-packet version 2 api flag mismatch");
     141             : 
     142             :   // Default flags
     143         252 :   arg->flags = clib_net_to_host_u32 (mp->flags);
     144             : 
     145         252 :   if (clib_net_to_host_u16 (mp->num_rx_queues) > 1)
     146           0 :     arg->num_rxqs = clib_net_to_host_u16 (mp->num_rx_queues);
     147             : 
     148         252 :   if (clib_net_to_host_u16 (mp->num_tx_queues) > 1)
     149           0 :     arg->num_txqs = clib_net_to_host_u16 (mp->num_tx_queues);
     150             : 
     151         252 :   arg->is_v2 = (arg->flags & AF_PACKET_API_FLAG_VERSION_2) ? 1 : 0;
     152         252 :   rv = af_packet_create_if (arg);
     153             : 
     154         252 : error:
     155         252 :   vec_free (arg->host_if_name);
     156         252 :   REPLY_MACRO2 (VL_API_AF_PACKET_CREATE_V3_REPLY, ({
     157             :                   rmp->sw_if_index = clib_host_to_net_u32 (arg->sw_if_index);
     158             :                 }));
     159             : }
     160             : 
     161             : static void
     162         252 : vl_api_af_packet_delete_t_handler (vl_api_af_packet_delete_t * mp)
     163             : {
     164             :   vl_api_af_packet_delete_reply_t *rmp;
     165         252 :   int rv = 0;
     166         252 :   u8 *host_if_name = NULL;
     167             : 
     168         252 :   host_if_name = format (0, "%s", mp->host_if_name);
     169         252 :   vec_add1 (host_if_name, 0);
     170             : 
     171         252 :   rv = af_packet_delete_if (host_if_name);
     172             : 
     173         252 :   vec_free (host_if_name);
     174             : 
     175         252 :   REPLY_MACRO (VL_API_AF_PACKET_DELETE_REPLY);
     176             : }
     177             : 
     178             : static void
     179           0 :   vl_api_af_packet_set_l4_cksum_offload_t_handler
     180             :   (vl_api_af_packet_set_l4_cksum_offload_t * mp)
     181             : {
     182             :   vl_api_af_packet_delete_reply_t *rmp;
     183           0 :   int rv = 0;
     184             : 
     185           0 :   rv = af_packet_set_l4_cksum_offload (ntohl (mp->sw_if_index), mp->set);
     186           0 :   REPLY_MACRO (VL_API_AF_PACKET_SET_L4_CKSUM_OFFLOAD_REPLY);
     187             : }
     188             : 
     189             : static void
     190         252 : af_packet_send_details (vpe_api_main_t * am,
     191             :                         vl_api_registration_t * reg,
     192             :                         af_packet_if_detail_t * af_packet_if, u32 context)
     193             : {
     194             :   vl_api_af_packet_details_t *mp;
     195         252 :   mp = vl_msg_api_alloc (sizeof (*mp));
     196         252 :   clib_memset (mp, 0, sizeof (*mp));
     197         252 :   mp->_vl_msg_id = htons (REPLY_MSG_ID_BASE + VL_API_AF_PACKET_DETAILS);
     198         252 :   mp->sw_if_index = htonl (af_packet_if->sw_if_index);
     199         252 :   clib_memcpy (mp->host_if_name, af_packet_if->host_if_name,
     200             :                MIN (ARRAY_LEN (mp->host_if_name) - 1,
     201             :                     strlen ((const char *) af_packet_if->host_if_name)));
     202             : 
     203         252 :   mp->context = context;
     204         252 :   vl_api_send_msg (reg, (u8 *) mp);
     205         252 : }
     206             : 
     207             : 
     208             : static void
     209         276 : vl_api_af_packet_dump_t_handler (vl_api_af_packet_dump_t * mp)
     210             : {
     211             :   int rv;
     212         276 :   vpe_api_main_t *am = &vpe_api_main;
     213             :   vl_api_registration_t *reg;
     214         276 :   af_packet_if_detail_t *out_af_packet_ifs = NULL;
     215         276 :   af_packet_if_detail_t *af_packet_if = NULL;
     216             : 
     217         276 :   reg = vl_api_client_index_to_registration (mp->client_index);
     218         276 :   if (!reg)
     219           0 :     return;
     220             : 
     221         276 :   rv = af_packet_dump_ifs (&out_af_packet_ifs);
     222         276 :   if (rv)
     223           0 :     return;
     224             : 
     225         528 :   vec_foreach (af_packet_if, out_af_packet_ifs)
     226             :   {
     227         252 :     af_packet_send_details (am, reg, af_packet_if, mp->context);
     228             :   }
     229             : 
     230         276 :   vec_free (out_af_packet_ifs);
     231             : }
     232             : 
     233             : #include <af_packet/af_packet.api.c>
     234             : static clib_error_t *
     235         559 : af_packet_api_hookup (vlib_main_t * vm)
     236             : {
     237             :   /*
     238             :    * Set up the (msg_name, crc, message-id) table
     239             :    */
     240         559 :   REPLY_MSG_ID_BASE = setup_message_id_table ();
     241             : 
     242         559 :   return 0;
     243             : }
     244             : 
     245        1119 : VLIB_API_INIT_FUNCTION (af_packet_api_hookup);
     246             : 
     247             : /*
     248             :  * fd.io coding-style-patch-verification: ON
     249             :  *
     250             :  * Local Variables:
     251             :  * eval: (c-set-style "gnu")
     252             :  * End:
     253             :  */

Generated by: LCOV version 1.14