LCOV - code coverage report
Current view: top level - plugins/nat/nat44-ed - nat44_ed_cli.c (source / functions) Hit Total Coverage
Test: coverage-filtered.info Lines: 58 951 6.1 %
Date: 2023-10-26 01:39:38 Functions: 61 91 67.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2018 Cisco and/or its affiliates.
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at:
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : /**
      16             :  * @file
      17             :  * @brief NAT44 CLI
      18             :  */
      19             : 
      20             : #include <vnet/fib/fib_table.h>
      21             : 
      22             : #include <nat/lib/log.h>
      23             : #include <nat/lib/nat_inlines.h>
      24             : #include <nat/lib/ipfix_logging.h>
      25             : 
      26             : #include <nat/nat44-ed/nat44_ed.h>
      27             : #include <nat/nat44-ed/nat44_ed_inlines.h>
      28             : #include <nat/nat44-ed/nat44_ed_affinity.h>
      29             : 
      30             : #define NAT44_ED_EXPECTED_ARGUMENT "expected required argument(s)"
      31             : 
      32             : static clib_error_t *
      33           0 : nat44_ed_enable_disable_command_fn (vlib_main_t *vm, unformat_input_t *input,
      34             :                                     vlib_cli_command_t *cmd)
      35             : {
      36           0 :   snat_main_t *sm = &snat_main;
      37           0 :   unformat_input_t _line_input, *line_input = &_line_input;
      38           0 :   clib_error_t *error = 0;
      39             : 
      40           0 :   nat44_config_t c = { 0 };
      41           0 :   u8 enable_set = 0, enable = 0;
      42             : 
      43           0 :   if (!unformat_user (input, unformat_line_input, line_input))
      44           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
      45             : 
      46           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
      47             :     {
      48           0 :       if (unformat (line_input, "inside-vrf %u", &c.inside_vrf))
      49             :         ;
      50           0 :       else if (unformat (line_input, "outside-vrf %u", &c.outside_vrf));
      51           0 :       else if (unformat (line_input, "sessions %u", &c.sessions));
      52           0 :       else if (!enable_set)
      53             :         {
      54           0 :           enable_set = 1;
      55           0 :           if (unformat (line_input, "disable"))
      56             :             ;
      57           0 :           else if (unformat (line_input, "enable"))
      58           0 :             enable = 1;
      59             :         }
      60             :       else
      61             :         {
      62           0 :           error = clib_error_return (0, "unknown input '%U'",
      63             :                                      format_unformat_error, line_input);
      64           0 :           goto done;
      65             :         }
      66             :     }
      67             : 
      68           0 :   if (!enable_set)
      69             :     {
      70           0 :       error = clib_error_return (0, "expected enable | disable");
      71           0 :       goto done;
      72             :     }
      73             : 
      74           0 :   if (enable)
      75             :     {
      76           0 :       if (sm->enabled)
      77             :         {
      78           0 :           error = clib_error_return (0, "already enabled");
      79           0 :           goto done;
      80             :         }
      81             : 
      82           0 :       if (nat44_plugin_enable (c) != 0)
      83           0 :         error = clib_error_return (0, "enable failed");
      84             :     }
      85             :   else
      86             :     {
      87           0 :       if (!sm->enabled)
      88             :         {
      89           0 :           error = clib_error_return (0, "already disabled");
      90           0 :           goto done;
      91             :         }
      92             : 
      93           0 :       if (nat44_plugin_disable () != 0)
      94           0 :         error = clib_error_return (0, "disable failed");
      95             :     }
      96             : 
      97           0 : done:
      98           0 :   unformat_free (line_input);
      99           0 :   return error;
     100             : }
     101             : 
     102             : static clib_error_t *
     103           0 : set_workers_command_fn (vlib_main_t * vm,
     104             :                         unformat_input_t * input, vlib_cli_command_t * cmd)
     105             : {
     106           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     107           0 :   uword *bitmap = 0;
     108           0 :   int rv = 0;
     109           0 :   clib_error_t *error = 0;
     110             : 
     111           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     112           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
     113             : 
     114           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     115             :     {
     116           0 :       if (unformat (line_input, "%U", unformat_bitmap_list, &bitmap))
     117             :         ;
     118             :       else
     119             :         {
     120           0 :           error = clib_error_return (0, "unknown input '%U'",
     121             :                                      format_unformat_error, line_input);
     122           0 :           goto done;
     123             :         }
     124             :     }
     125             : 
     126           0 :   if (bitmap == 0)
     127             :     {
     128           0 :       error = clib_error_return (0, "List of workers must be specified.");
     129           0 :       goto done;
     130             :     }
     131             : 
     132           0 :   rv = snat_set_workers (bitmap);
     133             : 
     134           0 :   clib_bitmap_free (bitmap);
     135             : 
     136           0 :   switch (rv)
     137             :     {
     138           0 :     case VNET_API_ERROR_INVALID_WORKER:
     139           0 :       error = clib_error_return (0, "Invalid worker(s).");
     140           0 :       goto done;
     141           0 :     case VNET_API_ERROR_FEATURE_DISABLED:
     142           0 :       error = clib_error_return (0,
     143             :                                  "Supported only if 2 or more workes available.");
     144           0 :       goto done;
     145           0 :     default:
     146           0 :       break;
     147             :     }
     148             : 
     149           0 : done:
     150           0 :   unformat_free (line_input);
     151             : 
     152           0 :   return error;
     153             : }
     154             : 
     155             : static clib_error_t *
     156           0 : nat_show_workers_command_fn (vlib_main_t *vm, unformat_input_t *input,
     157             :                              vlib_cli_command_t *cmd)
     158             : {
     159           0 :   snat_main_t *sm = &snat_main;
     160             :   u32 *worker;
     161             : 
     162           0 :   if (sm->num_workers > 1)
     163             :     {
     164           0 :       vlib_cli_output (vm, "%d workers", vec_len (sm->workers));
     165           0 :       vec_foreach (worker, sm->workers)
     166             :         {
     167           0 :           vlib_worker_thread_t *w =
     168           0 :             vlib_worker_threads + *worker + sm->first_worker_index;
     169           0 :           vlib_cli_output (vm, "  %s", w->name);
     170             :         }
     171             :     }
     172             : 
     173           0 :   return 0;
     174             : }
     175             : 
     176             : static clib_error_t *
     177           0 : snat_set_log_level_command_fn (vlib_main_t * vm,
     178             :                                unformat_input_t * input,
     179             :                                vlib_cli_command_t * cmd)
     180             : {
     181           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     182           0 :   snat_main_t *sm = &snat_main;
     183           0 :   u32 log_level = NAT_LOG_NONE;
     184           0 :   clib_error_t *error = 0;
     185             : 
     186           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     187           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
     188             : 
     189           0 :   if (!unformat (line_input, "%d", &log_level))
     190             :     {
     191           0 :       error = clib_error_return (0, "unknown input '%U'",
     192             :                                  format_unformat_error, line_input);
     193           0 :       goto done;
     194             :     }
     195           0 :   if (log_level > NAT_LOG_DEBUG)
     196             :     {
     197           0 :       error = clib_error_return (0, "unknown logging level '%d'", log_level);
     198           0 :       goto done;
     199             :     }
     200           0 :   sm->log_level = log_level;
     201             : 
     202           0 : done:
     203           0 :   unformat_free (line_input);
     204             : 
     205           0 :   return error;
     206             : }
     207             : 
     208             : static clib_error_t *
     209           0 : snat_ipfix_logging_enable_disable_command_fn (vlib_main_t * vm,
     210             :                                               unformat_input_t * input,
     211             :                                               vlib_cli_command_t * cmd)
     212             : {
     213           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     214           0 :   clib_error_t *error = 0;
     215             : 
     216           0 :   u32 domain_id = 0, src_port = 0;
     217           0 :   u8 enable_set = 0, enable = 0;
     218             : 
     219           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     220           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
     221             : 
     222           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     223             :     {
     224           0 :       if (unformat (line_input, "domain %d", &domain_id))
     225             :         ;
     226           0 :       else if (unformat (line_input, "src-port %d", &src_port))
     227             :         ;
     228           0 :       else if (!enable_set)
     229             :         {
     230           0 :           enable_set = 1;
     231           0 :           if (unformat (line_input, "disable"))
     232             :             ;
     233           0 :           else if (unformat (line_input, "enable"))
     234           0 :             enable = 1;
     235             :         }
     236             :       else
     237             :         {
     238           0 :           error = clib_error_return (0, "unknown input '%U'",
     239             :                                      format_unformat_error, line_input);
     240           0 :           goto done;
     241             :         }
     242             :     }
     243             : 
     244           0 :   if (!enable_set)
     245             :     {
     246           0 :       error = clib_error_return (0, "expected enable | disable");
     247           0 :       goto done;
     248             :     }
     249             : 
     250           0 :   if (nat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port))
     251             :     {
     252           0 :       error = clib_error_return (0, "ipfix logging enable failed");
     253           0 :       goto done;
     254             :     }
     255             : 
     256           0 : done:
     257           0 :   unformat_free (line_input);
     258             : 
     259           0 :   return error;
     260             : }
     261             : 
     262             : static clib_error_t *
     263           0 : nat44_show_hash_command_fn (vlib_main_t * vm, unformat_input_t * input,
     264             :                             vlib_cli_command_t * cmd)
     265             : {
     266           0 :   snat_main_t *sm = &snat_main;
     267           0 :   nat_affinity_main_t *nam = &nat_affinity_main;
     268             :   int i;
     269           0 :   int verbose = 0;
     270             : 
     271           0 :   if (unformat (input, "detail"))
     272           0 :     verbose = 1;
     273           0 :   else if (unformat (input, "verbose"))
     274           0 :     verbose = 2;
     275             : 
     276           0 :   vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose);
     277           0 :   vec_foreach_index (i, sm->per_thread_data)
     278             :   {
     279           0 :     vlib_cli_output (vm, "-------- thread %d %s --------\n",
     280           0 :                      i, vlib_worker_threads[i].name);
     281           0 :     vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose);
     282             :   }
     283             : 
     284           0 :   vlib_cli_output (vm, "%U", format_bihash_16_8, &nam->affinity_hash, verbose);
     285             : 
     286           0 :   vlib_cli_output (vm, "-------- hash table parameters --------\n");
     287           0 :   vlib_cli_output (vm, "translation buckets: %u", sm->translation_buckets);
     288           0 :   return 0;
     289             : }
     290             : 
     291             : static clib_error_t *
     292           0 : nat_set_mss_clamping_command_fn (vlib_main_t * vm, unformat_input_t * input,
     293             :                                  vlib_cli_command_t * cmd)
     294             : {
     295           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     296           0 :   snat_main_t *sm = &snat_main;
     297           0 :   clib_error_t *error = 0;
     298             :   u32 mss;
     299             : 
     300           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     301           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
     302             : 
     303           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     304             :     {
     305           0 :       if (unformat (line_input, "disable"))
     306           0 :         sm->mss_clamping = 0;
     307           0 :       else if (unformat (line_input, "%d", &mss))
     308           0 :         sm->mss_clamping = (u16) mss;
     309             :       else
     310             :         {
     311           0 :           error = clib_error_return (0, "unknown input '%U'",
     312             :                                      format_unformat_error, line_input);
     313           0 :           goto done;
     314             :         }
     315             :     }
     316             : 
     317           0 : done:
     318           0 :   unformat_free (line_input);
     319             : 
     320           0 :   return error;
     321             : }
     322             : 
     323             : static clib_error_t *
     324           0 : nat_show_mss_clamping_command_fn (vlib_main_t * vm, unformat_input_t * input,
     325             :                                   vlib_cli_command_t * cmd)
     326             : {
     327           0 :   snat_main_t *sm = &snat_main;
     328             : 
     329           0 :   if (sm->mss_clamping)
     330           0 :     vlib_cli_output (vm, "mss-clamping %d", sm->mss_clamping);
     331             :   else
     332           0 :     vlib_cli_output (vm, "mss-clamping disabled");
     333             : 
     334           0 :   return 0;
     335             : }
     336             : 
     337             : static clib_error_t *
     338           0 : add_address_command_fn (vlib_main_t * vm,
     339             :                         unformat_input_t * input, vlib_cli_command_t * cmd)
     340             : {
     341           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     342             :   ip4_address_t start_addr, end_addr, this_addr;
     343             :   u32 start_host_order, end_host_order;
     344           0 :   u32 vrf_id = ~0;
     345             :   int i, count;
     346           0 :   int is_add = 1;
     347           0 :   int rv = 0;
     348           0 :   clib_error_t *error = 0;
     349           0 :   u8 twice_nat = 0;
     350             : 
     351           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     352           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
     353             : 
     354           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     355             :     {
     356           0 :       if (unformat (line_input, "%U - %U",
     357             :                     unformat_ip4_address, &start_addr,
     358             :                     unformat_ip4_address, &end_addr))
     359             :         ;
     360           0 :       else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
     361             :         ;
     362           0 :       else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
     363           0 :         end_addr = start_addr;
     364           0 :       else if (unformat (line_input, "twice-nat"))
     365           0 :         twice_nat = 1;
     366           0 :       else if (unformat (line_input, "del"))
     367           0 :         is_add = 0;
     368             :       else
     369             :         {
     370           0 :           error = clib_error_return (0, "unknown input '%U'",
     371             :                                      format_unformat_error, line_input);
     372           0 :           goto done;
     373             :         }
     374             :     }
     375             : 
     376           0 :   start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
     377           0 :   end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
     378             : 
     379           0 :   if (end_host_order < start_host_order)
     380             :     {
     381           0 :       error = clib_error_return (0, "end address less than start address");
     382           0 :       goto done;
     383             :     }
     384             : 
     385           0 :   count = (end_host_order - start_host_order) + 1;
     386             : 
     387           0 :   if (count > 1024)
     388           0 :     nat_log_info ("%U - %U, %d addresses...",
     389             :                   format_ip4_address, &start_addr,
     390             :                   format_ip4_address, &end_addr, count);
     391             : 
     392           0 :   this_addr = start_addr;
     393             : 
     394           0 :   for (i = 0; i < count; i++)
     395             :     {
     396           0 :       if (is_add)
     397             :         {
     398           0 :           rv = nat44_ed_add_address (&this_addr, vrf_id, twice_nat);
     399             :         }
     400             :       else
     401             :         {
     402           0 :           rv = nat44_ed_del_address (this_addr, twice_nat);
     403             :         }
     404             : 
     405           0 :       switch (rv)
     406             :         {
     407           0 :         case VNET_API_ERROR_VALUE_EXIST:
     408           0 :           error = clib_error_return (0, "NAT address already in use.");
     409           0 :           goto done;
     410           0 :         case VNET_API_ERROR_NO_SUCH_ENTRY:
     411           0 :           error = clib_error_return (0, "NAT address not exist.");
     412           0 :           goto done;
     413           0 :         case VNET_API_ERROR_UNSPECIFIED:
     414             :           error =
     415           0 :             clib_error_return (0, "NAT address used in static mapping.");
     416           0 :           goto done;
     417           0 :         default:
     418           0 :           break;
     419             :         }
     420             : 
     421           0 :       increment_v4_address (&this_addr);
     422             :     }
     423             : 
     424           0 : done:
     425           0 :   unformat_free (line_input);
     426             : 
     427           0 :   return error;
     428             : }
     429             : 
     430             : static void
     431           0 : nat44_show_lru_summary (vlib_main_t * vm, snat_main_per_thread_data_t * tsm,
     432             :                         u64 now, u64 sess_timeout_time)
     433             : {
     434           0 :   snat_main_t *sm = &snat_main;
     435             :   dlist_elt_t *oldest_elt;
     436             :   snat_session_t *s;
     437             :   u32 oldest_index;
     438             : 
     439           0 :   if (tsm->lru_pool)
     440             :     {
     441             : #define _(n, d)                                                               \
     442             :   oldest_index =                                                              \
     443             :     clib_dlist_remove_head (tsm->lru_pool, tsm->n##_lru_head_index);          \
     444             :   if (~0 != oldest_index)                                                     \
     445             :     {                                                                         \
     446             :       oldest_elt = pool_elt_at_index (tsm->lru_pool, oldest_index);           \
     447             :       s = pool_elt_at_index (tsm->sessions, oldest_elt->value);               \
     448             :       sess_timeout_time =                                                     \
     449             :         s->last_heard + (f64) nat44_session_get_timeout (sm, s);              \
     450             :       vlib_cli_output (vm, d " LRU min session timeout %llu (now %llu)",      \
     451             :                        sess_timeout_time, now);                               \
     452             :       clib_dlist_addhead (tsm->lru_pool, tsm->n##_lru_head_index,             \
     453             :                           oldest_index);                                      \
     454             :     }
     455           0 :       _ (tcp_estab, "established tcp");
     456           0 :       _ (tcp_trans, "transitory tcp");
     457           0 :       _ (udp, "udp");
     458           0 :       _ (unk_proto, "unknown protocol");
     459           0 :       _ (icmp, "icmp");
     460             : #undef _
     461             :     }
     462           0 : }
     463             : 
     464             : static clib_error_t *
     465           0 : nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
     466             :                                vlib_cli_command_t * cmd)
     467             : {
     468             :   snat_main_per_thread_data_t *tsm;
     469           0 :   snat_main_t *sm = &snat_main;
     470             :   snat_session_t *s;
     471             : 
     472           0 :   u32 count = 0;
     473             : 
     474           0 :   u64 now = vlib_time_now (vm);
     475           0 :   u64 sess_timeout_time = 0;
     476             : 
     477             :   struct
     478             :   {
     479             :     u32 total;
     480             :     u32 timed_out;
     481           0 :   } udp = { 0 }, tcp = { 0 }, tcp_established = { 0 }, tcp_transitory = { 0 },
     482           0 :     icmp = { 0 }, other = { 0 };
     483             : 
     484             :   u32 fib;
     485             : 
     486           0 :   for (fib = 0; fib < vec_len (sm->max_translations_per_fib); fib++)
     487           0 :     vlib_cli_output (vm, "max translations per thread: %u fib %u",
     488           0 :                      sm->max_translations_per_fib[fib], fib);
     489             : 
     490           0 :   if (sm->num_workers > 1)
     491             :     {
     492           0 :       vec_foreach (tsm, sm->per_thread_data)
     493             :         {
     494           0 :           pool_foreach (s, tsm->sessions)
     495             :            {
     496           0 :              sess_timeout_time =
     497           0 :                s->last_heard + (f64) nat44_session_get_timeout (sm, s);
     498             : 
     499           0 :              switch (s->proto)
     500             :                {
     501           0 :                case IP_PROTOCOL_ICMP:
     502           0 :                  ++icmp.total;
     503           0 :                  if (now >= sess_timeout_time)
     504           0 :                    ++icmp.timed_out;
     505           0 :                  break;
     506           0 :                case IP_PROTOCOL_TCP:
     507           0 :                  ++tcp.total;
     508           0 :                  if (now >= sess_timeout_time)
     509           0 :                    ++tcp.timed_out;
     510           0 :                  if (nat44_ed_tcp_is_established (s->tcp_state))
     511             :                    {
     512           0 :                      ++tcp_established.total;
     513           0 :                      if (now >= sess_timeout_time)
     514           0 :                        ++tcp_established.timed_out;
     515             :                    }
     516             :                  else
     517             :                    {
     518           0 :                      ++tcp_transitory.total;
     519           0 :                      if (now >= sess_timeout_time)
     520           0 :                        ++tcp_transitory.timed_out;
     521             :                    }
     522           0 :                  break;
     523           0 :                case IP_PROTOCOL_UDP:
     524           0 :                  ++udp.total;
     525           0 :                  if (now >= sess_timeout_time)
     526           0 :                    ++udp.timed_out;
     527           0 :                  break;
     528           0 :                default:
     529           0 :                  ++other.total;
     530           0 :                  if (now >= sess_timeout_time)
     531           0 :                    ++other.timed_out;
     532           0 :                  break;
     533             :                }
     534             :            }
     535           0 :           nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
     536           0 :           count += pool_elts (tsm->sessions);
     537             :         }
     538             :     }
     539             :   else
     540             :     {
     541           0 :       tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
     542           0 :       pool_foreach (s, tsm->sessions)
     543             :        {
     544           0 :         sess_timeout_time = s->last_heard +
     545           0 :             (f64) nat44_session_get_timeout (sm, s);
     546             : 
     547           0 :         switch (s->proto)
     548             :           {
     549           0 :           case IP_PROTOCOL_ICMP:
     550           0 :             ++icmp.total;
     551           0 :             if (now >= sess_timeout_time)
     552           0 :               ++icmp.timed_out;
     553           0 :             break;
     554           0 :           case IP_PROTOCOL_TCP:
     555           0 :             ++tcp.total;
     556           0 :             if (now >= sess_timeout_time)
     557           0 :               ++tcp.timed_out;
     558           0 :             if (nat44_ed_tcp_is_established (s->tcp_state))
     559             :               {
     560           0 :                 ++tcp_established.total;
     561           0 :                 if (now >= sess_timeout_time)
     562           0 :                   ++tcp_established.timed_out;
     563             :               }
     564             :             else
     565             :               {
     566           0 :                 ++tcp_transitory.total;
     567           0 :                 if (now >= sess_timeout_time)
     568           0 :                   ++tcp_transitory.timed_out;
     569             :               }
     570           0 :             break;
     571           0 :           case IP_PROTOCOL_UDP:
     572           0 :             ++udp.total;
     573           0 :             if (now >= sess_timeout_time)
     574           0 :               ++udp.timed_out;
     575           0 :             break;
     576           0 :           default:
     577           0 :             ++other.total;
     578           0 :             if (now >= sess_timeout_time)
     579           0 :               ++other.timed_out;
     580           0 :             break;
     581             :           }
     582             :       }
     583           0 :       nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
     584           0 :       count = pool_elts (tsm->sessions);
     585             :     }
     586             : 
     587           0 :   u32 timed_out =
     588           0 :     tcp.timed_out + icmp.timed_out + udp.timed_out + other.timed_out;
     589           0 :   vlib_cli_output (vm, "total sessions: %u (timed out: %u)", count, timed_out);
     590           0 :   vlib_cli_output (vm, "tcp sessions:");
     591           0 :   vlib_cli_output (vm, "    total: %u (timed out: %u)", tcp.total,
     592             :                    tcp.timed_out);
     593           0 :   vlib_cli_output (vm, "        established: %u (timed out: %u)",
     594             :                    tcp_established.total, tcp_established.timed_out);
     595           0 :   vlib_cli_output (vm, "        transitory: %u (timed out: %u)",
     596             :                    tcp_transitory.total, tcp_transitory.timed_out);
     597           0 :   vlib_cli_output (vm, "udp sessions:");
     598           0 :   vlib_cli_output (vm, "    total: %u (timed out: %u)", udp.total,
     599             :                    udp.timed_out);
     600           0 :   vlib_cli_output (vm, "icmp sessions:");
     601           0 :   vlib_cli_output (vm, "    total: %u (timed out: %u)", icmp.total,
     602             :                    icmp.timed_out);
     603           0 :   vlib_cli_output (vm, "other sessions:");
     604           0 :   vlib_cli_output (vm, "    total: %u (timed out: %u)", other.total,
     605             :                    other.timed_out);
     606           0 :   return 0;
     607             : }
     608             : 
     609             : static clib_error_t *
     610           0 : nat44_show_addresses_command_fn (vlib_main_t * vm, unformat_input_t * input,
     611             :                                  vlib_cli_command_t * cmd)
     612             : {
     613           0 :   snat_main_t *sm = &snat_main;
     614             :   snat_address_t *ap;
     615             : 
     616           0 :   vlib_cli_output (vm, "NAT44 pool addresses:");
     617           0 :   vec_foreach (ap, sm->addresses)
     618             :     {
     619           0 :       vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
     620           0 :       if (ap->fib_index != ~0)
     621           0 :         vlib_cli_output (
     622             :           vm, "  tenant VRF: %u",
     623           0 :           fib_table_get (ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
     624             :       else
     625           0 :         vlib_cli_output (vm, "  tenant VRF independent");
     626             : 
     627           0 :       if (ap->addr_len != ~0)
     628           0 :         vlib_cli_output (vm, "  synced with interface address");
     629             :     }
     630           0 :   vlib_cli_output (vm, "NAT44 twice-nat pool addresses:");
     631           0 :   vec_foreach (ap, sm->twice_nat_addresses)
     632             :     {
     633           0 :       vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
     634           0 :       if (ap->fib_index != ~0)
     635           0 :           vlib_cli_output (vm, "  tenant VRF: %u",
     636           0 :             fib_table_get(ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
     637             :       else
     638           0 :         vlib_cli_output (vm, "  tenant VRF independent");
     639             : 
     640           0 :       if (ap->addr_len != ~0)
     641           0 :         vlib_cli_output (vm, "  synced with interface address");
     642             :     }
     643           0 :   return 0;
     644             : }
     645             : 
     646             : static clib_error_t *
     647           0 : snat_feature_command_fn (vlib_main_t * vm,
     648             :                          unformat_input_t * input, vlib_cli_command_t * cmd)
     649             : {
     650           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     651           0 :   vnet_main_t *vnm = vnet_get_main ();
     652           0 :   clib_error_t *error = 0;
     653             :   u32 sw_if_index;
     654           0 :   u32 *inside_sw_if_indices = 0;
     655           0 :   u32 *outside_sw_if_indices = 0;
     656           0 :   u8 is_output_feature = 0;
     657           0 :   int i, rv, is_del = 0;
     658             : 
     659           0 :   sw_if_index = ~0;
     660             : 
     661           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     662           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
     663             : 
     664           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     665             :     {
     666           0 :       if (unformat (line_input, "in %U", unformat_vnet_sw_interface,
     667             :                     vnm, &sw_if_index))
     668           0 :         vec_add1 (inside_sw_if_indices, sw_if_index);
     669           0 :       else if (unformat (line_input, "out %U", unformat_vnet_sw_interface,
     670             :                          vnm, &sw_if_index))
     671           0 :         vec_add1 (outside_sw_if_indices, sw_if_index);
     672           0 :       else if (unformat (line_input, "output-feature"))
     673           0 :         is_output_feature = 1;
     674           0 :       else if (unformat (line_input, "del"))
     675           0 :         is_del = 1;
     676             :       else
     677             :         {
     678           0 :           error = clib_error_return (0, "unknown input '%U'",
     679             :                                      format_unformat_error, line_input);
     680           0 :           goto done;
     681             :         }
     682             :     }
     683             : 
     684           0 :   if (vec_len (inside_sw_if_indices))
     685             :     {
     686           0 :       for (i = 0; i < vec_len (inside_sw_if_indices); i++)
     687             :         {
     688           0 :           sw_if_index = inside_sw_if_indices[i];
     689           0 :           if (is_output_feature)
     690             :             {
     691           0 :               if (is_del)
     692             :                 {
     693           0 :                   rv = nat44_ed_del_output_interface (sw_if_index);
     694             :                 }
     695             :               else
     696             :                 {
     697           0 :                   rv = nat44_ed_add_output_interface (sw_if_index);
     698             :                 }
     699           0 :               if (rv)
     700             :                 {
     701           0 :                   error = clib_error_return (0, "%s %U failed",
     702             :                                              is_del ? "del" : "add",
     703             :                                              format_vnet_sw_if_index_name,
     704             :                                              vnm, sw_if_index);
     705           0 :                   goto done;
     706             :                 }
     707             :             }
     708             :           else
     709             :             {
     710           0 :               if (is_del)
     711             :                 {
     712           0 :                   rv = nat44_ed_del_interface (sw_if_index, 1);
     713             :                 }
     714             :               else
     715             :                 {
     716           0 :                   rv = nat44_ed_add_interface (sw_if_index, 1);
     717             :                 }
     718           0 :               if (rv)
     719             :                 {
     720           0 :                   error = clib_error_return (0, "%s %U failed",
     721             :                                              is_del ? "del" : "add",
     722             :                                              format_vnet_sw_if_index_name,
     723             :                                              vnm, sw_if_index);
     724           0 :                   goto done;
     725             :                 }
     726             :             }
     727             :         }
     728             :     }
     729             : 
     730           0 :   if (vec_len (outside_sw_if_indices))
     731             :     {
     732           0 :       for (i = 0; i < vec_len (outside_sw_if_indices); i++)
     733             :         {
     734           0 :           sw_if_index = outside_sw_if_indices[i];
     735           0 :           if (is_output_feature)
     736             :             {
     737           0 :               if (is_del)
     738             :                 {
     739           0 :                   rv = nat44_ed_del_output_interface (sw_if_index);
     740             :                 }
     741             :               else
     742             :                 {
     743           0 :                   rv = nat44_ed_add_output_interface (sw_if_index);
     744             :                 }
     745           0 :               if (rv)
     746             :                 {
     747           0 :                   error = clib_error_return (0, "%s %U failed",
     748             :                                              is_del ? "del" : "add",
     749             :                                              format_vnet_sw_if_index_name,
     750             :                                              vnm, sw_if_index);
     751           0 :                   goto done;
     752             :                 }
     753             :             }
     754             :           else
     755             :             {
     756           0 :               if (is_del)
     757             :                 {
     758           0 :                   rv = nat44_ed_del_interface (sw_if_index, 0);
     759             :                 }
     760             :               else
     761             :                 {
     762           0 :                   rv = nat44_ed_add_interface (sw_if_index, 0);
     763             :                 }
     764           0 :               if (rv)
     765             :                 {
     766           0 :                   error = clib_error_return (0, "%s %U failed",
     767             :                                              is_del ? "del" : "add",
     768             :                                              format_vnet_sw_if_index_name,
     769             :                                              vnm, sw_if_index);
     770           0 :                   goto done;
     771             :                 }
     772             :             }
     773             :         }
     774             :     }
     775             : 
     776           0 : done:
     777           0 :   unformat_free (line_input);
     778           0 :   vec_free (inside_sw_if_indices);
     779           0 :   vec_free (outside_sw_if_indices);
     780             : 
     781           0 :   return error;
     782             : }
     783             : 
     784             : static clib_error_t *
     785           0 : nat44_show_interfaces_command_fn (vlib_main_t * vm, unformat_input_t * input,
     786             :                                   vlib_cli_command_t * cmd)
     787             : {
     788           0 :   snat_main_t *sm = &snat_main;
     789             :   snat_interface_t *i;
     790           0 :   vnet_main_t *vnm = vnet_get_main ();
     791             : 
     792           0 :   vlib_cli_output (vm, "NAT44 interfaces:");
     793           0 :   pool_foreach (i, sm->interfaces)
     794             :    {
     795           0 :      vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
     796             :                       i->sw_if_index,
     797           0 :                       (nat44_ed_is_interface_inside (i) &&
     798           0 :                        nat44_ed_is_interface_outside (i)) ?
     799             :                         "in out" :
     800           0 :                         (nat44_ed_is_interface_inside (i) ? "in" : "out"));
     801             :   }
     802             : 
     803           0 :   pool_foreach (i, sm->output_feature_interfaces)
     804             :    {
     805           0 :      vlib_cli_output (vm, " %U output-feature %s",
     806             :                       format_vnet_sw_if_index_name, vnm, i->sw_if_index,
     807           0 :                       (nat44_ed_is_interface_inside (i) &&
     808           0 :                        nat44_ed_is_interface_outside (i)) ?
     809             :                         "in out" :
     810           0 :                         (nat44_ed_is_interface_inside (i) ? "in" : "out"));
     811             :   }
     812             : 
     813           0 :   return 0;
     814             : }
     815             : 
     816             : static clib_error_t *
     817           0 : add_static_mapping_command_fn (vlib_main_t * vm,
     818             :                                unformat_input_t * input,
     819             :                                vlib_cli_command_t * cmd)
     820             : {
     821           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     822           0 :   vnet_main_t *vnm = vnet_get_main ();
     823           0 :   clib_error_t *error = 0;
     824             :   ip4_address_t l_addr, e_addr, pool_addr;
     825           0 :   u32 l_port = 0, e_port = 0, vrf_id = ~0;
     826           0 :   u8 l_port_set = 0, e_port_set = 0;
     827           0 :   int is_add = 1, rv;
     828           0 :   u32 flags = 0;
     829           0 :   u32 sw_if_index = ~0;
     830           0 :   ip_protocol_t proto = 0;
     831             : 
     832           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     833           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
     834             : 
     835           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     836             :     {
     837           0 :       if (unformat (line_input, "local %U %u", unformat_ip4_address, &l_addr,
     838             :                     &l_port))
     839             :         {
     840           0 :           l_port_set = 1;
     841             :         }
     842             :       else
     843           0 :         if (unformat (line_input, "local %U", unformat_ip4_address, &l_addr))
     844             :         ;
     845           0 :       else if (unformat (line_input, "external %U %u", unformat_ip4_address,
     846             :                          &e_addr, &e_port))
     847             :         {
     848           0 :           e_port_set = 1;
     849             :         }
     850           0 :       else if (unformat (line_input, "external %U", unformat_ip4_address,
     851             :                          &e_addr))
     852             :         ;
     853           0 :       else if (unformat (line_input, "external %U %u",
     854             :                          unformat_vnet_sw_interface, vnm, &sw_if_index,
     855             :                          &e_port))
     856             :         {
     857           0 :           flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
     858           0 :           e_port_set = 1;
     859             :         }
     860           0 :       else if (unformat (line_input, "external %U",
     861             :                          unformat_vnet_sw_interface, vnm, &sw_if_index))
     862             :         {
     863           0 :           flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
     864             :         }
     865           0 :       else if (unformat (line_input, "exact %U", unformat_ip4_address,
     866             :                          &pool_addr))
     867             :         {
     868           0 :           flags |= NAT_SM_FLAG_EXACT_ADDRESS;
     869             :         }
     870           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
     871             :         ;
     872           0 :       else if (unformat (line_input, "%U", unformat_ip_protocol, &proto))
     873             :         ;
     874           0 :       else if (unformat (line_input, "self-twice-nat"))
     875             :         {
     876           0 :           flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
     877             :         }
     878           0 :       else if (unformat (line_input, "twice-nat"))
     879             :         {
     880           0 :           flags |= NAT_SM_FLAG_TWICE_NAT;
     881             :         }
     882           0 :       else if (unformat (line_input, "out2in-only"))
     883             :         {
     884           0 :           flags |= NAT_SM_FLAG_OUT2IN_ONLY;
     885             :         }
     886           0 :       else if (unformat (line_input, "del"))
     887             :         {
     888           0 :           is_add = 0;
     889             :         }
     890             :       else
     891             :         {
     892           0 :           error = clib_error_return (0, "unknown input: '%U'",
     893             :                                      format_unformat_error, line_input);
     894           0 :           goto done;
     895             :         }
     896             :     }
     897             : 
     898           0 :   if (l_port_set != e_port_set)
     899             :     {
     900           0 :       error = clib_error_return (0, "Either both ports are set or none.");
     901           0 :       goto done;
     902             :     }
     903             : 
     904           0 :   if (!l_port_set)
     905             :     {
     906           0 :       flags |= NAT_SM_FLAG_ADDR_ONLY;
     907             :     }
     908             :   else
     909             :     {
     910           0 :       l_port = clib_host_to_net_u16 (l_port);
     911           0 :       e_port = clib_host_to_net_u16 (e_port);
     912             :     }
     913             : 
     914           0 :   if (is_add)
     915             :     {
     916             :       rv =
     917           0 :         nat44_ed_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
     918             :                                      vrf_id, sw_if_index, flags, pool_addr, 0);
     919             :     }
     920             :   else
     921             :     {
     922           0 :       rv = nat44_ed_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
     923             :                                         vrf_id, sw_if_index, flags);
     924             :     }
     925             : 
     926           0 :   switch (rv)
     927             :     {
     928           0 :     case VNET_API_ERROR_UNSUPPORTED:
     929           0 :       error = clib_error_return (0, "Plugin disabled.");
     930           0 :       break;
     931           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
     932           0 :       error = clib_error_return (0, "Mapping not exist.");
     933           0 :       break;
     934           0 :     case VNET_API_ERROR_VALUE_EXIST:
     935           0 :       error = clib_error_return (0, "Mapping already exist.");
     936           0 :       break;
     937           0 :     default:
     938           0 :       break;
     939             :     }
     940             : 
     941           0 : done:
     942           0 :   unformat_free (line_input);
     943             : 
     944           0 :   return error;
     945             : }
     946             : 
     947             : static clib_error_t *
     948           0 : add_identity_mapping_command_fn (vlib_main_t * vm,
     949             :                                  unformat_input_t * input,
     950             :                                  vlib_cli_command_t * cmd)
     951             : {
     952           0 :   unformat_input_t _line_input, *line_input = &_line_input;
     953           0 :   vnet_main_t *vnm = vnet_get_main ();
     954           0 :   clib_error_t *error = 0;
     955             : 
     956           0 :   int rv, is_add = 1, port_set = 0;
     957           0 :   u32 sw_if_index, port, flags, vrf_id = ~0;
     958           0 :   ip_protocol_t proto = 0;
     959             :   ip4_address_t addr;
     960             : 
     961           0 :   flags = NAT_SM_FLAG_IDENTITY_NAT;
     962             : 
     963           0 :   if (!unformat_user (input, unformat_line_input, line_input))
     964           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
     965             : 
     966           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
     967             :     {
     968           0 :       if (unformat (line_input, "%U", unformat_ip4_address, &addr))
     969             :         ;
     970           0 :       else if (unformat (line_input, "external %U",
     971             :                          unformat_vnet_sw_interface, vnm, &sw_if_index))
     972             :         {
     973           0 :           flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
     974             :         }
     975           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
     976             :         ;
     977           0 :       else if (unformat (line_input, "%U %u", unformat_ip_protocol, &proto,
     978             :                          &port))
     979             :         {
     980           0 :           port_set = 1;
     981             :         }
     982           0 :       else if (unformat (line_input, "del"))
     983             :         {
     984           0 :           is_add = 0;
     985             :         }
     986             :       else
     987             :         {
     988           0 :           error = clib_error_return (0, "unknown input: '%U'",
     989             :                                      format_unformat_error, line_input);
     990           0 :           goto done;
     991             :         }
     992             :     }
     993             : 
     994           0 :   if (!port_set)
     995             :     {
     996           0 :       flags |= NAT_SM_FLAG_ADDR_ONLY;
     997             :     }
     998             :   else
     999             :     {
    1000           0 :       port = clib_host_to_net_u16 (port);
    1001             :     }
    1002             : 
    1003           0 :   if (is_add)
    1004             :     {
    1005             : 
    1006           0 :       rv = nat44_ed_add_static_mapping (addr, addr, port, port, proto, vrf_id,
    1007             :                                         sw_if_index, flags, addr, 0);
    1008             :     }
    1009             :   else
    1010             :     {
    1011           0 :       rv = nat44_ed_del_static_mapping (addr, addr, port, port, proto, vrf_id,
    1012             :                                         sw_if_index, flags);
    1013             :     }
    1014             : 
    1015           0 :   switch (rv)
    1016             :     {
    1017           0 :     case VNET_API_ERROR_UNSUPPORTED:
    1018           0 :       error = clib_error_return (0, "Plugin disabled.");
    1019           0 :       break;
    1020           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
    1021           0 :       error = clib_error_return (0, "Mapping not exist.");
    1022           0 :       break;
    1023           0 :     case VNET_API_ERROR_VALUE_EXIST:
    1024           0 :       error = clib_error_return (0, "Mapping already exist.");
    1025           0 :       break;
    1026           0 :     default:
    1027           0 :       break;
    1028             :     }
    1029             : 
    1030           0 : done:
    1031           0 :   unformat_free (line_input);
    1032             : 
    1033           0 :   return error;
    1034             : }
    1035             : 
    1036             : static clib_error_t *
    1037           0 : add_lb_static_mapping_command_fn (vlib_main_t * vm,
    1038             :                                   unformat_input_t * input,
    1039             :                                   vlib_cli_command_t * cmd)
    1040             : {
    1041           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1042           0 :   clib_error_t *error = 0;
    1043             :   ip4_address_t l_addr, e_addr;
    1044           0 :   u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0, affinity = 0;
    1045           0 :   u8 proto_set = 0;
    1046             :   ip_protocol_t proto;
    1047           0 :   nat44_lb_addr_port_t *locals = 0, local;
    1048           0 :   int rv, is_add = 1;
    1049           0 :   u32 flags = 0;
    1050             : 
    1051           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1052           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1053             : 
    1054           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1055             :     {
    1056           0 :       if (unformat (line_input, "local %U:%u probability %u",
    1057             :                     unformat_ip4_address, &l_addr, &l_port, &probability))
    1058             :         {
    1059           0 :           clib_memset (&local, 0, sizeof (local));
    1060           0 :           local.addr = l_addr;
    1061           0 :           l_port = clib_host_to_net_u16 (l_port);
    1062           0 :           local.port = (u16) l_port;
    1063           0 :           local.probability = (u8) probability;
    1064           0 :           vec_add1 (locals, local);
    1065             :         }
    1066           0 :       else if (unformat (line_input, "local %U:%u vrf %u probability %u",
    1067             :                          unformat_ip4_address, &l_addr, &l_port, &vrf_id,
    1068             :                          &probability))
    1069             :         {
    1070           0 :           clib_memset (&local, 0, sizeof (local));
    1071           0 :           local.addr = l_addr;
    1072           0 :           l_port = clib_host_to_net_u16 (l_port);
    1073           0 :           local.port = (u16) l_port;
    1074           0 :           local.probability = (u8) probability;
    1075           0 :           local.vrf_id = vrf_id;
    1076           0 :           vec_add1 (locals, local);
    1077             :         }
    1078           0 :       else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
    1079             :                          &e_addr, &e_port))
    1080             :         {
    1081           0 :           e_port = clib_host_to_net_u16 (e_port);
    1082             :         }
    1083           0 :       else if (unformat (line_input, "protocol %U", unformat_ip_protocol,
    1084             :                          &proto))
    1085             :         {
    1086           0 :           proto_set = 1;
    1087             :         }
    1088           0 :       else if (unformat (line_input, "twice-nat"))
    1089             :         {
    1090           0 :           flags |= NAT_SM_FLAG_TWICE_NAT;
    1091             :         }
    1092           0 :       else if (unformat (line_input, "self-twice-nat"))
    1093             :         {
    1094           0 :           flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
    1095             :         }
    1096           0 :       else if (unformat (line_input, "out2in-only"))
    1097             :         {
    1098           0 :           flags |= NAT_SM_FLAG_OUT2IN_ONLY;
    1099             :         }
    1100           0 :       else if (unformat (line_input, "del"))
    1101             :         {
    1102           0 :           is_add = 0;
    1103             :         }
    1104           0 :       else if (unformat (line_input, "affinity %u", &affinity))
    1105             :         ;
    1106             :       else
    1107             :         {
    1108           0 :           error = clib_error_return (0, "unknown input: '%U'",
    1109             :                                      format_unformat_error, line_input);
    1110           0 :           goto done;
    1111             :         }
    1112             :     }
    1113             : 
    1114           0 :   if (vec_len (locals) < 2)
    1115             :     {
    1116           0 :       error = clib_error_return (0, "at least two local must be set");
    1117           0 :       goto done;
    1118             :     }
    1119             : 
    1120           0 :   if (!proto_set)
    1121             :     {
    1122           0 :       error = clib_error_return (0, "missing protocol");
    1123           0 :       goto done;
    1124             :     }
    1125             : 
    1126           0 :   if (is_add)
    1127             :     {
    1128           0 :       rv = nat44_ed_add_lb_static_mapping (e_addr, (u16) e_port, proto, locals,
    1129             :                                            flags, 0, affinity);
    1130             :     }
    1131             :   else
    1132             :     {
    1133           0 :       rv = nat44_ed_del_lb_static_mapping (e_addr, (u16) e_port, proto, flags);
    1134             :     }
    1135             : 
    1136           0 :   switch (rv)
    1137             :     {
    1138           0 :     case VNET_API_ERROR_INVALID_VALUE:
    1139           0 :       error = clib_error_return (0, "External port already in use.");
    1140           0 :       goto done;
    1141           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
    1142           0 :       if (is_add)
    1143           0 :         error = clib_error_return (0, "External address must be allocated.");
    1144             :       else
    1145           0 :         error = clib_error_return (0, "Mapping not exist.");
    1146           0 :       goto done;
    1147           0 :     case VNET_API_ERROR_VALUE_EXIST:
    1148           0 :       error = clib_error_return (0, "Mapping already exist.");
    1149           0 :       goto done;
    1150           0 :     default:
    1151           0 :       break;
    1152             :     }
    1153             : 
    1154           0 : done:
    1155           0 :   unformat_free (line_input);
    1156           0 :   vec_free (locals);
    1157             : 
    1158           0 :   return error;
    1159             : }
    1160             : 
    1161             : static clib_error_t *
    1162           0 : add_lb_backend_command_fn (vlib_main_t * vm,
    1163             :                            unformat_input_t * input, vlib_cli_command_t * cmd)
    1164             : {
    1165           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1166           0 :   clib_error_t *error = 0;
    1167             :   ip4_address_t l_addr, e_addr;
    1168           0 :   u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0;
    1169           0 :   int is_add = 1;
    1170             :   int rv;
    1171             :   ip_protocol_t proto;
    1172           0 :   u8 proto_set = 0;
    1173             : 
    1174           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1175           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1176             : 
    1177           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1178             :     {
    1179           0 :       if (unformat (line_input, "local %U:%u probability %u",
    1180             :                     unformat_ip4_address, &l_addr, &l_port, &probability))
    1181             :         ;
    1182           0 :       else if (unformat (line_input, "local %U:%u vrf %u probability %u",
    1183             :                          unformat_ip4_address, &l_addr, &l_port, &vrf_id,
    1184             :                          &probability))
    1185             :         ;
    1186           0 :       else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
    1187             :                          &e_addr, &e_port))
    1188             :         ;
    1189           0 :       else if (unformat (line_input, "protocol %U", unformat_ip_protocol,
    1190             :                          &proto))
    1191           0 :         proto_set = 1;
    1192           0 :       else if (unformat (line_input, "del"))
    1193           0 :         is_add = 0;
    1194             :       else
    1195             :         {
    1196           0 :           error = clib_error_return (0, "unknown input: '%U'",
    1197             :                                      format_unformat_error, line_input);
    1198           0 :           goto done;
    1199             :         }
    1200             :     }
    1201             : 
    1202           0 :   if (!l_port || !e_port)
    1203             :     {
    1204           0 :       error = clib_error_return (0, "local or external must be set");
    1205           0 :       goto done;
    1206             :     }
    1207             : 
    1208           0 :   if (!proto_set)
    1209             :     {
    1210           0 :       error = clib_error_return (0, "missing protocol");
    1211           0 :       goto done;
    1212             :     }
    1213             : 
    1214           0 :   rv = nat44_ed_add_del_lb_static_mapping_local (
    1215           0 :     e_addr, (u16) e_port, l_addr, l_port, proto, vrf_id, probability, is_add);
    1216             : 
    1217           0 :   switch (rv)
    1218             :     {
    1219           0 :     case VNET_API_ERROR_INVALID_VALUE:
    1220           0 :       error = clib_error_return (0, "External is not load-balancing static "
    1221             :                                  "mapping.");
    1222           0 :       goto done;
    1223           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
    1224           0 :       error = clib_error_return (0, "Mapping or back-end not exist.");
    1225           0 :       goto done;
    1226           0 :     case VNET_API_ERROR_VALUE_EXIST:
    1227           0 :       error = clib_error_return (0, "Back-end already exist.");
    1228           0 :       goto done;
    1229           0 :     case VNET_API_ERROR_UNSPECIFIED:
    1230           0 :       error = clib_error_return (0, "At least two back-ends must remain");
    1231           0 :       goto done;
    1232           0 :     default:
    1233           0 :       break;
    1234             :     }
    1235             : 
    1236           0 : done:
    1237           0 :   unformat_free (line_input);
    1238             : 
    1239           0 :   return error;
    1240             : }
    1241             : 
    1242             : static clib_error_t *
    1243           0 : nat44_show_static_mappings_command_fn (vlib_main_t * vm,
    1244             :                                        unformat_input_t * input,
    1245             :                                        vlib_cli_command_t * cmd)
    1246             : {
    1247           0 :   snat_main_t *sm = &snat_main;
    1248             :   snat_static_mapping_t *m;
    1249             :   snat_static_mapping_resolve_t *rp;
    1250             : 
    1251           0 :   vlib_cli_output (vm, "NAT44 static mappings:");
    1252           0 :   pool_foreach (m, sm->static_mappings)
    1253             :    {
    1254           0 :     vlib_cli_output (vm, " %U", format_snat_static_mapping, m);
    1255             :   }
    1256           0 :   vec_foreach (rp, sm->sm_to_resolve)
    1257           0 :     vlib_cli_output (vm, " %U", format_snat_static_map_to_resolve, rp);
    1258             : 
    1259           0 :   return 0;
    1260             : }
    1261             : 
    1262             : static clib_error_t *
    1263           0 : snat_add_interface_address_command_fn (vlib_main_t * vm,
    1264             :                                        unformat_input_t * input,
    1265             :                                        vlib_cli_command_t * cmd)
    1266             : {
    1267           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1268           0 :   vnet_main_t *vnm = vnet_get_main ();
    1269           0 :   clib_error_t *error = 0;
    1270           0 :   int rv, is_del = 0;
    1271           0 :   u8 twice_nat = 0;
    1272             :   u32 sw_if_index;
    1273             : 
    1274           0 :   sw_if_index = ~0;
    1275             : 
    1276           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1277           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1278             : 
    1279           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1280             :     {
    1281           0 :       if (unformat (line_input, "%U", unformat_vnet_sw_interface, vnm,
    1282             :                     &sw_if_index))
    1283             :         ;
    1284           0 :       else if (unformat (line_input, "twice-nat"))
    1285             :         {
    1286           0 :           twice_nat = 1;
    1287             :         }
    1288           0 :       else if (unformat (line_input, "del"))
    1289             :         {
    1290           0 :           is_del = 1;
    1291             :         }
    1292             :       else
    1293             :         {
    1294           0 :           error = clib_error_return (0, "unknown input '%U'",
    1295             :                                      format_unformat_error, line_input);
    1296           0 :           goto done;
    1297             :         }
    1298             :     }
    1299             : 
    1300           0 :   if (is_del)
    1301             :     {
    1302           0 :       rv = nat44_ed_del_interface_address (sw_if_index, twice_nat);
    1303             :     }
    1304             :   else
    1305             :     {
    1306           0 :       rv = nat44_ed_add_interface_address (sw_if_index, twice_nat);
    1307             :     }
    1308             : 
    1309           0 :   if (0 != rv)
    1310             :     {
    1311             :       error =
    1312           0 :         clib_error_return (0, "%s %U address failed", is_del ? "del" : "add",
    1313             :                            format_vnet_sw_if_index_name, vnm, sw_if_index);
    1314           0 :       goto done;
    1315             :     }
    1316             : 
    1317           0 : done:
    1318           0 :   unformat_free (line_input);
    1319             : 
    1320           0 :   return error;
    1321             : }
    1322             : 
    1323             : static clib_error_t *
    1324           0 : nat44_ed_add_del_vrf_table_command_fn (vlib_main_t *vm,
    1325             :                                        unformat_input_t *input,
    1326             :                                        vlib_cli_command_t *cmd)
    1327             : {
    1328           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1329           0 :   clib_error_t *error = 0;
    1330           0 :   bool is_add = true, not_set = true;
    1331           0 :   u32 vrf_id = ~0;
    1332             :   int rv;
    1333             : 
    1334           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1335           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1336             : 
    1337           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1338             :     {
    1339           0 :       if (unformat (line_input, "%u", &vrf_id))
    1340             :         ;
    1341           0 :       else if (not_set)
    1342             :         {
    1343           0 :           if (unformat (line_input, "add"))
    1344             :             {
    1345           0 :               is_add = true;
    1346             :             }
    1347           0 :           else if (unformat (line_input, "del"))
    1348             :             {
    1349           0 :               is_add = false;
    1350             :             }
    1351           0 :           not_set = false;
    1352             :         }
    1353             :       else
    1354             :         {
    1355           0 :           error = clib_error_return (0, "unknown input '%U'",
    1356             :                                      format_unformat_error, line_input);
    1357           0 :           goto done;
    1358             :         }
    1359             :     }
    1360             : 
    1361           0 :   if (not_set)
    1362             :     {
    1363           0 :       error = clib_error_return (0, "missing required parameter");
    1364           0 :       goto done;
    1365             :     }
    1366             : 
    1367           0 :   if (~0 == vrf_id)
    1368             :     {
    1369           0 :       error = clib_error_return (0, "missing vrf id");
    1370           0 :       goto done;
    1371             :     }
    1372             : 
    1373           0 :   rv = nat44_ed_add_del_vrf_table (vrf_id, is_add);
    1374           0 :   if (rv)
    1375             :     {
    1376           0 :       error = clib_error_return (0, "%s vrf table returned %d",
    1377             :                                  is_add ? "add" : "del", rv);
    1378             :     }
    1379             : 
    1380           0 : done:
    1381           0 :   unformat_free (line_input);
    1382             : 
    1383           0 :   return error;
    1384             : }
    1385             : 
    1386             : static clib_error_t *
    1387           0 : nat44_ed_add_del_vrf_route_command_fn (vlib_main_t *vm,
    1388             :                                        unformat_input_t *input,
    1389             :                                        vlib_cli_command_t *cmd)
    1390             : {
    1391           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1392           0 :   clib_error_t *error = 0;
    1393           0 :   bool is_add = true, not_set = true;
    1394           0 :   u32 vrf_id = ~0, table_vrf_id = ~0;
    1395             :   int rv;
    1396             : 
    1397           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1398           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1399             : 
    1400           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1401             :     {
    1402           0 :       if (unformat (line_input, "table %u", &table_vrf_id))
    1403             :         ;
    1404           0 :       else if (unformat (line_input, "%u", &vrf_id))
    1405             :         ;
    1406           0 :       else if (not_set)
    1407             :         {
    1408           0 :           if (unformat (line_input, "add"))
    1409             :             {
    1410           0 :               is_add = true;
    1411             :             }
    1412           0 :           else if (unformat (line_input, "del"))
    1413             :             {
    1414           0 :               is_add = false;
    1415             :             }
    1416           0 :           not_set = false;
    1417             :         }
    1418             :       else
    1419             :         {
    1420           0 :           error = clib_error_return (0, "unknown input '%U'",
    1421             :                                      format_unformat_error, line_input);
    1422           0 :           goto done;
    1423             :         }
    1424             :     }
    1425             : 
    1426           0 :   if (not_set)
    1427             :     {
    1428           0 :       error = clib_error_return (0, "missing required parameter");
    1429           0 :       goto done;
    1430             :     }
    1431             : 
    1432           0 :   if ((~0 == vrf_id) || (~0 == table_vrf_id))
    1433             :     {
    1434           0 :       error = clib_error_return (0, "missing vrf id");
    1435           0 :       goto done;
    1436             :     }
    1437             : 
    1438           0 :   rv = nat44_ed_add_del_vrf_route (table_vrf_id, vrf_id, is_add);
    1439           0 :   if (rv)
    1440             :     {
    1441           0 :       error = clib_error_return (0, "%s vrf table returned %d",
    1442             :                                  is_add ? "add" : "del", rv);
    1443             :     }
    1444             : 
    1445           0 : done:
    1446           0 :   unformat_free (line_input);
    1447             : 
    1448           0 :   return error;
    1449             : }
    1450             : 
    1451             : static clib_error_t *
    1452           0 : nat44_ed_show_vrf_tables_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1453             :                                      vlib_cli_command_t *cmd)
    1454             : {
    1455           0 :   snat_main_t *sm = &snat_main;
    1456             :   vrf_table_t *t;
    1457             :   vrf_route_t *r;
    1458           0 :   int i = 0;
    1459             : 
    1460           0 :   pool_foreach (t, sm->vrf_tables)
    1461             :     {
    1462           0 :       vlib_cli_output (vm, "table %u:", t->table_vrf_id);
    1463           0 :       pool_foreach (r, t->routes)
    1464             :         {
    1465           0 :           vlib_cli_output (vm, "[%u] vrf-id %u", i, r->vrf_id);
    1466           0 :           i++;
    1467             :         }
    1468             :     }
    1469             : 
    1470           0 :   return 0;
    1471             : }
    1472             : 
    1473             : static clib_error_t *
    1474           0 : nat44_show_interface_address_command_fn (vlib_main_t * vm,
    1475             :                                          unformat_input_t * input,
    1476             :                                          vlib_cli_command_t * cmd)
    1477             : {
    1478           0 :   snat_main_t *sm = &snat_main;
    1479           0 :   vnet_main_t *vnm = vnet_get_main ();
    1480             :   snat_address_resolve_t *ap;
    1481             : 
    1482           0 :   vlib_cli_output (vm, "NAT44 pool address interfaces:");
    1483           0 :   vec_foreach (ap, sm->addr_to_resolve)
    1484             :     {
    1485           0 :       vlib_cli_output (vm, " %U%s", format_vnet_sw_if_index_name, vnm,
    1486           0 :                        ap->sw_if_index, ap->is_twice_nat ? " twice-nat" : "");
    1487             :     }
    1488           0 :   return 0;
    1489             : }
    1490             : 
    1491             : static clib_error_t *
    1492          12 : nat44_show_sessions_command_fn (vlib_main_t * vm, unformat_input_t * input,
    1493             :                                 vlib_cli_command_t * cmd)
    1494             : {
    1495          12 :   unformat_input_t _line_input, *line_input = &_line_input;
    1496          12 :   clib_error_t *error = 0;
    1497             :   snat_main_per_thread_data_t *tsm;
    1498          12 :   snat_main_t *sm = &snat_main;
    1499             :   ip4_address_t i2o_sa, i2o_da, o2i_sa, o2i_da;
    1500          12 :   u8 filter_i2o_sa = 0, filter_i2o_da = 0;
    1501          12 :   u8 filter_o2i_sa = 0, filter_o2i_da = 0;
    1502             :   u16 i2o_sp, i2o_dp, o2i_sp, o2i_dp;
    1503          12 :   u8 filter_i2o_sp = 0, filter_i2o_dp = 0;
    1504          12 :   u8 filter_o2i_sp = 0, filter_o2i_dp = 0;
    1505             :   ip_protocol_t proto;
    1506          12 :   u8 filter_proto = 0;
    1507          12 :   u8 had_input = 1, filtering = 0;
    1508          12 :   int i = 0, showed_sessions;
    1509             : 
    1510          12 :   if (!unformat_user (input, unformat_line_input, line_input))
    1511             :     {
    1512          12 :       had_input = 0;
    1513          12 :       goto print;
    1514             :     }
    1515             : 
    1516           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1517             :     {
    1518           0 :       if (unformat (line_input, "filter i2o saddr %U", unformat_ip4_address,
    1519             :                     &i2o_sa))
    1520           0 :         filter_i2o_sa = filtering = 1;
    1521           0 :       else if (unformat (line_input, "filter i2o daddr %U",
    1522             :                          unformat_ip4_address, &i2o_da))
    1523           0 :         filter_i2o_da = filtering = 1;
    1524           0 :       else if (unformat (line_input, "filter o2i saddr %U",
    1525             :                          unformat_ip4_address, &o2i_sa))
    1526           0 :         filter_o2i_sa = filtering = 1;
    1527           0 :       else if (unformat (line_input, "filter o2i daddr %U",
    1528             :                          unformat_ip4_address, &o2i_da))
    1529           0 :         filter_o2i_da = filtering = 1;
    1530           0 :       else if (unformat (line_input, "filter i2o sport %u", &i2o_sp))
    1531           0 :         filter_i2o_sp = filtering = 1;
    1532           0 :       else if (unformat (line_input, "filter i2o dport %u", &i2o_dp))
    1533           0 :         filter_i2o_dp = filtering = 1;
    1534           0 :       else if (unformat (line_input, "filter o2i sport %u", &o2i_sp))
    1535           0 :         filter_o2i_sp = filtering = 1;
    1536           0 :       else if (unformat (line_input, "filter o2i dport %u", &o2i_dp))
    1537           0 :         filter_o2i_dp = filtering = 1;
    1538           0 :       else if (unformat (line_input, "filter i2o proto %U",
    1539             :                          unformat_ip_protocol, &proto))
    1540           0 :         filter_proto = filtering = 1;
    1541           0 :       else if (unformat (line_input, "filter o2i proto %U",
    1542             :                          unformat_ip_protocol, &proto))
    1543           0 :         filter_proto = filtering = 1;
    1544             :       else
    1545             :         {
    1546           0 :           error = clib_error_return (0, "unknown input '%U'",
    1547             :                                      format_unformat_error, line_input);
    1548           0 :           goto done;
    1549             :         }
    1550             :     }
    1551             : 
    1552           0 : print:
    1553          12 :   vlib_cli_output (vm, "NAT44 ED sessions:");
    1554             : 
    1555          52 :   vec_foreach_index (i, sm->per_thread_data)
    1556             :     {
    1557          40 :       tsm = vec_elt_at_index (sm->per_thread_data, i);
    1558             : 
    1559          80 :       vlib_cli_output (vm, "-------- thread %d %s: %d sessions --------\n",
    1560          40 :                        i, vlib_worker_threads[i].name,
    1561          40 :                        pool_elts (tsm->sessions));
    1562             : 
    1563          40 :       showed_sessions = 0;
    1564             :       snat_session_t *s;
    1565       13357 :       pool_foreach (s, tsm->sessions)
    1566             :         {
    1567       13317 :           if (filtering)
    1568             :             {
    1569           0 :               if (filter_i2o_sa && i2o_sa.as_u32 != s->i2o.match.saddr.as_u32)
    1570           0 :                 continue;
    1571           0 :               if (filter_i2o_da && i2o_da.as_u32 != s->i2o.match.daddr.as_u32)
    1572           0 :                 continue;
    1573           0 :               if (filter_o2i_sa && o2i_sa.as_u32 != s->o2i.match.saddr.as_u32)
    1574           0 :                 continue;
    1575           0 :               if (filter_o2i_da && o2i_da.as_u32 != s->o2i.match.daddr.as_u32)
    1576           0 :                 continue;
    1577           0 :               if (filter_i2o_sp &&
    1578           0 :                   i2o_sp != clib_net_to_host_u16 (s->i2o.match.sport))
    1579           0 :                 continue;
    1580           0 :               if (filter_i2o_dp &&
    1581           0 :                   i2o_dp != clib_net_to_host_u16 (s->i2o.match.dport))
    1582           0 :                 continue;
    1583           0 :               if (filter_o2i_sp &&
    1584           0 :                   o2i_sp != clib_net_to_host_u16 (s->o2i.match.sport))
    1585           0 :                 continue;
    1586           0 :               if (filter_o2i_dp &&
    1587           0 :                   o2i_dp != clib_net_to_host_u16 (s->o2i.match.dport))
    1588           0 :                 continue;
    1589           0 :               if (filter_proto && proto != s->proto)
    1590           0 :                 continue;
    1591           0 :               showed_sessions++;
    1592             :             }
    1593       13317 :           vlib_cli_output (vm, "  %U\n", format_snat_session, sm, tsm, s,
    1594             :                            vlib_time_now (vm));
    1595             :         }
    1596          40 :       if (filtering)
    1597             :         {
    1598           0 :           vlib_cli_output (vm,
    1599             :                            "Showed: %d, Filtered: %d of total %d "
    1600             :                            "sessions of thread %d\n\n",
    1601             :                            showed_sessions,
    1602           0 :                            pool_elts (tsm->sessions) - showed_sessions,
    1603           0 :                            pool_elts (tsm->sessions), i);
    1604             :         }
    1605             :     }
    1606             : 
    1607          12 : done:
    1608          12 :   if (had_input)
    1609           0 :     unformat_free (line_input);
    1610          12 :   return error;
    1611             : }
    1612             : 
    1613             : static clib_error_t *
    1614           0 : nat44_set_session_limit_command_fn (vlib_main_t * vm,
    1615             :                                     unformat_input_t * input,
    1616             :                                     vlib_cli_command_t * cmd)
    1617             : {
    1618           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1619           0 :   clib_error_t *error = 0;
    1620             : 
    1621           0 :   u32 session_limit = 0, vrf_id = 0;
    1622             : 
    1623           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1624           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1625             : 
    1626           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1627             :     {
    1628           0 :       if (unformat (line_input, "%u", &session_limit))
    1629             :         ;
    1630           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
    1631             :         ;
    1632             :       else
    1633             :         {
    1634           0 :           error = clib_error_return (0, "unknown input '%U'",
    1635             :                                      format_unformat_error, line_input);
    1636           0 :           goto done;
    1637             :         }
    1638             :     }
    1639             : 
    1640           0 :   if (!session_limit)
    1641           0 :     error = clib_error_return (0, "missing value of session limit");
    1642           0 :   else if (nat44_update_session_limit (session_limit, vrf_id))
    1643           0 :     error = clib_error_return (0, "nat44_set_session_limit failed");
    1644             : 
    1645           0 : done:
    1646           0 :   unformat_free (line_input);
    1647             : 
    1648           0 :   return error;
    1649             : }
    1650             : 
    1651             : static clib_error_t *
    1652           0 : nat44_del_session_command_fn (vlib_main_t * vm,
    1653             :                               unformat_input_t * input,
    1654             :                               vlib_cli_command_t * cmd)
    1655             : {
    1656           0 :   snat_main_t *sm = &snat_main;
    1657           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1658           0 :   u32 port = 0, eh_port = 0, vrf_id = sm->outside_vrf_id;
    1659           0 :   clib_error_t *error = 0;
    1660             :   ip4_address_t addr, eh_addr;
    1661             :   ip_protocol_t proto;
    1662           0 :   int is_in = 0;
    1663             :   int rv;
    1664             : 
    1665           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1666           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1667             : 
    1668           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1669             :     {
    1670           0 :       if (unformat (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
    1671             :                     unformat_ip_protocol, &proto))
    1672             :         ;
    1673           0 :       else if (unformat (line_input, "in"))
    1674             :         {
    1675           0 :           is_in = 1;
    1676           0 :           vrf_id = sm->inside_vrf_id;
    1677             :         }
    1678           0 :       else if (unformat (line_input, "out"))
    1679             :         {
    1680           0 :           is_in = 0;
    1681           0 :           vrf_id = sm->outside_vrf_id;
    1682             :         }
    1683           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
    1684             :         ;
    1685           0 :       else if (unformat (line_input, "external-host %U:%u",
    1686             :                          unformat_ip4_address, &eh_addr, &eh_port))
    1687             :         ;
    1688             :       else
    1689             :         {
    1690           0 :           error = clib_error_return (0, "unknown input '%U'",
    1691             :                                      format_unformat_error, line_input);
    1692           0 :           goto done;
    1693             :         }
    1694             :     }
    1695             : 
    1696           0 :   rv = nat44_ed_del_session (sm, &addr, clib_host_to_net_u16 (port), &eh_addr,
    1697           0 :                              clib_host_to_net_u16 (eh_port), proto, vrf_id,
    1698             :                              is_in);
    1699             : 
    1700           0 :   switch (rv)
    1701             :     {
    1702           0 :     case 0:
    1703           0 :       break;
    1704             : 
    1705           0 :     default:
    1706           0 :       error = clib_error_return (0, "nat44_del_session returned %d", rv);
    1707           0 :       goto done;
    1708             :     }
    1709             : 
    1710           0 : done:
    1711           0 :   unformat_free (line_input);
    1712             : 
    1713           0 :   return error;
    1714             : }
    1715             : 
    1716             : static clib_error_t *
    1717           0 : snat_forwarding_set_command_fn (vlib_main_t * vm,
    1718             :                                 unformat_input_t * input,
    1719             :                                 vlib_cli_command_t * cmd)
    1720             : {
    1721           0 :   snat_main_t *sm = &snat_main;
    1722           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1723           0 :   clib_error_t *error = 0;
    1724             : 
    1725           0 :   u8 enable_set = 0, enable = 0;
    1726             : 
    1727           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1728           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1729             : 
    1730           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1731             :     {
    1732           0 :       if (!enable_set)
    1733             :         {
    1734           0 :           enable_set = 1;
    1735           0 :           if (unformat (line_input, "disable"))
    1736             :             ;
    1737           0 :           else if (unformat (line_input, "enable"))
    1738           0 :             enable = 1;
    1739             :         }
    1740             :       else
    1741             :         {
    1742           0 :           error = clib_error_return (0, "unknown input '%U'",
    1743             :                                      format_unformat_error, line_input);
    1744           0 :           goto done;
    1745             :         }
    1746             :     }
    1747             : 
    1748           0 :   if (!enable_set)
    1749           0 :     error = clib_error_return (0, "expected enable | disable");
    1750             :   else
    1751           0 :     sm->forwarding_enabled = enable;
    1752             : 
    1753           0 : done:
    1754           0 :   unformat_free (line_input);
    1755           0 :   return error;
    1756             : }
    1757             : 
    1758             : static clib_error_t *
    1759           0 : set_timeout_command_fn (vlib_main_t * vm,
    1760             :                         unformat_input_t * input, vlib_cli_command_t * cmd)
    1761             : {
    1762           0 :   snat_main_t *sm = &snat_main;
    1763           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1764           0 :   clib_error_t *error = 0;
    1765             : 
    1766           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1767           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1768             : 
    1769           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1770             :     {
    1771           0 :       if (unformat (line_input, "udp %u", &sm->timeouts.udp));
    1772           0 :       else if (unformat (line_input, "tcp-established %u",
    1773             :                          &sm->timeouts.tcp.established));
    1774           0 :       else if (unformat (line_input, "tcp-transitory %u",
    1775             :                          &sm->timeouts.tcp.transitory));
    1776           0 :       else if (unformat (line_input, "icmp %u", &sm->timeouts.icmp));
    1777           0 :       else if (unformat (line_input, "reset"))
    1778           0 :         nat_reset_timeouts (&sm->timeouts);
    1779             :       else
    1780             :         {
    1781           0 :           error = clib_error_return (0, "unknown input '%U'",
    1782             :                                      format_unformat_error, line_input);
    1783           0 :           goto done;
    1784             :         }
    1785             :     }
    1786           0 : done:
    1787           0 :   unformat_free (line_input);
    1788           0 :   return error;
    1789             : }
    1790             : 
    1791             : static clib_error_t *
    1792           0 : nat_show_timeouts_command_fn (vlib_main_t * vm,
    1793             :                               unformat_input_t * input,
    1794             :                               vlib_cli_command_t * cmd)
    1795             : {
    1796           0 :   snat_main_t *sm = &snat_main;
    1797             : 
    1798           0 :   vlib_cli_output (vm, "udp timeout: %dsec", sm->timeouts.udp);
    1799           0 :   vlib_cli_output (vm, "tcp-established timeout: %dsec",
    1800             :                    sm->timeouts.tcp.established);
    1801           0 :   vlib_cli_output (vm, "tcp-transitory timeout: %dsec",
    1802             :                    sm->timeouts.tcp.transitory);
    1803           0 :   vlib_cli_output (vm, "icmp timeout: %dsec", sm->timeouts.icmp);
    1804             : 
    1805           0 :   return 0;
    1806             : }
    1807             : 
    1808             : static clib_error_t *
    1809           0 : set_frame_queue_nelts_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1810             :                                   vlib_cli_command_t *cmd)
    1811             : {
    1812           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1813           0 :   clib_error_t *error = 0;
    1814           0 :   u32 frame_queue_nelts = 0;
    1815             : 
    1816           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1817           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1818             : 
    1819           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1820             :     {
    1821           0 :       if (unformat (line_input, "%u", &frame_queue_nelts))
    1822             :         ;
    1823             :       else
    1824             :         {
    1825           0 :           error = clib_error_return (0, "unknown input '%U'",
    1826             :                                      format_unformat_error, line_input);
    1827           0 :           goto done;
    1828             :         }
    1829             :     }
    1830           0 :   if (!frame_queue_nelts)
    1831             :     {
    1832           0 :       error = clib_error_return (0, "frame_queue_nelts cannot be zero");
    1833           0 :       goto done;
    1834             :     }
    1835           0 :   if (nat44_ed_set_frame_queue_nelts (frame_queue_nelts) != 0)
    1836             :     {
    1837           0 :       error = clib_error_return (0, "snat_set_frame_queue_nelts failed");
    1838           0 :       goto done;
    1839             :     }
    1840           0 : done:
    1841           0 :   unformat_free (line_input);
    1842           0 :   return error;
    1843             : }
    1844             : 
    1845             : /*?
    1846             :  * @cliexpar
    1847             :  * @cliexstart{nat44}
    1848             :  * Enable nat44 plugin
    1849             :  * To enable nat44-ed, use:
    1850             :  *  vpp# nat44 plugin enable
    1851             :  * To disable nat44-ed, use:
    1852             :  *  vpp# nat44 plugin disable
    1853             :  * To set inside-vrf outside-vrf, use:
    1854             :  *  vpp# nat44 plugin enable inside-vrf <id> outside-vrf <id>
    1855             :  * @cliexend
    1856             : ?*/
    1857       62935 : VLIB_CLI_COMMAND (nat44_ed_enable_disable_command, static) = {
    1858             :   .path = "nat44 plugin",
    1859             :   .function = nat44_ed_enable_disable_command_fn,
    1860             :   .short_help =
    1861             :     "nat44 plugin <enable [sessions <max-number>] [inside-vrf <vrf-id>] "
    1862             :     "[outside-vrf <vrf-id>]>|disable",
    1863             : };
    1864             : 
    1865             : /*?
    1866             :  * @cliexpar
    1867             :  * @cliexstart{set snat workers}
    1868             :  * Set NAT workers if 2 or more workers available, use:
    1869             :  *  vpp# set snat workers 0-2,5
    1870             :  * @cliexend
    1871             : ?*/
    1872       62935 : VLIB_CLI_COMMAND (set_workers_command, static) = {
    1873             :   .path = "set nat workers",
    1874             :   .function = set_workers_command_fn,
    1875             :   .short_help = "set nat workers <workers-list>",
    1876             : };
    1877             : 
    1878             : /*?
    1879             :  * @cliexpar
    1880             :  * @cliexstart{show nat workers}
    1881             :  * Show NAT workers.
    1882             :  *  vpp# show nat workers:
    1883             :  *  2 workers
    1884             :  *    vpp_wk_0
    1885             :  *    vpp_wk_1
    1886             :  * @cliexend
    1887             : ?*/
    1888       62935 : VLIB_CLI_COMMAND (nat_show_workers_command, static) = {
    1889             :   .path = "show nat workers",
    1890             :   .short_help = "show nat workers",
    1891             :   .function = nat_show_workers_command_fn,
    1892             : };
    1893             : 
    1894             : /*?
    1895             :  * @cliexpar
    1896             :  * @cliexstart{set nat timeout}
    1897             :  * Set values of timeouts for NAT sessions (in seconds), use:
    1898             :  *  vpp# set nat timeout udp 120 tcp-established 7500 tcp-transitory 250 icmp 90
    1899             :  * To reset default values use:
    1900             :  *  vpp# set nat timeout reset
    1901             :  * @cliexend
    1902             : ?*/
    1903       62935 : VLIB_CLI_COMMAND (set_timeout_command, static) = {
    1904             :   .path = "set nat timeout",
    1905             :   .function = set_timeout_command_fn,
    1906             :   .short_help =
    1907             :     "set nat timeout [udp <sec> | tcp-established <sec> "
    1908             :     "tcp-transitory <sec> | icmp <sec> | reset]",
    1909             : };
    1910             : 
    1911             : /*?
    1912             :  * @cliexpar
    1913             :  * @cliexstart{show nat timeouts}
    1914             :  * Show values of timeouts for NAT sessions.
    1915             :  * vpp# show nat timeouts
    1916             :  * udp timeout: 300sec
    1917             :  * tcp-established timeout: 7440sec
    1918             :  * tcp-transitory timeout: 240sec
    1919             :  * icmp timeout: 60sec
    1920             :  * @cliexend
    1921             : ?*/
    1922       62935 : VLIB_CLI_COMMAND (nat_show_timeouts_command, static) = {
    1923             :   .path = "show nat timeouts",
    1924             :   .short_help = "show nat timeouts",
    1925             :   .function = nat_show_timeouts_command_fn,
    1926             : };
    1927             : 
    1928             : /*?
    1929             :  * @cliexpar
    1930             :  * @cliexstart{set nat frame-queue-nelts}
    1931             :  * Set number of worker handoff frame queue elements.
    1932             :  * @cliexend
    1933             : ?*/
    1934       62935 : VLIB_CLI_COMMAND (set_frame_queue_nelts_command, static) = {
    1935             :   .path = "set nat frame-queue-nelts",
    1936             :   .function = set_frame_queue_nelts_command_fn,
    1937             :   .short_help = "set nat frame-queue-nelts <number>",
    1938             : };
    1939             : 
    1940             : /*?
    1941             :  * @cliexpar
    1942             :  * @cliexstart{nat set logging level}
    1943             :  * To set NAT logging level use:
    1944             :  * Set nat logging level
    1945             :  * @cliexend
    1946             : ?*/
    1947       62935 : VLIB_CLI_COMMAND (snat_set_log_level_command, static) = {
    1948             :   .path = "nat set logging level",
    1949             :   .function = snat_set_log_level_command_fn,
    1950             :   .short_help = "nat set logging level <level>",
    1951             : };
    1952             : 
    1953             : /*?
    1954             :  * @cliexpar
    1955             :  * @cliexstart{snat ipfix logging}
    1956             :  * To enable NAT IPFIX logging use:
    1957             :  *  vpp# nat ipfix logging
    1958             :  * To set IPFIX exporter use:
    1959             :  *  vpp# set ipfix exporter collector 10.10.10.3 src 10.10.10.1
    1960             :  * @cliexend
    1961             : ?*/
    1962       62935 : VLIB_CLI_COMMAND (snat_ipfix_logging_enable_disable_command, static) = {
    1963             :   .path = "nat ipfix logging",
    1964             :   .function = snat_ipfix_logging_enable_disable_command_fn,
    1965             :   .short_help = "nat ipfix logging disable|<enable [domain <domain-id>] "
    1966             :                 "[src-port <port>]>",
    1967             : };
    1968             : 
    1969             : /*?
    1970             :  * @cliexpar
    1971             :  * @cliexstart{nat mss-clamping}
    1972             :  * Set TCP MSS rewriting configuration
    1973             :  * To enable TCP MSS rewriting use:
    1974             :  *  vpp# nat mss-clamping 1452
    1975             :  * To disbale TCP MSS rewriting use:
    1976             :  *  vpp# nat mss-clamping disable
    1977             :  * @cliexend
    1978             : ?*/
    1979       62935 : VLIB_CLI_COMMAND (nat_set_mss_clamping_command, static) = {
    1980             :     .path = "nat mss-clamping",
    1981             :     .short_help = "nat mss-clamping <mss-value>|disable",
    1982             :     .function = nat_set_mss_clamping_command_fn,
    1983             : };
    1984             : 
    1985             : /*?
    1986             :  * @cliexpar
    1987             :  * @cliexstart{show nat mss-clamping}
    1988             :  * Show TCP MSS rewriting configuration
    1989             :  * @cliexend
    1990             : ?*/
    1991       62935 : VLIB_CLI_COMMAND (nat_show_mss_clamping_command, static) = {
    1992             :     .path = "show nat mss-clamping",
    1993             :     .short_help = "show nat mss-clamping",
    1994             :     .function = nat_show_mss_clamping_command_fn,
    1995             : };
    1996             : 
    1997             : /*?
    1998             :  * @cliexpar
    1999             :  * @cliexstart{show nat44 hash tables}
    2000             :  * Show NAT44 hash tables
    2001             :  * @cliexend
    2002             : ?*/
    2003       62935 : VLIB_CLI_COMMAND (nat44_show_hash, static) = {
    2004             :   .path = "show nat44 hash tables",
    2005             :   .short_help = "show nat44 hash tables [detail|verbose]",
    2006             :   .function = nat44_show_hash_command_fn,
    2007             : };
    2008             : 
    2009             : /*?
    2010             :  * @cliexpar
    2011             :  * @cliexstart{nat44 add address}
    2012             :  * Add/delete NAT44 pool address.
    2013             :  * To add NAT44 pool address use:
    2014             :  *  vpp# nat44 add address 172.16.1.3
    2015             :  *  vpp# nat44 add address 172.16.2.2 - 172.16.2.24
    2016             :  * To add NAT44 pool address for specific tenant (identified by VRF id) use:
    2017             :  *  vpp# nat44 add address 172.16.1.3 tenant-vrf 10
    2018             :  * @cliexend
    2019             : ?*/
    2020       62935 : VLIB_CLI_COMMAND (add_address_command, static) = {
    2021             :   .path = "nat44 add address",
    2022             :   .short_help = "nat44 add address <ip4-range-start> [- <ip4-range-end>] "
    2023             :                 "[tenant-vrf <vrf-id>] [twice-nat] [del]",
    2024             :   .function = add_address_command_fn,
    2025             : };
    2026             : 
    2027             : /*?
    2028             :  * @cliexpar
    2029             :  * @cliexstart{show nat44 summary}
    2030             :  * Show NAT44 summary
    2031             :  * vpp# show nat44 summary
    2032             :  * @cliexend
    2033             : ?*/
    2034       62935 : VLIB_CLI_COMMAND (nat44_show_summary_command, static) = {
    2035             :   .path = "show nat44 summary",
    2036             :   .short_help = "show nat44 summary",
    2037             :   .function = nat44_show_summary_command_fn,
    2038             : };
    2039             : 
    2040             : /*?
    2041             :  * @cliexpar
    2042             :  * @cliexstart{show nat44 addresses}
    2043             :  * Show NAT44 pool addresses.
    2044             :  * vpp# show nat44 addresses
    2045             :  * NAT44 pool addresses:
    2046             :  * 172.16.2.2
    2047             :  *   tenant VRF independent
    2048             :  *   10 busy udp ports
    2049             :  *   0 busy tcp ports
    2050             :  *   0 busy icmp ports
    2051             :  * 172.16.1.3
    2052             :  *   tenant VRF: 10
    2053             :  *   0 busy udp ports
    2054             :  *   2 busy tcp ports
    2055             :  *   0 busy icmp ports
    2056             :  * NAT44 twice-nat pool addresses:
    2057             :  * 10.20.30.72
    2058             :  *   tenant VRF independent
    2059             :  *   0 busy udp ports
    2060             :  *   0 busy tcp ports
    2061             :  *   0 busy icmp ports
    2062             :  * @cliexend
    2063             : ?*/
    2064       62935 : VLIB_CLI_COMMAND (nat44_show_addresses_command, static) = {
    2065             :   .path = "show nat44 addresses",
    2066             :   .short_help = "show nat44 addresses",
    2067             :   .function = nat44_show_addresses_command_fn,
    2068             : };
    2069             : 
    2070             : /*?
    2071             :  * @cliexpar
    2072             :  * @cliexstart{set interface nat44}
    2073             :  * Enable/disable NAT44 feature on the interface.
    2074             :  * To enable NAT44 feature with local network interface use:
    2075             :  *  vpp# set interface nat44 in GigabitEthernet0/8/0
    2076             :  * To enable NAT44 feature with external network interface use:
    2077             :  *  vpp# set interface nat44 out GigabitEthernet0/a/0
    2078             :  * @cliexend
    2079             : ?*/
    2080       62935 : VLIB_CLI_COMMAND (set_interface_snat_command, static) = {
    2081             :   .path = "set interface nat44",
    2082             :   .function = snat_feature_command_fn,
    2083             :   .short_help = "set interface nat44 in <intfc> out <intfc> [output-feature] "
    2084             :                 "[del]",
    2085             : };
    2086             : 
    2087             : /*?
    2088             :  * @cliexpar
    2089             :  * @cliexstart{show nat44 interfaces}
    2090             :  * Show interfaces with NAT44 feature.
    2091             :  * vpp# show nat44 interfaces
    2092             :  * NAT44 interfaces:
    2093             :  *  GigabitEthernet0/8/0 in
    2094             :  *  GigabitEthernet0/a/0 out
    2095             :  * @cliexend
    2096             : ?*/
    2097       62935 : VLIB_CLI_COMMAND (nat44_show_interfaces_command, static) = {
    2098             :   .path = "show nat44 interfaces",
    2099             :   .short_help = "show nat44 interfaces",
    2100             :   .function = nat44_show_interfaces_command_fn,
    2101             : };
    2102             : 
    2103             : /*?
    2104             :  * @cliexpar
    2105             :  * @cliexstart{nat44 add static mapping}
    2106             :  * Static mapping allows hosts on the external network to initiate connection
    2107             :  * to to the local network host.
    2108             :  * To create static mapping between local host address 10.0.0.3 port 6303 and
    2109             :  * external address 4.4.4.4 port 3606 for TCP protocol use:
    2110             :  *  vpp# nat44 add static mapping tcp local 10.0.0.3 6303 external 4.4.4.4 3606
    2111             :  * If not runnig "static mapping only" NAT plugin mode use before:
    2112             :  *  vpp# nat44 add address 4.4.4.4
    2113             :  * To create address only static mapping between local and external address use:
    2114             :  *  vpp# nat44 add static mapping local 10.0.0.3 external 4.4.4.4
    2115             :  * To create ICMP static mapping between local and external with ICMP echo
    2116             :  * identifier 10 use:
    2117             :  *  vpp# nat44 add static mapping icmp local 10.0.0.3 10 external 4.4.4.4 10
    2118             :  * To force use of specific pool address, vrf independent
    2119             :  *  vpp# nat44 add static mapping local 10.0.0.2 1234 external 10.0.2.2 1234 twice-nat exact 10.0.1.2
    2120             :  * @cliexend
    2121             : ?*/
    2122       62935 : VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
    2123             :   .path = "nat44 add static mapping",
    2124             :   .function = add_static_mapping_command_fn,
    2125             :   .short_help =
    2126             :     "nat44 add static mapping tcp|udp|icmp local <addr> [<port|icmp-echo-id>] "
    2127             :     "external <addr> [<port|icmp-echo-id>] [vrf <table-id>] [twice-nat|self-twice-nat] "
    2128             :     "[out2in-only] [exact <pool-addr>] [del]",
    2129             : };
    2130             : 
    2131             : /*?
    2132             :  * @cliexpar
    2133             :  * @cliexstart{nat44 add identity mapping}
    2134             :  * Identity mapping translate an IP address to itself.
    2135             :  * To create identity mapping for address 10.0.0.3 port 6303 for TCP protocol
    2136             :  * use:
    2137             :  *  vpp# nat44 add identity mapping 10.0.0.3 tcp 6303
    2138             :  * To create identity mapping for address 10.0.0.3 use:
    2139             :  *  vpp# nat44 add identity mapping 10.0.0.3
    2140             :  * To create identity mapping for DHCP addressed interface use:
    2141             :  *  vpp# nat44 add identity mapping external GigabitEthernet0/a/0 tcp 3606
    2142             :  * @cliexend
    2143             : ?*/
    2144       62935 : VLIB_CLI_COMMAND (add_identity_mapping_command, static) = {
    2145             :   .path = "nat44 add identity mapping",
    2146             :   .function = add_identity_mapping_command_fn,
    2147             :   .short_help = "nat44 add identity mapping <ip4-addr>|external <interface> "
    2148             :     "[<protocol> <port>] [vrf <table-id>] [del]",
    2149             : };
    2150             : 
    2151             : /*?
    2152             :  * @cliexpar
    2153             :  * @cliexstart{nat44 add load-balancing static mapping}
    2154             :  * Service load balancing using NAT44
    2155             :  * To add static mapping with load balancing for service with external IP
    2156             :  * address 1.2.3.4 and TCP port 80 and mapped to 2 local servers
    2157             :  * 10.100.10.10:8080 and 10.100.10.20:8080 with probability 80% resp. 20% use:
    2158             :  *  vpp# nat44 add load-balancing static mapping protocol tcp external 1.2.3.4:80 local 10.100.10.10:8080 probability 80 local 10.100.10.20:8080 probability 20
    2159             :  * @cliexend
    2160             : ?*/
    2161       62935 : VLIB_CLI_COMMAND (add_lb_static_mapping_command, static) = {
    2162             :   .path = "nat44 add load-balancing static mapping",
    2163             :   .function = add_lb_static_mapping_command_fn,
    2164             :   .short_help =
    2165             :     "nat44 add load-balancing static mapping protocol tcp|udp "
    2166             :     "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
    2167             :     "probability <n> [twice-nat|self-twice-nat] [out2in-only] "
    2168             :     "[affinity <timeout-seconds>] [del]",
    2169             : };
    2170             : 
    2171             : /*?
    2172             :  * @cliexpar
    2173             :  * @cliexstart{nat44 add load-balancing static mapping}
    2174             :  * Modify service load balancing using NAT44
    2175             :  * To add new back-end server 10.100.10.30:8080 for service load balancing
    2176             :  * static mapping with external IP address 1.2.3.4 and TCP port 80 use:
    2177             :  *  vpp# nat44 add load-balancing back-end protocol tcp external 1.2.3.4:80 local 10.100.10.30:8080 probability 25
    2178             :  * @cliexend
    2179             : ?*/
    2180       62935 : VLIB_CLI_COMMAND (add_lb_backend_command, static) = {
    2181             :   .path = "nat44 add load-balancing back-end",
    2182             :   .function = add_lb_backend_command_fn,
    2183             :   .short_help =
    2184             :     "nat44 add load-balancing back-end protocol tcp|udp "
    2185             :     "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
    2186             :     "probability <n> [del]",
    2187             : };
    2188             : 
    2189             : /*?
    2190             :  * @cliexpar
    2191             :  * @cliexstart{show nat44 static mappings}
    2192             :  * Show NAT44 static mappings.
    2193             :  * vpp# show nat44 static mappings
    2194             :  * NAT44 static mappings:
    2195             :  *  local 10.0.0.3 external 4.4.4.4 vrf 0
    2196             :  *  tcp local 192.168.0.4:6303 external 4.4.4.3:3606 vrf 0
    2197             :  *  tcp vrf 0 external 1.2.3.4:80  out2in-only
    2198             :  *   local 10.100.10.10:8080 probability 80
    2199             :  *   local 10.100.10.20:8080 probability 20
    2200             :  *  tcp local 10.100.3.8:8080 external 169.10.10.1:80 vrf 0 twice-nat
    2201             :  *  tcp local 10.0.0.10:3603 external GigabitEthernet0/a/0:6306 vrf 10
    2202             :  * @cliexend
    2203             : ?*/
    2204       62935 : VLIB_CLI_COMMAND (nat44_show_static_mappings_command, static) = {
    2205             :   .path = "show nat44 static mappings",
    2206             :   .short_help = "show nat44 static mappings",
    2207             :   .function = nat44_show_static_mappings_command_fn,
    2208             : };
    2209             : 
    2210             : /*?
    2211             :  * @cliexpar
    2212             :  * @cliexstart{nat44 add interface address}
    2213             :  * Use NAT44 pool address from specific interfce
    2214             :  * To add NAT44 pool address from specific interface use:
    2215             :  *  vpp# nat44 add interface address GigabitEthernet0/8/0
    2216             :  * @cliexend
    2217             : ?*/
    2218       62935 : VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = {
    2219             :   .path = "nat44 add interface address",
    2220             :   .function = snat_add_interface_address_command_fn,
    2221             :   .short_help = "nat44 add interface address <interface> [twice-nat] [del]",
    2222             : };
    2223             : 
    2224             : /*?
    2225             :  * @cliexpar
    2226             :  * @cliexstart{nat44 vrf table}
    2227             :  * Add empty inter VRF routing table
    2228             :  *  vpp# nat44 vrf table add 10
    2229             :  * @cliexend
    2230             : ?*/
    2231       62935 : VLIB_CLI_COMMAND (nat44_ed_add_del_vrf_table_command, static) = {
    2232             :   .path = "nat44 vrf table",
    2233             :   .short_help = "nat44 vrf table [add|del] <vrf-id>",
    2234             :   .function = nat44_ed_add_del_vrf_table_command_fn,
    2235             : };
    2236             : 
    2237             : /*?
    2238             :  * @cliexpar
    2239             :  * @cliexstart{nat44 vrf route}
    2240             :  * Add inter VRF route record to VRF routing table
    2241             :  *  vpp# nat44 vrf route add table 10 20
    2242             :  * @cliexend
    2243             : ?*/
    2244       62935 : VLIB_CLI_COMMAND (nat44_ed_add_del_vrf_route_command, static) = {
    2245             :   .path = "nat44 vrf route",
    2246             :   .short_help = "nat44 vrf route [add|del] table <vrf-id> <vrf-id>",
    2247             :   .function = nat44_ed_add_del_vrf_route_command_fn,
    2248             : };
    2249             : 
    2250             : /*?
    2251             :  * @cliexpar
    2252             :  * @cliexstart{show nat44 vrf tables}
    2253             :  * Show inter VRF route tables
    2254             :  *  vpp# show nat44 vrf tables
    2255             :  * @cliexend
    2256             : ?*/
    2257       62935 : VLIB_CLI_COMMAND (nat44_ed_show_vrf_tables_command, static) = {
    2258             :   .path = "show nat44 vrf tables",
    2259             :   .short_help = "show nat44 vrf tables",
    2260             :   .function = nat44_ed_show_vrf_tables_command_fn,
    2261             : };
    2262             : 
    2263             : /*?
    2264             :  * @cliexpar
    2265             :  * @cliexstart{show nat44 interface address}
    2266             :  * Show NAT44 pool address interfaces
    2267             :  * vpp# show nat44 interface address
    2268             :  * NAT44 pool address interfaces:
    2269             :  *  GigabitEthernet0/a/0
    2270             :  * NAT44 twice-nat pool address interfaces:
    2271             :  *  GigabitEthernet0/8/0
    2272             :  * @cliexend
    2273             : ?*/
    2274       62935 : VLIB_CLI_COMMAND (nat44_show_interface_address_command, static) = {
    2275             :   .path = "show nat44 interface address",
    2276             :   .short_help = "show nat44 interface address",
    2277             :   .function = nat44_show_interface_address_command_fn,
    2278             : };
    2279             : 
    2280             : /*?
    2281             :  * @cliexpar
    2282             :  * @cliexstart{show nat44 sessions}
    2283             :  * Show NAT44 sessions.
    2284             :  * @cliexend
    2285             : ?*/
    2286       62935 : VLIB_CLI_COMMAND (nat44_show_sessions_command, static) = {
    2287             :   .path = "show nat44 sessions",
    2288             :   .short_help = "show nat44 sessions [filter {i2o | o2i} {saddr <ip4-addr> "
    2289             :                 "| sport <n> | daddr <ip4-addr> | dport <n> | proto <proto>} "
    2290             :                 "[filter .. [..]]]",
    2291             :   .function = nat44_show_sessions_command_fn,
    2292             : };
    2293             : 
    2294             : /*?
    2295             :  * @cliexpar
    2296             :  * @cliexstart{set nat44 session limit}
    2297             :  * Set NAT44 session limit.
    2298             :  * @cliexend
    2299             : ?*/
    2300       62935 : VLIB_CLI_COMMAND (nat44_set_session_limit_command, static) = {
    2301             :   .path = "set nat44 session limit",
    2302             :   .short_help = "set nat44 session limit <limit> [vrf <table-id>]",
    2303             :   .function = nat44_set_session_limit_command_fn,
    2304             : };
    2305             : 
    2306             : /*?
    2307             :  * @cliexpar
    2308             :  * @cliexstart{nat44 del session}
    2309             :  * To administratively delete NAT44 session by inside address and port use:
    2310             :  *  vpp# nat44 del session in 10.0.0.3:6303 tcp
    2311             :  * To administratively delete NAT44 session by outside address and port use:
    2312             :  *  vpp# nat44 del session out 1.0.0.3:6033 udp
    2313             :  * @cliexend
    2314             : ?*/
    2315       62935 : VLIB_CLI_COMMAND (nat44_del_session_command, static) = {
    2316             :     .path = "nat44 del session",
    2317             :     .short_help = "nat44 del session in|out <addr>:<port> tcp|udp|icmp [vrf <id>] [external-host <addr>:<port>]",
    2318             :     .function = nat44_del_session_command_fn,
    2319             : };
    2320             : 
    2321             : /*?
    2322             :  * @cliexpar
    2323             :  * @cliexstart{nat44 forwarding}
    2324             :  * Enable or disable forwarding
    2325             :  * Forward packets which don't match existing translation
    2326             :  * or static mapping instead of dropping them.
    2327             :  * To enable forwarding, use:
    2328             :  *  vpp# nat44 forwarding enable
    2329             :  * To disable forwarding, use:
    2330             :  *  vpp# nat44 forwarding disable
    2331             :  * @cliexend
    2332             : ?*/
    2333       62935 : VLIB_CLI_COMMAND (snat_forwarding_set_command, static) = {
    2334             :   .path = "nat44 forwarding",
    2335             :   .short_help = "nat44 forwarding enable|disable",
    2336             :   .function = snat_forwarding_set_command_fn,
    2337             : };
    2338             : 
    2339             : /*
    2340             :  * fd.io coding-style-patch-verification: ON
    2341             :  *
    2342             :  * Local Variables:
    2343             :  * eval: (c-set-style "gnu")
    2344             :  * End:
    2345             :  */

Generated by: LCOV version 1.14