LCOV - code coverage report
Current view: top level - plugins/nat/nat66 - nat66_cli.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 5 149 3.4 %
Date: 2023-07-05 22:20:52 Functions: 10 17 58.8 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 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             :  * @file
      17             :  * @brief NAT66 CLI
      18             :  */
      19             : 
      20             : #include <nat/nat66/nat66.h>
      21             : #include <vnet/fib/fib_table.h>
      22             : 
      23             : #define NAT66_EXPECTED_ARGUMENT "expected required argument(s)"
      24             : #define NAT66_PLUGIN_DISABLED   "error plugin disabled"
      25             : 
      26             : #define CHECK_ENABLED()                                                       \
      27             :   do                                                                          \
      28             :     {                                                                         \
      29             :       if (PREDICT_FALSE (!nat66_main.enabled))                                \
      30             :         {                                                                     \
      31             :           return clib_error_return (0, NAT66_PLUGIN_DISABLED);                \
      32             :         }                                                                     \
      33             :     }                                                                         \
      34             :   while (0)
      35             : 
      36             : static clib_error_t *
      37           0 : nat66_enable_disable_command_fn (vlib_main_t *vm, unformat_input_t *input,
      38             :                                  vlib_cli_command_t *cmd)
      39             : {
      40           0 :   nat66_main_t *nm = &nat66_main;
      41           0 :   unformat_input_t _line_input, *line_input = &_line_input;
      42           0 :   clib_error_t *error = 0;
      43             : 
      44           0 :   u32 outside_vrf = 0;
      45           0 :   u8 enable_set = 0, enable = 0;
      46             : 
      47           0 :   if (!unformat_user (input, unformat_line_input, line_input))
      48           0 :     return clib_error_return (0, NAT66_EXPECTED_ARGUMENT);
      49             : 
      50           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
      51             :     {
      52           0 :       if (unformat (line_input, "outside-vrf %u", &outside_vrf))
      53             :         ;
      54           0 :       else if (!enable_set)
      55             :         {
      56           0 :           enable_set = 1;
      57           0 :           if (unformat (line_input, "disable"))
      58             :             ;
      59           0 :           else if (unformat (line_input, "enable"))
      60           0 :             enable = 1;
      61             :         }
      62             :       else
      63             :         {
      64           0 :           error = clib_error_return (0, "unknown input '%U'",
      65             :                                      format_unformat_error, line_input);
      66           0 :           goto done;
      67             :         }
      68             :     }
      69             : 
      70           0 :   if (!enable_set)
      71             :     {
      72           0 :       error = clib_error_return (0, "expected enable | disable");
      73           0 :       goto done;
      74             :     }
      75             : 
      76           0 :   if (enable)
      77             :     {
      78           0 :       if (nm->enabled)
      79             :         {
      80           0 :           error = clib_error_return (0, "already enabled");
      81           0 :           goto done;
      82             :         }
      83             : 
      84           0 :       if (nat66_plugin_enable (outside_vrf) != 0)
      85           0 :         error = clib_error_return (0, "enable failed");
      86             :     }
      87             :   else
      88             :     {
      89           0 :       if (!nm->enabled)
      90             :         {
      91           0 :           error = clib_error_return (0, "already disabled");
      92           0 :           goto done;
      93             :         }
      94             : 
      95           0 :       if (nat66_plugin_disable () != 0)
      96           0 :         error = clib_error_return (0, "disable failed");
      97             :     }
      98             : 
      99           0 : done:
     100           0 :   unformat_free (line_input);
     101           0 :   return error;
     102             : }
     103             : 
     104             : static clib_error_t *
     105           0 : nat66_interface_feature_command_fn (vlib_main_t * vm,
     106             :                                     unformat_input_t * input,
     107             :                                     vlib_cli_command_t * cmd)
     108             : {
     109           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     110           0 :   vnet_main_t *vnm = vnet_get_main ();
     111           0 :   clib_error_t *error = 0;
     112             :   u32 sw_if_index;
     113           0 :   u32 *inside_sw_if_indices = 0;
     114           0 :   u32 *outside_sw_if_indices = 0;
     115           0 :   u8 is_add = 1;
     116             :   int i, rv;
     117             : 
     118           0 :   CHECK_ENABLED ();
     119             : 
     120           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     121           0 :     return clib_error_return (0, NAT66_EXPECTED_ARGUMENT);
     122             : 
     123           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     124             :     {
     125           0 :       if (unformat (line_input, "in %U", unformat_vnet_sw_interface,
     126             :                     vnm, &sw_if_index))
     127           0 :         vec_add1 (inside_sw_if_indices, sw_if_index);
     128           0 :       else if (unformat (line_input, "out %U", unformat_vnet_sw_interface,
     129             :                          vnm, &sw_if_index))
     130           0 :         vec_add1 (outside_sw_if_indices, sw_if_index);
     131           0 :       else if (unformat (line_input, "del"))
     132           0 :         is_add = 0;
     133             :       else
     134             :         {
     135           0 :           error = clib_error_return (0, "unknown input '%U'",
     136             :                                      format_unformat_error, line_input);
     137           0 :           goto done;
     138             :         }
     139             :     }
     140             : 
     141           0 :   if (vec_len (inside_sw_if_indices))
     142             :     {
     143           0 :       for (i = 0; i < vec_len (inside_sw_if_indices); i++)
     144             :         {
     145           0 :           sw_if_index = inside_sw_if_indices[i];
     146           0 :           rv = nat66_interface_add_del (sw_if_index, 1, is_add);
     147           0 :           switch (rv)
     148             :             {
     149           0 :             case VNET_API_ERROR_NO_SUCH_ENTRY:
     150             :               error =
     151           0 :                 clib_error_return (0, "%U NAT66 feature not enabled.",
     152             :                                    format_vnet_sw_interface_name, vnm,
     153             :                                    vnet_get_sw_interface (vnm, sw_if_index));
     154           0 :               goto done;
     155           0 :             case VNET_API_ERROR_VALUE_EXIST:
     156             :               error =
     157           0 :                 clib_error_return (0, "%U NAT66 feature already enabled.",
     158             :                                    format_vnet_sw_interface_name, vnm,
     159             :                                    vnet_get_sw_interface (vnm, sw_if_index));
     160           0 :               goto done;
     161           0 :             case VNET_API_ERROR_INVALID_VALUE:
     162             :             case VNET_API_ERROR_INVALID_VALUE_2:
     163             :               error =
     164           0 :                 clib_error_return (0,
     165             :                                    "%U NAT66 feature enable/disable failed.",
     166             :                                    format_vnet_sw_interface_name, vnm,
     167             :                                    vnet_get_sw_interface (vnm, sw_if_index));
     168           0 :               goto done;
     169           0 :             default:
     170           0 :               break;
     171             : 
     172             :             }
     173             :         }
     174             :     }
     175             : 
     176           0 :   if (vec_len (outside_sw_if_indices))
     177             :     {
     178           0 :       for (i = 0; i < vec_len (outside_sw_if_indices); i++)
     179             :         {
     180           0 :           sw_if_index = outside_sw_if_indices[i];
     181           0 :           rv = nat66_interface_add_del (sw_if_index, 0, is_add);
     182           0 :           switch (rv)
     183             :             {
     184           0 :             case VNET_API_ERROR_NO_SUCH_ENTRY:
     185             :               error =
     186           0 :                 clib_error_return (0, "%U NAT66 feature not enabled.",
     187             :                                    format_vnet_sw_interface_name, vnm,
     188             :                                    vnet_get_sw_interface (vnm, sw_if_index));
     189           0 :               goto done;
     190           0 :             case VNET_API_ERROR_VALUE_EXIST:
     191             :               error =
     192           0 :                 clib_error_return (0, "%U NAT66 feature already enabled.",
     193             :                                    format_vnet_sw_interface_name, vnm,
     194             :                                    vnet_get_sw_interface (vnm, sw_if_index));
     195           0 :               goto done;
     196           0 :             case VNET_API_ERROR_INVALID_VALUE:
     197             :             case VNET_API_ERROR_INVALID_VALUE_2:
     198             :               error =
     199           0 :                 clib_error_return (0,
     200             :                                    "%U NAT66 feature enable/disable failed.",
     201             :                                    format_vnet_sw_interface_name, vnm,
     202             :                                    vnet_get_sw_interface (vnm, sw_if_index));
     203           0 :               goto done;
     204           0 :             default:
     205           0 :               break;
     206             : 
     207             :             }
     208             :         }
     209             :     }
     210             : 
     211           0 : done:
     212           0 :   unformat_free (line_input);
     213           0 :   vec_free (inside_sw_if_indices);
     214           0 :   vec_free (outside_sw_if_indices);
     215             : 
     216           0 :   return error;
     217             : }
     218             : 
     219             : static int
     220           0 : nat66_cli_interface_walk (nat66_interface_t * i, void *ctx)
     221             : {
     222           0 :   vlib_main_t *vm = ctx;
     223           0 :   vnet_main_t *vnm = vnet_get_main ();
     224           0 :   vlib_cli_output (vm, " %U %s", format_vnet_sw_interface_name, vnm,
     225             :                    vnet_get_sw_interface (vnm, i->sw_if_index),
     226           0 :                    nat66_interface_is_inside (i) ? "in" : "out");
     227           0 :   return 0;
     228             : }
     229             : 
     230             : static clib_error_t *
     231           0 : nat66_show_interfaces_command_fn (vlib_main_t * vm, unformat_input_t * input,
     232             :                                   vlib_cli_command_t * cmd)
     233             : {
     234           0 :   CHECK_ENABLED ();
     235           0 :   vlib_cli_output (vm, "NAT66 interfaces:");
     236           0 :   nat66_interfaces_walk (nat66_cli_interface_walk, vm);
     237           0 :   return 0;
     238             : }
     239             : 
     240             : static clib_error_t *
     241           0 : nat66_add_del_static_mapping_command_fn (vlib_main_t * vm,
     242             :                                          unformat_input_t * input,
     243             :                                          vlib_cli_command_t * cmd)
     244             : {
     245           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     246           0 :   clib_error_t *error = 0;
     247             :   ip6_address_t l_addr, e_addr;
     248           0 :   u32 vrf_id = 0;
     249           0 :   u8 is_add = 1;
     250             :   int rv;
     251             : 
     252           0 :   CHECK_ENABLED ();
     253             : 
     254           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     255           0 :     return clib_error_return (0, NAT66_EXPECTED_ARGUMENT);
     256             : 
     257           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     258             :     {
     259           0 :       if (unformat (line_input, "local %U external %U",
     260             :                     unformat_ip6_address, &l_addr,
     261             :                     unformat_ip6_address, &e_addr))
     262             :         ;
     263           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
     264             :         ;
     265           0 :       else if (unformat (line_input, "del"))
     266           0 :         is_add = 0;
     267             :       else
     268             :         {
     269           0 :           error = clib_error_return (0, "unknown input: '%U'",
     270             :                                      format_unformat_error, line_input);
     271           0 :           goto done;
     272             :         }
     273             :     }
     274             : 
     275           0 :   rv = nat66_static_mapping_add_del (&l_addr, &e_addr, vrf_id, is_add);
     276             : 
     277           0 :   switch (rv)
     278             :     {
     279           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
     280           0 :       error = clib_error_return (0, "NAT66 static mapping entry not exist.");
     281           0 :       goto done;
     282           0 :     case VNET_API_ERROR_VALUE_EXIST:
     283           0 :       error = clib_error_return (0, "NAT66 static mapping entry exist.");
     284           0 :       goto done;
     285           0 :     default:
     286           0 :       break;
     287             :     }
     288             : 
     289           0 : done:
     290           0 :   unformat_free (line_input);
     291             : 
     292           0 :   return error;
     293             : }
     294             : 
     295             : static int
     296           0 : nat66_cli_static_mapping_walk (nat66_static_mapping_t * sm, void *ctx)
     297             : {
     298           0 :   nat66_main_t *nm = &nat66_main;
     299           0 :   vlib_main_t *vm = ctx;
     300             :   fib_table_t *fib;
     301             :   vlib_counter_t vc;
     302             : 
     303           0 :   fib = fib_table_get (sm->fib_index, FIB_PROTOCOL_IP6);
     304           0 :   if (!fib)
     305           0 :     return -1;
     306             : 
     307           0 :   vlib_get_combined_counter (&nm->session_counters, sm - nm->sm, &vc);
     308             : 
     309           0 :   vlib_cli_output (vm, " local %U external %U vrf %d",
     310             :                    format_ip6_address, &sm->l_addr,
     311             :                    format_ip6_address, &sm->e_addr, fib->ft_table_id);
     312           0 :   vlib_cli_output (vm, "  total pkts %lld, total bytes %lld", vc.packets,
     313             :                    vc.bytes);
     314             : 
     315           0 :   return 0;
     316             : }
     317             : 
     318             : static clib_error_t *
     319           0 : nat66_show_static_mappings_command_fn (vlib_main_t * vm,
     320             :                                        unformat_input_t * input,
     321             :                                        vlib_cli_command_t * cmd)
     322             : {
     323           0 :   CHECK_ENABLED ();
     324           0 :   vlib_cli_output (vm, "NAT66 static mappings:");
     325           0 :   nat66_static_mappings_walk (nat66_cli_static_mapping_walk, vm);
     326           0 :   return 0;
     327             : }
     328             : 
     329             : /*?
     330             :  * @cliexpar
     331             :  * @cliexstart{nat66}
     332             :  * To enable NAT66 plugin
     333             :  *  vpp# nat66 enable
     334             :  * To disable NAT66 plugin
     335             :  *  vpp# nat66 disable
     336             :  * To enable NAT66 plugin with outside-vrf id 10
     337             :  *  vpp# nat66 enable outside-vrf 10
     338             :  * @cliexend
     339             : ?*/
     340       73509 : VLIB_CLI_COMMAND (nat66_enable_disable_command, static) = {
     341             :   .path = "nat66",
     342             :   .short_help = "nat66 <enable [outside-vrf <vrf-id>]>|disable",
     343             :   .function = nat66_enable_disable_command_fn,
     344             : };
     345             : 
     346             : /*?
     347             :  * @cliexpar
     348             :  * @cliexstart{set interface nat66}
     349             :  * Enable/disable NAT66 feature on the interface.
     350             :  * To enable NAT66 feature with local (IPv6) network interface
     351             :  * GigabitEthernet0/8/0 and external (IPv4) network interface
     352             :  * GigabitEthernet0/a/0 use:
     353             :  *  vpp# set interface nat66 in GigabitEthernet0/8/0 out GigabitEthernet0/a/0
     354             :  * @cliexend
     355             : ?*/
     356       73509 : VLIB_CLI_COMMAND (set_interface_nat66_command, static) = {
     357             :   .path = "set interface nat66",
     358             :   .short_help = "set interface nat66 in|out <intfc> [del]",
     359             :   .function = nat66_interface_feature_command_fn,
     360             : };
     361             : 
     362             : /*?
     363             :  * @cliexpar
     364             :  * @cliexstart{show nat66 interfaces}
     365             :  * Show interfaces with NAT66 feature.
     366             :  * To show interfaces with NAT66 feature use:
     367             :  *  vpp# show nat66 interfaces
     368             :  *  NAT66 interfaces:
     369             :  *   GigabitEthernet0/8/0 in
     370             :  *   GigabitEthernet0/a/0 out
     371             :  * @cliexend
     372             : ?*/
     373       73509 : VLIB_CLI_COMMAND (show_nat66_interfaces_command, static) = {
     374             :   .path = "show nat66 interfaces",
     375             :   .short_help = "show nat66 interfaces",
     376             :   .function = nat66_show_interfaces_command_fn,
     377             : };
     378             : 
     379             : /*?
     380             :  * @cliexpar
     381             :  * @cliexstart{nat66 add static mapping}
     382             :  * Add/delete NAT66 static mapping entry.
     383             :  * To add NAT66 static mapping entry use:
     384             :  *  vpp# nat66 add static mapping local fd01:1::4 external 2001:db8:c000:223::
     385             :  *  vpp# nat66 add static mapping local fd01:1::2 external 2001:db8:c000:221:: vrf 10
     386             :  * @cliexend
     387             : ?*/
     388       73509 : VLIB_CLI_COMMAND (show_nat66_add_del_static_mapping_command, static) = {
     389             :   .path = "nat66 add static mapping",
     390             :   .short_help = "nat66 add static mapping local <ip6-addr> external <ip6-addr>"
     391             :                 " [vfr <table-id>] [del]",
     392             :   .function = nat66_add_del_static_mapping_command_fn,
     393             : };
     394             : 
     395             : /*?
     396             :  * @cliexpar
     397             :  * @cliexstart{show nat66 static mappings}
     398             :  * Show NAT66 static mappings.
     399             :  * To show NAT66 static mappings use:
     400             :  *  vpp# show nat66 static mappings
     401             :  *  NAT66 static mappings:
     402             :  *   local fd01:1::4 external 2001:db8:c000:223:: vrf 0
     403             :  *   local fd01:1::2 external 2001:db8:c000:221:: vrf 10
     404             :  * @cliexend
     405             : ?*/
     406       73509 : VLIB_CLI_COMMAND (show_nat66_static_mappings_command, static) = {
     407             :   .path = "show nat66 static mappings",
     408             :   .short_help = "show nat66 static mappings",
     409             :   .function = nat66_show_static_mappings_command_fn,
     410             : };
     411             : 
     412             : /*
     413             :  * fd.io coding-style-patch-verification: ON
     414             :  *
     415             :  * Local Variables:
     416             :  * eval: (c-set-style "gnu")
     417             :  * End:
     418             :  */

Generated by: LCOV version 1.14