LCOV - code coverage report
Current view: top level - plugins/geneve - geneve_api.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 48 101 47.5 %
Date: 2023-07-05 22:20:52 Functions: 5 8 62.5 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2017 SUSE LLC.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       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             : 
      17             : #include <vnet/vnet.h>
      18             : #include <vlibmemory/api.h>
      19             : 
      20             : #include <vnet/interface.h>
      21             : #include <vnet/api_errno.h>
      22             : #include <vnet/feature/feature.h>
      23             : #include <vnet/fib/fib_table.h>
      24             : #include <vnet/ip/ip_types_api.h>
      25             : 
      26             : #include <geneve/geneve.h>
      27             : 
      28             : /* define message IDs */
      29             : #include <vnet/format_fns.h>
      30             : #include <geneve/geneve.api_enum.h>
      31             : #include <geneve/geneve.api_types.h>
      32             : 
      33             : /**
      34             :  * Base message ID fot the plugin
      35             :  */
      36             : static u32 geneve_base_msg_id;
      37             : #define REPLY_MSG_ID_BASE geneve_base_msg_id
      38             : 
      39             : #include <vlibapi/api_helper_macros.h>
      40             : 
      41             : static void
      42           0 :   vl_api_sw_interface_set_geneve_bypass_t_handler
      43             :   (vl_api_sw_interface_set_geneve_bypass_t * mp)
      44             : {
      45             :   vl_api_sw_interface_set_geneve_bypass_reply_t *rmp;
      46           0 :   int rv = 0;
      47           0 :   u32 sw_if_index = ntohl (mp->sw_if_index);
      48             : 
      49           0 :   VALIDATE_SW_IF_INDEX (mp);
      50             : 
      51           0 :   vnet_int_geneve_bypass_mode (sw_if_index, mp->is_ipv6, mp->enable);
      52           0 :   BAD_SW_IF_INDEX_LABEL;
      53             : 
      54           0 :   REPLY_MACRO (VL_API_SW_INTERFACE_SET_GENEVE_BYPASS_REPLY);
      55             : }
      56             : 
      57          62 : static void vl_api_geneve_add_del_tunnel_t_handler
      58             :   (vl_api_geneve_add_del_tunnel_t * mp)
      59             : {
      60             :   vl_api_geneve_add_del_tunnel_reply_t *rmp;
      61          62 :   int rv = 0;
      62          62 :   ip4_main_t *im = &ip4_main;
      63             : 
      64          62 :   uword *p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id));
      65          62 :   if (!p)
      66             :     {
      67           0 :       rv = VNET_API_ERROR_NO_SUCH_FIB;
      68           0 :       goto out;
      69             :     }
      70             : 
      71          62 :   vnet_geneve_add_del_tunnel_args_t a = {
      72          62 :     .is_add = mp->is_add,
      73          62 :     .is_ip6 = mp->remote_address.af,
      74          62 :     .mcast_sw_if_index = ntohl (mp->mcast_sw_if_index),
      75          62 :     .encap_fib_index = p[0],
      76          62 :     .decap_next_index = ntohl (mp->decap_next_index),
      77          62 :     .vni = ntohl (mp->vni),
      78             :   };
      79             : 
      80          62 :   ip_address_decode (&mp->remote_address, &a.remote);
      81          62 :   ip_address_decode (&mp->local_address, &a.local);
      82             : 
      83             :   /* Check src & dst are different */
      84          62 :   if (ip46_address_cmp (&a.remote, &a.local) == 0)
      85             :     {
      86           0 :       rv = VNET_API_ERROR_SAME_SRC_DST;
      87           0 :       goto out;
      88             :     }
      89         103 :   if (ip46_address_is_multicast (&a.remote) &&
      90          41 :       !vnet_sw_if_index_is_api_valid (a.mcast_sw_if_index))
      91             :     {
      92           0 :       rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
      93           0 :       goto out;
      94             :     }
      95             : 
      96          62 :   u32 sw_if_index = ~0;
      97          62 :   rv = vnet_geneve_add_del_tunnel (&a, &sw_if_index);
      98             : 
      99          62 : out:
     100             :   /* *INDENT-OFF* */
     101          62 :   REPLY_MACRO2(VL_API_GENEVE_ADD_DEL_TUNNEL_REPLY,
     102             :   ({
     103             :     rmp->sw_if_index = ntohl (sw_if_index);
     104             :   }));
     105             :   /* *INDENT-ON* */
     106             : }
     107             : 
     108           2 : static void vl_api_geneve_add_del_tunnel2_t_handler
     109             :   (vl_api_geneve_add_del_tunnel2_t * mp)
     110             : {
     111             :   vl_api_geneve_add_del_tunnel2_reply_t *rmp;
     112           2 :   int rv = 0;
     113           2 :   ip4_main_t *im = &ip4_main;
     114             : 
     115           2 :   uword *p = hash_get (im->fib_index_by_table_id, ntohl (mp->encap_vrf_id));
     116           2 :   if (!p)
     117             :     {
     118           0 :       rv = VNET_API_ERROR_NO_SUCH_FIB;
     119           0 :       goto out;
     120             :     }
     121             : 
     122           2 :   vnet_geneve_add_del_tunnel_args_t a = {
     123           2 :     .is_add = mp->is_add,
     124           2 :     .is_ip6 = mp->remote_address.af,
     125           2 :     .mcast_sw_if_index = ntohl (mp->mcast_sw_if_index),
     126           2 :     .encap_fib_index = p[0],
     127           2 :     .decap_next_index = ntohl (mp->decap_next_index),
     128           2 :     .vni = ntohl (mp->vni),
     129           2 :     .l3_mode = mp->l3_mode,
     130             :   };
     131             : 
     132           2 :   ip_address_decode (&mp->remote_address, &a.remote);
     133           2 :   ip_address_decode (&mp->local_address, &a.local);
     134             : 
     135             :   /* Check src & dst are different */
     136           2 :   if (ip46_address_cmp (&a.remote, &a.local) == 0)
     137             :     {
     138           0 :       rv = VNET_API_ERROR_SAME_SRC_DST;
     139           0 :       goto out;
     140             :     }
     141           2 :   if (ip46_address_is_multicast (&a.remote) &&
     142           0 :       !vnet_sw_if_index_is_api_valid (a.mcast_sw_if_index))
     143             :     {
     144           0 :       rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
     145           0 :       goto out;
     146             :     }
     147             : 
     148           2 :   u32 sw_if_index = ~0;
     149           2 :   rv = vnet_geneve_add_del_tunnel (&a, &sw_if_index);
     150             : 
     151           2 : out:
     152             :   /* *INDENT-OFF* */
     153           2 :   REPLY_MACRO2(VL_API_GENEVE_ADD_DEL_TUNNEL2_REPLY,
     154             :   ({
     155             :     rmp->sw_if_index = ntohl (sw_if_index);
     156             :   }));
     157             :   /* *INDENT-ON* */
     158             : }
     159             : 
     160           0 : static void send_geneve_tunnel_details
     161             :   (geneve_tunnel_t * t, vl_api_registration_t * reg, u32 context)
     162             : {
     163             :   vl_api_geneve_tunnel_details_t *rmp;
     164           0 :   ip4_main_t *im4 = &ip4_main;
     165           0 :   ip6_main_t *im6 = &ip6_main;
     166           0 :   u8 is_ipv6 = !ip46_address_is_ip4 (&t->remote);
     167             : 
     168           0 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     169           0 :   clib_memset (rmp, 0, sizeof (*rmp));
     170           0 :   rmp->_vl_msg_id = ntohs (VL_API_GENEVE_TUNNEL_DETAILS + REPLY_MSG_ID_BASE);
     171           0 :   ip_address_encode (&t->local, is_ipv6 ? IP46_TYPE_IP6 : IP46_TYPE_IP4,
     172             :                      &rmp->src_address);
     173           0 :   ip_address_encode (&t->remote, is_ipv6 ? IP46_TYPE_IP6 : IP46_TYPE_IP4,
     174             :                      &rmp->dst_address);
     175           0 :   rmp->encap_vrf_id =
     176           0 :     htonl (is_ipv6 ? im6->fibs[t->encap_fib_index].
     177           0 :            ft_table_id : im4->fibs[t->encap_fib_index].ft_table_id);
     178             : 
     179           0 :   rmp->mcast_sw_if_index = htonl (t->mcast_sw_if_index);
     180           0 :   rmp->vni = htonl (t->vni);
     181           0 :   rmp->decap_next_index = htonl (t->decap_next_index);
     182           0 :   rmp->sw_if_index = htonl (t->sw_if_index);
     183           0 :   rmp->context = context;
     184             : 
     185           0 :   vl_api_send_msg (reg, (u8 *) rmp);
     186           0 : }
     187             : 
     188           0 : static void vl_api_geneve_tunnel_dump_t_handler
     189             :   (vl_api_geneve_tunnel_dump_t * mp)
     190             : {
     191             :   vl_api_registration_t *reg;
     192           0 :   geneve_main_t *vxm = &geneve_main;
     193             :   geneve_tunnel_t *t;
     194             :   u32 sw_if_index;
     195             : 
     196           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
     197           0 :   if (!reg)
     198           0 :     return;
     199             : 
     200           0 :   sw_if_index = ntohl (mp->sw_if_index);
     201             : 
     202           0 :   if (~0 == sw_if_index)
     203             :     {
     204             :       /* *INDENT-OFF* */
     205           0 :       pool_foreach (t, vxm->tunnels)
     206             :        {
     207           0 :         send_geneve_tunnel_details(t, reg, mp->context);
     208             :       }
     209             :       /* *INDENT-ON* */
     210             :     }
     211             :   else
     212             :     {
     213           0 :       if ((sw_if_index >= vec_len (vxm->tunnel_index_by_sw_if_index)) ||
     214           0 :           (~0 == vxm->tunnel_index_by_sw_if_index[sw_if_index]))
     215             :         {
     216           0 :           return;
     217             :         }
     218           0 :       t = &vxm->tunnels[vxm->tunnel_index_by_sw_if_index[sw_if_index]];
     219           0 :       send_geneve_tunnel_details (t, reg, mp->context);
     220             :     }
     221             : }
     222             : 
     223             : /*
     224             :  * geneve_api_hookup
     225             :  * Add geneve's API message handlers to the table.
     226             :  */
     227             : /* API definitions */
     228             : #include <vnet/format_fns.h>
     229             : #include <geneve/geneve.api.c>
     230             : 
     231             : static clib_error_t *
     232         559 : geneve_api_hookup (vlib_main_t * vm)
     233             : {
     234         559 :   api_main_t *am = vlibapi_get_main ();
     235             : 
     236             :   /*
     237             :    * Set up the (msg_name, crc, message-id) table
     238             :    */
     239         559 :   geneve_base_msg_id = setup_message_id_table ();
     240             : 
     241         559 :   vl_api_increase_msg_trace_size (
     242             :     am, VL_API_GENEVE_ADD_DEL_TUNNEL + REPLY_MSG_ID_BASE, 16 * sizeof (u32));
     243             : 
     244         559 :   return 0;
     245             : }
     246             : 
     247        1119 : VLIB_API_INIT_FUNCTION (geneve_api_hookup);
     248             : 
     249             : #include <vlib/unix/plugin.h>
     250             : #include <vpp/app/version.h>
     251             : 
     252             : /* *INDENT-OFF* */
     253             : VLIB_PLUGIN_REGISTER () = {
     254             :     .version = VPP_BUILD_VER,
     255             :     .description = "GENEVE Tunnels",
     256             : };
     257             : /* *INDENT-ON* */
     258             : 
     259             : /*
     260             :  * fd.io coding-style-patch-verification: ON
     261             :  *
     262             :  * Local Variables:
     263             :  * eval: (c-set-style "gnu")
     264             :  * End:
     265             :  */

Generated by: LCOV version 1.14