LCOV - code coverage report
Current view: top level - plugins/nat/nat44-ei - nat44_ei_cli.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 222 787 28.2 %
Date: 2023-07-05 22:20:52 Functions: 77 98 78.6 %

          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             : 
      18             : #include <nat/lib/log.h>
      19             : #include <nat/lib/nat_inlines.h>
      20             : #include <nat/lib/ipfix_logging.h>
      21             : 
      22             : #include <nat/nat44-ei/nat44_ei.h>
      23             : #include <nat/nat44-ei/nat44_ei_ha.h>
      24             : 
      25             : #define NAT44_EI_EXPECTED_ARGUMENT "expected required argument(s)"
      26             : 
      27             : u8 *
      28       10451 : format_nat44_ei_session (u8 *s, va_list *args)
      29             : {
      30       10451 :   nat44_ei_main_per_thread_data_t *tnm =
      31             :     va_arg (*args, nat44_ei_main_per_thread_data_t *);
      32       10451 :   nat44_ei_session_t *sess = va_arg (*args, nat44_ei_session_t *);
      33             : 
      34       10451 :   if (nat44_ei_is_unk_proto_session (sess))
      35             :     {
      36             :       s =
      37           0 :         format (s, "  i2o %U proto %u fib %u\n", format_ip4_address,
      38           0 :                 &sess->in2out.addr, sess->in2out.port, sess->in2out.fib_index);
      39             :       s =
      40           0 :         format (s, "  o2i %U proto %u fib %u\n", format_ip4_address,
      41           0 :                 &sess->out2in.addr, sess->out2in.port, sess->out2in.fib_index);
      42             :     }
      43             :   else
      44             :     {
      45       20902 :       s = format (s, "  i2o %U proto %U port %d fib %d\n", format_ip4_address,
      46       10451 :                   &sess->in2out.addr, format_nat_protocol, sess->nat_proto,
      47       10451 :                   clib_net_to_host_u16 (sess->in2out.port),
      48             :                   sess->in2out.fib_index);
      49       20902 :       s = format (s, "  o2i %U proto %U port %d fib %d\n", format_ip4_address,
      50       10451 :                   &sess->out2in.addr, format_nat_protocol, sess->nat_proto,
      51       10451 :                   clib_net_to_host_u16 (sess->out2in.port),
      52             :                   sess->out2in.fib_index);
      53             :     }
      54             : 
      55       10451 :   s = format (s, "       index %llu\n", sess - tnm->sessions);
      56       10451 :   s = format (s, "       last heard %.2f\n", sess->last_heard);
      57       10451 :   s = format (s, "       total pkts %d, total bytes %lld\n", sess->total_pkts,
      58             :               sess->total_bytes);
      59       10451 :   if (nat44_ei_is_session_static (sess))
      60          38 :     s = format (s, "       static translation\n");
      61             :   else
      62       10413 :     s = format (s, "       dynamic translation\n");
      63             : 
      64       10451 :   return s;
      65             : }
      66             : 
      67             : u8 *
      68       10384 : format_nat44_ei_user (u8 *s, va_list *args)
      69             : {
      70       10384 :   nat44_ei_main_per_thread_data_t *tnm =
      71             :     va_arg (*args, nat44_ei_main_per_thread_data_t *);
      72       10384 :   nat44_ei_user_t *u = va_arg (*args, nat44_ei_user_t *);
      73       10384 :   int verbose = va_arg (*args, int);
      74             :   dlist_elt_t *head, *elt;
      75             :   u32 elt_index, head_index;
      76             :   u32 session_index;
      77             :   nat44_ei_session_t *sess;
      78             : 
      79       10384 :   s = format (s, "%U: %d dynamic translations, %d static translations\n",
      80             :               format_ip4_address, &u->addr, u->nsessions, u->nstaticsessions);
      81             : 
      82       10384 :   if (verbose == 0)
      83           0 :     return s;
      84             : 
      85       10384 :   if (u->nsessions || u->nstaticsessions)
      86             :     {
      87       10384 :       head_index = u->sessions_per_user_list_head_index;
      88       10384 :       head = pool_elt_at_index (tnm->list_pool, head_index);
      89             : 
      90       10384 :       elt_index = head->next;
      91       10384 :       elt = pool_elt_at_index (tnm->list_pool, elt_index);
      92       10384 :       session_index = elt->value;
      93             : 
      94       20835 :       while (session_index != ~0)
      95             :         {
      96       10451 :           sess = pool_elt_at_index (tnm->sessions, session_index);
      97             : 
      98       10451 :           s = format (s, "  %U\n", format_nat44_ei_session, tnm, sess);
      99             : 
     100       10451 :           elt_index = elt->next;
     101       10451 :           elt = pool_elt_at_index (tnm->list_pool, elt_index);
     102       10451 :           session_index = elt->value;
     103             :         }
     104             :     }
     105             : 
     106       10384 :   return s;
     107             : }
     108             : 
     109             : u8 *
     110          30 : format_nat44_ei_static_mapping (u8 *s, va_list *args)
     111             : {
     112          30 :   nat44_ei_static_mapping_t *m = va_arg (*args, nat44_ei_static_mapping_t *);
     113             :   nat44_ei_lb_addr_port_t *local;
     114             : 
     115          30 :   if (is_sm_identity_nat (m->flags))
     116             :     {
     117           1 :       if (is_sm_addr_only (m->flags))
     118           1 :         s = format (s, "identity mapping %U", format_ip4_address,
     119             :                     &m->local_addr);
     120             :       else
     121           0 :         s = format (s, "identity mapping %U %U:%d", format_nat_protocol,
     122           0 :                     m->proto, format_ip4_address, &m->local_addr,
     123           0 :                     clib_net_to_host_u16 (m->local_port));
     124             : 
     125           3 :       pool_foreach (local, m->locals)
     126             :         {
     127           2 :           s = format (s, " vrf %d", local->vrf_id);
     128             :         }
     129             : 
     130           1 :       return s;
     131             :     }
     132             : 
     133          29 :   if (is_sm_addr_only (m->flags))
     134             :     {
     135          15 :       s = format (s, "local %U external %U vrf %d", format_ip4_address,
     136             :                   &m->local_addr, format_ip4_address, &m->external_addr,
     137             :                   m->vrf_id);
     138             :     }
     139             :   else
     140             :     {
     141          42 :       s = format (s, "%U local %U:%d external %U:%d vrf %d",
     142          14 :                   format_nat_protocol, m->proto, format_ip4_address,
     143          14 :                   &m->local_addr, clib_net_to_host_u16 (m->local_port),
     144             :                   format_ip4_address, &m->external_addr,
     145          14 :                   clib_net_to_host_u16 (m->external_port), m->vrf_id);
     146             :     }
     147          29 :   return s;
     148             : }
     149             : 
     150             : u8 *
     151           1 : format_nat44_ei_static_map_to_resolve (u8 *s, va_list *args)
     152             : {
     153           1 :   nat44_ei_static_map_resolve_t *m =
     154             :     va_arg (*args, nat44_ei_static_map_resolve_t *);
     155           1 :   vnet_main_t *vnm = vnet_get_main ();
     156             : 
     157           1 :   if (is_sm_addr_only (m->flags))
     158             :     s =
     159           0 :       format (s, "local %U external %U vrf %d", format_ip4_address, &m->l_addr,
     160             :               format_vnet_sw_if_index_name, vnm, m->sw_if_index, m->vrf_id);
     161             :   else
     162           3 :     s = format (s, "%U local %U:%d external %U:%d vrf %d", format_nat_protocol,
     163           1 :                 m->proto, format_ip4_address, &m->l_addr,
     164           1 :                 clib_net_to_host_u16 (m->l_port), format_vnet_sw_if_index_name,
     165           1 :                 vnm, m->sw_if_index, clib_net_to_host_u16 (m->e_port),
     166             :                 m->vrf_id);
     167             : 
     168           1 :   return s;
     169             : }
     170             : 
     171             : static clib_error_t *
     172           0 : nat44_ei_enable_disable_command_fn (vlib_main_t *vm, unformat_input_t *input,
     173             :                                     vlib_cli_command_t *cmd)
     174             : {
     175           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     176           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     177           0 :   clib_error_t *error = 0;
     178             : 
     179           0 :   nat44_ei_config_t c = { 0 };
     180           0 :   u8 enable_set = 0, enable = 0, mode_set = 0;
     181             : 
     182           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     183           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
     184             : 
     185           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     186             :     {
     187           0 :       if (!mode_set && unformat (line_input, "static-mapping-only"))
     188             :         {
     189           0 :           mode_set = 1;
     190           0 :           c.static_mapping_only = 1;
     191           0 :           if (unformat (line_input, "connection-tracking"))
     192             :             {
     193           0 :               c.connection_tracking = 1;
     194             :             }
     195             :         }
     196           0 :       else if (!mode_set && unformat (line_input, "out2in-dpo"))
     197             :         {
     198           0 :           mode_set = 1;
     199           0 :           c.out2in_dpo = 1;
     200             :         }
     201           0 :       else if (unformat (line_input, "inside-vrf %u", &c.inside_vrf))
     202             :         ;
     203           0 :       else if (unformat (line_input, "outside-vrf %u", &c.outside_vrf))
     204             :         ;
     205           0 :       else if (unformat (line_input, "users %u", &c.users))
     206             :         ;
     207           0 :       else if (unformat (line_input, "sessions %u", &c.sessions))
     208             :         ;
     209           0 :       else if (unformat (line_input, "user-sessions %u", &c.user_sessions))
     210             :         ;
     211           0 :       else if (!enable_set)
     212             :         {
     213           0 :           enable_set = 1;
     214           0 :           if (unformat (line_input, "disable"))
     215             :             ;
     216           0 :           else if (unformat (line_input, "enable"))
     217           0 :             enable = 1;
     218             :         }
     219             :       else
     220             :         {
     221           0 :           error = clib_error_return (0, "unknown input '%U'",
     222             :                                      format_unformat_error, line_input);
     223           0 :           goto done;
     224             :         }
     225             :     }
     226             : 
     227           0 :   if (!enable_set)
     228             :     {
     229           0 :       error = clib_error_return (0, "expected enable | disable");
     230           0 :       goto done;
     231             :     }
     232             : 
     233           0 :   if (enable)
     234             :     {
     235           0 :       if (nm->enabled)
     236             :         {
     237           0 :           error = clib_error_return (0, "already enabled");
     238           0 :           goto done;
     239             :         }
     240             : 
     241           0 :       if (nat44_ei_plugin_enable (c) != 0)
     242           0 :         error = clib_error_return (0, "enable failed");
     243             :     }
     244             :   else
     245             :     {
     246           0 :       if (!nm->enabled)
     247             :         {
     248           0 :           error = clib_error_return (0, "already disabled");
     249           0 :           goto done;
     250             :         }
     251             : 
     252           0 :       if (nat44_ei_plugin_disable () != 0)
     253           0 :         error = clib_error_return (0, "disable failed");
     254             :     }
     255             : 
     256           0 : done:
     257           0 :   unformat_free (line_input);
     258           0 :   return error;
     259             : }
     260             : 
     261             : static clib_error_t *
     262           0 : set_workers_command_fn (vlib_main_t *vm, unformat_input_t *input,
     263             :                         vlib_cli_command_t *cmd)
     264             : {
     265           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     266           0 :   uword *bitmap = 0;
     267           0 :   int rv = 0;
     268           0 :   clib_error_t *error = 0;
     269             : 
     270           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     271           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
     272             : 
     273           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     274             :     {
     275           0 :       if (unformat (line_input, "%U", unformat_bitmap_list, &bitmap))
     276             :         ;
     277             :       else
     278             :         {
     279           0 :           error = clib_error_return (0, "unknown input '%U'",
     280             :                                      format_unformat_error, line_input);
     281           0 :           goto done;
     282             :         }
     283             :     }
     284             : 
     285           0 :   if (bitmap == 0)
     286             :     {
     287           0 :       error = clib_error_return (0, "List of workers must be specified.");
     288           0 :       goto done;
     289             :     }
     290             : 
     291           0 :   rv = nat44_ei_set_workers (bitmap);
     292             : 
     293           0 :   clib_bitmap_free (bitmap);
     294             : 
     295           0 :   switch (rv)
     296             :     {
     297           0 :     case VNET_API_ERROR_INVALID_WORKER:
     298           0 :       error = clib_error_return (0, "Invalid worker(s).");
     299           0 :       goto done;
     300           0 :     case VNET_API_ERROR_FEATURE_DISABLED:
     301             :       error =
     302           0 :         clib_error_return (0, "Supported only if 2 or more workes available.");
     303           0 :       goto done;
     304           0 :     default:
     305           0 :       break;
     306             :     }
     307             : 
     308           0 : done:
     309           0 :   unformat_free (line_input);
     310             : 
     311           0 :   return error;
     312             : }
     313             : 
     314             : static clib_error_t *
     315           0 : nat_show_workers_command_fn (vlib_main_t *vm, unformat_input_t *input,
     316             :                              vlib_cli_command_t *cmd)
     317             : {
     318           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     319             :   u32 *worker;
     320             : 
     321           0 :   if (nm->num_workers > 1)
     322             :     {
     323           0 :       vlib_cli_output (vm, "%d workers", vec_len (nm->workers));
     324           0 :       vec_foreach (worker, nm->workers)
     325             :         {
     326           0 :           vlib_worker_thread_t *w =
     327           0 :             vlib_worker_threads + *worker + nm->first_worker_index;
     328           0 :           vlib_cli_output (vm, "  %s", w->name);
     329             :         }
     330             :     }
     331             : 
     332           0 :   return 0;
     333             : }
     334             : 
     335             : static clib_error_t *
     336           0 : nat44_ei_set_log_level_command_fn (vlib_main_t *vm, unformat_input_t *input,
     337             :                                    vlib_cli_command_t *cmd)
     338             : {
     339           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     340           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     341           0 :   u32 log_level = NAT_LOG_NONE;
     342           0 :   clib_error_t *error = 0;
     343             : 
     344           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     345           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
     346             : 
     347           0 :   if (!unformat (line_input, "%d", &log_level))
     348             :     {
     349           0 :       error = clib_error_return (0, "unknown input '%U'",
     350             :                                  format_unformat_error, line_input);
     351           0 :       goto done;
     352             :     }
     353           0 :   if (log_level > NAT_LOG_DEBUG)
     354             :     {
     355           0 :       error = clib_error_return (0, "unknown logging level '%d'", log_level);
     356           0 :       goto done;
     357             :     }
     358           0 :   nm->log_level = log_level;
     359             : 
     360           0 : done:
     361           0 :   unformat_free (line_input);
     362             : 
     363           0 :   return error;
     364             : }
     365             : 
     366             : static clib_error_t *
     367           0 : nat44_ei_ipfix_logging_enable_disable_command_fn (vlib_main_t *vm,
     368             :                                                   unformat_input_t *input,
     369             :                                                   vlib_cli_command_t *cmd)
     370             : {
     371           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     372           0 :   clib_error_t *error = 0;
     373             : 
     374           0 :   u32 domain_id = 0, src_port = 0;
     375           0 :   u8 enable_set = 0, enable = 0;
     376             : 
     377           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     378           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
     379             : 
     380           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     381             :     {
     382           0 :       if (unformat (line_input, "domain %d", &domain_id))
     383             :         ;
     384           0 :       else if (unformat (line_input, "src-port %d", &src_port))
     385             :         ;
     386           0 :       else if (unformat (line_input, "disable"))
     387           0 :         enable = 0;
     388           0 :       else if (!enable_set)
     389             :         {
     390           0 :           enable_set = 1;
     391           0 :           if (unformat (line_input, "disable"))
     392             :             ;
     393           0 :           else if (unformat (line_input, "enable"))
     394           0 :             enable = 1;
     395             :         }
     396             :       else
     397             :         {
     398           0 :           error = clib_error_return (0, "unknown input '%U'",
     399             :                                      format_unformat_error, line_input);
     400           0 :           goto done;
     401             :         }
     402             :     }
     403             : 
     404           0 :   if (!enable_set)
     405             :     {
     406           0 :       error = clib_error_return (0, "expected enable | disable");
     407           0 :       goto done;
     408             :     }
     409             : 
     410           0 :   if (nat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port))
     411             :     {
     412           0 :       error = clib_error_return (0, "ipfix logging enable failed");
     413           0 :       goto done;
     414             :     }
     415             : 
     416           0 : done:
     417           0 :   unformat_free (line_input);
     418             : 
     419           0 :   return error;
     420             : }
     421             : 
     422             : static clib_error_t *
     423          55 : nat44_ei_show_hash_command_fn (vlib_main_t *vm, unformat_input_t *input,
     424             :                                vlib_cli_command_t *cmd)
     425             : {
     426          55 :   nat44_ei_main_t *nm = &nat44_ei_main;
     427             :   nat44_ei_main_per_thread_data_t *tnm;
     428             :   int i;
     429          55 :   int verbose = 0;
     430             : 
     431          55 :   if (unformat (input, "detail"))
     432          55 :     verbose = 1;
     433           0 :   else if (unformat (input, "verbose"))
     434           0 :     verbose = 2;
     435             : 
     436          55 :   vlib_cli_output (vm, "%U", format_bihash_8_8, &nm->static_mapping_by_local,
     437             :                    verbose);
     438          55 :   vlib_cli_output (vm, "%U", format_bihash_8_8,
     439             :                    &nm->static_mapping_by_external, verbose);
     440         110 :   vec_foreach_index (i, nm->per_thread_data)
     441             :     {
     442          55 :       tnm = vec_elt_at_index (nm->per_thread_data, i);
     443          55 :       vlib_cli_output (vm, "-------- thread %d %s --------\n", i,
     444          55 :                        vlib_worker_threads[i].name);
     445             : 
     446          55 :       vlib_cli_output (vm, "%U", format_bihash_8_8, &nm->in2out, verbose);
     447          55 :       vlib_cli_output (vm, "%U", format_bihash_8_8, &nm->out2in, verbose);
     448          55 :       vlib_cli_output (vm, "%U", format_bihash_8_8, &tnm->user_hash, verbose);
     449             :     }
     450             : 
     451          55 :   vlib_cli_output (vm, "-------- hash table parameters --------\n");
     452          55 :   vlib_cli_output (vm, "translation buckets: %u", nm->translation_buckets);
     453          55 :   vlib_cli_output (vm, "user buckets: %u", nm->user_buckets);
     454          55 :   return 0;
     455             : }
     456             : 
     457             : static clib_error_t *
     458           0 : nat44_ei_set_alloc_addr_and_port_alg_command_fn (vlib_main_t *vm,
     459             :                                                  unformat_input_t *input,
     460             :                                                  vlib_cli_command_t *cmd)
     461             : {
     462           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     463           0 :   clib_error_t *error = 0;
     464             :   u32 psid, psid_offset, psid_length, port_start, port_end;
     465             : 
     466           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     467           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
     468             : 
     469           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     470             :     {
     471           0 :       if (unformat (line_input, "default"))
     472           0 :         nat44_ei_set_alloc_default ();
     473           0 :       else if (unformat (line_input,
     474             :                          "map-e psid %d psid-offset %d psid-len %d", &psid,
     475             :                          &psid_offset, &psid_length))
     476           0 :         nat44_ei_set_alloc_mape ((u16) psid, (u16) psid_offset,
     477           0 :                                  (u16) psid_length);
     478           0 :       else if (unformat (line_input, "port-range %d - %d", &port_start,
     479             :                          &port_end))
     480             :         {
     481           0 :           if (port_end <= port_start)
     482             :             {
     483           0 :               error = clib_error_return (
     484             :                 0, "The end-port must be greater than start-port");
     485           0 :               goto done;
     486             :             }
     487           0 :           nat44_ei_set_alloc_range ((u16) port_start, (u16) port_end);
     488             :         }
     489             :       else
     490             :         {
     491           0 :           error = clib_error_return (0, "unknown input '%U'",
     492             :                                      format_unformat_error, line_input);
     493           0 :           goto done;
     494             :         }
     495             :     }
     496             : 
     497           0 : done:
     498           0 :   unformat_free (line_input);
     499             : 
     500           0 :   return error;
     501             : };
     502             : 
     503             : u8 *
     504          55 : format_nat44_ei_addr_and_port_alloc_alg (u8 *s, va_list *args)
     505             : {
     506          55 :   u32 i = va_arg (*args, u32);
     507          55 :   u8 *t = 0;
     508             : 
     509          55 :   switch (i)
     510             :     {
     511             : #define _(v, N, s)                                                            \
     512             :   case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_##N:                                  \
     513             :     t = (u8 *) s;                                                             \
     514             :     break;
     515          55 :       foreach_nat44_ei_addr_and_port_alloc_alg
     516             : #undef _
     517           0 :         default : s = format (s, "unknown");
     518           0 :       return s;
     519             :     }
     520          55 :   s = format (s, "%s", t);
     521          55 :   return s;
     522             : }
     523             : 
     524             : static clib_error_t *
     525          55 : nat44_ei_show_alloc_addr_and_port_alg_command_fn (vlib_main_t *vm,
     526             :                                                   unformat_input_t *input,
     527             :                                                   vlib_cli_command_t *cmd)
     528             : {
     529          55 :   nat44_ei_main_t *nm = &nat44_ei_main;
     530             : 
     531          55 :   vlib_cli_output (vm, "NAT address and port: %U",
     532             :                    format_nat44_ei_addr_and_port_alloc_alg,
     533          55 :                    nm->addr_and_port_alloc_alg);
     534          55 :   switch (nm->addr_and_port_alloc_alg)
     535             :     {
     536           1 :     case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_MAPE:
     537           1 :       vlib_cli_output (vm, "  psid %d psid-offset %d psid-len %d", nm->psid,
     538           1 :                        nm->psid_offset, nm->psid_length);
     539           1 :       break;
     540           1 :     case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_RANGE:
     541           1 :       vlib_cli_output (vm, "  start-port %d end-port %d", nm->start_port,
     542           1 :                        nm->end_port);
     543           1 :       break;
     544          53 :     default:
     545          53 :       break;
     546             :     }
     547             : 
     548          55 :   return 0;
     549             : }
     550             : 
     551             : static clib_error_t *
     552           0 : nat_set_mss_clamping_command_fn (vlib_main_t *vm, unformat_input_t *input,
     553             :                                  vlib_cli_command_t *cmd)
     554             : {
     555           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     556           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     557           0 :   clib_error_t *error = 0;
     558             :   u32 mss;
     559             : 
     560           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     561           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
     562             : 
     563           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     564             :     {
     565           0 :       if (unformat (line_input, "disable"))
     566           0 :         nm->mss_clamping = 0;
     567           0 :       else if (unformat (line_input, "%d", &mss))
     568           0 :         nm->mss_clamping = (u16) mss;
     569             :       else
     570             :         {
     571           0 :           error = clib_error_return (0, "unknown input '%U'",
     572             :                                      format_unformat_error, line_input);
     573           0 :           goto done;
     574             :         }
     575             :     }
     576             : 
     577           0 : done:
     578           0 :   unformat_free (line_input);
     579             : 
     580           0 :   return error;
     581             : }
     582             : 
     583             : static clib_error_t *
     584           0 : nat_show_mss_clamping_command_fn (vlib_main_t *vm, unformat_input_t *input,
     585             :                                   vlib_cli_command_t *cmd)
     586             : {
     587           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     588             : 
     589           0 :   if (nm->mss_clamping)
     590           0 :     vlib_cli_output (vm, "mss-clamping %d", nm->mss_clamping);
     591             :   else
     592           0 :     vlib_cli_output (vm, "mss-clamping disabled");
     593             : 
     594           0 :   return 0;
     595             : }
     596             : 
     597             : static clib_error_t *
     598           0 : nat_ha_failover_command_fn (vlib_main_t *vm, unformat_input_t *input,
     599             :                             vlib_cli_command_t *cmd)
     600             : {
     601           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     602             :   ip4_address_t addr;
     603           0 :   u32 port, session_refresh_interval = 10;
     604             :   int rv;
     605           0 :   clib_error_t *error = 0;
     606             : 
     607           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     608           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
     609             : 
     610           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     611             :     {
     612           0 :       if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
     613             :         ;
     614           0 :       else if (unformat (line_input, "refresh-interval %u",
     615             :                          &session_refresh_interval))
     616             :         ;
     617             :       else
     618             :         {
     619           0 :           error = clib_error_return (0, "unknown input '%U'",
     620             :                                      format_unformat_error, line_input);
     621           0 :           goto done;
     622             :         }
     623             :     }
     624             : 
     625           0 :   rv = nat_ha_set_failover (vm, &addr, (u16) port, session_refresh_interval);
     626           0 :   if (rv)
     627           0 :     error = clib_error_return (0, "set HA failover failed");
     628             : 
     629           0 : done:
     630           0 :   unformat_free (line_input);
     631             : 
     632           0 :   return error;
     633             : }
     634             : 
     635             : static clib_error_t *
     636           0 : nat_ha_listener_command_fn (vlib_main_t *vm, unformat_input_t *input,
     637             :                             vlib_cli_command_t *cmd)
     638             : {
     639           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     640             :   ip4_address_t addr;
     641           0 :   u32 port, path_mtu = 512;
     642             :   int rv;
     643           0 :   clib_error_t *error = 0;
     644             : 
     645           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     646           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
     647             : 
     648           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     649             :     {
     650           0 :       if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
     651             :         ;
     652           0 :       else if (unformat (line_input, "path-mtu %u", &path_mtu))
     653             :         ;
     654             :       else
     655             :         {
     656           0 :           error = clib_error_return (0, "unknown input '%U'",
     657             :                                      format_unformat_error, line_input);
     658           0 :           goto done;
     659             :         }
     660             :     }
     661             : 
     662           0 :   rv = nat_ha_set_listener (vm, &addr, (u16) port, path_mtu);
     663           0 :   if (rv)
     664           0 :     error = clib_error_return (0, "set HA listener failed");
     665             : 
     666           0 : done:
     667           0 :   unformat_free (line_input);
     668             : 
     669           0 :   return error;
     670             : }
     671             : 
     672             : static clib_error_t *
     673          55 : nat_show_ha_command_fn (vlib_main_t *vm, unformat_input_t *input,
     674             :                         vlib_cli_command_t *cmd)
     675             : {
     676             :   ip4_address_t addr;
     677             :   u16 port;
     678             :   u32 path_mtu, session_refresh_interval, resync_ack_missed;
     679             :   u8 in_resync;
     680             : 
     681          55 :   nat_ha_get_listener (&addr, &port, &path_mtu);
     682          55 :   if (!port)
     683             :     {
     684          15 :       vlib_cli_output (vm, "NAT HA disabled\n");
     685          15 :       return 0;
     686             :     }
     687             : 
     688          40 :   vlib_cli_output (vm, "LISTENER:\n");
     689          40 :   vlib_cli_output (vm, "  %U:%u path-mtu %u\n", format_ip4_address, &addr,
     690             :                    port, path_mtu);
     691             : 
     692          40 :   nat_ha_get_failover (&addr, &port, &session_refresh_interval);
     693          40 :   vlib_cli_output (vm, "FAILOVER:\n");
     694          40 :   if (port)
     695           1 :     vlib_cli_output (vm, "  %U:%u refresh-interval %usec\n",
     696             :                      format_ip4_address, &addr, port,
     697             :                      session_refresh_interval);
     698             :   else
     699          39 :     vlib_cli_output (vm, "  NA\n");
     700             : 
     701          40 :   nat_ha_get_resync_status (&in_resync, &resync_ack_missed);
     702          40 :   vlib_cli_output (vm, "RESYNC:\n");
     703          40 :   if (in_resync)
     704           0 :     vlib_cli_output (vm, "  in progress\n");
     705             :   else
     706          40 :     vlib_cli_output (vm, "  completed (%d ACK missed)\n", resync_ack_missed);
     707             : 
     708          40 :   return 0;
     709             : }
     710             : 
     711             : static clib_error_t *
     712           0 : nat_ha_flush_command_fn (vlib_main_t *vm, unformat_input_t *input,
     713             :                          vlib_cli_command_t *cmd)
     714             : {
     715           0 :   nat_ha_flush (0);
     716           0 :   return 0;
     717             : }
     718             : 
     719             : static clib_error_t *
     720           0 : nat_ha_resync_command_fn (vlib_main_t *vm, unformat_input_t *input,
     721             :                           vlib_cli_command_t *cmd)
     722             : {
     723           0 :   clib_error_t *error = 0;
     724             : 
     725           0 :   if (nat_ha_resync (0, 0, 0))
     726           0 :     error = clib_error_return (0, "NAT HA resync already running");
     727             : 
     728           0 :   return error;
     729             : }
     730             : 
     731             : static clib_error_t *
     732           0 : add_address_command_fn (vlib_main_t *vm, unformat_input_t *input,
     733             :                         vlib_cli_command_t *cmd)
     734             : {
     735           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     736           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
     737             :   ip4_address_t start_addr, end_addr, this_addr;
     738             :   u32 start_host_order, end_host_order;
     739           0 :   u32 vrf_id = ~0;
     740             :   int i, count;
     741           0 :   int is_add = 1;
     742           0 :   int rv = 0;
     743           0 :   clib_error_t *error = 0;
     744             : 
     745           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     746           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
     747             : 
     748           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     749             :     {
     750           0 :       if (unformat (line_input, "%U - %U", unformat_ip4_address, &start_addr,
     751             :                     unformat_ip4_address, &end_addr))
     752             :         ;
     753           0 :       else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
     754             :         ;
     755           0 :       else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
     756           0 :         end_addr = start_addr;
     757           0 :       else if (unformat (line_input, "del"))
     758           0 :         is_add = 0;
     759             :       else
     760             :         {
     761           0 :           error = clib_error_return (0, "unknown input '%U'",
     762             :                                      format_unformat_error, line_input);
     763           0 :           goto done;
     764             :         }
     765             :     }
     766             : 
     767           0 :   if (nm->static_mapping_only)
     768             :     {
     769           0 :       error = clib_error_return (0, "static mapping only mode");
     770           0 :       goto done;
     771             :     }
     772             : 
     773           0 :   start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
     774           0 :   end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
     775             : 
     776           0 :   if (end_host_order < start_host_order)
     777             :     {
     778           0 :       error = clib_error_return (0, "end address less than start address");
     779           0 :       goto done;
     780             :     }
     781             : 
     782           0 :   count = (end_host_order - start_host_order) + 1;
     783             : 
     784           0 :   if (count > 1024)
     785           0 :     nat44_ei_log_info ("%U - %U, %d addresses...", format_ip4_address,
     786             :                        &start_addr, format_ip4_address, &end_addr, count);
     787             : 
     788           0 :   this_addr = start_addr;
     789             : 
     790           0 :   for (i = 0; i < count; i++)
     791             :     {
     792           0 :       if (is_add)
     793           0 :         rv = nat44_ei_add_address (&this_addr, vrf_id);
     794             :       else
     795           0 :         rv = nat44_ei_del_address (this_addr, 0);
     796             : 
     797           0 :       switch (rv)
     798             :         {
     799           0 :         case VNET_API_ERROR_VALUE_EXIST:
     800           0 :           error = clib_error_return (0, "NAT address already in use.");
     801           0 :           goto done;
     802           0 :         case VNET_API_ERROR_NO_SUCH_ENTRY:
     803           0 :           error = clib_error_return (0, "NAT address not exist.");
     804           0 :           goto done;
     805           0 :         case VNET_API_ERROR_UNSPECIFIED:
     806           0 :           error = clib_error_return (0, "NAT address used in static mapping.");
     807           0 :           goto done;
     808           0 :         case VNET_API_ERROR_FEATURE_DISABLED:
     809           0 :           goto done;
     810           0 :         default:
     811           0 :           break;
     812             :         }
     813             : 
     814           0 :       if (nm->out2in_dpo)
     815           0 :         nat44_ei_add_del_address_dpo (this_addr, is_add);
     816             : 
     817           0 :       increment_v4_address (&this_addr);
     818             :     }
     819             : 
     820           0 : done:
     821           0 :   unformat_free (line_input);
     822             : 
     823           0 :   return error;
     824             : }
     825             : 
     826             : static clib_error_t *
     827          55 : nat44_ei_show_addresses_command_fn (vlib_main_t *vm, unformat_input_t *input,
     828             :                                     vlib_cli_command_t *cmd)
     829             : {
     830          55 :   nat44_ei_main_t *nm = &nat44_ei_main;
     831             :   nat44_ei_address_t *ap;
     832             : 
     833          55 :   vlib_cli_output (vm, "NAT44 pool addresses:");
     834         193 :   vec_foreach (ap, nm->addresses)
     835             :     {
     836         138 :       vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
     837         138 :       if (ap->fib_index != ~0)
     838           5 :         vlib_cli_output (
     839             :           vm, "  tenant VRF: %u",
     840           5 :           fib_table_get (ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
     841             :       else
     842         133 :         vlib_cli_output (vm, "  tenant VRF independent");
     843             : #define _(N, i, n, s)                                                         \
     844             :   vlib_cli_output (vm, "  %d busy %s ports", ap->busy_ports[i], s);
     845         138 :       foreach_nat_protocol
     846             : #undef _
     847             :     }
     848          55 :   return 0;
     849             : }
     850             : 
     851             : static clib_error_t *
     852           0 : nat44_ei_feature_command_fn (vlib_main_t *vm, unformat_input_t *input,
     853             :                              vlib_cli_command_t *cmd)
     854             : {
     855           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     856           0 :   vnet_main_t *vnm = vnet_get_main ();
     857           0 :   clib_error_t *error = 0;
     858             :   u32 sw_if_index;
     859           0 :   u32 *inside_sw_if_indices = 0;
     860           0 :   u32 *outside_sw_if_indices = 0;
     861           0 :   u8 is_output_feature = 0;
     862           0 :   int i, rv, is_del = 0;
     863             : 
     864           0 :   sw_if_index = ~0;
     865             : 
     866           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     867           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
     868             : 
     869           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     870             :     {
     871           0 :       if (unformat (line_input, "in %U", unformat_vnet_sw_interface, vnm,
     872             :                     &sw_if_index))
     873           0 :         vec_add1 (inside_sw_if_indices, sw_if_index);
     874           0 :       else if (unformat (line_input, "out %U", unformat_vnet_sw_interface, vnm,
     875             :                          &sw_if_index))
     876           0 :         vec_add1 (outside_sw_if_indices, sw_if_index);
     877           0 :       else if (unformat (line_input, "output-feature"))
     878           0 :         is_output_feature = 1;
     879           0 :       else if (unformat (line_input, "del"))
     880           0 :         is_del = 1;
     881             :       else
     882             :         {
     883           0 :           error = clib_error_return (0, "unknown input '%U'",
     884             :                                      format_unformat_error, line_input);
     885           0 :           goto done;
     886             :         }
     887             :     }
     888             : 
     889           0 :   if (vec_len (inside_sw_if_indices))
     890             :     {
     891           0 :       for (i = 0; i < vec_len (inside_sw_if_indices); i++)
     892             :         {
     893           0 :           sw_if_index = inside_sw_if_indices[i];
     894           0 :           if (is_output_feature)
     895             :             {
     896           0 :               if (is_del)
     897             :                 {
     898           0 :                   rv = nat44_ei_del_output_interface (sw_if_index);
     899             :                 }
     900             :               else
     901             :                 {
     902           0 :                   rv = nat44_ei_add_output_interface (sw_if_index);
     903             :                 }
     904           0 :               if (rv)
     905             :                 {
     906           0 :                   error = clib_error_return (
     907             :                     0, "%s %U failed", is_del ? "del" : "add",
     908             :                     format_vnet_sw_if_index_name, vnm, sw_if_index);
     909           0 :                   goto done;
     910             :                 }
     911             :             }
     912             :           else
     913             :             {
     914           0 :               if (is_del)
     915             :                 {
     916           0 :                   rv = nat44_ei_del_interface (sw_if_index, 1);
     917             :                 }
     918             :               else
     919             :                 {
     920           0 :                   rv = nat44_ei_add_interface (sw_if_index, 1);
     921             :                 }
     922           0 :               if (rv)
     923             :                 {
     924           0 :                   error = clib_error_return (
     925             :                     0, "%s %U failed", is_del ? "del" : "add",
     926             :                     format_vnet_sw_if_index_name, vnm, sw_if_index);
     927           0 :                   goto done;
     928             :                 }
     929             :             }
     930             :         }
     931             :     }
     932             : 
     933           0 :   if (vec_len (outside_sw_if_indices))
     934             :     {
     935           0 :       for (i = 0; i < vec_len (outside_sw_if_indices); i++)
     936             :         {
     937           0 :           sw_if_index = outside_sw_if_indices[i];
     938           0 :           if (is_output_feature)
     939             :             {
     940           0 :               if (is_del)
     941             :                 {
     942           0 :                   rv = nat44_ei_del_output_interface (sw_if_index);
     943             :                 }
     944             :               else
     945             :                 {
     946           0 :                   rv = nat44_ei_add_output_interface (sw_if_index);
     947             :                 }
     948           0 :               if (rv)
     949             :                 {
     950           0 :                   error = clib_error_return (
     951             :                     0, "%s %U failed", is_del ? "del" : "add",
     952             :                     format_vnet_sw_if_index_name, vnm, sw_if_index);
     953           0 :                   goto done;
     954             :                 }
     955             :             }
     956             :           else
     957             :             {
     958           0 :               if (is_del)
     959             :                 {
     960           0 :                   rv = nat44_ei_del_interface (sw_if_index, 0);
     961             :                 }
     962             :               else
     963             :                 {
     964           0 :                   rv = nat44_ei_add_interface (sw_if_index, 0);
     965             :                 }
     966           0 :               if (rv)
     967             :                 {
     968           0 :                   error = clib_error_return (
     969             :                     0, "%s %U failed", is_del ? "del" : "add",
     970             :                     format_vnet_sw_if_index_name, vnm, sw_if_index);
     971           0 :                   goto done;
     972             :                 }
     973             :             }
     974             :         }
     975             :     }
     976             : 
     977           0 : done:
     978           0 :   unformat_free (line_input);
     979           0 :   vec_free (inside_sw_if_indices);
     980           0 :   vec_free (outside_sw_if_indices);
     981             : 
     982           0 :   return error;
     983             : }
     984             : 
     985             : static clib_error_t *
     986          55 : nat44_ei_show_interfaces_command_fn (vlib_main_t *vm, unformat_input_t *input,
     987             :                                      vlib_cli_command_t *cmd)
     988             : {
     989          55 :   nat44_ei_main_t *nm = &nat44_ei_main;
     990             :   nat44_ei_interface_t *i;
     991          55 :   vnet_main_t *vnm = vnet_get_main ();
     992             : 
     993          55 :   vlib_cli_output (vm, "NAT44 interfaces:");
     994         153 :   pool_foreach (i, nm->interfaces)
     995             :     {
     996         196 :       vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
     997             :                        i->sw_if_index,
     998         150 :                        (nat44_ei_interface_is_inside (i) &&
     999          52 :                         nat44_ei_interface_is_outside (i)) ?
    1000             :                          "in out" :
    1001          97 :                          (nat44_ei_interface_is_inside (i) ? "in" : "out"));
    1002             :     }
    1003             : 
    1004          59 :   pool_foreach (i, nm->output_feature_interfaces)
    1005             :     {
    1006           8 :       vlib_cli_output (vm, " %U output-feature %s",
    1007             :                        format_vnet_sw_if_index_name, vnm, i->sw_if_index,
    1008           8 :                        (nat44_ei_interface_is_inside (i) &&
    1009           4 :                         nat44_ei_interface_is_outside (i)) ?
    1010             :                          "in out" :
    1011           0 :                          (nat44_ei_interface_is_inside (i) ? "in" : "out"));
    1012             :     }
    1013             : 
    1014          55 :   return 0;
    1015             : }
    1016             : 
    1017             : static clib_error_t *
    1018           0 : add_static_mapping_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1019             :                                vlib_cli_command_t *cmd)
    1020             : {
    1021           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1022           0 :   vnet_main_t *vnm = vnet_get_main ();
    1023           0 :   clib_error_t *error = 0;
    1024             :   int rv;
    1025             : 
    1026           0 :   nat_protocol_t proto = NAT_PROTOCOL_OTHER;
    1027           0 :   ip4_address_t l_addr, e_addr, pool_addr = { 0 };
    1028           0 :   u32 l_port = 0, e_port = 0, vrf_id = ~0;
    1029           0 :   u8 l_port_set = 0, e_port_set = 0;
    1030           0 :   u32 sw_if_index = ~0, flags = 0;
    1031           0 :   int is_add = 1;
    1032             : 
    1033           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1034           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
    1035             : 
    1036           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1037             :     {
    1038           0 :       if (unformat (line_input, "local %U %u", unformat_ip4_address, &l_addr,
    1039             :                     &l_port))
    1040             :         {
    1041           0 :           l_port_set = 1;
    1042             :         }
    1043           0 :       else if (unformat (line_input, "local %U", unformat_ip4_address,
    1044             :                          &l_addr))
    1045             :         ;
    1046           0 :       else if (unformat (line_input, "external %U %u", unformat_ip4_address,
    1047             :                          &e_addr, &e_port))
    1048             :         {
    1049           0 :           e_port_set = 1;
    1050             :         }
    1051           0 :       else if (unformat (line_input, "external %U", unformat_ip4_address,
    1052             :                          &e_addr))
    1053             :         ;
    1054           0 :       else if (unformat (line_input, "external %U %u",
    1055             :                          unformat_vnet_sw_interface, vnm, &sw_if_index,
    1056             :                          &e_port))
    1057             :         {
    1058           0 :           e_port_set = 1;
    1059             :         }
    1060           0 :       else if (unformat (line_input, "external %U", unformat_vnet_sw_interface,
    1061             :                          vnm, &sw_if_index))
    1062             :         ;
    1063           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
    1064             :         ;
    1065           0 :       else if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
    1066             :         ;
    1067           0 :       else if (unformat (line_input, "del"))
    1068             :         {
    1069           0 :           is_add = 0;
    1070             :         }
    1071             :       else
    1072             :         {
    1073           0 :           error = clib_error_return (0, "unknown input: '%U'",
    1074             :                                      format_unformat_error, line_input);
    1075           0 :           goto done;
    1076             :         }
    1077             :     }
    1078             : 
    1079           0 :   if (l_port_set != e_port_set)
    1080             :     {
    1081           0 :       error = clib_error_return (0, "Either both ports are set or none.");
    1082           0 :       goto done;
    1083             :     }
    1084             : 
    1085           0 :   if (!l_port_set)
    1086             :     {
    1087           0 :       flags |= NAT44_EI_SM_FLAG_ADDR_ONLY;
    1088             :     }
    1089             :   else
    1090             :     {
    1091           0 :       l_port = clib_host_to_net_u16 (l_port);
    1092           0 :       e_port = clib_host_to_net_u16 (e_port);
    1093             :     }
    1094             : 
    1095           0 :   if (sw_if_index != ~0)
    1096             :     {
    1097           0 :       flags |= NAT44_EI_SM_FLAG_SWITCH_ADDRESS;
    1098             :     }
    1099             : 
    1100           0 :   if (is_add)
    1101             :     {
    1102             :       rv =
    1103           0 :         nat44_ei_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
    1104             :                                      vrf_id, sw_if_index, flags, pool_addr, 0);
    1105             :     }
    1106             :   else
    1107             :     {
    1108           0 :       rv = nat44_ei_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
    1109             :                                         vrf_id, sw_if_index, flags);
    1110             :     }
    1111             : 
    1112           0 :   switch (rv)
    1113             :     {
    1114           0 :     case VNET_API_ERROR_INVALID_VALUE:
    1115           0 :       error = clib_error_return (0, "External port already in use.");
    1116           0 :       goto done;
    1117           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
    1118           0 :       if (is_add)
    1119           0 :         error = clib_error_return (0, "External address must be allocated.");
    1120             :       else
    1121           0 :         error = clib_error_return (0, "Mapping not exist.");
    1122           0 :       goto done;
    1123           0 :     case VNET_API_ERROR_NO_SUCH_FIB:
    1124           0 :       error = clib_error_return (0, "No such VRF id.");
    1125           0 :       goto done;
    1126           0 :     case VNET_API_ERROR_VALUE_EXIST:
    1127           0 :       error = clib_error_return (0, "Mapping already exist.");
    1128           0 :       goto done;
    1129           0 :     case VNET_API_ERROR_FEATURE_DISABLED:
    1130           0 :       goto done;
    1131           0 :     default:
    1132           0 :       break;
    1133             :     }
    1134             : 
    1135           0 : done:
    1136           0 :   unformat_free (line_input);
    1137             : 
    1138           0 :   return error;
    1139             : }
    1140             : 
    1141             : static clib_error_t *
    1142           0 : add_identity_mapping_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1143             :                                  vlib_cli_command_t *cmd)
    1144             : {
    1145           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1146           0 :   vnet_main_t *vnm = vnet_get_main ();
    1147           0 :   clib_error_t *error = 0;
    1148             : 
    1149           0 :   int rv, is_add = 1, port_set = 0;
    1150           0 :   u32 sw_if_index = ~0, port, flags, vrf_id = ~0;
    1151           0 :   nat_protocol_t proto = NAT_PROTOCOL_OTHER;
    1152             :   ip4_address_t addr;
    1153             : 
    1154           0 :   flags = NAT44_EI_SM_FLAG_IDENTITY_NAT;
    1155             : 
    1156           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1157           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
    1158             : 
    1159           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1160             :     {
    1161           0 :       if (unformat (line_input, "%U", unformat_ip4_address, &addr))
    1162             :         ;
    1163           0 :       else if (unformat (line_input, "external %U", unformat_vnet_sw_interface,
    1164             :                          vnm, &sw_if_index))
    1165             :         ;
    1166           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
    1167             :         ;
    1168           0 :       else if (unformat (line_input, "%U %u", unformat_nat_protocol, &proto,
    1169             :                          &port))
    1170             :         {
    1171           0 :           port_set = 1;
    1172             :         }
    1173           0 :       else if (unformat (line_input, "del"))
    1174             :         {
    1175           0 :           is_add = 0;
    1176             :         }
    1177             :       else
    1178             :         {
    1179           0 :           error = clib_error_return (0, "unknown input: '%U'",
    1180             :                                      format_unformat_error, line_input);
    1181           0 :           goto done;
    1182             :         }
    1183             :     }
    1184             : 
    1185           0 :   if (!port_set)
    1186             :     {
    1187           0 :       flags |= NAT44_EI_SM_FLAG_ADDR_ONLY;
    1188             :     }
    1189             :   else
    1190             :     {
    1191           0 :       port = clib_host_to_net_u16 (port);
    1192             :     }
    1193             : 
    1194           0 :   if (sw_if_index != ~0)
    1195             :     {
    1196           0 :       flags |= NAT44_EI_SM_FLAG_SWITCH_ADDRESS;
    1197             :     }
    1198             : 
    1199           0 :   if (is_add)
    1200             :     {
    1201             : 
    1202           0 :       rv = nat44_ei_add_static_mapping (addr, addr, port, port, proto, vrf_id,
    1203             :                                         sw_if_index, flags, addr, 0);
    1204             :     }
    1205             :   else
    1206             :     {
    1207           0 :       rv = nat44_ei_del_static_mapping (addr, addr, port, port, proto, vrf_id,
    1208             :                                         sw_if_index, flags);
    1209             :     }
    1210             : 
    1211           0 :   switch (rv)
    1212             :     {
    1213           0 :     case VNET_API_ERROR_INVALID_VALUE:
    1214           0 :       error = clib_error_return (0, "External port already in use.");
    1215           0 :       goto done;
    1216           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
    1217           0 :       if (is_add)
    1218           0 :         error = clib_error_return (0, "External address must be allocated.");
    1219             :       else
    1220           0 :         error = clib_error_return (0, "Mapping not exist.");
    1221           0 :       goto done;
    1222           0 :     case VNET_API_ERROR_NO_SUCH_FIB:
    1223           0 :       error = clib_error_return (0, "No such VRF id.");
    1224           0 :       goto done;
    1225           0 :     case VNET_API_ERROR_VALUE_EXIST:
    1226           0 :       error = clib_error_return (0, "Mapping already exist.");
    1227           0 :       goto done;
    1228           0 :     default:
    1229           0 :       break;
    1230             :     }
    1231             : 
    1232           0 : done:
    1233           0 :   unformat_free (line_input);
    1234             : 
    1235           0 :   return error;
    1236             : }
    1237             : 
    1238             : static clib_error_t *
    1239          55 : nat44_ei_show_static_mappings_command_fn (vlib_main_t *vm,
    1240             :                                           unformat_input_t *input,
    1241             :                                           vlib_cli_command_t *cmd)
    1242             : {
    1243          55 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1244             :   nat44_ei_static_mapping_t *m;
    1245             :   nat44_ei_static_map_resolve_t *rp;
    1246             : 
    1247          55 :   vlib_cli_output (vm, "NAT44 static mappings:");
    1248          85 :   pool_foreach (m, nm->static_mappings)
    1249             :     {
    1250          30 :       vlib_cli_output (vm, " %U", format_nat44_ei_static_mapping, m);
    1251             :     }
    1252          56 :   vec_foreach (rp, nm->to_resolve)
    1253           1 :     vlib_cli_output (vm, " %U", format_nat44_ei_static_map_to_resolve, rp);
    1254             : 
    1255          55 :   return 0;
    1256             : }
    1257             : 
    1258             : static clib_error_t *
    1259           0 : nat44_ei_add_interface_address_command_fn (vlib_main_t *vm,
    1260             :                                            unformat_input_t *input,
    1261             :                                            vlib_cli_command_t *cmd)
    1262             : {
    1263           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1264           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1265           0 :   clib_error_t *error = 0;
    1266           0 :   int rv, is_del = 0;
    1267             :   u32 sw_if_index;
    1268             : 
    1269           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1270           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
    1271             : 
    1272           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1273             :     {
    1274           0 :       if (unformat (line_input, "%U", unformat_vnet_sw_interface,
    1275             :                     nm->vnet_main, &sw_if_index))
    1276             :         ;
    1277           0 :       else if (unformat (line_input, "del"))
    1278             :         {
    1279           0 :           is_del = 1;
    1280             :         }
    1281             :       else
    1282             :         {
    1283           0 :           error = clib_error_return (0, "unknown input '%U'",
    1284             :                                      format_unformat_error, line_input);
    1285           0 :           goto done;
    1286             :         }
    1287             :     }
    1288             : 
    1289           0 :   if (!is_del)
    1290             :     {
    1291           0 :       rv = nat44_ei_add_interface_address (sw_if_index);
    1292           0 :       if (rv)
    1293             :         {
    1294           0 :           error = clib_error_return (0, "add address returned %d", rv);
    1295             :         }
    1296             :     }
    1297             :   else
    1298             :     {
    1299           0 :       rv = nat44_ei_del_interface_address (sw_if_index);
    1300           0 :       if (rv)
    1301             :         {
    1302           0 :           error = clib_error_return (0, "del address returned %d", rv);
    1303             :         }
    1304             :     }
    1305             : 
    1306           0 : done:
    1307           0 :   unformat_free (line_input);
    1308             : 
    1309           0 :   return error;
    1310             : }
    1311             : 
    1312             : static clib_error_t *
    1313          55 : nat44_ei_show_interface_address_command_fn (vlib_main_t *vm,
    1314             :                                             unformat_input_t *input,
    1315             :                                             vlib_cli_command_t *cmd)
    1316             : {
    1317          55 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1318          55 :   vnet_main_t *vnm = vnet_get_main ();
    1319             :   u32 *sw_if_index;
    1320             : 
    1321          55 :   vlib_cli_output (vm, "NAT44 pool address interfaces:");
    1322          59 :   vec_foreach (sw_if_index, nm->auto_add_sw_if_indices)
    1323             :     {
    1324           4 :       vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name, vnm,
    1325             :                        *sw_if_index);
    1326             :     }
    1327          55 :   return 0;
    1328             : }
    1329             : 
    1330             : static clib_error_t *
    1331          55 : nat44_ei_show_sessions_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1332             :                                    vlib_cli_command_t *cmd)
    1333             : {
    1334          55 :   unformat_input_t _line_input, *line_input = &_line_input;
    1335          55 :   clib_error_t *error = 0;
    1336             :   ip4_address_t saddr;
    1337          55 :   u8 filter_saddr = 0;
    1338             : 
    1339             :   nat44_ei_main_per_thread_data_t *tnm;
    1340          55 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1341             : 
    1342          55 :   int detail = 0;
    1343          55 :   int i = 0;
    1344             : 
    1345          55 :   if (!unformat_user (input, unformat_line_input, line_input))
    1346           0 :     goto print;
    1347             : 
    1348         110 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1349             :     {
    1350          55 :       if (unformat (line_input, "detail"))
    1351          55 :         detail = 1;
    1352           0 :       else if (unformat (line_input, "filter saddr %U", unformat_ip4_address,
    1353             :                          &saddr))
    1354           0 :         filter_saddr = 1;
    1355             :       else
    1356             :         {
    1357           0 :           error = clib_error_return (0, "unknown input '%U'",
    1358             :                                      format_unformat_error, line_input);
    1359           0 :           break;
    1360             :         }
    1361             :     }
    1362          55 :   unformat_free (line_input);
    1363             : 
    1364          55 : print:
    1365          55 :   vlib_cli_output (vm, "NAT44 sessions:");
    1366             : 
    1367         110 :   vec_foreach_index (i, nm->per_thread_data)
    1368             :     {
    1369          55 :       tnm = vec_elt_at_index (nm->per_thread_data, i);
    1370             : 
    1371         110 :       vlib_cli_output (vm, "-------- thread %d %s: %d sessions --------\n", i,
    1372          55 :                        vlib_worker_threads[i].name, pool_elts (tnm->sessions));
    1373             : 
    1374             :       nat44_ei_user_t *u;
    1375       10439 :       pool_foreach (u, tnm->users)
    1376             :         {
    1377       10384 :           if (filter_saddr && saddr.as_u32 != u->addr.as_u32)
    1378           0 :             continue;
    1379       10384 :           vlib_cli_output (vm, "  %U", format_nat44_ei_user, tnm, u, detail);
    1380             :         }
    1381             :     }
    1382          55 :   return error;
    1383             : }
    1384             : 
    1385             : static clib_error_t *
    1386           0 : nat44_ei_del_user_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1387             :                               vlib_cli_command_t *cmd)
    1388             : {
    1389           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1390           0 :   clib_error_t *error = 0;
    1391             :   ip4_address_t addr;
    1392           0 :   u32 fib_index = 0;
    1393             :   int rv;
    1394             : 
    1395           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1396           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
    1397             : 
    1398           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1399             :     {
    1400           0 :       if (unformat (line_input, "%U", unformat_ip4_address, &addr))
    1401             :         ;
    1402           0 :       else if (unformat (line_input, "fib %u", &fib_index))
    1403             :         ;
    1404             :       else
    1405             :         {
    1406           0 :           error = clib_error_return (0, "unknown input '%U'",
    1407             :                                      format_unformat_error, line_input);
    1408           0 :           goto done;
    1409             :         }
    1410             :     }
    1411             : 
    1412           0 :   rv = nat44_ei_user_del (&addr, fib_index);
    1413             : 
    1414           0 :   if (!rv)
    1415             :     {
    1416           0 :       error = clib_error_return (0, "nat44_ei_user_del returned %d", rv);
    1417             :     }
    1418             : 
    1419           0 : done:
    1420           0 :   unformat_free (line_input);
    1421             : 
    1422           0 :   return error;
    1423             : }
    1424             : 
    1425             : static clib_error_t *
    1426           1 : nat44_ei_clear_sessions_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1427             :                                     vlib_cli_command_t *cmd)
    1428             : {
    1429           1 :   clib_error_t *error = 0;
    1430           1 :   nat44_ei_sessions_clear ();
    1431           1 :   return error;
    1432             : }
    1433             : 
    1434             : static clib_error_t *
    1435           0 : nat44_ei_del_session_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1436             :                                  vlib_cli_command_t *cmd)
    1437             : {
    1438           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1439           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1440           0 :   u32 port = 0, vrf_id = nm->outside_vrf_id;
    1441           0 :   clib_error_t *error = 0;
    1442             :   nat_protocol_t proto;
    1443             :   ip4_address_t addr;
    1444           0 :   int rv, is_in = 0;
    1445             : 
    1446           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1447           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
    1448             : 
    1449           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1450             :     {
    1451           0 :       if (unformat (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
    1452             :                     unformat_nat_protocol, &proto))
    1453             :         ;
    1454           0 :       else if (unformat (line_input, "in"))
    1455             :         {
    1456           0 :           is_in = 1;
    1457           0 :           vrf_id = nm->inside_vrf_id;
    1458             :         }
    1459           0 :       else if (unformat (line_input, "out"))
    1460             :         {
    1461           0 :           is_in = 0;
    1462           0 :           vrf_id = nm->outside_vrf_id;
    1463             :         }
    1464           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
    1465             :         ;
    1466             :       else
    1467             :         {
    1468           0 :           error = clib_error_return (0, "unknown input '%U'",
    1469             :                                      format_unformat_error, line_input);
    1470           0 :           goto done;
    1471             :         }
    1472             :     }
    1473             : 
    1474           0 :   rv = nat44_ei_del_session (nm, &addr, clib_host_to_net_u16 (port), proto,
    1475             :                              vrf_id, is_in);
    1476             : 
    1477           0 :   switch (rv)
    1478             :     {
    1479           0 :     case 0:
    1480           0 :       break;
    1481             : 
    1482           0 :     default:
    1483           0 :       error = clib_error_return (0, "nat44_ei_del_session returned %d", rv);
    1484           0 :       goto done;
    1485             :     }
    1486             : 
    1487           0 : done:
    1488           0 :   unformat_free (line_input);
    1489             : 
    1490           0 :   return error;
    1491             : }
    1492             : 
    1493             : static clib_error_t *
    1494           0 : nat44_ei_forwarding_set_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1495             :                                     vlib_cli_command_t *cmd)
    1496             : {
    1497           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1498           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1499           0 :   clib_error_t *error = 0;
    1500             : 
    1501           0 :   u8 enable_set = 0, enable = 0;
    1502             : 
    1503           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1504           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
    1505             : 
    1506           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1507             :     {
    1508           0 :       if (!enable_set)
    1509             :         {
    1510           0 :           enable_set = 1;
    1511           0 :           if (unformat (line_input, "disable"))
    1512             :             ;
    1513           0 :           else if (unformat (line_input, "enable"))
    1514           0 :             enable = 1;
    1515             :         }
    1516             :       else
    1517             :         {
    1518           0 :           error = clib_error_return (0, "unknown input '%U'",
    1519             :                                      format_unformat_error, line_input);
    1520           0 :           goto done;
    1521             :         }
    1522             :     }
    1523             : 
    1524           0 :   if (!enable_set)
    1525           0 :     error = clib_error_return (0, "expected enable | disable");
    1526             :   else
    1527           0 :     nm->forwarding_enabled = enable;
    1528             : 
    1529           0 : done:
    1530           0 :   unformat_free (line_input);
    1531           0 :   return error;
    1532             : }
    1533             : 
    1534             : static clib_error_t *
    1535           0 : set_timeout_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1536             :                         vlib_cli_command_t *cmd)
    1537             : {
    1538           0 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1539           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1540           0 :   clib_error_t *error = 0;
    1541             : 
    1542           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1543           0 :     return clib_error_return (0, NAT44_EI_EXPECTED_ARGUMENT);
    1544             : 
    1545           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1546             :     {
    1547           0 :       if (unformat (line_input, "udp %u", &nm->timeouts.udp))
    1548             :         ;
    1549           0 :       else if (unformat (line_input, "tcp-established %u",
    1550             :                          &nm->timeouts.tcp.established))
    1551             :         ;
    1552           0 :       else if (unformat (line_input, "tcp-transitory %u",
    1553             :                          &nm->timeouts.tcp.transitory))
    1554             :         ;
    1555           0 :       else if (unformat (line_input, "icmp %u", &nm->timeouts.icmp))
    1556             :         ;
    1557           0 :       else if (unformat (line_input, "reset"))
    1558           0 :         nat_reset_timeouts (&nm->timeouts);
    1559             :       else
    1560             :         {
    1561           0 :           error = clib_error_return (0, "unknown input '%U'",
    1562             :                                      format_unformat_error, line_input);
    1563           0 :           goto done;
    1564             :         }
    1565             :     }
    1566           0 : done:
    1567           0 :   unformat_free (line_input);
    1568           0 :   return error;
    1569             : }
    1570             : 
    1571             : static clib_error_t *
    1572          55 : nat_show_timeouts_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1573             :                               vlib_cli_command_t *cmd)
    1574             : {
    1575          55 :   nat44_ei_main_t *nm = &nat44_ei_main;
    1576             : 
    1577          55 :   vlib_cli_output (vm, "udp timeout: %dsec", nm->timeouts.udp);
    1578          55 :   vlib_cli_output (vm, "tcp-established timeout: %dsec",
    1579             :                    nm->timeouts.tcp.established);
    1580          55 :   vlib_cli_output (vm, "tcp-transitory timeout: %dsec",
    1581             :                    nm->timeouts.tcp.transitory);
    1582          55 :   vlib_cli_output (vm, "icmp timeout: %dsec", nm->timeouts.icmp);
    1583             : 
    1584          55 :   return 0;
    1585             : }
    1586             : 
    1587             : /*?
    1588             :  * @cliexpar
    1589             :  * @cliexstart{nat44 ei}
    1590             :  * Enable nat44 ei plugin
    1591             :  * To enable nat44-ei, use:
    1592             :  *  vpp# nat44 ei plugin enable
    1593             :  * To disable nat44-ei, use:
    1594             :  *  vpp# nat44 ei plugin disable
    1595             :  * To enable nat44 ei static mapping only, use:
    1596             :  *  vpp# nat44 ei plugin enable static-mapping
    1597             :  * To enable nat44 ei static mapping with connection tracking, use:
    1598             :  *  vpp# nat44 ei plugin enable static-mapping connection-tracking
    1599             :  * To enable nat44 ei out2in dpo, use:
    1600             :  *  vpp# nat44 ei plugin enable out2in-dpo
    1601             :  * To set inside-vrf outside-vrf, use:
    1602             :  *  vpp# nat44 ei plugin enable inside-vrf <id> outside-vrf <id>
    1603             :  * @cliexend
    1604             : ?*/
    1605       82469 : VLIB_CLI_COMMAND (nat44_ei_enable_disable_command, static) = {
    1606             :   .path = "nat44 ei plugin",
    1607             :   .short_help =
    1608             :     "nat44 ei plugin <enable [sessions <max-number>] [users <max-number>] "
    1609             :     "[static-mappig-only [connection-tracking]|out2in-dpo] [inside-vrf "
    1610             :     "<vrf-id>] [outside-vrf <vrf-id>] [user-sessions <max-number>]>|disable",
    1611             :   .function = nat44_ei_enable_disable_command_fn,
    1612             : };
    1613             : 
    1614             : /*?
    1615             :  * @cliexpar
    1616             :  * @cliexstart{set snat44 ei workers}
    1617             :  * Set NAT workers if 2 or more workers available, use:
    1618             :  *  vpp# set snat44 ei workers 0-2,5
    1619             :  * @cliexend
    1620             : ?*/
    1621       82469 : VLIB_CLI_COMMAND (set_workers_command, static) = {
    1622             :   .path = "set nat44 ei workers",
    1623             :   .function = set_workers_command_fn,
    1624             :   .short_help = "set nat44 ei workers <workers-list>",
    1625             : };
    1626             : 
    1627             : /*?
    1628             :  * @cliexpar
    1629             :  * @cliexstart{show nat44 ei workers}
    1630             :  * Show NAT workers.
    1631             :  *  vpp# show nat44 ei workers:
    1632             :  *  2 workers
    1633             :  *    vpp_wk_0
    1634             :  *    vpp_wk_1
    1635             :  * @cliexend
    1636             : ?*/
    1637       82469 : VLIB_CLI_COMMAND (nat_show_workers_command, static) = {
    1638             :   .path = "show nat44 ei workers",
    1639             :   .short_help = "show nat44 ei workers",
    1640             :   .function = nat_show_workers_command_fn,
    1641             : };
    1642             : 
    1643             : /*?
    1644             :  * @cliexpar
    1645             :  * @cliexstart{set nat44 ei timeout}
    1646             :  * Set values of timeouts for NAT sessions (in seconds), use:
    1647             :  *  vpp# set nat44 ei timeout udp 120 tcp-established 7500 tcp-transitory 250
    1648             : icmp 90
    1649             :  * To reset default values use:
    1650             :  *  vpp# set nat44 ei timeout reset
    1651             :  * @cliexend
    1652             : ?*/
    1653       82469 : VLIB_CLI_COMMAND (set_timeout_command, static) = {
    1654             :   .path = "set nat44 ei timeout",
    1655             :   .function = set_timeout_command_fn,
    1656             :   .short_help = "set nat44 ei timeout [udp <sec> | tcp-established <sec> "
    1657             :                 "tcp-transitory <sec> | icmp <sec> | reset]",
    1658             : };
    1659             : 
    1660             : /*?
    1661             :  * @cliexpar
    1662             :  * @cliexstart{show nat44 ei timeouts}
    1663             :  * Show values of timeouts for NAT sessions.
    1664             :  * vpp# show nat44 ei timeouts
    1665             :  * udp timeout: 300sec
    1666             :  * tcp-established timeout: 7440sec
    1667             :  * tcp-transitory timeout: 240sec
    1668             :  * icmp timeout: 60sec
    1669             :  * @cliexend
    1670             : ?*/
    1671       82469 : VLIB_CLI_COMMAND (nat_show_timeouts_command, static) = {
    1672             :   .path = "show nat44 ei timeouts",
    1673             :   .short_help = "show nat44 ei timeouts",
    1674             :   .function = nat_show_timeouts_command_fn,
    1675             : };
    1676             : 
    1677             : /*?
    1678             :  * @cliexpar
    1679             :  * @cliexstart{nat44 ei set logging level}
    1680             :  * To set NAT logging level use:
    1681             :  * Set nat44 ei logging level
    1682             :  * @cliexend
    1683             : ?*/
    1684       82469 : VLIB_CLI_COMMAND (nat44_ei_set_log_level_command, static) = {
    1685             :   .path = "nat44 ei set logging level",
    1686             :   .function = nat44_ei_set_log_level_command_fn,
    1687             :   .short_help = "nat44 ei set logging level <level>",
    1688             : };
    1689             : 
    1690             : /*?
    1691             :  * @cliexpar
    1692             :  * @cliexstart{snat44 ei ipfix logging}
    1693             :  * To enable NAT IPFIX logging use:
    1694             :  *  vpp# nat44 ei ipfix logging
    1695             :  * To set IPFIX exporter use:
    1696             :  *  vpp# set ipfix exporter collector 10.10.10.3 src 10.10.10.1
    1697             :  * @cliexend
    1698             : ?*/
    1699       82469 : VLIB_CLI_COMMAND (nat44_ei_ipfix_logging_enable_disable_command, static) = {
    1700             :   .path = "nat44 ei ipfix logging",
    1701             :   .function = nat44_ei_ipfix_logging_enable_disable_command_fn,
    1702             :   .short_help = "nat44 ei ipfix logging <enable [domain <domain-id>] "
    1703             :                 "[src-port <port>]>|disable",
    1704             : };
    1705             : 
    1706             : /*?
    1707             :  * @cliexpar
    1708             :  * @cliexstart{nat44 ei addr-port-assignment-alg}
    1709             :  * Set address and port assignment algorithm
    1710             :  * For the MAP-E CE limit port choice based on PSID use:
    1711             :  *  vpp# nat44 ei addr-port-assignment-alg map-e psid 10 psid-offset 6 psid-len
    1712             : 6
    1713             :  * For port range use:
    1714             :  *  vpp# nat44 ei addr-port-assignment-alg port-range <start-port> - <end-port>
    1715             :  * To set standard (default) address and port assignment algorithm use:
    1716             :  *  vpp# nat44 ei addr-port-assignment-alg default
    1717             :  * @cliexend
    1718             : ?*/
    1719       82469 : VLIB_CLI_COMMAND (nat44_ei_set_alloc_addr_and_port_alg_command, static) = {
    1720             :   .path = "nat44 ei addr-port-assignment-alg",
    1721             :   .short_help = "nat44 ei addr-port-assignment-alg <alg-name> [<alg-params>]",
    1722             :   .function = nat44_ei_set_alloc_addr_and_port_alg_command_fn,
    1723             : };
    1724             : 
    1725             : /*?
    1726             :  * @cliexpar
    1727             :  * @cliexstart{show nat44 ei addr-port-assignment-alg}
    1728             :  * Show address and port assignment algorithm
    1729             :  * @cliexend
    1730             : ?*/
    1731       82469 : VLIB_CLI_COMMAND (nat44_ei_show_alloc_addr_and_port_alg_command, static) = {
    1732             :   .path = "show nat44 ei addr-port-assignment-alg",
    1733             :   .short_help = "show nat44 ei addr-port-assignment-alg",
    1734             :   .function = nat44_ei_show_alloc_addr_and_port_alg_command_fn,
    1735             : };
    1736             : 
    1737             : /*?
    1738             :  * @cliexpar
    1739             :  * @cliexstart{nat44 ei mss-clamping}
    1740             :  * Set TCP MSS rewriting configuration
    1741             :  * To enable TCP MSS rewriting use:
    1742             :  *  vpp# nat44 ei mss-clamping 1452
    1743             :  * To disbale TCP MSS rewriting use:
    1744             :  *  vpp# nat44 ei mss-clamping disable
    1745             :  * @cliexend
    1746             : ?*/
    1747       82469 : VLIB_CLI_COMMAND (nat_set_mss_clamping_command, static) = {
    1748             :   .path = "nat44 ei mss-clamping",
    1749             :   .short_help = "nat44 ei mss-clamping <mss-value>|disable",
    1750             :   .function = nat_set_mss_clamping_command_fn,
    1751             : };
    1752             : 
    1753             : /*?
    1754             :  * @cliexpar
    1755             :  * @cliexstart{show nat44 ei mss-clamping}
    1756             :  * Show TCP MSS rewriting configuration
    1757             :  * @cliexend
    1758             : ?*/
    1759       82469 : VLIB_CLI_COMMAND (nat_show_mss_clamping_command, static) = {
    1760             :   .path = "show nat44 ei mss-clamping",
    1761             :   .short_help = "show nat44 ei mss-clamping",
    1762             :   .function = nat_show_mss_clamping_command_fn,
    1763             : };
    1764             : 
    1765             : /*?
    1766             :  * @cliexpar
    1767             :  * @cliexstart{nat44 ei ha failover}
    1768             :  * Set HA failover (remote settings)
    1769             :  * @cliexend
    1770             : ?*/
    1771       82469 : VLIB_CLI_COMMAND (nat_ha_failover_command, static) = {
    1772             :   .path = "nat44 ei ha failover",
    1773             :   .short_help =
    1774             :     "nat44 ei ha failover <ip4-address>:<port> [refresh-interval <sec>]",
    1775             :   .function = nat_ha_failover_command_fn,
    1776             : };
    1777             : 
    1778             : /*?
    1779             :  * @cliexpar
    1780             :  * @cliexstart{nat44 ei ha listener}
    1781             :  * Set HA listener (local settings)
    1782             :  * @cliexend
    1783             : ?*/
    1784       82469 : VLIB_CLI_COMMAND (nat_ha_listener_command, static) = {
    1785             :   .path = "nat44 ei ha listener",
    1786             :   .short_help =
    1787             :     "nat44 ei ha listener <ip4-address>:<port> [path-mtu <path-mtu>]",
    1788             :   .function = nat_ha_listener_command_fn,
    1789             : };
    1790             : 
    1791             : /*?
    1792             :  * @cliexpar
    1793             :  * @cliexstart{show nat44 ei ha}
    1794             :  * Show HA configuration/status
    1795             :  * @cliexend
    1796             : ?*/
    1797       82469 : VLIB_CLI_COMMAND (nat_show_ha_command, static) = {
    1798             :   .path = "show nat44 ei ha",
    1799             :   .short_help = "show nat44 ei ha",
    1800             :   .function = nat_show_ha_command_fn,
    1801             : };
    1802             : 
    1803             : /*?
    1804             :  * @cliexpar
    1805             :  * @cliexstart{nat44 ei ha flush}
    1806             :  * Flush the current HA data (for testing)
    1807             :  * @cliexend
    1808             : ?*/
    1809       82469 : VLIB_CLI_COMMAND (nat_ha_flush_command, static) = {
    1810             :   .path = "nat44 ei ha flush",
    1811             :   .short_help = "nat44 ei ha flush",
    1812             :   .function = nat_ha_flush_command_fn,
    1813             : };
    1814             : 
    1815             : /*?
    1816             :  * @cliexpar
    1817             :  * @cliexstart{nat44 ei ha resync}
    1818             :  * Resync HA (resend existing sessions to new failover)
    1819             :  * @cliexend
    1820             : ?*/
    1821       82469 : VLIB_CLI_COMMAND (nat_ha_resync_command, static) = {
    1822             :   .path = "nat44 ei ha resync",
    1823             :   .short_help = "nat44 ei ha resync",
    1824             :   .function = nat_ha_resync_command_fn,
    1825             : };
    1826             : 
    1827             : /*?
    1828             :  * @cliexpar
    1829             :  * @cliexstart{show nat44 ei hash tables}
    1830             :  * Show NAT44 hash tables
    1831             :  * @cliexend
    1832             : ?*/
    1833       82469 : VLIB_CLI_COMMAND (nat44_ei_show_hash, static) = {
    1834             :   .path = "show nat44 ei hash tables",
    1835             :   .short_help = "show nat44 ei hash tables [detail|verbose]",
    1836             :   .function = nat44_ei_show_hash_command_fn,
    1837             : };
    1838             : 
    1839             : /*?
    1840             :  * @cliexpar
    1841             :  * @cliexstart{nat44 ei add address}
    1842             :  * Add/delete NAT44 pool address.
    1843             :  * To add NAT44 pool address use:
    1844             :  *  vpp# nat44 ei add address 172.16.1.3
    1845             :  *  vpp# nat44 ei add address 172.16.2.2 - 172.16.2.24
    1846             :  * To add NAT44 pool address for specific tenant (identified by VRF id) use:
    1847             :  *  vpp# nat44 ei add address 172.16.1.3 tenant-vrf 10
    1848             :  * @cliexend
    1849             : ?*/
    1850       82469 : VLIB_CLI_COMMAND (add_address_command, static) = {
    1851             :   .path = "nat44 ei add address",
    1852             :   .short_help = "nat44 ei add address <ip4-range-start> [- <ip4-range-end>] "
    1853             :                 "[tenant-vrf <vrf-id>] [del]",
    1854             :   .function = add_address_command_fn,
    1855             : };
    1856             : 
    1857             : /*?
    1858             :  * @cliexpar
    1859             :  * @cliexstart{show nat44 ei addresses}
    1860             :  * Show NAT44 pool addresses.
    1861             :  * vpp# show nat44 ei addresses
    1862             :  * NAT44 pool addresses:
    1863             :  * 172.16.2.2
    1864             :  *   tenant VRF independent
    1865             :  *   10 busy udp ports
    1866             :  *   0 busy tcp ports
    1867             :  *   0 busy icmp ports
    1868             :  * 172.16.1.3
    1869             :  *   tenant VRF: 10
    1870             :  *   0 busy udp ports
    1871             :  *   2 busy tcp ports
    1872             :  *   0 busy icmp ports
    1873             :  * @cliexend
    1874             : ?*/
    1875       82469 : VLIB_CLI_COMMAND (nat44_ei_show_addresses_command, static) = {
    1876             :   .path = "show nat44 ei addresses",
    1877             :   .short_help = "show nat44 ei addresses",
    1878             :   .function = nat44_ei_show_addresses_command_fn,
    1879             : };
    1880             : 
    1881             : /*?
    1882             :  * @cliexpar
    1883             :  * @cliexstart{set interface nat44}
    1884             :  * Enable/disable NAT44 feature on the interface.
    1885             :  * To enable NAT44 feature with local network interface use:
    1886             :  *  vpp# set interface nat44 ei in GigabitEthernet0/8/0
    1887             :  * To enable NAT44 feature with external network interface use:
    1888             :  *  vpp# set interface nat44 ei out GigabitEthernet0/a/0
    1889             :  * @cliexend
    1890             : ?*/
    1891       82469 : VLIB_CLI_COMMAND (set_interface_nat44_ei_command, static) = {
    1892             :   .path = "set interface nat44 ei",
    1893             :   .function = nat44_ei_feature_command_fn,
    1894             :   .short_help =
    1895             :     "set interface nat44 ei in <intfc> out <intfc> [output-feature] "
    1896             :     "[del]",
    1897             : };
    1898             : 
    1899             : /*?
    1900             :  * @cliexpar
    1901             :  * @cliexstart{show nat44 ei interfaces}
    1902             :  * Show interfaces with NAT44 feature.
    1903             :  * vpp# show nat44 ei interfaces
    1904             :  * NAT44 interfaces:
    1905             :  *  GigabitEthernet0/8/0 in
    1906             :  *  GigabitEthernet0/a/0 out
    1907             :  * @cliexend
    1908             : ?*/
    1909       82469 : VLIB_CLI_COMMAND (nat44_ei_show_interfaces_command, static) = {
    1910             :   .path = "show nat44 ei interfaces",
    1911             :   .short_help = "show nat44 ei interfaces",
    1912             :   .function = nat44_ei_show_interfaces_command_fn,
    1913             : };
    1914             : 
    1915             : /*?
    1916             :  * @cliexpar
    1917             :  * @cliexstart{nat44 ei add static mapping}
    1918             :  * Static mapping allows hosts on the external network to initiate connection
    1919             :  * to to the local network host.
    1920             :  * To create static mapping between local host address 10.0.0.3 port 6303 and
    1921             :  * external address 4.4.4.4 port 3606 for TCP protocol use:
    1922             :  *  vpp# nat44 ei add static mapping tcp local 10.0.0.3 6303 external 4.4.4.4
    1923             : 3606
    1924             :  * If not runnig "static mapping only" NAT plugin mode use before:
    1925             :  *  vpp# nat44 ei add address 4.4.4.4
    1926             :  * To create address only static mapping between local and external address
    1927             : use:
    1928             :  *  vpp# nat44 ei add static mapping local 10.0.0.3 external 4.4.4.4
    1929             :  * To create ICMP static mapping between local and external with ICMP echo
    1930             :  * identifier 10 use:
    1931             :  *  vpp# nat44 ei add static mapping icmp local 10.0.0.3 10 external 4.4.4.4 10
    1932             :  * @cliexend
    1933             : ?*/
    1934       82469 : VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
    1935             :   .path = "nat44 ei add static mapping",
    1936             :   .function = add_static_mapping_command_fn,
    1937             :   .short_help = "nat44 ei add static mapping tcp|udp|icmp local <addr> "
    1938             :                 "[<port|icmp-echo-id>] "
    1939             :                 "external <addr> [<port|icmp-echo-id>] [vrf <table-id>] [del]",
    1940             : };
    1941             : 
    1942             : /*?
    1943             :  * @cliexpar
    1944             :  * @cliexstart{nat44 ei add identity mapping}
    1945             :  * Identity mapping translate an IP address to itself.
    1946             :  * To create identity mapping for address 10.0.0.3 port 6303 for TCP protocol
    1947             :  * use:
    1948             :  *  vpp# nat44 ei add identity mapping 10.0.0.3 tcp 6303
    1949             :  * To create identity mapping for address 10.0.0.3 use:
    1950             :  *  vpp# nat44 ei add identity mapping 10.0.0.3
    1951             :  * To create identity mapping for DHCP addressed interface use:
    1952             :  *  vpp# nat44 ei add identity mapping external GigabitEthernet0/a/0 tcp 3606
    1953             :  * @cliexend
    1954             : ?*/
    1955       82469 : VLIB_CLI_COMMAND (add_identity_mapping_command, static) = {
    1956             :   .path = "nat44 ei add identity mapping",
    1957             :   .function = add_identity_mapping_command_fn,
    1958             :   .short_help =
    1959             :     "nat44 ei add identity mapping <ip4-addr>|external <interface> "
    1960             :     "[<protocol> <port>] [vrf <table-id>] [del]",
    1961             : };
    1962             : 
    1963             : /*?
    1964             :  * @cliexpar
    1965             :  * @cliexstart{show nat44 ei static mappings}
    1966             :  * Show NAT44 static mappings.
    1967             :  * vpp# show nat44 ei static mappings
    1968             :  * NAT44 static mappings:
    1969             :  *  local 10.0.0.3 external 4.4.4.4 vrf 0
    1970             :  *  tcp local 192.168.0.4:6303 external 4.4.4.3:3606 vrf 0
    1971             :  *  tcp vrf 0 external 1.2.3.4:80
    1972             :  *   local 10.100.10.10:8080 probability 80
    1973             :  *   local 10.100.10.20:8080 probability 20
    1974             :  *  tcp local 10.0.0.10:3603 external GigabitEthernet0/a/0:6306 vrf 10
    1975             :  * @cliexend
    1976             : ?*/
    1977       82469 : VLIB_CLI_COMMAND (nat44_ei_show_static_mappings_command, static) = {
    1978             :   .path = "show nat44 ei static mappings",
    1979             :   .short_help = "show nat44 ei static mappings",
    1980             :   .function = nat44_ei_show_static_mappings_command_fn,
    1981             : };
    1982             : 
    1983             : /*?
    1984             :  * @cliexpar
    1985             :  * @cliexstart{nat44 ei add interface address}
    1986             :  * Use NAT44 pool address from specific interfce
    1987             :  * To add NAT44 pool address from specific interface use:
    1988             :  *  vpp# nat44 ei add interface address GigabitEthernet0/8/0
    1989             :  * @cliexend
    1990             : ?*/
    1991       82469 : VLIB_CLI_COMMAND (nat44_ei_add_interface_address_command, static) = {
    1992             :   .path = "nat44 ei add interface address",
    1993             :   .short_help = "nat44 ei add interface address <interface> [del]",
    1994             :   .function = nat44_ei_add_interface_address_command_fn,
    1995             : };
    1996             : 
    1997             : /*?
    1998             :  * @cliexpar
    1999             :  * @cliexstart{show nat44 ei interface address}
    2000             :  * Show NAT44 pool address interfaces
    2001             :  * vpp# show nat44 ei interface address
    2002             :  * NAT44 pool address interfaces:
    2003             :  *  GigabitEthernet0/a/0
    2004             :  * @cliexend
    2005             : ?*/
    2006       82469 : VLIB_CLI_COMMAND (nat44_ei_show_interface_address_command, static) = {
    2007             :   .path = "show nat44 ei interface address",
    2008             :   .short_help = "show nat44 ei interface address",
    2009             :   .function = nat44_ei_show_interface_address_command_fn,
    2010             : };
    2011             : 
    2012             : /*?
    2013             :  * @cliexpar
    2014             :  * @cliexstart{show nat44 ei sessions}
    2015             :  * Show NAT44 sessions.
    2016             :  * @cliexend
    2017             : ?*/
    2018       82469 : VLIB_CLI_COMMAND (nat44_ei_show_sessions_command, static) = {
    2019             :   .path = "show nat44 ei sessions",
    2020             :   .short_help = "show nat44 ei sessions [detail] [filter saddr <ip>]",
    2021             :   .function = nat44_ei_show_sessions_command_fn,
    2022             : };
    2023             : 
    2024             : /*?
    2025             :  * @cliexpar
    2026             :  * @cliexstart{nat44 ei del user}
    2027             :  * To delete all NAT44 user sessions:
    2028             :  *  vpp# nat44 ei del user 10.0.0.3
    2029             :  * @cliexend
    2030             : ?*/
    2031       82469 : VLIB_CLI_COMMAND (nat44_ei_del_user_command, static) = {
    2032             :   .path = "nat44 ei del user",
    2033             :   .short_help = "nat44 ei del user <addr> [fib <index>]",
    2034             :   .function = nat44_ei_del_user_command_fn,
    2035             : };
    2036             : 
    2037             : /*?
    2038             :  * @cliexpar
    2039             :  * @cliexstart{clear nat44 ei sessions}
    2040             :  * To clear all NAT44 sessions
    2041             :  *  vpp# clear nat44 ei sessions
    2042             :  * @cliexend
    2043             : ?*/
    2044       82469 : VLIB_CLI_COMMAND (nat44_ei_clear_sessions_command, static) = {
    2045             :   .path = "clear nat44 ei sessions",
    2046             :   .short_help = "clear nat44 ei sessions",
    2047             :   .function = nat44_ei_clear_sessions_command_fn,
    2048             : };
    2049             : 
    2050             : /*?
    2051             :  * @cliexpar
    2052             :  * @cliexstart{nat44 ei del session}
    2053             :  * To administratively delete NAT44 session by inside address and port use:
    2054             :  *  vpp# nat44 ei del session in 10.0.0.3:6303 tcp
    2055             :  * To administratively delete NAT44 session by outside address and port use:
    2056             :  *  vpp# nat44 ei del session out 1.0.0.3:6033 udp
    2057             :  * @cliexend
    2058             : ?*/
    2059       82469 : VLIB_CLI_COMMAND (nat44_ei_del_session_command, static) = {
    2060             :   .path = "nat44 ei del session",
    2061             :   .short_help = "nat44 ei del session in|out <addr>:<port> tcp|udp|icmp [vrf "
    2062             :                 "<id>] [external-host <addr>:<port>]",
    2063             :   .function = nat44_ei_del_session_command_fn,
    2064             : };
    2065             : 
    2066             : /*?
    2067             :  * @cliexpar
    2068             :  * @cliexstart{nat44 ei forwarding}
    2069             :  * Enable or disable forwarding
    2070             :  * Forward packets which don't match existing translation
    2071             :  * or static mapping instead of dropping them.
    2072             :  * To enable forwarding, use:
    2073             :  *  vpp# nat44 ei forwarding enable
    2074             :  * To disable forwarding, use:
    2075             :  *  vpp# nat44 ei forwarding disable
    2076             :  * @cliexend
    2077             : ?*/
    2078       82469 : VLIB_CLI_COMMAND (nat44_ei_forwarding_set_command, static) = {
    2079             :   .path = "nat44 ei forwarding",
    2080             :   .short_help = "nat44 ei forwarding enable|disable",
    2081             :   .function = nat44_ei_forwarding_set_command_fn,
    2082             : };
    2083             : 
    2084             : /*
    2085             :  * fd.io coding-style-patch-verification: ON
    2086             :  *
    2087             :  * Local Variables:
    2088             :  * eval: (c-set-style "gnu")
    2089             :  * End:
    2090             :  */

Generated by: LCOV version 1.14