LCOV - code coverage report
Current view: top level - plugins/nat/nat64 - nat64_api.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 192 205 93.7 %
Date: 2023-10-26 01:39:38 Functions: 19 19 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2020 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/ip/ip_types_api.h>
      17             : #include <vlibmemory/api.h>
      18             : #include <nat/nat64/nat64.h>
      19             : #include <nat/nat64/nat64.api_enum.h>
      20             : #include <nat/nat64/nat64.api_types.h>
      21             : #include <vnet/fib/fib_table.h>
      22             : #include <vnet/ip/ip.h>
      23             : 
      24             : #define REPLY_MSG_ID_BASE nm->msg_id_base
      25             : #include <vlibapi/api_helper_macros.h>
      26             : 
      27             : static void
      28          40 :   vl_api_nat64_plugin_enable_disable_t_handler
      29             :   (vl_api_nat64_plugin_enable_disable_t * mp)
      30             : {
      31          40 :   nat64_main_t *nm = &nat64_main;
      32             :   vl_api_nat64_plugin_enable_disable_reply_t *rmp;
      33          40 :   nat64_config_t c = { 0 };
      34          40 :   int rv = 0;
      35          40 :   if (mp->enable)
      36             :     {
      37          20 :       c.bib_buckets = ntohl (mp->bib_buckets);
      38          20 :       c.bib_memory_size = ntohl (mp->bib_memory_size);
      39          20 :       c.st_buckets = ntohl (mp->st_buckets);
      40          20 :       c.st_memory_size = ntohl (mp->st_memory_size);
      41          20 :       rv = nat64_plugin_enable (c);
      42             :     }
      43             :   else
      44             :     {
      45          20 :       rv = nat64_plugin_disable ();
      46             :     }
      47          40 :   REPLY_MACRO (VL_API_NAT64_PLUGIN_ENABLE_DISABLE_REPLY);
      48             : }
      49             : 
      50             : static void
      51           2 : vl_api_nat64_set_timeouts_t_handler (vl_api_nat64_set_timeouts_t * mp)
      52             : {
      53           2 :   nat64_main_t *nm = &nat64_main;
      54             :   vl_api_nat64_set_timeouts_reply_t *rmp;
      55           2 :   int rv = 0;
      56             : 
      57           2 :   nm->udp_timeout = ntohl (mp->udp);
      58           2 :   nm->tcp_est_timeout = ntohl (mp->tcp_established);
      59           2 :   nm->tcp_trans_timeout = ntohl (mp->tcp_transitory);
      60           2 :   nm->icmp_timeout = ntohl (mp->icmp);
      61             : 
      62           2 :   REPLY_MACRO (VL_API_NAT64_SET_TIMEOUTS_REPLY);
      63             : }
      64             : 
      65             : static void
      66           2 : vl_api_nat64_get_timeouts_t_handler (vl_api_nat64_get_timeouts_t * mp)
      67             : {
      68           2 :   nat64_main_t *nm = &nat64_main;
      69             :   vl_api_nat64_get_timeouts_reply_t *rmp;
      70           2 :   int rv = 0;
      71             : 
      72             :   /* *INDENT-OFF* */
      73           2 :   REPLY_MACRO2 (VL_API_NAT64_GET_TIMEOUTS_REPLY,
      74             :   ({
      75             :     rmp->udp = htonl (nm->udp_timeout);
      76             :     rmp->tcp_established = htonl (nm->tcp_est_timeout);
      77             :     rmp->tcp_transitory = htonl (nm->tcp_trans_timeout);
      78             :     rmp->icmp = htonl (nm->icmp_timeout);
      79             :   }))
      80             :   /* *INDENT-ON* */
      81             : }
      82             : 
      83             : static void
      84          20 :   vl_api_nat64_add_del_pool_addr_range_t_handler
      85             :   (vl_api_nat64_add_del_pool_addr_range_t * mp)
      86             : {
      87          20 :   nat64_main_t *nm = &nat64_main;
      88             :   vl_api_nat64_add_del_pool_addr_range_reply_t *rmp;
      89          20 :   int rv = 0;
      90             :   ip4_address_t this_addr;
      91             :   u32 start_host_order, end_host_order;
      92             :   u32 vrf_id;
      93             :   int i, count;
      94             :   u32 *tmp;
      95             : 
      96          20 :   tmp = (u32 *) mp->start_addr;
      97          20 :   start_host_order = clib_host_to_net_u32 (tmp[0]);
      98          20 :   tmp = (u32 *) mp->end_addr;
      99          20 :   end_host_order = clib_host_to_net_u32 (tmp[0]);
     100             : 
     101          20 :   count = (end_host_order - start_host_order) + 1;
     102             : 
     103          20 :   vrf_id = clib_host_to_net_u32 (mp->vrf_id);
     104             : 
     105          20 :   memcpy (&this_addr.as_u8, mp->start_addr, 4);
     106             : 
     107          50 :   for (i = 0; i < count; i++)
     108             :     {
     109          30 :       if ((rv = nat64_add_del_pool_addr (0, &this_addr, vrf_id, mp->is_add)))
     110           0 :         goto send_reply;
     111             : 
     112          30 :       increment_v4_address (&this_addr);
     113             :     }
     114             : 
     115          20 : send_reply:
     116          20 :   REPLY_MACRO (VL_API_NAT64_ADD_DEL_POOL_ADDR_RANGE_REPLY);
     117             : }
     118             : 
     119             : typedef struct nat64_api_walk_ctx_t_
     120             : {
     121             :   vl_api_registration_t *reg;
     122             :   u32 context;
     123             :   nat64_db_t *db;
     124             : } nat64_api_walk_ctx_t;
     125             : 
     126             : static int
     127           2 : nat64_api_pool_walk (nat64_address_t * a, void *arg)
     128             : {
     129           2 :   nat64_main_t *nm = &nat64_main;
     130             :   vl_api_nat64_pool_addr_details_t *rmp;
     131           2 :   nat64_api_walk_ctx_t *ctx = arg;
     132             : 
     133           2 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     134           2 :   clib_memset (rmp, 0, sizeof (*rmp));
     135           2 :   rmp->_vl_msg_id = ntohs (VL_API_NAT64_POOL_ADDR_DETAILS + nm->msg_id_base);
     136           2 :   clib_memcpy (rmp->address, &(a->addr), 4);
     137           2 :   if (a->fib_index != ~0)
     138             :     {
     139           0 :       fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP6);
     140           0 :       if (!fib)
     141           0 :         return -1;
     142           0 :       rmp->vrf_id = ntohl (fib->ft_table_id);
     143             :     }
     144             :   else
     145           2 :     rmp->vrf_id = ~0;
     146           2 :   rmp->context = ctx->context;
     147             : 
     148           2 :   vl_api_send_msg (ctx->reg, (u8 *) rmp);
     149             : 
     150           2 :   return 0;
     151             : }
     152             : 
     153             : static void
     154           4 : vl_api_nat64_pool_addr_dump_t_handler (vl_api_nat64_pool_addr_dump_t * mp)
     155             : {
     156             :   vl_api_registration_t *reg;
     157             : 
     158           4 :   reg = vl_api_client_index_to_registration (mp->client_index);
     159           4 :   if (!reg)
     160           0 :     return;
     161             : 
     162           4 :   nat64_api_walk_ctx_t ctx = {
     163             :     .reg = reg,
     164           4 :     .context = mp->context,
     165             :   };
     166             : 
     167           4 :   nat64_pool_addr_walk (nat64_api_pool_walk, &ctx);
     168             : }
     169             : 
     170             : static void
     171          35 : vl_api_nat64_add_del_interface_t_handler (vl_api_nat64_add_del_interface_t *
     172             :                                           mp)
     173             : {
     174          35 :   nat64_main_t *nm = &nat64_main;
     175             :   vl_api_nat64_add_del_interface_reply_t *rmp;
     176          35 :   int rv = 0;
     177             : 
     178          35 :   VALIDATE_SW_IF_INDEX (mp);
     179             : 
     180             :   rv =
     181          35 :     nat64_interface_add_del (ntohl (mp->sw_if_index),
     182          35 :                              mp->flags & NAT_API_IS_INSIDE, mp->is_add);
     183             : 
     184          35 :   BAD_SW_IF_INDEX_LABEL;
     185             : 
     186          35 :   REPLY_MACRO (VL_API_NAT64_ADD_DEL_INTERFACE_REPLY);
     187             : }
     188             : 
     189             : static int
     190           2 : nat64_api_interface_walk (nat64_interface_t * i, void *arg)
     191             : {
     192           2 :   nat64_main_t *nm = &nat64_main;
     193             :   vl_api_nat64_interface_details_t *rmp;
     194           2 :   nat64_api_walk_ctx_t *ctx = arg;
     195             : 
     196           2 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     197           2 :   clib_memset (rmp, 0, sizeof (*rmp));
     198           2 :   rmp->_vl_msg_id = ntohs (VL_API_NAT64_INTERFACE_DETAILS + nm->msg_id_base);
     199           2 :   rmp->sw_if_index = ntohl (i->sw_if_index);
     200             : 
     201           2 :   if (nat64_interface_is_inside (i))
     202           1 :     rmp->flags |= NAT_API_IS_INSIDE;
     203           2 :   if (nat64_interface_is_outside (i))
     204           1 :     rmp->flags |= NAT_API_IS_OUTSIDE;
     205             : 
     206           2 :   rmp->context = ctx->context;
     207             : 
     208           2 :   vl_api_send_msg (ctx->reg, (u8 *) rmp);
     209             : 
     210           2 :   return 0;
     211             : }
     212             : 
     213             : static void
     214           2 : vl_api_nat64_interface_dump_t_handler (vl_api_nat64_interface_dump_t * mp)
     215             : {
     216             :   vl_api_registration_t *reg;
     217             : 
     218           2 :   reg = vl_api_client_index_to_registration (mp->client_index);
     219           2 :   if (!reg)
     220           0 :     return;
     221             : 
     222           2 :   nat64_api_walk_ctx_t ctx = {
     223             :     .reg = reg,
     224           2 :     .context = mp->context,
     225             :   };
     226             : 
     227           2 :   nat64_interfaces_walk (nat64_api_interface_walk, &ctx);
     228             : }
     229             : 
     230             : static void
     231          11 :   vl_api_nat64_add_del_static_bib_t_handler
     232             :   (vl_api_nat64_add_del_static_bib_t * mp)
     233             : {
     234          11 :   nat64_main_t *nm = &nat64_main;
     235             :   vl_api_nat64_add_del_static_bib_reply_t *rmp;
     236             :   ip6_address_t in_addr;
     237             :   ip4_address_t out_addr;
     238          11 :   int rv = 0;
     239             : 
     240          11 :   memcpy (&in_addr.as_u8, mp->i_addr, 16);
     241          11 :   memcpy (&out_addr.as_u8, mp->o_addr, 4);
     242             : 
     243             :   rv =
     244          11 :     nat64_add_del_static_bib_entry (&in_addr, &out_addr,
     245          11 :                                     clib_net_to_host_u16 (mp->i_port),
     246          11 :                                     clib_net_to_host_u16 (mp->o_port),
     247          11 :                                     mp->proto,
     248             :                                     clib_net_to_host_u32 (mp->vrf_id),
     249          11 :                                     mp->is_add);
     250             : 
     251          11 :   REPLY_MACRO (VL_API_NAT64_ADD_DEL_STATIC_BIB_REPLY);
     252             : }
     253             : 
     254             : static int
     255           1 : nat64_api_bib_walk (nat64_db_bib_entry_t * bibe, void *arg)
     256             : {
     257           1 :   nat64_main_t *nm = &nat64_main;
     258             :   vl_api_nat64_bib_details_t *rmp;
     259           1 :   nat64_api_walk_ctx_t *ctx = arg;
     260             :   fib_table_t *fib;
     261             : 
     262           1 :   fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
     263           1 :   if (!fib)
     264           0 :     return -1;
     265             : 
     266           1 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     267           1 :   clib_memset (rmp, 0, sizeof (*rmp));
     268           1 :   rmp->_vl_msg_id = ntohs (VL_API_NAT64_BIB_DETAILS + nm->msg_id_base);
     269           1 :   rmp->context = ctx->context;
     270           1 :   clib_memcpy (rmp->i_addr, &(bibe->in_addr), 16);
     271           1 :   clib_memcpy (rmp->o_addr, &(bibe->out_addr), 4);
     272           1 :   rmp->i_port = bibe->in_port;
     273           1 :   rmp->o_port = bibe->out_port;
     274           1 :   rmp->vrf_id = ntohl (fib->ft_table_id);
     275           1 :   rmp->proto = bibe->proto;
     276           1 :   if (bibe->is_static)
     277           1 :     rmp->flags |= NAT_API_IS_STATIC;
     278           1 :   rmp->ses_num = ntohl (bibe->ses_num);
     279             : 
     280           1 :   vl_api_send_msg (ctx->reg, (u8 *) rmp);
     281             : 
     282           1 :   return 0;
     283             : }
     284             : 
     285             : static void
     286           2 : vl_api_nat64_bib_dump_t_handler (vl_api_nat64_bib_dump_t * mp)
     287             : {
     288           2 :   nat64_main_t *nm = &nat64_main;
     289             :   vl_api_registration_t *reg;
     290             :   nat64_db_t *db;
     291             : 
     292           2 :   reg = vl_api_client_index_to_registration (mp->client_index);
     293           2 :   if (!reg)
     294           0 :     return;
     295             : 
     296           2 :   nat64_api_walk_ctx_t ctx = {
     297             :     .reg = reg,
     298           2 :     .context = mp->context,
     299             :   };
     300             : 
     301             :   /* *INDENT-OFF* */
     302           4 :   vec_foreach (db, nm->db)
     303           2 :     nat64_db_bib_walk (db, mp->proto, nat64_api_bib_walk, &ctx);
     304             :   /* *INDENT-ON* */
     305             : }
     306             : 
     307             : static int
     308          10 : nat64_api_st_walk (nat64_db_st_entry_t * ste, void *arg)
     309             : {
     310          10 :   nat64_main_t *nm = &nat64_main;
     311             :   vl_api_nat64_st_details_t *rmp;
     312          10 :   nat64_api_walk_ctx_t *ctx = arg;
     313             :   nat64_db_bib_entry_t *bibe;
     314             :   fib_table_t *fib;
     315             : 
     316          10 :   bibe = nat64_db_bib_entry_by_index (ctx->db, ste->proto, ste->bibe_index);
     317          10 :   if (!bibe)
     318           0 :     return -1;
     319             : 
     320          10 :   fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
     321          10 :   if (!fib)
     322           0 :     return -1;
     323             : 
     324          10 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     325          10 :   clib_memset (rmp, 0, sizeof (*rmp));
     326          10 :   rmp->_vl_msg_id = ntohs (VL_API_NAT64_ST_DETAILS + nm->msg_id_base);
     327          10 :   rmp->context = ctx->context;
     328          10 :   clib_memcpy (rmp->il_addr, &(bibe->in_addr), 16);
     329          10 :   clib_memcpy (rmp->ol_addr, &(bibe->out_addr), 4);
     330          10 :   rmp->il_port = bibe->in_port;
     331          10 :   rmp->ol_port = bibe->out_port;
     332          10 :   clib_memcpy (rmp->ir_addr, &(ste->in_r_addr), 16);
     333          10 :   clib_memcpy (rmp->or_addr, &(ste->out_r_addr), 4);
     334          10 :   rmp->il_port = ste->r_port;
     335          10 :   rmp->vrf_id = ntohl (fib->ft_table_id);
     336          10 :   rmp->proto = ste->proto;
     337             : 
     338          10 :   vl_api_send_msg (ctx->reg, (u8 *) rmp);
     339             : 
     340          10 :   return 0;
     341             : }
     342             : 
     343             : static void
     344           6 : vl_api_nat64_st_dump_t_handler (vl_api_nat64_st_dump_t * mp)
     345             : {
     346           6 :   nat64_main_t *nm = &nat64_main;
     347             :   vl_api_registration_t *reg;
     348             :   nat64_db_t *db;
     349             : 
     350           6 :   reg = vl_api_client_index_to_registration (mp->client_index);
     351           6 :   if (!reg)
     352           0 :     return;
     353             : 
     354           6 :   nat64_api_walk_ctx_t ctx = {
     355             :     .reg = reg,
     356           6 :     .context = mp->context,
     357             :   };
     358             : 
     359             :   /* *INDENT-OFF* */
     360          12 :   vec_foreach (db, nm->db)
     361             :     {
     362           6 :       ctx.db = db;
     363           6 :       nat64_db_st_walk (db, mp->proto, nat64_api_st_walk, &ctx);
     364             :     }
     365             :   /* *INDENT-ON* */
     366             : }
     367             : 
     368             : static void
     369           2 : vl_api_nat64_add_del_prefix_t_handler (vl_api_nat64_add_del_prefix_t * mp)
     370             : {
     371           2 :   nat64_main_t *nm = &nat64_main;
     372             :   vl_api_nat64_add_del_prefix_reply_t *rmp;
     373             :   ip6_address_t prefix;
     374           2 :   int rv = 0;
     375             : 
     376           2 :   memcpy (&prefix.as_u8, mp->prefix.address, 16);
     377             : 
     378             :   rv =
     379           2 :     nat64_add_del_prefix (&prefix, mp->prefix.len,
     380           2 :                           clib_net_to_host_u32 (mp->vrf_id), mp->is_add);
     381           2 :   REPLY_MACRO (VL_API_NAT64_ADD_DEL_PREFIX_REPLY);
     382             : }
     383             : 
     384             : static int
     385           3 : nat64_api_prefix_walk (nat64_prefix_t * p, void *arg)
     386             : {
     387           3 :   nat64_main_t *nm = &nat64_main;
     388             :   vl_api_nat64_prefix_details_t *rmp;
     389           3 :   nat64_api_walk_ctx_t *ctx = arg;
     390             : 
     391           3 :   rmp = vl_msg_api_alloc (sizeof (*rmp));
     392           3 :   clib_memset (rmp, 0, sizeof (*rmp));
     393           3 :   rmp->_vl_msg_id = ntohs (VL_API_NAT64_PREFIX_DETAILS + nm->msg_id_base);
     394           3 :   clib_memcpy (rmp->prefix.address, &(p->prefix), 16);
     395           3 :   rmp->prefix.len = p->plen;
     396           3 :   rmp->vrf_id = ntohl (p->vrf_id);
     397           3 :   rmp->context = ctx->context;
     398             : 
     399           3 :   vl_api_send_msg (ctx->reg, (u8 *) rmp);
     400             : 
     401           3 :   return 0;
     402             : }
     403             : 
     404             : static void
     405           2 : vl_api_nat64_prefix_dump_t_handler (vl_api_nat64_prefix_dump_t * mp)
     406             : {
     407             :   vl_api_registration_t *reg;
     408             : 
     409           2 :   reg = vl_api_client_index_to_registration (mp->client_index);
     410           2 :   if (!reg)
     411           0 :     return;
     412             : 
     413           2 :   nat64_api_walk_ctx_t ctx = {
     414             :     .reg = reg,
     415           2 :     .context = mp->context,
     416             :   };
     417             : 
     418           2 :   nat64_prefix_walk (nat64_api_prefix_walk, &ctx);
     419             : }
     420             : 
     421             : static void
     422           1 :   vl_api_nat64_add_del_interface_addr_t_handler
     423             :   (vl_api_nat64_add_del_interface_addr_t * mp)
     424             : {
     425           1 :   nat64_main_t *nm = &nat64_main;
     426             :   vl_api_nat64_add_del_interface_addr_reply_t *rmp;
     427           1 :   u32 sw_if_index = ntohl (mp->sw_if_index);
     428           1 :   int rv = 0;
     429             : 
     430           1 :   VALIDATE_SW_IF_INDEX (mp);
     431             : 
     432           1 :   rv = nat64_add_interface_address (sw_if_index, mp->is_add);
     433             : 
     434           1 :   BAD_SW_IF_INDEX_LABEL;
     435             : 
     436           1 :   REPLY_MACRO (VL_API_NAT64_ADD_DEL_INTERFACE_ADDR_REPLY);
     437             : }
     438             : 
     439             : /* API definitions */
     440             : #include <vnet/format_fns.h>
     441             : #include <nat/nat64/nat64.api.c>
     442             : 
     443             : /* Set up the API message handling tables */
     444             : clib_error_t *
     445         575 : nat64_api_hookup (vlib_main_t * vm)
     446             : {
     447         575 :   nat64_main_t *nm = &nat64_main;
     448         575 :   nm->msg_id_base = setup_message_id_table ();
     449         575 :   return 0;
     450             : }
     451             : 
     452             : /*
     453             :  * fd.io coding-style-patch-verification: ON
     454             :  *
     455             :  * Local Variables:
     456             :  * eval: (c-set-style "gnu")
     457             :  * End:
     458             :  */

Generated by: LCOV version 1.14