LCOV - code coverage report
Current view: top level - vnet/udp - udp_api.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 76 81 93.8 %
Date: 2023-10-26 01:39:38 Functions: 9 9 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018-2019 Cisco and/or its affiliates.
       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             : #include <vnet/vnet.h>
      17             : #include <vlibmemory/api.h>
      18             : 
      19             : #include <vnet/udp/udp_local.h>
      20             : #include <vnet/udp/udp_encap.h>
      21             : #include <vnet/fib/fib_table.h>
      22             : #include <vnet/ip/ip_types_api.h>
      23             : #include <vnet/udp/udp.h>
      24             : 
      25             : #include <vnet/format_fns.h>
      26             : #include <vnet/udp/udp.api_enum.h>
      27             : #include <vnet/udp/udp.api_types.h>
      28             : 
      29             : #define REPLY_MSG_ID_BASE udp_main.msg_id_base
      30             : #include <vlibapi/api_helper_macros.h>
      31             : 
      32             : static void
      33          83 : send_udp_encap_details (const udp_encap_t * ue, vl_api_registration_t * reg,
      34             :                         u32 context)
      35             : {
      36             :   vl_api_udp_encap_details_t *mp;
      37             : 
      38          83 :   mp = vl_msg_api_alloc (sizeof (*mp));
      39          83 :   clib_memset (mp, 0, sizeof (*mp));
      40          83 :   mp->_vl_msg_id = ntohs (REPLY_MSG_ID_BASE + VL_API_UDP_ENCAP_DETAILS);
      41          83 :   mp->context = context;
      42             : 
      43          83 :   if (FIB_PROTOCOL_IP4 == ue->ue_ip_proto)
      44             :     {
      45          53 :       clib_memcpy (&mp->udp_encap.src_ip.un.ip4,
      46             :                    &ue->ue_hdrs.ip4.ue_ip4.src_address, 4);
      47          53 :       clib_memcpy (&mp->udp_encap.dst_ip.un.ip4,
      48             :                    &ue->ue_hdrs.ip4.ue_ip4.dst_address, 4);
      49          53 :       mp->udp_encap.dst_ip.af = ip_address_family_encode (AF_IP4);
      50          53 :       mp->udp_encap.src_ip.af = ip_address_family_encode (AF_IP4);
      51             : 
      52             :       /* ports aren't byte swapped because they are stored in network
      53             :        * byte order */
      54          53 :       mp->udp_encap.src_port = ue->ue_hdrs.ip4.ue_udp.src_port;
      55          53 :       mp->udp_encap.dst_port = ue->ue_hdrs.ip4.ue_udp.dst_port;
      56             :     }
      57             :   else
      58             :     {
      59          30 :       clib_memcpy (&mp->udp_encap.src_ip.un.ip6,
      60             :                    &ue->ue_hdrs.ip6.ue_ip6.src_address, 16);
      61          30 :       clib_memcpy (&mp->udp_encap.dst_ip.un.ip6,
      62             :                    &ue->ue_hdrs.ip6.ue_ip6.dst_address, 16);
      63          30 :       mp->udp_encap.dst_ip.af = ip_address_family_encode (AF_IP6);
      64          30 :       mp->udp_encap.src_ip.af = ip_address_family_encode (AF_IP6);
      65             : 
      66             :       /* ports aren't byte swapped because they are stored in network
      67             :        * byte order */
      68          30 :       mp->udp_encap.src_port = ue->ue_hdrs.ip6.ue_udp.src_port;
      69          30 :       mp->udp_encap.dst_port = ue->ue_hdrs.ip6.ue_udp.dst_port;
      70             :     }
      71             : 
      72          83 :   mp->udp_encap.table_id =
      73          83 :     htonl (fib_table_get_table_id (ue->ue_fib_index, ue->ue_ip_proto));
      74          83 :   mp->udp_encap.id = htonl (ue - udp_encap_pool);
      75             : 
      76          83 :   vl_api_send_msg (reg, (u8 *) mp);
      77          83 : }
      78             : 
      79             : static void
      80          29 : vl_api_udp_encap_dump_t_handler (vl_api_udp_encap_dump_t *mp)
      81             : {
      82             :   vl_api_registration_t *reg;
      83             :   udp_encap_t *ue;
      84             : 
      85          29 :   reg = vl_api_client_index_to_registration (mp->client_index);
      86          29 :   if (!reg)
      87           0 :     return;
      88             : 
      89             :   /* *INDENT-OFF* */
      90         112 :   pool_foreach (ue, udp_encap_pool)
      91             :    {
      92          83 :     send_udp_encap_details(ue, reg, mp->context);
      93             :   }
      94             :   /* *INDENT-ON* */
      95             : }
      96             : 
      97             : static void
      98          10 : vl_api_udp_encap_add_t_handler (vl_api_udp_encap_add_t *mp)
      99             : {
     100             :   vl_api_udp_encap_add_reply_t *rmp;
     101             :   ip46_address_t src_ip, dst_ip;
     102             :   udp_encap_fixup_flags_t flags;
     103             :   u32 fib_index, table_id;
     104             :   fib_protocol_t fproto;
     105             :   ip46_type_t itype;
     106             :   index_t uei;
     107          10 :   int rv = 0;
     108             : 
     109          10 :   uei = INDEX_INVALID;
     110          10 :   table_id = ntohl (mp->udp_encap.table_id);
     111             : 
     112          10 :   itype = ip_address_decode (&mp->udp_encap.src_ip, &src_ip);
     113          10 :   itype = ip_address_decode (&mp->udp_encap.dst_ip, &dst_ip);
     114          10 :   fproto = fib_proto_from_ip46 (itype);
     115          10 :   fib_index = fib_table_find (fproto, table_id);
     116             : 
     117          10 :   if (~0 == fib_index)
     118             :     {
     119           0 :       rv = VNET_API_ERROR_NO_SUCH_TABLE;
     120           0 :       goto done;
     121             :     }
     122             : 
     123          10 :   flags = UDP_ENCAP_FIXUP_NONE;
     124          10 :   if (mp->udp_encap.src_port == 0)
     125           4 :     flags |= UDP_ENCAP_FIXUP_UDP_SRC_PORT_ENTROPY;
     126             : 
     127          10 :   uei = udp_encap_add_and_lock (fproto, fib_index, &src_ip, &dst_ip,
     128          10 :                                 ntohs (mp->udp_encap.src_port),
     129          10 :                                 ntohs (mp->udp_encap.dst_port), flags);
     130             : 
     131          10 : done:
     132             :   /* *INDENT-OFF* */
     133          10 :   REPLY_MACRO2 (VL_API_UDP_ENCAP_ADD_REPLY,
     134             :   ({
     135             :     rmp->id = ntohl (uei);
     136             :   }));
     137             :   /* *INDENT-ON* */
     138             : 
     139             : }
     140             : 
     141             : static void
     142          10 : vl_api_udp_encap_del_t_handler (vl_api_udp_encap_del_t *mp)
     143             : {
     144             :   vl_api_udp_encap_del_reply_t *rmp;
     145          10 :   int rv = 0;
     146             : 
     147          10 :   udp_encap_unlock (ntohl (mp->id));
     148             : 
     149          10 :   REPLY_MACRO (VL_API_UDP_ENCAP_DEL_REPLY);
     150             : }
     151             : 
     152             : u32
     153           3 : udp_api_decap_proto_to_index (vlib_main_t *vm,
     154             :                               vl_api_udp_decap_next_proto_t iproto)
     155             : {
     156           3 :   switch (iproto)
     157             :     {
     158           1 :     case UDP_API_DECAP_PROTO_IP4:
     159           1 :       return vlib_get_node_by_name (vm, (u8 *) "ip4-input")->index;
     160           1 :     case UDP_API_DECAP_PROTO_IP6:
     161           1 :       return vlib_get_node_by_name (vm, (u8 *) "ip6-input")->index;
     162           1 :     case UDP_API_DECAP_PROTO_MPLS:
     163           1 :       return vlib_get_node_by_name (vm, (u8 *) "mpls-input")->index;
     164             :     }
     165           0 :   return ~0;
     166             : }
     167             : 
     168             : static void
     169           6 : vl_api_udp_decap_add_del_t_handler (vl_api_udp_decap_add_del_t *mp)
     170             : {
     171             :   vl_api_udp_decap_add_del_reply_t *rmp;
     172           6 :   vlib_main_t *vm = vlib_get_main ();
     173           6 :   int rv = 0;
     174             : 
     175           6 :   if (mp->is_add)
     176             :     {
     177             :       u32 node_index =
     178           3 :         udp_api_decap_proto_to_index (vm, ntohl (mp->udp_decap.next_proto));
     179           3 :       if (node_index == ~0)
     180           0 :         rv = VNET_API_ERROR_INVALID_PROTOCOL;
     181             :       else
     182           3 :         udp_register_dst_port (vm, ntohs (mp->udp_decap.port), node_index,
     183           3 :                                mp->udp_decap.is_ip4);
     184             :     }
     185             :   else
     186           3 :     udp_unregister_dst_port (vm, ntohs (mp->udp_decap.port),
     187           3 :                              mp->udp_decap.is_ip4);
     188           6 :   REPLY_MACRO (VL_API_UDP_DECAP_ADD_DEL_REPLY);
     189             : }
     190             : 
     191             : #include <vnet/udp/udp.api.c>
     192             : static clib_error_t *
     193         575 : udp_api_hookup (vlib_main_t * vm)
     194             : {
     195         575 :   api_main_t *am = vlibapi_get_main ();
     196             : 
     197             :   /*
     198             :    * Set up the (msg_name, crc, message-id) table
     199             :    */
     200         575 :   REPLY_MSG_ID_BASE = setup_message_id_table ();
     201             : 
     202             :   /* Mark these APIs as mp safe */
     203         575 :   vl_api_set_msg_thread_safe (am, REPLY_MSG_ID_BASE + VL_API_UDP_ENCAP_ADD, 1);
     204         575 :   vl_api_set_msg_thread_safe (am, REPLY_MSG_ID_BASE + VL_API_UDP_ENCAP_DEL, 1);
     205         575 :   vl_api_set_msg_thread_safe (am, REPLY_MSG_ID_BASE + VL_API_UDP_ENCAP_DUMP,
     206             :                               1);
     207             : 
     208         575 :   return 0;
     209             : }
     210             : 
     211        9215 : VLIB_API_INIT_FUNCTION (udp_api_hookup);
     212             : 
     213             : /*
     214             :  * fd.io coding-style-patch-verification: ON
     215             :  *
     216             :  * Local Variables:
     217             :  * eval: (c-set-style "gnu")
     218             :  * End:
     219             :  */

Generated by: LCOV version 1.14