LCOV - code coverage report
Current view: top level - plugins/nat/nat64 - nat64_cli.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 121 379 31.9 %
Date: 2023-10-26 01:39:38 Functions: 32 38 84.2 %

          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/fib/fib_table.h>
      17             : #include <nat/nat64/nat64.h>
      18             : 
      19             : #define NAT64_EXPECTED_ARGUMENT "expected required argument(s)"
      20             : 
      21             : static clib_error_t *
      22           0 : nat64_plugin_enable_disable_command_fn (vlib_main_t * vm,
      23             :                                         unformat_input_t * input,
      24             :                                         vlib_cli_command_t * cmd)
      25             : {
      26           0 :   unformat_input_t _line_input, *line_input = &_line_input;
      27           0 :   u8 enable = 0, is_set = 0;
      28           0 :   clib_error_t *error = 0;
      29           0 :   nat64_config_t c = { 0 };
      30             : 
      31           0 :   if (!unformat_user (input, unformat_line_input, line_input))
      32           0 :     return clib_error_return (0, NAT64_EXPECTED_ARGUMENT);
      33             : 
      34           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
      35             :     {
      36           0 :       if (!is_set && unformat (line_input, "enable"))
      37             :         {
      38           0 :           unformat (line_input, "bib-buckets %u", &c.bib_buckets);
      39           0 :           unformat (line_input, "bib-memory %u", &c.bib_memory_size);
      40           0 :           unformat (line_input, "st-buckets %u", &c.st_buckets);
      41           0 :           unformat (line_input, "st-memory %u", &c.st_memory_size);
      42           0 :           enable = 1;
      43             :         }
      44           0 :       else if (!is_set && unformat (line_input, "disable"));
      45             :       else
      46             :         {
      47           0 :           error = clib_error_return (0, "unknown input '%U'",
      48             :                                      format_unformat_error, line_input);
      49           0 :           goto done;
      50             :         }
      51           0 :       is_set = 1;
      52             :     }
      53             : 
      54           0 :   if (enable)
      55             :     {
      56           0 :       if (nat64_plugin_enable (c))
      57           0 :         error = clib_error_return (0, "plugin enable failed");
      58             :     }
      59             :   else
      60             :     {
      61           0 :       if (nat64_plugin_disable ())
      62           0 :         error = clib_error_return (0, "plugin disable failed");
      63             :     }
      64           0 : done:
      65           0 :   unformat_free (line_input);
      66           0 :   return error;
      67             : }
      68             : 
      69             : static clib_error_t *
      70           0 : nat64_add_del_pool_addr_command_fn (vlib_main_t * vm,
      71             :                                     unformat_input_t * input,
      72             :                                     vlib_cli_command_t * cmd)
      73             : {
      74           0 :   unformat_input_t _line_input, *line_input = &_line_input;
      75             :   ip4_address_t start_addr, end_addr, this_addr;
      76             :   u32 start_host_order, end_host_order;
      77             :   int i, count, rv;
      78           0 :   u32 vrf_id = ~0;
      79           0 :   u8 is_add = 1;
      80           0 :   clib_error_t *error = 0;
      81             : 
      82             :   /* Get a line of input. */
      83           0 :   if (!unformat_user (input, unformat_line_input, line_input))
      84           0 :     return clib_error_return (0, NAT64_EXPECTED_ARGUMENT);
      85             : 
      86           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
      87             :     {
      88           0 :       if (unformat (line_input, "%U - %U",
      89             :                     unformat_ip4_address, &start_addr,
      90             :                     unformat_ip4_address, &end_addr))
      91             :         ;
      92           0 :       else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
      93             :         ;
      94           0 :       else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
      95           0 :         end_addr = start_addr;
      96           0 :       else if (unformat (line_input, "del"))
      97           0 :         is_add = 0;
      98             :       else
      99             :         {
     100           0 :           error = clib_error_return (0, "unknown input '%U'",
     101             :                                      format_unformat_error, line_input);
     102           0 :           goto done;
     103             :         }
     104             :     }
     105             : 
     106           0 :   start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
     107           0 :   end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
     108             : 
     109           0 :   if (end_host_order < start_host_order)
     110             :     {
     111           0 :       error = clib_error_return (0, "end address less than start address");
     112           0 :       goto done;
     113             :     }
     114             : 
     115           0 :   count = (end_host_order - start_host_order) + 1;
     116           0 :   this_addr = start_addr;
     117             : 
     118           0 :   for (i = 0; i < count; i++)
     119             :     {
     120           0 :       rv = nat64_add_del_pool_addr (0, &this_addr, vrf_id, is_add);
     121             : 
     122           0 :       switch (rv)
     123             :         {
     124           0 :         case VNET_API_ERROR_NO_SUCH_ENTRY:
     125             :           error =
     126           0 :             clib_error_return (0, "NAT64 pool address %U not exist.",
     127             :                                format_ip4_address, &this_addr);
     128           0 :           goto done;
     129           0 :         case VNET_API_ERROR_VALUE_EXIST:
     130             :           error =
     131           0 :             clib_error_return (0, "NAT64 pool address %U exist.",
     132             :                                format_ip4_address, &this_addr);
     133           0 :           goto done;
     134           0 :         default:
     135           0 :           break;
     136             : 
     137             :         }
     138           0 :       increment_v4_address (&this_addr);
     139             :     }
     140             : 
     141           0 : done:
     142           0 :   unformat_free (line_input);
     143             : 
     144           0 :   return error;
     145             : }
     146             : 
     147             : static int
     148          24 : nat64_cli_pool_walk (nat64_address_t * ap, void *ctx)
     149             : {
     150          24 :   vlib_main_t *vm = ctx;
     151             : 
     152          24 :   if (ap->fib_index != ~0)
     153             :     {
     154             :       fib_table_t *fib;
     155           2 :       fib = fib_table_get (ap->fib_index, FIB_PROTOCOL_IP6);
     156           2 :       if (!fib)
     157           0 :         return -1;
     158           2 :       vlib_cli_output (vm, " %U tenant VRF: %u", format_ip4_address,
     159             :                        &ap->addr, fib->ft_table_id);
     160             :     }
     161             :   else
     162          22 :     vlib_cli_output (vm, " %U", format_ip4_address, &ap->addr);
     163             : 
     164             : #define _(N, i, n, s) \
     165             :   vlib_cli_output (vm, "  %d busy %s ports", ap->busy_##n##_ports, s);
     166          24 :   foreach_nat_protocol
     167             : #undef _
     168          24 :     return 0;
     169             : }
     170             : 
     171             : static clib_error_t *
     172          20 : nat64_show_pool_command_fn (vlib_main_t * vm,
     173             :                             unformat_input_t * input,
     174             :                             vlib_cli_command_t * cmd)
     175             : {
     176          20 :   vlib_cli_output (vm, "NAT64 pool:");
     177          20 :   nat64_pool_addr_walk (nat64_cli_pool_walk, vm);
     178             : 
     179          20 :   return 0;
     180             : }
     181             : 
     182             : static clib_error_t *
     183           0 : nat64_interface_feature_command_fn (vlib_main_t * vm,
     184             :                                     unformat_input_t *
     185             :                                     input, vlib_cli_command_t * cmd)
     186             : {
     187           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     188           0 :   vnet_main_t *vnm = vnet_get_main ();
     189           0 :   clib_error_t *error = 0;
     190             :   u32 sw_if_index;
     191           0 :   u32 *inside_sw_if_indices = 0;
     192           0 :   u32 *outside_sw_if_indices = 0;
     193           0 :   u8 is_add = 1;
     194             :   int i, rv;
     195             : 
     196             :   /* Get a line of input. */
     197           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     198           0 :     return clib_error_return (0, NAT64_EXPECTED_ARGUMENT);
     199             : 
     200           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     201             :     {
     202           0 :       if (unformat (line_input, "in %U", unformat_vnet_sw_interface,
     203             :                     vnm, &sw_if_index))
     204           0 :         vec_add1 (inside_sw_if_indices, sw_if_index);
     205           0 :       else if (unformat (line_input, "out %U", unformat_vnet_sw_interface,
     206             :                          vnm, &sw_if_index))
     207           0 :         vec_add1 (outside_sw_if_indices, sw_if_index);
     208           0 :       else if (unformat (line_input, "del"))
     209           0 :         is_add = 0;
     210             :       else
     211             :         {
     212           0 :           error = clib_error_return (0, "unknown input '%U'",
     213             :                                      format_unformat_error, line_input);
     214           0 :           goto done;
     215             :         }
     216             :     }
     217             : 
     218           0 :   if (vec_len (inside_sw_if_indices))
     219             :     {
     220           0 :       for (i = 0; i < vec_len (inside_sw_if_indices); i++)
     221             :         {
     222           0 :           sw_if_index = inside_sw_if_indices[i];
     223           0 :           rv = nat64_interface_add_del (sw_if_index, 1, is_add);
     224           0 :           switch (rv)
     225             :             {
     226           0 :             case VNET_API_ERROR_NO_SUCH_ENTRY:
     227             :               error =
     228           0 :                 clib_error_return (0, "%U NAT64 feature not enabled.",
     229             :                                    format_vnet_sw_if_index_name, vnm,
     230             :                                    sw_if_index);
     231           0 :               goto done;
     232           0 :             case VNET_API_ERROR_VALUE_EXIST:
     233             :               error =
     234           0 :                 clib_error_return (0, "%U NAT64 feature already enabled.",
     235             :                                    format_vnet_sw_if_index_name, vnm,
     236             :                                    vnm, sw_if_index);
     237           0 :               goto done;
     238           0 :             case VNET_API_ERROR_INVALID_VALUE:
     239             :             case VNET_API_ERROR_INVALID_VALUE_2:
     240             :               error =
     241           0 :                 clib_error_return (0,
     242             :                                    "%U NAT64 feature enable/disable failed.",
     243             :                                    format_vnet_sw_if_index_name, vnm,
     244             :                                    sw_if_index);
     245           0 :               goto done;
     246           0 :             default:
     247           0 :               break;
     248             : 
     249             :             }
     250             :         }
     251             :     }
     252             : 
     253           0 :   if (vec_len (outside_sw_if_indices))
     254             :     {
     255           0 :       for (i = 0; i < vec_len (outside_sw_if_indices); i++)
     256             :         {
     257           0 :           sw_if_index = outside_sw_if_indices[i];
     258           0 :           rv = nat64_interface_add_del (sw_if_index, 0, is_add);
     259           0 :           switch (rv)
     260             :             {
     261           0 :             case VNET_API_ERROR_NO_SUCH_ENTRY:
     262             :               error =
     263           0 :                 clib_error_return (0, "%U NAT64 feature not enabled.",
     264             :                                    format_vnet_sw_if_index_name, vnm,
     265             :                                    sw_if_index);
     266           0 :               goto done;
     267           0 :             case VNET_API_ERROR_VALUE_EXIST:
     268             :               error =
     269           0 :                 clib_error_return (0, "%U NAT64 feature already enabled.",
     270             :                                    format_vnet_sw_if_index_name, vnm,
     271             :                                    sw_if_index);
     272           0 :               goto done;
     273           0 :             case VNET_API_ERROR_INVALID_VALUE:
     274             :             case VNET_API_ERROR_INVALID_VALUE_2:
     275             :               error =
     276           0 :                 clib_error_return (0,
     277             :                                    "%U NAT64 feature enable/disable failed.",
     278             :                                    format_vnet_sw_if_index_name, vnm,
     279             :                                    sw_if_index);
     280           0 :               goto done;
     281           0 :             default:
     282           0 :               break;
     283             : 
     284             :             }
     285             :         }
     286             :     }
     287             : 
     288           0 : done:
     289           0 :   unformat_free (line_input);
     290           0 :   vec_free (inside_sw_if_indices);
     291           0 :   vec_free (outside_sw_if_indices);
     292             : 
     293           0 :   return error;
     294             : }
     295             : 
     296             : static int
     297          30 : nat64_cli_interface_walk (nat64_interface_t * i, void *ctx)
     298             : {
     299          30 :   vlib_main_t *vm = ctx;
     300          30 :   vnet_main_t *vnm = vnet_get_main ();
     301             : 
     302          30 :   vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
     303             :                    i->sw_if_index,
     304          30 :                    (nat64_interface_is_inside (i)
     305          17 :                     && nat64_interface_is_outside (i)) ? "in out" :
     306          29 :                    nat64_interface_is_inside (i) ? "in" : "out");
     307          30 :   return 0;
     308             : }
     309             : 
     310             : static clib_error_t *
     311          20 : nat64_show_interfaces_command_fn (vlib_main_t * vm,
     312             :                                   unformat_input_t *
     313             :                                   input, vlib_cli_command_t * cmd)
     314             : {
     315          20 :   vlib_cli_output (vm, "NAT64 interfaces:");
     316          20 :   nat64_interfaces_walk (nat64_cli_interface_walk, vm);
     317             : 
     318          20 :   return 0;
     319             : }
     320             : 
     321             : static clib_error_t *
     322           0 : nat64_add_del_static_bib_command_fn (vlib_main_t *
     323             :                                      vm,
     324             :                                      unformat_input_t
     325             :                                      * input, vlib_cli_command_t * cmd)
     326             : {
     327           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     328           0 :   clib_error_t *error = 0;
     329           0 :   u8 is_add = 1;
     330             :   ip6_address_t in_addr;
     331             :   ip4_address_t out_addr;
     332           0 :   u32 in_port = 0;
     333           0 :   u32 out_port = 0;
     334           0 :   u32 vrf_id = 0, protocol;
     335           0 :   nat_protocol_t proto = 0;
     336           0 :   u8 p = 0;
     337             :   int rv;
     338             : 
     339           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     340           0 :     return clib_error_return (0, NAT64_EXPECTED_ARGUMENT);
     341             : 
     342           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     343             :     {
     344           0 :       if (unformat (line_input, "%U %u", unformat_ip6_address,
     345             :                     &in_addr, &in_port))
     346             :         ;
     347           0 :       else if (unformat (line_input, "%U %u", unformat_ip4_address,
     348             :                          &out_addr, &out_port))
     349             :         ;
     350           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
     351             :         ;
     352           0 :       else if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
     353             :         ;
     354             :       else
     355           0 :         if (unformat
     356             :             (line_input, "%U %U %u", unformat_ip6_address, &in_addr,
     357             :              unformat_ip4_address, &out_addr, &protocol))
     358           0 :         p = (u8) protocol;
     359           0 :       else if (unformat (line_input, "del"))
     360           0 :         is_add = 0;
     361             :       else
     362             :         {
     363           0 :           error = clib_error_return (0, "unknown input: '%U'",
     364             :                                      format_unformat_error, line_input);
     365           0 :           goto done;
     366             :         }
     367             :     }
     368             : 
     369           0 :   if (!p)
     370             :     {
     371           0 :       if (!in_port)
     372             :         {
     373             :           error =
     374           0 :             clib_error_return (0, "inside port and address  must be set");
     375           0 :           goto done;
     376             :         }
     377             : 
     378           0 :       if (!out_port)
     379             :         {
     380             :           error =
     381           0 :             clib_error_return (0, "outside port and address  must be set");
     382           0 :           goto done;
     383             :         }
     384             : 
     385           0 :       p = nat_proto_to_ip_proto (proto);
     386             :     }
     387             : 
     388             :   rv =
     389           0 :     nat64_add_del_static_bib_entry (&in_addr, &out_addr, (u16) in_port,
     390           0 :                                     (u16) out_port, p, vrf_id, is_add);
     391             : 
     392           0 :   switch (rv)
     393             :     {
     394           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
     395           0 :       error = clib_error_return (0, "NAT64 BIB entry not exist.");
     396           0 :       goto done;
     397           0 :     case VNET_API_ERROR_VALUE_EXIST:
     398           0 :       error = clib_error_return (0, "NAT64 BIB entry exist.");
     399           0 :       goto done;
     400           0 :     case VNET_API_ERROR_UNSPECIFIED:
     401           0 :       error = clib_error_return (0, "Crerate NAT64 BIB entry failed.");
     402           0 :       goto done;
     403           0 :     case VNET_API_ERROR_INVALID_VALUE:
     404             :       error =
     405           0 :         clib_error_return (0,
     406             :                            "Outside address %U and port %u already in use.",
     407             :                            format_ip4_address, &out_addr, out_port);
     408           0 :       goto done;
     409           0 :     case VNET_API_ERROR_INVALID_VALUE_2:
     410           0 :       error = clib_error_return (0, "Invalid outside port.");
     411           0 :     default:
     412           0 :       break;
     413             :     }
     414             : 
     415           0 : done:
     416           0 :   unformat_free (line_input);
     417             : 
     418           0 :   return error;
     419             : }
     420             : 
     421             : static int
     422          34 : nat64_cli_bib_walk (nat64_db_bib_entry_t * bibe, void *ctx)
     423             : {
     424          34 :   vlib_main_t *vm = ctx;
     425             :   fib_table_t *fib;
     426             : 
     427          34 :   fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
     428          34 :   if (!fib)
     429           0 :     return -1;
     430             : 
     431          34 :   switch (bibe->proto)
     432             :     {
     433          31 :     case IP_PROTOCOL_ICMP:
     434             :     case IP_PROTOCOL_TCP:
     435             :     case IP_PROTOCOL_UDP:
     436          62 :       vlib_cli_output (vm, " %U %u %U %u protocol %U vrf %u %s %u sessions",
     437             :                        format_ip6_address, &bibe->in_addr,
     438          31 :                        clib_net_to_host_u16 (bibe->in_port),
     439             :                        format_ip4_address, &bibe->out_addr,
     440          31 :                        clib_net_to_host_u16 (bibe->out_port),
     441             :                        format_nat_protocol,
     442          31 :                        ip_proto_to_nat_proto (bibe->proto), fib->ft_table_id,
     443          31 :                        bibe->is_static ? "static" : "dynamic", bibe->ses_num);
     444          31 :       break;
     445           3 :     default:
     446           3 :       vlib_cli_output (vm, " %U %U protocol %u vrf %u %s %u sessions",
     447             :                        format_ip6_address, &bibe->in_addr,
     448             :                        format_ip4_address, &bibe->out_addr,
     449           3 :                        bibe->proto, fib->ft_table_id,
     450           3 :                        bibe->is_static ? "static" : "dynamic", bibe->ses_num);
     451             :     }
     452          34 :   return 0;
     453             : }
     454             : 
     455             : static clib_error_t *
     456          20 : nat64_show_bib_command_fn (vlib_main_t * vm,
     457             :                            unformat_input_t * input, vlib_cli_command_t * cmd)
     458             : {
     459          20 :   nat64_main_t *nm = &nat64_main;
     460          20 :   unformat_input_t _line_input, *line_input = &_line_input;
     461          20 :   clib_error_t *error = 0;
     462          20 :   u32 proto = NAT_PROTOCOL_OTHER;
     463          20 :   u8 p = 255;
     464             :   nat64_db_t *db;
     465             : 
     466          20 :   if (!unformat_user (input, unformat_line_input, line_input))
     467           0 :     return clib_error_return (0, NAT64_EXPECTED_ARGUMENT);
     468             : 
     469          20 :   if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
     470           0 :     p = nat_proto_to_ip_proto (proto);
     471          20 :   else if (unformat (line_input, "unknown"))
     472           0 :     p = 0;
     473          20 :   else if (unformat (line_input, "all"))
     474             :     ;
     475             :   else
     476             :     {
     477           0 :       error = clib_error_return (0, "unknown input: '%U'",
     478             :                                  format_unformat_error, line_input);
     479           0 :       goto done;
     480             :     }
     481             : 
     482          20 :   if (p == 255)
     483          20 :     vlib_cli_output (vm, "NAT64 BIB entries:");
     484             :   else
     485           0 :     vlib_cli_output (vm, "NAT64 %U BIB entries:", format_nat_protocol, proto);
     486             : 
     487             :   /* *INDENT-OFF* */
     488          40 :   vec_foreach (db, nm->db)
     489          20 :     nat64_db_bib_walk (db, p, nat64_cli_bib_walk, vm);
     490             :   /* *INDENT-ON* */
     491             : 
     492          20 : done:
     493          20 :   unformat_free (line_input);
     494             : 
     495          20 :   return error;
     496             : }
     497             : 
     498             : typedef struct nat64_cli_st_walk_ctx_t_
     499             : {
     500             :   vlib_main_t *vm;
     501             :   nat64_db_t *db;
     502             : } nat64_cli_st_walk_ctx_t;
     503             : 
     504             : static int
     505          32 : nat64_cli_st_walk (nat64_db_st_entry_t * ste, void *arg)
     506             : {
     507          32 :   nat64_cli_st_walk_ctx_t *ctx = arg;
     508          32 :   vlib_main_t *vm = ctx->vm;
     509             :   nat64_db_bib_entry_t *bibe;
     510             :   fib_table_t *fib;
     511             : 
     512          32 :   bibe = nat64_db_bib_entry_by_index (ctx->db, ste->proto, ste->bibe_index);
     513          32 :   if (!bibe)
     514           0 :     return -1;
     515             : 
     516          32 :   fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
     517          32 :   if (!fib)
     518           0 :     return -1;
     519             : 
     520          32 :   u32 vrf_id = fib->ft_table_id;
     521             : 
     522          32 :   if (ste->proto == IP_PROTOCOL_ICMP)
     523           6 :     vlib_cli_output (vm, " %U %U %u %U %U %u protocol %U vrf %u",
     524             :                      format_ip6_address, &bibe->in_addr,
     525             :                      format_ip6_address, &ste->in_r_addr,
     526           6 :                      clib_net_to_host_u16 (bibe->in_port),
     527             :                      format_ip4_address, &bibe->out_addr,
     528             :                      format_ip4_address, &ste->out_r_addr,
     529           6 :                      clib_net_to_host_u16 (bibe->out_port),
     530             :                      format_nat_protocol,
     531           6 :                      ip_proto_to_nat_proto (bibe->proto), vrf_id);
     532          26 :   else if (ste->proto == IP_PROTOCOL_TCP || ste->proto == IP_PROTOCOL_UDP)
     533          23 :     vlib_cli_output (vm, " %U %u %U %u %U %u %U %u protcol %U vrf %u",
     534             :                      format_ip6_address, &bibe->in_addr,
     535          23 :                      clib_net_to_host_u16 (bibe->in_port),
     536             :                      format_ip6_address, &ste->in_r_addr,
     537          23 :                      clib_net_to_host_u16 (ste->r_port),
     538             :                      format_ip4_address, &bibe->out_addr,
     539          23 :                      clib_net_to_host_u16 (bibe->out_port),
     540             :                      format_ip4_address, &ste->out_r_addr,
     541          23 :                      clib_net_to_host_u16 (ste->r_port),
     542             :                      format_nat_protocol,
     543          23 :                      ip_proto_to_nat_proto (bibe->proto), vrf_id);
     544             :   else
     545           3 :     vlib_cli_output (vm, " %U %U %U %U protocol %u vrf %u",
     546             :                      format_ip6_address, &bibe->in_addr,
     547             :                      format_ip6_address, &ste->in_r_addr,
     548             :                      format_ip4_address, &bibe->out_addr,
     549             :                      format_ip4_address, &ste->out_r_addr,
     550           3 :                      bibe->proto, vrf_id);
     551             : 
     552          32 :   return 0;
     553             : }
     554             : 
     555             : static clib_error_t *
     556          20 : nat64_show_st_command_fn (vlib_main_t * vm,
     557             :                           unformat_input_t * input, vlib_cli_command_t * cmd)
     558             : {
     559          20 :   nat64_main_t *nm = &nat64_main;
     560          20 :   unformat_input_t _line_input, *line_input = &_line_input;
     561          20 :   clib_error_t *error = 0;
     562          20 :   u32 proto = NAT_PROTOCOL_OTHER;
     563          20 :   u8 p = 255;
     564             :   nat64_db_t *db;
     565          20 :   nat64_cli_st_walk_ctx_t ctx = {
     566             :     .vm = vm,
     567             :   };
     568             : 
     569          20 :   if (!unformat_user (input, unformat_line_input, line_input))
     570           0 :     return clib_error_return (0, NAT64_EXPECTED_ARGUMENT);
     571             : 
     572          20 :   if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
     573           0 :     p = nat_proto_to_ip_proto (proto);
     574          20 :   else if (unformat (line_input, "unknown"))
     575           0 :     p = 0;
     576          20 :   else if (unformat (line_input, "all"))
     577             :     ;
     578             :   else
     579             :     {
     580           0 :       error = clib_error_return (0, "unknown input: '%U'",
     581             :                                  format_unformat_error, line_input);
     582           0 :       goto done;
     583             :     }
     584             : 
     585          20 :   if (p == 255)
     586          20 :     vlib_cli_output (vm, "NAT64 sessions:");
     587             :   else
     588           0 :     vlib_cli_output (vm, "NAT64 %U sessions:", format_nat_protocol, proto);
     589             :   /* *INDENT-OFF* */
     590          40 :   vec_foreach (db, nm->db)
     591             :     {
     592          20 :       ctx.db = db;
     593          20 :       nat64_db_st_walk (db, p, nat64_cli_st_walk, &ctx);
     594             :     }
     595             :   /* *INDENT-ON* */
     596             : 
     597          20 : done:
     598          20 :   unformat_free (line_input);
     599             : 
     600          20 :   return error;
     601             : }
     602             : 
     603             : static clib_error_t *
     604           0 : nat64_add_del_prefix_command_fn (vlib_main_t * vm, unformat_input_t * input,
     605             :                                  vlib_cli_command_t * cmd)
     606             : {
     607           0 :   nat64_main_t *nm = &nat64_main;
     608           0 :   vnet_main_t *vnm = vnet_get_main ();
     609           0 :   clib_error_t *error = 0;
     610           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     611           0 :   u8 is_add = 1;
     612           0 :   u32 vrf_id = 0, sw_if_index = ~0;
     613             :   ip6_address_t prefix;
     614           0 :   u32 plen = 0;
     615             :   int rv;
     616             : 
     617           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     618           0 :     return clib_error_return (0, NAT64_EXPECTED_ARGUMENT);
     619             : 
     620           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     621             :     {
     622           0 :       if (unformat
     623             :           (line_input, "%U/%u", unformat_ip6_address, &prefix, &plen))
     624             :         ;
     625           0 :       else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
     626             :         ;
     627           0 :       else if (unformat (line_input, "del"))
     628           0 :         is_add = 0;
     629             :       else
     630           0 :         if (unformat
     631             :             (line_input, "interface %U", unformat_vnet_sw_interface, vnm,
     632             :              &sw_if_index))
     633             :         ;
     634             :       else
     635             :         {
     636           0 :           error = clib_error_return (0, "unknown input: '%U'",
     637             :                                      format_unformat_error, line_input);
     638           0 :           goto done;
     639             :         }
     640             :     }
     641             : 
     642           0 :   if (!plen)
     643             :     {
     644           0 :       error = clib_error_return (0, "NAT64 prefix must be set.");
     645           0 :       goto done;
     646             :     }
     647             : 
     648           0 :   rv = nat64_add_del_prefix (&prefix, (u8) plen, vrf_id, is_add);
     649             : 
     650           0 :   switch (rv)
     651             :     {
     652           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
     653           0 :       error = clib_error_return (0, "NAT64 prefix not exist.");
     654           0 :       goto done;
     655           0 :     case VNET_API_ERROR_INVALID_VALUE:
     656           0 :       error = clib_error_return (0, "Invalid prefix length.");
     657           0 :       goto done;
     658           0 :     default:
     659           0 :       break;
     660             :     }
     661             : 
     662             :   /*
     663             :    * Add RX interface route, whenNAT isn't running on the real input
     664             :    * interface
     665             :    */
     666           0 :   if (sw_if_index != ~0)
     667             :     {
     668             :       u32 fib_index;
     669           0 :       fib_prefix_t fibpfx = {
     670             :         .fp_len = plen,
     671             :         .fp_proto = FIB_PROTOCOL_IP6,
     672             :         .fp_addr = {
     673             :                     .ip6 = prefix}
     674             :       };
     675             : 
     676           0 :       if (is_add)
     677             :         {
     678             :           fib_index =
     679           0 :             fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6,
     680           0 :                                                vrf_id, nm->fib_src_hi);
     681           0 :           fib_table_entry_update_one_path (fib_index, &fibpfx,
     682           0 :                                            nm->fib_src_hi,
     683             :                                            FIB_ENTRY_FLAG_NONE,
     684             :                                            DPO_PROTO_IP6, NULL,
     685             :                                            sw_if_index, ~0, 0,
     686             :                                            NULL, FIB_ROUTE_PATH_INTF_RX);
     687             :         }
     688             :       else
     689             :         {
     690           0 :           fib_index = fib_table_find (FIB_PROTOCOL_IP6, vrf_id);
     691           0 :           fib_table_entry_path_remove (fib_index, &fibpfx,
     692           0 :                                        nm->fib_src_hi,
     693             :                                        DPO_PROTO_IP6, NULL,
     694             :                                        sw_if_index, ~0, 1,
     695             :                                        FIB_ROUTE_PATH_INTF_RX);
     696           0 :           fib_table_unlock (fib_index, FIB_PROTOCOL_IP6, nm->fib_src_hi);
     697             :         }
     698             :     }
     699             : 
     700           0 : done:
     701           0 :   unformat_free (line_input);
     702             : 
     703           0 :   return error;
     704             : }
     705             : 
     706             : static int
     707           2 : nat64_cli_prefix_walk (nat64_prefix_t * p, void *ctx)
     708             : {
     709           2 :   vlib_main_t *vm = ctx;
     710             : 
     711           2 :   vlib_cli_output (vm, " %U/%u tenant-vrf %u",
     712           2 :                    format_ip6_address, &p->prefix, p->plen, p->vrf_id);
     713             : 
     714           2 :   return 0;
     715             : }
     716             : 
     717             : static clib_error_t *
     718          20 : nat64_show_prefix_command_fn (vlib_main_t * vm,
     719             :                               unformat_input_t * input,
     720             :                               vlib_cli_command_t * cmd)
     721             : {
     722          20 :   vlib_cli_output (vm, "NAT64 prefix:");
     723          20 :   nat64_prefix_walk (nat64_cli_prefix_walk, vm);
     724             : 
     725          20 :   return 0;
     726             : }
     727             : 
     728             : static clib_error_t *
     729           0 : nat64_add_interface_address_command_fn (vlib_main_t * vm,
     730             :                                         unformat_input_t * input,
     731             :                                         vlib_cli_command_t * cmd)
     732             : {
     733           0 :   vnet_main_t *vnm = vnet_get_main ();
     734           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     735             :   u32 sw_if_index;
     736             :   int rv;
     737           0 :   int is_add = 1;
     738           0 :   clib_error_t *error = 0;
     739             : 
     740             :   /* Get a line of input. */
     741           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     742           0 :     return clib_error_return (0, NAT64_EXPECTED_ARGUMENT);
     743             : 
     744           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     745             :     {
     746           0 :       if (unformat
     747             :           (line_input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index));
     748           0 :       else if (unformat (line_input, "del"))
     749           0 :         is_add = 0;
     750             :       else
     751             :         {
     752           0 :           error = clib_error_return (0, "unknown input '%U'",
     753             :                                      format_unformat_error, line_input);
     754           0 :           goto done;
     755             :         }
     756             :     }
     757             : 
     758           0 :   rv = nat64_add_interface_address (sw_if_index, is_add);
     759             : 
     760           0 :   switch (rv)
     761             :     {
     762           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
     763           0 :       error = clib_error_return (0, "entry not exist");
     764           0 :       break;
     765           0 :     case VNET_API_ERROR_VALUE_EXIST:
     766           0 :       error = clib_error_return (0, "entry exist");
     767           0 :       break;
     768           0 :     default:
     769           0 :       break;
     770             :     }
     771             : 
     772           0 : done:
     773           0 :   unformat_free (line_input);
     774             : 
     775           0 :   return error;
     776             : }
     777             : 
     778             : /* *INDENT-OFF* */
     779             : /*?
     780             :  * @cliexpar
     781             :  * @cliexstart{nat64 plugin}
     782             :  * Enable/disable NAT64 plugin.
     783             :  * To enable NAT64 plugin use:
     784             :  *  vpp# nat64 plugin enable
     785             :  * To enable NAT64 plugin and configure buckets/memory:
     786             :  *  vpp# nat64 plugin enable bib-buckets <n> bib-memory <s> \
     787             :  *    st-buckets <n> st-memory <s>
     788             :  * To disable NAT64 plugin:
     789             :  *  vpp# nat64 plugin disable
     790             :  * @cliexend
     791             : ?*/
     792       83095 : VLIB_CLI_COMMAND (nat64_plugin_enable_disable_command, static) =
     793             : {
     794             :   .path = "nat64 plugin",
     795             :   .short_help = "nat64 plugin <enable "
     796             :                 "[bib-buckets <count>] [bib-memory <size>] "
     797             :                 "[st-buckets <count>] [st-memory <size>] | disable>",
     798             :   .function = nat64_plugin_enable_disable_command_fn,
     799             : };
     800             : 
     801             : /*?
     802             :  * @cliexpar
     803             :  * @cliexstart{nat64 add pool address}
     804             :  * Add/delete NAT64 pool address.
     805             :  * To add single NAT64 pool address use:
     806             :  *  vpp# nat64 add pool address 10.1.1.10
     807             :  * To add NAT64 pool address range use:
     808             :  *  vpp# nat64 add pool address 10.1.1.2 - 10.1.1.5
     809             :  * To add NAT64 pool address for specific tenant use:
     810             :  *  vpp# nat64 add pool address 10.1.1.100 tenant-vrf 100
     811             :  * @cliexend
     812             : ?*/
     813       83095 : VLIB_CLI_COMMAND (nat64_add_pool_address_command, static) = {
     814             :   .path = "nat64 add pool address",
     815             :   .short_help = "nat64 add pool address <ip4-range-start> [- <ip4-range-end>] "
     816             :                 "[tenant-vrf <vrf-id>] [del]",
     817             :   .function = nat64_add_del_pool_addr_command_fn,
     818             : };
     819             : 
     820             : /*?
     821             :  * @cliexpar
     822             :  * @cliexstart{show nat64 pool}
     823             :  * Show NAT64 pool.
     824             :  *  vpp# show nat64 pool
     825             :  *  NAT64 pool:
     826             :  *   10.1.1.3 tenant VRF: 0
     827             :  *   10.1.1.10 tenant VRF: 10
     828             :  * @cliexend
     829             : ?*/
     830       83095 : VLIB_CLI_COMMAND (show_nat64_pool_command, static) = {
     831             :   .path = "show nat64 pool",
     832             :   .short_help = "show nat64 pool",
     833             :   .function = nat64_show_pool_command_fn,
     834             : };
     835             : 
     836             : /*?
     837             :  * @cliexpar
     838             :  * @cliexstart{set interface nat64}
     839             :  * Enable/disable NAT64 feature on the interface.
     840             :  * To enable NAT64 feature with local (IPv6) network interface
     841             :  * GigabitEthernet0/8/0 and external (IPv4) network interface
     842             :  * GigabitEthernet0/a/0 use:
     843             :  *  vpp# set interface nat64 in GigabitEthernet0/8/0 out GigabitEthernet0/a/0
     844             :  * @cliexend
     845             : ?*/
     846       83095 : VLIB_CLI_COMMAND (set_interface_nat64_command, static) = {
     847             :   .path = "set interface nat64",
     848             :   .short_help = "set interface nat64 in|out <intfc> [del]",
     849             :   .function = nat64_interface_feature_command_fn,
     850             : };
     851             : 
     852             : /*?
     853             :  * @cliexpar
     854             :  * @cliexstart{show nat64 interfaces}
     855             :  * Show interfaces with NAT64 feature.
     856             :  * To show interfaces with NAT64 feature use:
     857             :  *  vpp# show nat64 interfaces
     858             :  *  NAT64 interfaces:
     859             :  *   GigabitEthernet0/8/0 in
     860             :  *   GigabitEthernet0/a/0 out
     861             :  * @cliexend
     862             : ?*/
     863       83095 : VLIB_CLI_COMMAND (show_nat64_interfaces_command, static) = {
     864             :   .path = "show nat64 interfaces",
     865             :   .short_help = "show nat64 interfaces",
     866             :   .function = nat64_show_interfaces_command_fn,
     867             : };
     868             : 
     869             : /*?
     870             :  * @cliexpar
     871             :  * @cliexstart{nat64 add static bib}
     872             :  * Add/delete NAT64 static BIB entry.
     873             :  * To create NAT64 satatic BIB entry use:
     874             :  *  vpp# nat64 add static bib 2001:db8:c000:221:: 1234 10.1.1.3 5678 tcp
     875             :  *  vpp# nat64 add static bib 2001:db8:c000:221:: 1234 10.1.1.3 5678 udp vrf 10
     876             :  * @cliexend
     877             : ?*/
     878       83095 : VLIB_CLI_COMMAND (nat64_add_del_static_bib_command, static) = {
     879             :   .path = "nat64 add static bib",
     880             :   .short_help = "nat64 add static bib <ip6-addr> <port> <ip4-addr> <port> "
     881             :                 "tcp|udp|icmp [vfr <table-id>] [del]",
     882             :   .function = nat64_add_del_static_bib_command_fn,
     883             : };
     884             : 
     885             : /*?
     886             :  * @cliexpar
     887             :  * @cliexstart{show nat64 bib}
     888             :  * Show NAT64 BIB entries.
     889             :  * To show NAT64 TCP BIB entries use:
     890             :  *  vpp# show nat64 bib tcp
     891             :  *  NAT64 tcp BIB:
     892             :  *   fd01:1::2 6303 10.0.0.3 62303 tcp vrf 0 dynamic 1 sessions
     893             :  *   2001:db8:c000:221:: 1234 10.1.1.3 5678 tcp vrf 0 static 2 sessions
     894             :  * To show NAT64 UDP BIB entries use:
     895             :  *  vpp# show nat64 bib udp
     896             :  *  NAT64 udp BIB:
     897             :  *   fd01:1::2 6304 10.0.0.3 10546 udp vrf 0 dynamic 10 sessions
     898             :  *   2001:db8:c000:221:: 1234 10.1.1.3 5678 udp vrf 10 static 0 sessions
     899             :  * To show NAT64 ICMP BIB entries use:
     900             :  *  vpp# show nat64 bib icmp
     901             :  *  NAT64 icmp BIB:
     902             :  *   fd01:1::2 6305 10.0.0.3 63209 icmp vrf 10 dynamic 1 sessions
     903             :  * @cliexend
     904             : ?*/
     905       83095 : VLIB_CLI_COMMAND (show_nat64_bib_command, static) = {
     906             :   .path = "show nat64 bib",
     907             :   .short_help = "show nat64 bib all|tcp|udp|icmp|unknown",
     908             :   .function = nat64_show_bib_command_fn,
     909             : };
     910             : 
     911             : /*?
     912             :  * @cliexpar
     913             :  * @cliexstart{show nat64 session table}
     914             :  * Show NAT64 session table.
     915             :  * To show NAT64 TCP session table use:
     916             :  *  vpp# show nat64 session table tcp
     917             :  *  NAT64 tcp session table:
     918             :  *   fd01:1::2 6303 64:ff9b::ac10:202 20 10.0.0.3 62303 172.16.2.2 20 tcp vrf 0
     919             :  *   fd01:3::2 6303 64:ff9b::ac10:202 20 10.0.10.3 21300 172.16.2.2 20 tcp vrf 10
     920             :  * To show NAT64 UDP session table use:
     921             :  * #vpp show nat64 session table udp
     922             :  * NAT64 udp session table:
     923             :  *  fd01:1::2 6304 64:ff9b::ac10:202 20 10.0.0.3 10546 172.16.2.2 20 udp vrf 0
     924             :  *  fd01:3::2 6304 64:ff9b::ac10:202 20 10.0.10.3 58627 172.16.2.2 20 udp vrf 10
     925             :  *  fd01:1::2 1235 64:ff9b::a00:3 4023 10.0.0.3 24488 10.0.0.3 4023 udp vrf 0
     926             :  *  fd01:1::3 23 64:ff9b::a00:3 24488 10.0.0.3 4023 10.0.0.3 24488 udp vrf 0
     927             :  * To show NAT64 ICMP session table use:
     928             :  * #vpp show nat64 session table icmp
     929             :  * NAT64 icmp session table:
     930             :  *  fd01:1::2 64:ff9b::ac10:202 6305 10.0.0.3 172.16.2.2 63209 icmp vrf 0
     931             :  * @cliexend
     932             : ?*/
     933       83095 : VLIB_CLI_COMMAND (show_nat64_st_command, static) = {
     934             :   .path = "show nat64 session table",
     935             :   .short_help = "show nat64 session table all|tcp|udp|icmp|unknown",
     936             :   .function = nat64_show_st_command_fn,
     937             : };
     938             : 
     939             : /*?
     940             :  * @cliexpar
     941             :  * @cliexstart{nat64 add prefix}
     942             :  * Set NAT64 prefix for generating IPv6 representations of IPv4 addresses.
     943             :  * To set NAT64 global prefix use:
     944             :  *  vpp# nat64 add prefix 2001:db8::/32
     945             :  * To set NAT64 prefix for specific tenant use:
     946             :  *  vpp# nat64 add prefix 2001:db8:122:300::/56 tenant-vrf 10
     947             :  * @cliexend
     948             : ?*/
     949       83095 : VLIB_CLI_COMMAND (nat64_add_del_prefix_command, static) = {
     950             :   .path = "nat64 add prefix",
     951             :   .short_help = "nat64 add prefix <ip6-prefix>/<plen> [tenant-vrf <vrf-id>] "
     952             :                 "[del] [interface <interface]",
     953             :   .function = nat64_add_del_prefix_command_fn,
     954             : };
     955             : 
     956             : /*?
     957             :  * @cliexpar
     958             :  * @cliexstart{show nat64 prefix}
     959             :  * Show NAT64 prefix.
     960             :  * To show NAT64 prefix use:
     961             :  *  vpp# show nat64 prefix
     962             :  *  NAT64 prefix:
     963             :  *   2001:db8::/32 tenant-vrf 0
     964             :  *   2001:db8:122:300::/56 tenant-vrf 10
     965             :  * @cliexend
     966             : ?*/
     967       83095 : VLIB_CLI_COMMAND (show_nat64_prefix_command, static) = {
     968             :   .path = "show nat64 prefix",
     969             :   .short_help = "show nat64 prefix",
     970             :   .function = nat64_show_prefix_command_fn,
     971             : };
     972             : 
     973             : /*?
     974             :  * @cliexpar
     975             :  * @cliexstart{nat64 add interface address}
     976             :  * Add/delete NAT64 pool address from specific (DHCP addressed) interface.
     977             :  * To add NAT64 pool address from specific interface use:
     978             :  *  vpp# nat64 add interface address GigabitEthernet0/8/0
     979             :  * @cliexend
     980             : ?*/
     981       83095 : VLIB_CLI_COMMAND (nat64_add_interface_address_command, static) = {
     982             :     .path = "nat64 add interface address",
     983             :     .short_help = "nat64 add interface address <interface> [del]",
     984             :     .function = nat64_add_interface_address_command_fn,
     985             : };
     986             : /* *INDENT-ON* */
     987             : 
     988             : /*
     989             :  * fd.io coding-style-patch-verification: ON
     990             :  *
     991             :  * Local Variables:
     992             :  * eval: (c-set-style "gnu")
     993             :  * End:
     994             :  */

Generated by: LCOV version 1.14