LCOV - code coverage report
Current view: top level - plugins/gtpu - gtpu_api.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 26 125 20.8 %
Date: 2023-07-05 22:20:52 Functions: 4 9 44.4 %

          Line data    Source code
       1             : /*
       2             :  *------------------------------------------------------------------
       3             :  * gtpu_api.c - gtpu api
       4             :  *
       5             :  * Copyright (c) 2017 Intel 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/interface.h>
      21             : #include <vnet/api_errno.h>
      22             : #include <vnet/feature/feature.h>
      23             : #include <vnet/fib/fib_table.h>
      24             : 
      25             : #include <vppinfra/byte_order.h>
      26             : #include <vlibmemory/api.h>
      27             : #include <vnet/ip/ip_types_api.h>
      28             : #include <gtpu/gtpu.h>
      29             : 
      30             : #include <vnet/format_fns.h>
      31             : #include <gtpu/gtpu.api_enum.h>
      32             : #include <gtpu/gtpu.api_types.h>
      33             : 
      34             : #define REPLY_MSG_ID_BASE gtm->msg_id_base
      35             : #include <vlibapi/api_helper_macros.h>
      36             : 
      37             : static void
      38           0 : vl_api_gtpu_offload_rx_t_handler (vl_api_gtpu_offload_rx_t * mp)
      39             : {
      40             :   vl_api_gtpu_offload_rx_reply_t *rmp;
      41           0 :   int rv = 0;
      42           0 :   vl_api_interface_index_t hw_if_index = ntohl (mp->hw_if_index);
      43           0 :   vl_api_interface_index_t sw_if_index = ntohl (mp->sw_if_index);
      44             : 
      45           0 :   if (!vnet_hw_interface_is_valid (vnet_get_main (), hw_if_index))
      46             :     {
      47           0 :       rv = VNET_API_ERROR_NO_SUCH_ENTRY;
      48           0 :       goto err;
      49             :     }
      50           0 :   VALIDATE_SW_IF_INDEX (mp);
      51             : 
      52           0 :   u32 t_index = vnet_gtpu_get_tunnel_index (sw_if_index);
      53           0 :   if (t_index == ~0)
      54             :     {
      55           0 :       rv = VNET_API_ERROR_INVALID_SW_IF_INDEX_2;
      56           0 :       goto err;
      57             :     }
      58             : 
      59           0 :   gtpu_main_t *gtm = &gtpu_main;
      60           0 :   gtpu_tunnel_t *t = pool_elt_at_index (gtm->tunnels, t_index);
      61           0 :   if (!ip46_address_is_ip4 (&t->dst))
      62             :     {
      63           0 :       rv = VNET_API_ERROR_INVALID_ADDRESS_FAMILY;
      64           0 :       goto err;
      65             :     }
      66             : 
      67           0 :   if ((t->decap_next_index != GTPU_INPUT_NEXT_IP4_INPUT) &&
      68           0 :       (t->decap_next_index != GTPU_INPUT_NEXT_IP6_INPUT))
      69             :     {
      70           0 :       rv = VNET_API_ERROR_INVALID_ADDRESS_FAMILY;
      71           0 :       goto err;
      72             :     }
      73             : 
      74           0 :   vnet_main_t *vnm = vnet_get_main ();
      75           0 :   vnet_hw_interface_t *hw_if = vnet_get_hw_interface (vnm, hw_if_index);
      76           0 :   ip4_main_t *im = &ip4_main;
      77           0 :   u32 rx_fib_index =
      78           0 :     vec_elt (im->fib_index_by_sw_if_index, hw_if->sw_if_index);
      79             : 
      80           0 :   if (t->encap_fib_index != rx_fib_index)
      81             :     {
      82           0 :       rv = VNET_API_ERROR_NO_SUCH_FIB;
      83           0 :       goto err;
      84             :     }
      85             : 
      86           0 :   if (vnet_gtpu_add_del_rx_flow (hw_if_index, t_index, mp->enable))
      87             :     {
      88           0 :       rv = VNET_API_ERROR_UNSPECIFIED;
      89           0 :       goto err;
      90             :     }
      91           0 :   BAD_SW_IF_INDEX_LABEL;
      92           0 : err:
      93             : 
      94           0 :   REPLY_MACRO (VL_API_GTPU_OFFLOAD_RX_REPLY);
      95             : }
      96             : 
      97             : static void
      98           0 :   vl_api_sw_interface_set_gtpu_bypass_t_handler
      99             :   (vl_api_sw_interface_set_gtpu_bypass_t * mp)
     100             : {
     101             :   vl_api_sw_interface_set_gtpu_bypass_reply_t *rmp;
     102           0 :   int rv = 0;
     103           0 :   u32 sw_if_index = ntohl (mp->sw_if_index);
     104           0 :   gtpu_main_t *gtm = &gtpu_main;
     105             : 
     106           0 :   VALIDATE_SW_IF_INDEX (mp);
     107             : 
     108           0 :   vnet_int_gtpu_bypass_mode (sw_if_index, mp->is_ipv6, mp->enable);
     109           0 :   BAD_SW_IF_INDEX_LABEL;
     110             : 
     111           0 :   REPLY_MACRO (VL_API_SW_INTERFACE_SET_GTPU_BYPASS_REPLY);
     112             : }
     113             : 
     114         106 : static void vl_api_gtpu_add_del_tunnel_t_handler
     115             :   (vl_api_gtpu_add_del_tunnel_t * mp)
     116             : {
     117             :   vl_api_gtpu_add_del_tunnel_reply_t *rmp;
     118         106 :   int rv = 0;
     119         106 :   gtpu_main_t *gtm = &gtpu_main;
     120             : 
     121         106 :   vnet_gtpu_add_mod_del_tunnel_args_t a = {
     122         106 :     .opn = mp->is_add ? GTPU_ADD_TUNNEL : GTPU_DEL_TUNNEL,
     123         106 :     .mcast_sw_if_index = ntohl (mp->mcast_sw_if_index),
     124         106 :     .decap_next_index = ntohl (mp->decap_next_index),
     125         106 :     .teid = ntohl (mp->teid),
     126         106 :     .tteid = ntohl (mp->tteid),
     127             :   };
     128         106 :   ip_address_decode (&mp->dst_address, &a.dst);
     129         106 :   ip_address_decode (&mp->src_address, &a.src);
     130             : 
     131         106 :   u8 is_ipv6 = !ip46_address_is_ip4 (&a.dst);
     132         106 :   a.encap_fib_index = fib_table_find (fib_ip_proto (is_ipv6),
     133             :                                       ntohl (mp->encap_vrf_id));
     134         106 :   if (a.encap_fib_index == ~0)
     135             :     {
     136           0 :       rv = VNET_API_ERROR_NO_SUCH_FIB;
     137           0 :       goto out;
     138             :     }
     139             : 
     140             :   /* Check src & dst are different */
     141         106 :   if (ip46_address_cmp (&a.dst, &a.src) == 0)
     142             :     {
     143           0 :       rv = VNET_API_ERROR_SAME_SRC_DST;
     144           0 :       goto out;
     145             :     }
     146         187 :   if (ip46_address_is_multicast (&a.dst) &&
     147          81 :       !vnet_sw_if_index_is_api_valid (a.mcast_sw_if_index))
     148             :     {
     149           0 :       rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
     150           0 :       goto out;
     151             :     }
     152             : 
     153         106 :   u32 sw_if_index = ~0;
     154         106 :   rv = vnet_gtpu_add_mod_del_tunnel (&a, &sw_if_index);
     155             : 
     156         106 : out:
     157             :   /* *INDENT-OFF* */
     158         106 :   REPLY_MACRO2(VL_API_GTPU_ADD_DEL_TUNNEL_REPLY,
     159             :   ({
     160             :     rmp->sw_if_index = ntohl (sw_if_index);
     161             :   }));
     162             :   /* *INDENT-ON* */
     163             : }
     164             : 
     165           0 : static void vl_api_gtpu_tunnel_update_tteid_t_handler
     166             :   (vl_api_gtpu_tunnel_update_tteid_t * mp)
     167             : {
     168             :   vl_api_gtpu_tunnel_update_tteid_reply_t *rmp;
     169           0 :   int rv = 0;
     170           0 :   gtpu_main_t *gtm = &gtpu_main;
     171             : 
     172           0 :   vnet_gtpu_add_mod_del_tunnel_args_t a = {
     173             :     .opn = GTPU_UPD_TTEID,
     174           0 :     .teid = ntohl (mp->teid),
     175           0 :     .tteid = ntohl (mp->tteid),
     176             :   };
     177           0 :   ip_address_decode (&mp->dst_address, &a.dst);
     178             : 
     179           0 :   u8 is_ipv6 = !ip46_address_is_ip4 (&a.dst);
     180           0 :   a.encap_fib_index = fib_table_find (fib_ip_proto (is_ipv6),
     181             :                                       ntohl (mp->encap_vrf_id));
     182           0 :   if (a.encap_fib_index == ~0)
     183             :     {
     184           0 :       rv = VNET_API_ERROR_NO_SUCH_FIB;
     185           0 :       goto out;
     186             :     }
     187             : 
     188           0 :   rv = vnet_gtpu_add_mod_del_tunnel (&a, 0);
     189             : 
     190           0 : out:
     191           0 :   REPLY_MACRO (VL_API_GTPU_TUNNEL_UPDATE_TTEID_REPLY);
     192             : }
     193             : 
     194           0 : static void send_gtpu_tunnel_details
     195             :   (gtpu_tunnel_t * t, vl_api_registration_t * reg, u32 context)
     196             : {
     197             :   vl_api_gtpu_tunnel_details_t *rmp;
     198           0 :   gtpu_main_t *gtm = &gtpu_main;
     199           0 :   ip4_main_t *im4 = &ip4_main;
     200           0 :   ip6_main_t *im6 = &ip6_main;
     201           0 :   u8 is_ipv6 = !ip46_address_is_ip4 (&t->dst);
     202             : 
     203           0 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     204           0 :   clib_memset (rmp, 0, sizeof (*rmp));
     205           0 :   rmp->_vl_msg_id = ntohs (VL_API_GTPU_TUNNEL_DETAILS + gtm->msg_id_base);
     206             : 
     207           0 :   ip_address_encode (&t->src, is_ipv6 ? IP46_TYPE_IP6 : IP46_TYPE_IP4,
     208             :                      &rmp->src_address);
     209           0 :   ip_address_encode (&t->dst, is_ipv6 ? IP46_TYPE_IP6 : IP46_TYPE_IP4,
     210             :                      &rmp->dst_address);
     211             : 
     212           0 :   rmp->encap_vrf_id =
     213           0 :     is_ipv6 ? htonl (im6->fibs[t->encap_fib_index].ft_table_id) :
     214           0 :     htonl (im4->fibs[t->encap_fib_index].ft_table_id);
     215           0 :   rmp->mcast_sw_if_index = htonl (t->mcast_sw_if_index);
     216           0 :   rmp->teid = htonl (t->teid);
     217           0 :   rmp->tteid = htonl (t->tteid);
     218           0 :   rmp->decap_next_index = htonl (t->decap_next_index);
     219           0 :   rmp->sw_if_index = htonl (t->sw_if_index);
     220           0 :   rmp->context = context;
     221             : 
     222           0 :   vl_api_send_msg (reg, (u8 *) rmp);
     223           0 : }
     224             : 
     225             : static void
     226           0 : vl_api_gtpu_tunnel_dump_t_handler (vl_api_gtpu_tunnel_dump_t * mp)
     227             : {
     228             :   vl_api_registration_t *reg;
     229           0 :   gtpu_main_t *gtm = &gtpu_main;
     230             :   gtpu_tunnel_t *t;
     231             :   u32 sw_if_index;
     232             : 
     233           0 :   reg = vl_api_client_index_to_registration (mp->client_index);
     234           0 :   if (!reg)
     235           0 :     return;
     236             : 
     237           0 :   sw_if_index = ntohl (mp->sw_if_index);
     238             : 
     239           0 :   if (~0 == sw_if_index)
     240             :     {
     241             :       /* *INDENT-OFF* */
     242           0 :       pool_foreach (t, gtm->tunnels)
     243             :        {
     244           0 :         send_gtpu_tunnel_details(t, reg, mp->context);
     245             :       }
     246             :       /* *INDENT-ON* */
     247             :     }
     248             :   else
     249             :     {
     250           0 :       if ((sw_if_index >= vec_len (gtm->tunnel_index_by_sw_if_index)) ||
     251           0 :           (~0 == gtm->tunnel_index_by_sw_if_index[sw_if_index]))
     252             :         {
     253           0 :           return;
     254             :         }
     255           0 :       t = &gtm->tunnels[gtm->tunnel_index_by_sw_if_index[sw_if_index]];
     256           0 :       send_gtpu_tunnel_details (t, reg, mp->context);
     257             :     }
     258             : }
     259             : 
     260             : #include <gtpu/gtpu.api.c>
     261             : static clib_error_t *
     262         559 : gtpu_api_hookup (vlib_main_t * vm)
     263             : {
     264         559 :   gtpu_main_t *gtm = &gtpu_main;
     265             : 
     266         559 :   gtm->msg_id_base = setup_message_id_table ();
     267         559 :   return 0;
     268             : }
     269             : 
     270        1119 : VLIB_API_INIT_FUNCTION (gtpu_api_hookup);
     271             : 
     272             : /*
     273             :  * fd.io coding-style-patch-verification: ON
     274             :  *
     275             :  * Local Variables:
     276             :  * eval: (c-set-style "gnu")
     277             :  * End:
     278             :  */

Generated by: LCOV version 1.14