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 948 6.1 %
Date: 2023-07-05 22:20:52 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 :           local.port = (u16) l_port;
    1062           0 :           local.probability = (u8) probability;
    1063           0 :           vec_add1 (locals, local);
    1064             :         }
    1065           0 :       else if (unformat (line_input, "local %U:%u vrf %u probability %u",
    1066             :                          unformat_ip4_address, &l_addr, &l_port, &vrf_id,
    1067             :                          &probability))
    1068             :         {
    1069           0 :           clib_memset (&local, 0, sizeof (local));
    1070           0 :           local.addr = l_addr;
    1071           0 :           local.port = (u16) l_port;
    1072           0 :           local.probability = (u8) probability;
    1073           0 :           local.vrf_id = vrf_id;
    1074           0 :           vec_add1 (locals, local);
    1075             :         }
    1076           0 :       else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
    1077             :                          &e_addr, &e_port))
    1078             :         ;
    1079           0 :       else if (unformat (line_input, "protocol %U", unformat_ip_protocol,
    1080             :                          &proto))
    1081             :         {
    1082           0 :           proto_set = 1;
    1083             :         }
    1084           0 :       else if (unformat (line_input, "twice-nat"))
    1085             :         {
    1086           0 :           flags |= NAT_SM_FLAG_TWICE_NAT;
    1087             :         }
    1088           0 :       else if (unformat (line_input, "self-twice-nat"))
    1089             :         {
    1090           0 :           flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
    1091             :         }
    1092           0 :       else if (unformat (line_input, "out2in-only"))
    1093             :         {
    1094           0 :           flags |= NAT_SM_FLAG_OUT2IN_ONLY;
    1095             :         }
    1096           0 :       else if (unformat (line_input, "del"))
    1097             :         {
    1098           0 :           is_add = 0;
    1099             :         }
    1100           0 :       else if (unformat (line_input, "affinity %u", &affinity))
    1101             :         ;
    1102             :       else
    1103             :         {
    1104           0 :           error = clib_error_return (0, "unknown input: '%U'",
    1105             :                                      format_unformat_error, line_input);
    1106           0 :           goto done;
    1107             :         }
    1108             :     }
    1109             : 
    1110           0 :   if (vec_len (locals) < 2)
    1111             :     {
    1112           0 :       error = clib_error_return (0, "at least two local must be set");
    1113           0 :       goto done;
    1114             :     }
    1115             : 
    1116           0 :   if (!proto_set)
    1117             :     {
    1118           0 :       error = clib_error_return (0, "missing protocol");
    1119           0 :       goto done;
    1120             :     }
    1121             : 
    1122           0 :   if (is_add)
    1123             :     {
    1124           0 :       rv = nat44_ed_add_lb_static_mapping (e_addr, (u16) e_port, proto, locals,
    1125             :                                            flags, 0, affinity);
    1126             :     }
    1127             :   else
    1128             :     {
    1129           0 :       rv = nat44_ed_del_lb_static_mapping (e_addr, (u16) e_port, proto, flags);
    1130             :     }
    1131             : 
    1132           0 :   switch (rv)
    1133             :     {
    1134           0 :     case VNET_API_ERROR_INVALID_VALUE:
    1135           0 :       error = clib_error_return (0, "External port already in use.");
    1136           0 :       goto done;
    1137           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
    1138           0 :       if (is_add)
    1139           0 :         error = clib_error_return (0, "External address must be allocated.");
    1140             :       else
    1141           0 :         error = clib_error_return (0, "Mapping not exist.");
    1142           0 :       goto done;
    1143           0 :     case VNET_API_ERROR_VALUE_EXIST:
    1144           0 :       error = clib_error_return (0, "Mapping already exist.");
    1145           0 :       goto done;
    1146           0 :     default:
    1147           0 :       break;
    1148             :     }
    1149             : 
    1150           0 : done:
    1151           0 :   unformat_free (line_input);
    1152           0 :   vec_free (locals);
    1153             : 
    1154           0 :   return error;
    1155             : }
    1156             : 
    1157             : static clib_error_t *
    1158           0 : add_lb_backend_command_fn (vlib_main_t * vm,
    1159             :                            unformat_input_t * input, vlib_cli_command_t * cmd)
    1160             : {
    1161           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1162           0 :   clib_error_t *error = 0;
    1163             :   ip4_address_t l_addr, e_addr;
    1164           0 :   u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0;
    1165           0 :   int is_add = 1;
    1166             :   int rv;
    1167             :   ip_protocol_t proto;
    1168           0 :   u8 proto_set = 0;
    1169             : 
    1170           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1171           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1172             : 
    1173           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1174             :     {
    1175           0 :       if (unformat (line_input, "local %U:%u probability %u",
    1176             :                     unformat_ip4_address, &l_addr, &l_port, &probability))
    1177             :         ;
    1178           0 :       else if (unformat (line_input, "local %U:%u vrf %u probability %u",
    1179             :                          unformat_ip4_address, &l_addr, &l_port, &vrf_id,
    1180             :                          &probability))
    1181             :         ;
    1182           0 :       else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
    1183             :                          &e_addr, &e_port))
    1184             :         ;
    1185           0 :       else if (unformat (line_input, "protocol %U", unformat_ip_protocol,
    1186             :                          &proto))
    1187           0 :         proto_set = 1;
    1188           0 :       else if (unformat (line_input, "del"))
    1189           0 :         is_add = 0;
    1190             :       else
    1191             :         {
    1192           0 :           error = clib_error_return (0, "unknown input: '%U'",
    1193             :                                      format_unformat_error, line_input);
    1194           0 :           goto done;
    1195             :         }
    1196             :     }
    1197             : 
    1198           0 :   if (!l_port || !e_port)
    1199             :     {
    1200           0 :       error = clib_error_return (0, "local or external must be set");
    1201           0 :       goto done;
    1202             :     }
    1203             : 
    1204           0 :   if (!proto_set)
    1205             :     {
    1206           0 :       error = clib_error_return (0, "missing protocol");
    1207           0 :       goto done;
    1208             :     }
    1209             : 
    1210           0 :   rv = nat44_ed_add_del_lb_static_mapping_local (
    1211           0 :     e_addr, (u16) e_port, l_addr, l_port, proto, vrf_id, probability, is_add);
    1212             : 
    1213           0 :   switch (rv)
    1214             :     {
    1215           0 :     case VNET_API_ERROR_INVALID_VALUE:
    1216           0 :       error = clib_error_return (0, "External is not load-balancing static "
    1217             :                                  "mapping.");
    1218           0 :       goto done;
    1219           0 :     case VNET_API_ERROR_NO_SUCH_ENTRY:
    1220           0 :       error = clib_error_return (0, "Mapping or back-end not exist.");
    1221           0 :       goto done;
    1222           0 :     case VNET_API_ERROR_VALUE_EXIST:
    1223           0 :       error = clib_error_return (0, "Back-end already exist.");
    1224           0 :       goto done;
    1225           0 :     case VNET_API_ERROR_UNSPECIFIED:
    1226           0 :       error = clib_error_return (0, "At least two back-ends must remain");
    1227           0 :       goto done;
    1228           0 :     default:
    1229           0 :       break;
    1230             :     }
    1231             : 
    1232           0 : done:
    1233           0 :   unformat_free (line_input);
    1234             : 
    1235           0 :   return error;
    1236             : }
    1237             : 
    1238             : static clib_error_t *
    1239           0 : nat44_show_static_mappings_command_fn (vlib_main_t * vm,
    1240             :                                        unformat_input_t * input,
    1241             :                                        vlib_cli_command_t * cmd)
    1242             : {
    1243           0 :   snat_main_t *sm = &snat_main;
    1244             :   snat_static_mapping_t *m;
    1245             :   snat_static_mapping_resolve_t *rp;
    1246             : 
    1247           0 :   vlib_cli_output (vm, "NAT44 static mappings:");
    1248           0 :   pool_foreach (m, sm->static_mappings)
    1249             :    {
    1250           0 :     vlib_cli_output (vm, " %U", format_snat_static_mapping, m);
    1251             :   }
    1252           0 :   vec_foreach (rp, sm->sm_to_resolve)
    1253           0 :     vlib_cli_output (vm, " %U", format_snat_static_map_to_resolve, rp);
    1254             : 
    1255           0 :   return 0;
    1256             : }
    1257             : 
    1258             : static clib_error_t *
    1259           0 : snat_add_interface_address_command_fn (vlib_main_t * vm,
    1260             :                                        unformat_input_t * input,
    1261             :                                        vlib_cli_command_t * cmd)
    1262             : {
    1263           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1264           0 :   vnet_main_t *vnm = vnet_get_main ();
    1265           0 :   clib_error_t *error = 0;
    1266           0 :   int rv, is_del = 0;
    1267           0 :   u8 twice_nat = 0;
    1268             :   u32 sw_if_index;
    1269             : 
    1270           0 :   sw_if_index = ~0;
    1271             : 
    1272           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1273           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1274             : 
    1275           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1276             :     {
    1277           0 :       if (unformat (line_input, "%U", unformat_vnet_sw_interface, vnm,
    1278             :                     &sw_if_index))
    1279             :         ;
    1280           0 :       else if (unformat (line_input, "twice-nat"))
    1281             :         {
    1282           0 :           twice_nat = 1;
    1283             :         }
    1284           0 :       else if (unformat (line_input, "del"))
    1285             :         {
    1286           0 :           is_del = 1;
    1287             :         }
    1288             :       else
    1289             :         {
    1290           0 :           error = clib_error_return (0, "unknown input '%U'",
    1291             :                                      format_unformat_error, line_input);
    1292           0 :           goto done;
    1293             :         }
    1294             :     }
    1295             : 
    1296           0 :   if (is_del)
    1297             :     {
    1298           0 :       rv = nat44_ed_del_interface_address (sw_if_index, twice_nat);
    1299             :     }
    1300             :   else
    1301             :     {
    1302           0 :       rv = nat44_ed_add_interface_address (sw_if_index, twice_nat);
    1303             :     }
    1304             : 
    1305           0 :   if (0 != rv)
    1306             :     {
    1307             :       error =
    1308           0 :         clib_error_return (0, "%s %U address failed", is_del ? "del" : "add",
    1309             :                            format_vnet_sw_if_index_name, vnm, sw_if_index);
    1310           0 :       goto done;
    1311             :     }
    1312             : 
    1313           0 : done:
    1314           0 :   unformat_free (line_input);
    1315             : 
    1316           0 :   return error;
    1317             : }
    1318             : 
    1319             : static clib_error_t *
    1320           0 : nat44_ed_add_del_vrf_table_command_fn (vlib_main_t *vm,
    1321             :                                        unformat_input_t *input,
    1322             :                                        vlib_cli_command_t *cmd)
    1323             : {
    1324           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1325           0 :   clib_error_t *error = 0;
    1326           0 :   bool is_add = true, not_set = true;
    1327           0 :   u32 vrf_id = ~0;
    1328             :   int rv;
    1329             : 
    1330           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1331           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1332             : 
    1333           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1334             :     {
    1335           0 :       if (unformat (line_input, "%u", &vrf_id))
    1336             :         ;
    1337           0 :       else if (not_set)
    1338             :         {
    1339           0 :           if (unformat (line_input, "add"))
    1340             :             {
    1341           0 :               is_add = true;
    1342             :             }
    1343           0 :           else if (unformat (line_input, "del"))
    1344             :             {
    1345           0 :               is_add = false;
    1346             :             }
    1347           0 :           not_set = false;
    1348             :         }
    1349             :       else
    1350             :         {
    1351           0 :           error = clib_error_return (0, "unknown input '%U'",
    1352             :                                      format_unformat_error, line_input);
    1353           0 :           goto done;
    1354             :         }
    1355             :     }
    1356             : 
    1357           0 :   if (not_set)
    1358             :     {
    1359           0 :       error = clib_error_return (0, "missing required parameter");
    1360           0 :       goto done;
    1361             :     }
    1362             : 
    1363           0 :   if (~0 == vrf_id)
    1364             :     {
    1365           0 :       error = clib_error_return (0, "missing vrf id");
    1366           0 :       goto done;
    1367             :     }
    1368             : 
    1369           0 :   rv = nat44_ed_add_del_vrf_table (vrf_id, is_add);
    1370           0 :   if (rv)
    1371             :     {
    1372           0 :       error = clib_error_return (0, "%s vrf table returned %d",
    1373             :                                  is_add ? "add" : "del", rv);
    1374             :     }
    1375             : 
    1376           0 : done:
    1377           0 :   unformat_free (line_input);
    1378             : 
    1379           0 :   return error;
    1380             : }
    1381             : 
    1382             : static clib_error_t *
    1383           0 : nat44_ed_add_del_vrf_route_command_fn (vlib_main_t *vm,
    1384             :                                        unformat_input_t *input,
    1385             :                                        vlib_cli_command_t *cmd)
    1386             : {
    1387           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1388           0 :   clib_error_t *error = 0;
    1389           0 :   bool is_add = true, not_set = true;
    1390           0 :   u32 vrf_id = ~0, table_vrf_id = ~0;
    1391             :   int rv;
    1392             : 
    1393           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1394           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1395             : 
    1396           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1397             :     {
    1398           0 :       if (unformat (line_input, "table %u", &table_vrf_id))
    1399             :         ;
    1400           0 :       else if (unformat (line_input, "%u", &vrf_id))
    1401             :         ;
    1402           0 :       else if (not_set)
    1403             :         {
    1404           0 :           if (unformat (line_input, "add"))
    1405             :             {
    1406           0 :               is_add = true;
    1407             :             }
    1408           0 :           else if (unformat (line_input, "del"))
    1409             :             {
    1410           0 :               is_add = false;
    1411             :             }
    1412           0 :           not_set = false;
    1413             :         }
    1414             :       else
    1415             :         {
    1416           0 :           error = clib_error_return (0, "unknown input '%U'",
    1417             :                                      format_unformat_error, line_input);
    1418           0 :           goto done;
    1419             :         }
    1420             :     }
    1421             : 
    1422           0 :   if (not_set)
    1423             :     {
    1424           0 :       error = clib_error_return (0, "missing required parameter");
    1425           0 :       goto done;
    1426             :     }
    1427             : 
    1428           0 :   if ((~0 == vrf_id) || (~0 == table_vrf_id))
    1429             :     {
    1430           0 :       error = clib_error_return (0, "missing vrf id");
    1431           0 :       goto done;
    1432             :     }
    1433             : 
    1434           0 :   rv = nat44_ed_add_del_vrf_route (table_vrf_id, vrf_id, is_add);
    1435           0 :   if (rv)
    1436             :     {
    1437           0 :       error = clib_error_return (0, "%s vrf table returned %d",
    1438             :                                  is_add ? "add" : "del", rv);
    1439             :     }
    1440             : 
    1441           0 : done:
    1442           0 :   unformat_free (line_input);
    1443             : 
    1444           0 :   return error;
    1445             : }
    1446             : 
    1447             : static clib_error_t *
    1448           0 : nat44_ed_show_vrf_tables_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1449             :                                      vlib_cli_command_t *cmd)
    1450             : {
    1451           0 :   snat_main_t *sm = &snat_main;
    1452             :   vrf_table_t *t;
    1453             :   vrf_route_t *r;
    1454           0 :   int i = 0;
    1455             : 
    1456           0 :   pool_foreach (t, sm->vrf_tables)
    1457             :     {
    1458           0 :       vlib_cli_output (vm, "table %u:", t->table_vrf_id);
    1459           0 :       pool_foreach (r, t->routes)
    1460             :         {
    1461           0 :           vlib_cli_output (vm, "[%u] vrf-id %u", i, r->vrf_id);
    1462           0 :           i++;
    1463             :         }
    1464             :     }
    1465             : 
    1466           0 :   return 0;
    1467             : }
    1468             : 
    1469             : static clib_error_t *
    1470           0 : nat44_show_interface_address_command_fn (vlib_main_t * vm,
    1471             :                                          unformat_input_t * input,
    1472             :                                          vlib_cli_command_t * cmd)
    1473             : {
    1474           0 :   snat_main_t *sm = &snat_main;
    1475           0 :   vnet_main_t *vnm = vnet_get_main ();
    1476             :   snat_address_resolve_t *ap;
    1477             : 
    1478           0 :   vlib_cli_output (vm, "NAT44 pool address interfaces:");
    1479           0 :   vec_foreach (ap, sm->addr_to_resolve)
    1480             :     {
    1481           0 :       vlib_cli_output (vm, " %U%s", format_vnet_sw_if_index_name, vnm,
    1482           0 :                        ap->sw_if_index, ap->is_twice_nat ? " twice-nat" : "");
    1483             :     }
    1484           0 :   return 0;
    1485             : }
    1486             : 
    1487             : static clib_error_t *
    1488          12 : nat44_show_sessions_command_fn (vlib_main_t * vm, unformat_input_t * input,
    1489             :                                 vlib_cli_command_t * cmd)
    1490             : {
    1491          12 :   unformat_input_t _line_input, *line_input = &_line_input;
    1492          12 :   clib_error_t *error = 0;
    1493             :   snat_main_per_thread_data_t *tsm;
    1494          12 :   snat_main_t *sm = &snat_main;
    1495             :   ip4_address_t i2o_sa, i2o_da, o2i_sa, o2i_da;
    1496          12 :   u8 filter_i2o_sa = 0, filter_i2o_da = 0;
    1497          12 :   u8 filter_o2i_sa = 0, filter_o2i_da = 0;
    1498             :   u16 i2o_sp, i2o_dp, o2i_sp, o2i_dp;
    1499          12 :   u8 filter_i2o_sp = 0, filter_i2o_dp = 0;
    1500          12 :   u8 filter_o2i_sp = 0, filter_o2i_dp = 0;
    1501             :   ip_protocol_t proto;
    1502          12 :   u8 filter_proto = 0;
    1503          12 :   u8 had_input = 1, filtering = 0;
    1504          12 :   int i = 0, showed_sessions;
    1505             : 
    1506          12 :   if (!unformat_user (input, unformat_line_input, line_input))
    1507             :     {
    1508          12 :       had_input = 0;
    1509          12 :       goto print;
    1510             :     }
    1511             : 
    1512           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1513             :     {
    1514           0 :       if (unformat (line_input, "filter i2o saddr %U", unformat_ip4_address,
    1515             :                     &i2o_sa))
    1516           0 :         filter_i2o_sa = filtering = 1;
    1517           0 :       else if (unformat (line_input, "filter i2o daddr %U",
    1518             :                          unformat_ip4_address, &i2o_da))
    1519           0 :         filter_i2o_da = filtering = 1;
    1520           0 :       else if (unformat (line_input, "filter o2i saddr %U",
    1521             :                          unformat_ip4_address, &o2i_sa))
    1522           0 :         filter_o2i_sa = filtering = 1;
    1523           0 :       else if (unformat (line_input, "filter o2i daddr %U",
    1524             :                          unformat_ip4_address, &o2i_da))
    1525           0 :         filter_o2i_da = filtering = 1;
    1526           0 :       else if (unformat (line_input, "filter i2o sport %u", &i2o_sp))
    1527           0 :         filter_i2o_sp = filtering = 1;
    1528           0 :       else if (unformat (line_input, "filter i2o dport %u", &i2o_dp))
    1529           0 :         filter_i2o_dp = filtering = 1;
    1530           0 :       else if (unformat (line_input, "filter o2i sport %u", &o2i_sp))
    1531           0 :         filter_o2i_sp = filtering = 1;
    1532           0 :       else if (unformat (line_input, "filter o2i dport %u", &o2i_dp))
    1533           0 :         filter_o2i_dp = filtering = 1;
    1534           0 :       else if (unformat (line_input, "filter i2o proto %U",
    1535             :                          unformat_ip_protocol, &proto))
    1536           0 :         filter_proto = filtering = 1;
    1537           0 :       else if (unformat (line_input, "filter o2i proto %U",
    1538             :                          unformat_ip_protocol, &proto))
    1539           0 :         filter_proto = filtering = 1;
    1540             :       else
    1541             :         {
    1542           0 :           error = clib_error_return (0, "unknown input '%U'",
    1543             :                                      format_unformat_error, line_input);
    1544           0 :           goto done;
    1545             :         }
    1546             :     }
    1547             : 
    1548           0 : print:
    1549          12 :   vlib_cli_output (vm, "NAT44 ED sessions:");
    1550             : 
    1551          52 :   vec_foreach_index (i, sm->per_thread_data)
    1552             :     {
    1553          40 :       tsm = vec_elt_at_index (sm->per_thread_data, i);
    1554             : 
    1555          80 :       vlib_cli_output (vm, "-------- thread %d %s: %d sessions --------\n",
    1556          40 :                        i, vlib_worker_threads[i].name,
    1557          40 :                        pool_elts (tsm->sessions));
    1558             : 
    1559          40 :       showed_sessions = 0;
    1560             :       snat_session_t *s;
    1561       13357 :       pool_foreach (s, tsm->sessions)
    1562             :         {
    1563       13317 :           if (filtering)
    1564             :             {
    1565           0 :               if (filter_i2o_sa && i2o_sa.as_u32 != s->i2o.match.saddr.as_u32)
    1566           0 :                 continue;
    1567           0 :               if (filter_i2o_da && i2o_da.as_u32 != s->i2o.match.daddr.as_u32)
    1568           0 :                 continue;
    1569           0 :               if (filter_o2i_sa && o2i_sa.as_u32 != s->o2i.match.saddr.as_u32)
    1570           0 :                 continue;
    1571           0 :               if (filter_o2i_da && o2i_da.as_u32 != s->o2i.match.daddr.as_u32)
    1572           0 :                 continue;
    1573           0 :               if (filter_i2o_sp &&
    1574           0 :                   i2o_sp != clib_net_to_host_u16 (s->i2o.match.sport))
    1575           0 :                 continue;
    1576           0 :               if (filter_i2o_dp &&
    1577           0 :                   i2o_dp != clib_net_to_host_u16 (s->i2o.match.dport))
    1578           0 :                 continue;
    1579           0 :               if (filter_o2i_sp &&
    1580           0 :                   o2i_sp != clib_net_to_host_u16 (s->o2i.match.sport))
    1581           0 :                 continue;
    1582           0 :               if (filter_o2i_dp &&
    1583           0 :                   o2i_dp != clib_net_to_host_u16 (s->o2i.match.dport))
    1584           0 :                 continue;
    1585           0 :               if (filter_proto && proto != s->proto)
    1586           0 :                 continue;
    1587           0 :               showed_sessions++;
    1588             :             }
    1589       13317 :           vlib_cli_output (vm, "  %U\n", format_snat_session, sm, tsm, s,
    1590             :                            vlib_time_now (vm));
    1591             :         }
    1592          40 :       if (filtering)
    1593             :         {
    1594           0 :           vlib_cli_output (vm,
    1595             :                            "Showed: %d, Filtered: %d of total %d "
    1596             :                            "sessions of thread %d\n\n",
    1597             :                            showed_sessions,
    1598           0 :                            pool_elts (tsm->sessions) - showed_sessions,
    1599           0 :                            pool_elts (tsm->sessions), i);
    1600             :         }
    1601             :     }
    1602             : 
    1603          12 : done:
    1604          12 :   if (had_input)
    1605           0 :     unformat_free (line_input);
    1606          12 :   return error;
    1607             : }
    1608             : 
    1609             : static clib_error_t *
    1610           0 : nat44_set_session_limit_command_fn (vlib_main_t * vm,
    1611             :                                     unformat_input_t * input,
    1612             :                                     vlib_cli_command_t * cmd)
    1613             : {
    1614           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1615           0 :   clib_error_t *error = 0;
    1616             : 
    1617           0 :   u32 session_limit = 0, vrf_id = 0;
    1618             : 
    1619           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1620           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1621             : 
    1622           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1623             :     {
    1624           0 :       if (unformat (line_input, "%u", &session_limit))
    1625             :         ;
    1626           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
    1627             :         ;
    1628             :       else
    1629             :         {
    1630           0 :           error = clib_error_return (0, "unknown input '%U'",
    1631             :                                      format_unformat_error, line_input);
    1632           0 :           goto done;
    1633             :         }
    1634             :     }
    1635             : 
    1636           0 :   if (!session_limit)
    1637           0 :     error = clib_error_return (0, "missing value of session limit");
    1638           0 :   else if (nat44_update_session_limit (session_limit, vrf_id))
    1639           0 :     error = clib_error_return (0, "nat44_set_session_limit failed");
    1640             : 
    1641           0 : done:
    1642           0 :   unformat_free (line_input);
    1643             : 
    1644           0 :   return error;
    1645             : }
    1646             : 
    1647             : static clib_error_t *
    1648           0 : nat44_del_session_command_fn (vlib_main_t * vm,
    1649             :                               unformat_input_t * input,
    1650             :                               vlib_cli_command_t * cmd)
    1651             : {
    1652           0 :   snat_main_t *sm = &snat_main;
    1653           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1654           0 :   u32 port = 0, eh_port = 0, vrf_id = sm->outside_vrf_id;
    1655           0 :   clib_error_t *error = 0;
    1656             :   ip4_address_t addr, eh_addr;
    1657             :   ip_protocol_t proto;
    1658           0 :   int is_in = 0;
    1659             :   int rv;
    1660             : 
    1661           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1662           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1663             : 
    1664           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1665             :     {
    1666           0 :       if (unformat (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
    1667             :                     unformat_ip_protocol, &proto))
    1668             :         ;
    1669           0 :       else if (unformat (line_input, "in"))
    1670             :         {
    1671           0 :           is_in = 1;
    1672           0 :           vrf_id = sm->inside_vrf_id;
    1673             :         }
    1674           0 :       else if (unformat (line_input, "out"))
    1675             :         {
    1676           0 :           is_in = 0;
    1677           0 :           vrf_id = sm->outside_vrf_id;
    1678             :         }
    1679           0 :       else if (unformat (line_input, "vrf %u", &vrf_id))
    1680             :         ;
    1681           0 :       else if (unformat (line_input, "external-host %U:%u",
    1682             :                          unformat_ip4_address, &eh_addr, &eh_port))
    1683             :         ;
    1684             :       else
    1685             :         {
    1686           0 :           error = clib_error_return (0, "unknown input '%U'",
    1687             :                                      format_unformat_error, line_input);
    1688           0 :           goto done;
    1689             :         }
    1690             :     }
    1691             : 
    1692           0 :   rv = nat44_ed_del_session (sm, &addr, clib_host_to_net_u16 (port), &eh_addr,
    1693           0 :                              clib_host_to_net_u16 (eh_port), proto, vrf_id,
    1694             :                              is_in);
    1695             : 
    1696           0 :   switch (rv)
    1697             :     {
    1698           0 :     case 0:
    1699           0 :       break;
    1700             : 
    1701           0 :     default:
    1702           0 :       error = clib_error_return (0, "nat44_del_session returned %d", rv);
    1703           0 :       goto done;
    1704             :     }
    1705             : 
    1706           0 : done:
    1707           0 :   unformat_free (line_input);
    1708             : 
    1709           0 :   return error;
    1710             : }
    1711             : 
    1712             : static clib_error_t *
    1713           0 : snat_forwarding_set_command_fn (vlib_main_t * vm,
    1714             :                                 unformat_input_t * input,
    1715             :                                 vlib_cli_command_t * cmd)
    1716             : {
    1717           0 :   snat_main_t *sm = &snat_main;
    1718           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1719           0 :   clib_error_t *error = 0;
    1720             : 
    1721           0 :   u8 enable_set = 0, enable = 0;
    1722             : 
    1723           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1724           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1725             : 
    1726           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1727             :     {
    1728           0 :       if (!enable_set)
    1729             :         {
    1730           0 :           enable_set = 1;
    1731           0 :           if (unformat (line_input, "disable"))
    1732             :             ;
    1733           0 :           else if (unformat (line_input, "enable"))
    1734           0 :             enable = 1;
    1735             :         }
    1736             :       else
    1737             :         {
    1738           0 :           error = clib_error_return (0, "unknown input '%U'",
    1739             :                                      format_unformat_error, line_input);
    1740           0 :           goto done;
    1741             :         }
    1742             :     }
    1743             : 
    1744           0 :   if (!enable_set)
    1745           0 :     error = clib_error_return (0, "expected enable | disable");
    1746             :   else
    1747           0 :     sm->forwarding_enabled = enable;
    1748             : 
    1749           0 : done:
    1750           0 :   unformat_free (line_input);
    1751           0 :   return error;
    1752             : }
    1753             : 
    1754             : static clib_error_t *
    1755           0 : set_timeout_command_fn (vlib_main_t * vm,
    1756             :                         unformat_input_t * input, vlib_cli_command_t * cmd)
    1757             : {
    1758           0 :   snat_main_t *sm = &snat_main;
    1759           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1760           0 :   clib_error_t *error = 0;
    1761             : 
    1762           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1763           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1764             : 
    1765           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1766             :     {
    1767           0 :       if (unformat (line_input, "udp %u", &sm->timeouts.udp));
    1768           0 :       else if (unformat (line_input, "tcp-established %u",
    1769             :                          &sm->timeouts.tcp.established));
    1770           0 :       else if (unformat (line_input, "tcp-transitory %u",
    1771             :                          &sm->timeouts.tcp.transitory));
    1772           0 :       else if (unformat (line_input, "icmp %u", &sm->timeouts.icmp));
    1773           0 :       else if (unformat (line_input, "reset"))
    1774           0 :         nat_reset_timeouts (&sm->timeouts);
    1775             :       else
    1776             :         {
    1777           0 :           error = clib_error_return (0, "unknown input '%U'",
    1778             :                                      format_unformat_error, line_input);
    1779           0 :           goto done;
    1780             :         }
    1781             :     }
    1782           0 : done:
    1783           0 :   unformat_free (line_input);
    1784           0 :   return error;
    1785             : }
    1786             : 
    1787             : static clib_error_t *
    1788           0 : nat_show_timeouts_command_fn (vlib_main_t * vm,
    1789             :                               unformat_input_t * input,
    1790             :                               vlib_cli_command_t * cmd)
    1791             : {
    1792           0 :   snat_main_t *sm = &snat_main;
    1793             : 
    1794           0 :   vlib_cli_output (vm, "udp timeout: %dsec", sm->timeouts.udp);
    1795           0 :   vlib_cli_output (vm, "tcp-established timeout: %dsec",
    1796             :                    sm->timeouts.tcp.established);
    1797           0 :   vlib_cli_output (vm, "tcp-transitory timeout: %dsec",
    1798             :                    sm->timeouts.tcp.transitory);
    1799           0 :   vlib_cli_output (vm, "icmp timeout: %dsec", sm->timeouts.icmp);
    1800             : 
    1801           0 :   return 0;
    1802             : }
    1803             : 
    1804             : static clib_error_t *
    1805           0 : set_frame_queue_nelts_command_fn (vlib_main_t *vm, unformat_input_t *input,
    1806             :                                   vlib_cli_command_t *cmd)
    1807             : {
    1808           0 :   unformat_input_t _line_input, *line_input = &_line_input;
    1809           0 :   clib_error_t *error = 0;
    1810           0 :   u32 frame_queue_nelts = 0;
    1811             : 
    1812           0 :   if (!unformat_user (input, unformat_line_input, line_input))
    1813           0 :     return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
    1814             : 
    1815           0 :   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    1816             :     {
    1817           0 :       if (unformat (line_input, "%u", &frame_queue_nelts))
    1818             :         ;
    1819             :       else
    1820             :         {
    1821           0 :           error = clib_error_return (0, "unknown input '%U'",
    1822             :                                      format_unformat_error, line_input);
    1823           0 :           goto done;
    1824             :         }
    1825             :     }
    1826           0 :   if (!frame_queue_nelts)
    1827             :     {
    1828           0 :       error = clib_error_return (0, "frame_queue_nelts cannot be zero");
    1829           0 :       goto done;
    1830             :     }
    1831           0 :   if (nat44_ed_set_frame_queue_nelts (frame_queue_nelts) != 0)
    1832             :     {
    1833           0 :       error = clib_error_return (0, "snat_set_frame_queue_nelts failed");
    1834           0 :       goto done;
    1835             :     }
    1836           0 : done:
    1837           0 :   unformat_free (line_input);
    1838           0 :   return error;
    1839             : }
    1840             : 
    1841             : /*?
    1842             :  * @cliexpar
    1843             :  * @cliexstart{nat44}
    1844             :  * Enable nat44 plugin
    1845             :  * To enable nat44-ed, use:
    1846             :  *  vpp# nat44 plugin enable
    1847             :  * To disable nat44-ed, use:
    1848             :  *  vpp# nat44 plugin disable
    1849             :  * To set inside-vrf outside-vrf, use:
    1850             :  *  vpp# nat44 plugin enable inside-vrf <id> outside-vrf <id>
    1851             :  * @cliexend
    1852             : ?*/
    1853       56709 : VLIB_CLI_COMMAND (nat44_ed_enable_disable_command, static) = {
    1854             :   .path = "nat44 plugin",
    1855             :   .function = nat44_ed_enable_disable_command_fn,
    1856             :   .short_help =
    1857             :     "nat44 plugin <enable [sessions <max-number>] [inside-vrf <vrf-id>] "
    1858             :     "[outside-vrf <vrf-id>]>|disable",
    1859             : };
    1860             : 
    1861             : /*?
    1862             :  * @cliexpar
    1863             :  * @cliexstart{set snat workers}
    1864             :  * Set NAT workers if 2 or more workers available, use:
    1865             :  *  vpp# set snat workers 0-2,5
    1866             :  * @cliexend
    1867             : ?*/
    1868       56709 : VLIB_CLI_COMMAND (set_workers_command, static) = {
    1869             :   .path = "set nat workers",
    1870             :   .function = set_workers_command_fn,
    1871             :   .short_help = "set nat workers <workers-list>",
    1872             : };
    1873             : 
    1874             : /*?
    1875             :  * @cliexpar
    1876             :  * @cliexstart{show nat workers}
    1877             :  * Show NAT workers.
    1878             :  *  vpp# show nat workers:
    1879             :  *  2 workers
    1880             :  *    vpp_wk_0
    1881             :  *    vpp_wk_1
    1882             :  * @cliexend
    1883             : ?*/
    1884       56709 : VLIB_CLI_COMMAND (nat_show_workers_command, static) = {
    1885             :   .path = "show nat workers",
    1886             :   .short_help = "show nat workers",
    1887             :   .function = nat_show_workers_command_fn,
    1888             : };
    1889             : 
    1890             : /*?
    1891             :  * @cliexpar
    1892             :  * @cliexstart{set nat timeout}
    1893             :  * Set values of timeouts for NAT sessions (in seconds), use:
    1894             :  *  vpp# set nat timeout udp 120 tcp-established 7500 tcp-transitory 250 icmp 90
    1895             :  * To reset default values use:
    1896             :  *  vpp# set nat timeout reset
    1897             :  * @cliexend
    1898             : ?*/
    1899       56709 : VLIB_CLI_COMMAND (set_timeout_command, static) = {
    1900             :   .path = "set nat timeout",
    1901             :   .function = set_timeout_command_fn,
    1902             :   .short_help =
    1903             :     "set nat timeout [udp <sec> | tcp-established <sec> "
    1904             :     "tcp-transitory <sec> | icmp <sec> | reset]",
    1905             : };
    1906             : 
    1907             : /*?
    1908             :  * @cliexpar
    1909             :  * @cliexstart{show nat timeouts}
    1910             :  * Show values of timeouts for NAT sessions.
    1911             :  * vpp# show nat timeouts
    1912             :  * udp timeout: 300sec
    1913             :  * tcp-established timeout: 7440sec
    1914             :  * tcp-transitory timeout: 240sec
    1915             :  * icmp timeout: 60sec
    1916             :  * @cliexend
    1917             : ?*/
    1918       56709 : VLIB_CLI_COMMAND (nat_show_timeouts_command, static) = {
    1919             :   .path = "show nat timeouts",
    1920             :   .short_help = "show nat timeouts",
    1921             :   .function = nat_show_timeouts_command_fn,
    1922             : };
    1923             : 
    1924             : /*?
    1925             :  * @cliexpar
    1926             :  * @cliexstart{set nat frame-queue-nelts}
    1927             :  * Set number of worker handoff frame queue elements.
    1928             :  * @cliexend
    1929             : ?*/
    1930       56709 : VLIB_CLI_COMMAND (set_frame_queue_nelts_command, static) = {
    1931             :   .path = "set nat frame-queue-nelts",
    1932             :   .function = set_frame_queue_nelts_command_fn,
    1933             :   .short_help = "set nat frame-queue-nelts <number>",
    1934             : };
    1935             : 
    1936             : /*?
    1937             :  * @cliexpar
    1938             :  * @cliexstart{nat set logging level}
    1939             :  * To set NAT logging level use:
    1940             :  * Set nat logging level
    1941             :  * @cliexend
    1942             : ?*/
    1943       56709 : VLIB_CLI_COMMAND (snat_set_log_level_command, static) = {
    1944             :   .path = "nat set logging level",
    1945             :   .function = snat_set_log_level_command_fn,
    1946             :   .short_help = "nat set logging level <level>",
    1947             : };
    1948             : 
    1949             : /*?
    1950             :  * @cliexpar
    1951             :  * @cliexstart{snat ipfix logging}
    1952             :  * To enable NAT IPFIX logging use:
    1953             :  *  vpp# nat ipfix logging
    1954             :  * To set IPFIX exporter use:
    1955             :  *  vpp# set ipfix exporter collector 10.10.10.3 src 10.10.10.1
    1956             :  * @cliexend
    1957             : ?*/
    1958       56709 : VLIB_CLI_COMMAND (snat_ipfix_logging_enable_disable_command, static) = {
    1959             :   .path = "nat ipfix logging",
    1960             :   .function = snat_ipfix_logging_enable_disable_command_fn,
    1961             :   .short_help = "nat ipfix logging disable|<enable [domain <domain-id>] "
    1962             :                 "[src-port <port>]>",
    1963             : };
    1964             : 
    1965             : /*?
    1966             :  * @cliexpar
    1967             :  * @cliexstart{nat mss-clamping}
    1968             :  * Set TCP MSS rewriting configuration
    1969             :  * To enable TCP MSS rewriting use:
    1970             :  *  vpp# nat mss-clamping 1452
    1971             :  * To disbale TCP MSS rewriting use:
    1972             :  *  vpp# nat mss-clamping disable
    1973             :  * @cliexend
    1974             : ?*/
    1975       56709 : VLIB_CLI_COMMAND (nat_set_mss_clamping_command, static) = {
    1976             :     .path = "nat mss-clamping",
    1977             :     .short_help = "nat mss-clamping <mss-value>|disable",
    1978             :     .function = nat_set_mss_clamping_command_fn,
    1979             : };
    1980             : 
    1981             : /*?
    1982             :  * @cliexpar
    1983             :  * @cliexstart{show nat mss-clamping}
    1984             :  * Show TCP MSS rewriting configuration
    1985             :  * @cliexend
    1986             : ?*/
    1987       56709 : VLIB_CLI_COMMAND (nat_show_mss_clamping_command, static) = {
    1988             :     .path = "show nat mss-clamping",
    1989             :     .short_help = "show nat mss-clamping",
    1990             :     .function = nat_show_mss_clamping_command_fn,
    1991             : };
    1992             : 
    1993             : /*?
    1994             :  * @cliexpar
    1995             :  * @cliexstart{show nat44 hash tables}
    1996             :  * Show NAT44 hash tables
    1997             :  * @cliexend
    1998             : ?*/
    1999       56709 : VLIB_CLI_COMMAND (nat44_show_hash, static) = {
    2000             :   .path = "show nat44 hash tables",
    2001             :   .short_help = "show nat44 hash tables [detail|verbose]",
    2002             :   .function = nat44_show_hash_command_fn,
    2003             : };
    2004             : 
    2005             : /*?
    2006             :  * @cliexpar
    2007             :  * @cliexstart{nat44 add address}
    2008             :  * Add/delete NAT44 pool address.
    2009             :  * To add NAT44 pool address use:
    2010             :  *  vpp# nat44 add address 172.16.1.3
    2011             :  *  vpp# nat44 add address 172.16.2.2 - 172.16.2.24
    2012             :  * To add NAT44 pool address for specific tenant (identified by VRF id) use:
    2013             :  *  vpp# nat44 add address 172.16.1.3 tenant-vrf 10
    2014             :  * @cliexend
    2015             : ?*/
    2016       56709 : VLIB_CLI_COMMAND (add_address_command, static) = {
    2017             :   .path = "nat44 add address",
    2018             :   .short_help = "nat44 add address <ip4-range-start> [- <ip4-range-end>] "
    2019             :                 "[tenant-vrf <vrf-id>] [twice-nat] [del]",
    2020             :   .function = add_address_command_fn,
    2021             : };
    2022             : 
    2023             : /*?
    2024             :  * @cliexpar
    2025             :  * @cliexstart{show nat44 summary}
    2026             :  * Show NAT44 summary
    2027             :  * vpp# show nat44 summary
    2028             :  * @cliexend
    2029             : ?*/
    2030       56709 : VLIB_CLI_COMMAND (nat44_show_summary_command, static) = {
    2031             :   .path = "show nat44 summary",
    2032             :   .short_help = "show nat44 summary",
    2033             :   .function = nat44_show_summary_command_fn,
    2034             : };
    2035             : 
    2036             : /*?
    2037             :  * @cliexpar
    2038             :  * @cliexstart{show nat44 addresses}
    2039             :  * Show NAT44 pool addresses.
    2040             :  * vpp# show nat44 addresses
    2041             :  * NAT44 pool addresses:
    2042             :  * 172.16.2.2
    2043             :  *   tenant VRF independent
    2044             :  *   10 busy udp ports
    2045             :  *   0 busy tcp ports
    2046             :  *   0 busy icmp ports
    2047             :  * 172.16.1.3
    2048             :  *   tenant VRF: 10
    2049             :  *   0 busy udp ports
    2050             :  *   2 busy tcp ports
    2051             :  *   0 busy icmp ports
    2052             :  * NAT44 twice-nat pool addresses:
    2053             :  * 10.20.30.72
    2054             :  *   tenant VRF independent
    2055             :  *   0 busy udp ports
    2056             :  *   0 busy tcp ports
    2057             :  *   0 busy icmp ports
    2058             :  * @cliexend
    2059             : ?*/
    2060       56709 : VLIB_CLI_COMMAND (nat44_show_addresses_command, static) = {
    2061             :   .path = "show nat44 addresses",
    2062             :   .short_help = "show nat44 addresses",
    2063             :   .function = nat44_show_addresses_command_fn,
    2064             : };
    2065             : 
    2066             : /*?
    2067             :  * @cliexpar
    2068             :  * @cliexstart{set interface nat44}
    2069             :  * Enable/disable NAT44 feature on the interface.
    2070             :  * To enable NAT44 feature with local network interface use:
    2071             :  *  vpp# set interface nat44 in GigabitEthernet0/8/0
    2072             :  * To enable NAT44 feature with external network interface use:
    2073             :  *  vpp# set interface nat44 out GigabitEthernet0/a/0
    2074             :  * @cliexend
    2075             : ?*/
    2076       56709 : VLIB_CLI_COMMAND (set_interface_snat_command, static) = {
    2077             :   .path = "set interface nat44",
    2078             :   .function = snat_feature_command_fn,
    2079             :   .short_help = "set interface nat44 in <intfc> out <intfc> [output-feature] "
    2080             :                 "[del]",
    2081             : };
    2082             : 
    2083             : /*?
    2084             :  * @cliexpar
    2085             :  * @cliexstart{show nat44 interfaces}
    2086             :  * Show interfaces with NAT44 feature.
    2087             :  * vpp# show nat44 interfaces
    2088             :  * NAT44 interfaces:
    2089             :  *  GigabitEthernet0/8/0 in
    2090             :  *  GigabitEthernet0/a/0 out
    2091             :  * @cliexend
    2092             : ?*/
    2093       56709 : VLIB_CLI_COMMAND (nat44_show_interfaces_command, static) = {
    2094             :   .path = "show nat44 interfaces",
    2095             :   .short_help = "show nat44 interfaces",
    2096             :   .function = nat44_show_interfaces_command_fn,
    2097             : };
    2098             : 
    2099             : /*?
    2100             :  * @cliexpar
    2101             :  * @cliexstart{nat44 add static mapping}
    2102             :  * Static mapping allows hosts on the external network to initiate connection
    2103             :  * to to the local network host.
    2104             :  * To create static mapping between local host address 10.0.0.3 port 6303 and
    2105             :  * external address 4.4.4.4 port 3606 for TCP protocol use:
    2106             :  *  vpp# nat44 add static mapping tcp local 10.0.0.3 6303 external 4.4.4.4 3606
    2107             :  * If not runnig "static mapping only" NAT plugin mode use before:
    2108             :  *  vpp# nat44 add address 4.4.4.4
    2109             :  * To create address only static mapping between local and external address use:
    2110             :  *  vpp# nat44 add static mapping local 10.0.0.3 external 4.4.4.4
    2111             :  * To create ICMP static mapping between local and external with ICMP echo
    2112             :  * identifier 10 use:
    2113             :  *  vpp# nat44 add static mapping icmp local 10.0.0.3 10 external 4.4.4.4 10
    2114             :  * To force use of specific pool address, vrf independent
    2115             :  *  vpp# nat44 add static mapping local 10.0.0.2 1234 external 10.0.2.2 1234 twice-nat exact 10.0.1.2
    2116             :  * @cliexend
    2117             : ?*/
    2118       56709 : VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
    2119             :   .path = "nat44 add static mapping",
    2120             :   .function = add_static_mapping_command_fn,
    2121             :   .short_help =
    2122             :     "nat44 add static mapping tcp|udp|icmp local <addr> [<port|icmp-echo-id>] "
    2123             :     "external <addr> [<port|icmp-echo-id>] [vrf <table-id>] [twice-nat|self-twice-nat] "
    2124             :     "[out2in-only] [exact <pool-addr>] [del]",
    2125             : };
    2126             : 
    2127             : /*?
    2128             :  * @cliexpar
    2129             :  * @cliexstart{nat44 add identity mapping}
    2130             :  * Identity mapping translate an IP address to itself.
    2131             :  * To create identity mapping for address 10.0.0.3 port 6303 for TCP protocol
    2132             :  * use:
    2133             :  *  vpp# nat44 add identity mapping 10.0.0.3 tcp 6303
    2134             :  * To create identity mapping for address 10.0.0.3 use:
    2135             :  *  vpp# nat44 add identity mapping 10.0.0.3
    2136             :  * To create identity mapping for DHCP addressed interface use:
    2137             :  *  vpp# nat44 add identity mapping external GigabitEthernet0/a/0 tcp 3606
    2138             :  * @cliexend
    2139             : ?*/
    2140       56709 : VLIB_CLI_COMMAND (add_identity_mapping_command, static) = {
    2141             :   .path = "nat44 add identity mapping",
    2142             :   .function = add_identity_mapping_command_fn,
    2143             :   .short_help = "nat44 add identity mapping <ip4-addr>|external <interface> "
    2144             :     "[<protocol> <port>] [vrf <table-id>] [del]",
    2145             : };
    2146             : 
    2147             : /*?
    2148             :  * @cliexpar
    2149             :  * @cliexstart{nat44 add load-balancing static mapping}
    2150             :  * Service load balancing using NAT44
    2151             :  * To add static mapping with load balancing for service with external IP
    2152             :  * address 1.2.3.4 and TCP port 80 and mapped to 2 local servers
    2153             :  * 10.100.10.10:8080 and 10.100.10.20:8080 with probability 80% resp. 20% use:
    2154             :  *  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
    2155             :  * @cliexend
    2156             : ?*/
    2157       56709 : VLIB_CLI_COMMAND (add_lb_static_mapping_command, static) = {
    2158             :   .path = "nat44 add load-balancing static mapping",
    2159             :   .function = add_lb_static_mapping_command_fn,
    2160             :   .short_help =
    2161             :     "nat44 add load-balancing static mapping protocol tcp|udp "
    2162             :     "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
    2163             :     "probability <n> [twice-nat|self-twice-nat] [out2in-only] "
    2164             :     "[affinity <timeout-seconds>] [del]",
    2165             : };
    2166             : 
    2167             : /*?
    2168             :  * @cliexpar
    2169             :  * @cliexstart{nat44 add load-balancing static mapping}
    2170             :  * Modify service load balancing using NAT44
    2171             :  * To add new back-end server 10.100.10.30:8080 for service load balancing
    2172             :  * static mapping with external IP address 1.2.3.4 and TCP port 80 use:
    2173             :  *  vpp# nat44 add load-balancing back-end protocol tcp external 1.2.3.4:80 local 10.100.10.30:8080 probability 25
    2174             :  * @cliexend
    2175             : ?*/
    2176       56709 : VLIB_CLI_COMMAND (add_lb_backend_command, static) = {
    2177             :   .path = "nat44 add load-balancing back-end",
    2178             :   .function = add_lb_backend_command_fn,
    2179             :   .short_help =
    2180             :     "nat44 add load-balancing back-end protocol tcp|udp "
    2181             :     "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
    2182             :     "probability <n> [del]",
    2183             : };
    2184             : 
    2185             : /*?
    2186             :  * @cliexpar
    2187             :  * @cliexstart{show nat44 static mappings}
    2188             :  * Show NAT44 static mappings.
    2189             :  * vpp# show nat44 static mappings
    2190             :  * NAT44 static mappings:
    2191             :  *  local 10.0.0.3 external 4.4.4.4 vrf 0
    2192             :  *  tcp local 192.168.0.4:6303 external 4.4.4.3:3606 vrf 0
    2193             :  *  tcp vrf 0 external 1.2.3.4:80  out2in-only
    2194             :  *   local 10.100.10.10:8080 probability 80
    2195             :  *   local 10.100.10.20:8080 probability 20
    2196             :  *  tcp local 10.100.3.8:8080 external 169.10.10.1:80 vrf 0 twice-nat
    2197             :  *  tcp local 10.0.0.10:3603 external GigabitEthernet0/a/0:6306 vrf 10
    2198             :  * @cliexend
    2199             : ?*/
    2200       56709 : VLIB_CLI_COMMAND (nat44_show_static_mappings_command, static) = {
    2201             :   .path = "show nat44 static mappings",
    2202             :   .short_help = "show nat44 static mappings",
    2203             :   .function = nat44_show_static_mappings_command_fn,
    2204             : };
    2205             : 
    2206             : /*?
    2207             :  * @cliexpar
    2208             :  * @cliexstart{nat44 add interface address}
    2209             :  * Use NAT44 pool address from specific interfce
    2210             :  * To add NAT44 pool address from specific interface use:
    2211             :  *  vpp# nat44 add interface address GigabitEthernet0/8/0
    2212             :  * @cliexend
    2213             : ?*/
    2214       56709 : VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = {
    2215             :   .path = "nat44 add interface address",
    2216             :   .function = snat_add_interface_address_command_fn,
    2217             :   .short_help = "nat44 add interface address <interface> [twice-nat] [del]",
    2218             : };
    2219             : 
    2220             : /*?
    2221             :  * @cliexpar
    2222             :  * @cliexstart{nat44 vrf table}
    2223             :  * Add empty inter VRF routing table
    2224             :  *  vpp# nat44 vrf table add 10
    2225             :  * @cliexend
    2226             : ?*/
    2227       56709 : VLIB_CLI_COMMAND (nat44_ed_add_del_vrf_table_command, static) = {
    2228             :   .path = "nat44 vrf table",
    2229             :   .short_help = "nat44 vrf table [add|del] <vrf-id>",
    2230             :   .function = nat44_ed_add_del_vrf_table_command_fn,
    2231             : };
    2232             : 
    2233             : /*?
    2234             :  * @cliexpar
    2235             :  * @cliexstart{nat44 vrf route}
    2236             :  * Add inter VRF route record to VRF routing table
    2237             :  *  vpp# nat44 vrf route add table 10 20
    2238             :  * @cliexend
    2239             : ?*/
    2240       56709 : VLIB_CLI_COMMAND (nat44_ed_add_del_vrf_route_command, static) = {
    2241             :   .path = "nat44 vrf route",
    2242             :   .short_help = "nat44 vrf route [add|del] table <vrf-id> <vrf-id>",
    2243             :   .function = nat44_ed_add_del_vrf_route_command_fn,
    2244             : };
    2245             : 
    2246             : /*?
    2247             :  * @cliexpar
    2248             :  * @cliexstart{show nat44 vrf tables}
    2249             :  * Show inter VRF route tables
    2250             :  *  vpp# show nat44 vrf tables
    2251             :  * @cliexend
    2252             : ?*/
    2253       56709 : VLIB_CLI_COMMAND (nat44_ed_show_vrf_tables_command, static) = {
    2254             :   .path = "show nat44 vrf tables",
    2255             :   .short_help = "show nat44 vrf tables",
    2256             :   .function = nat44_ed_show_vrf_tables_command_fn,
    2257             : };
    2258             : 
    2259             : /*?
    2260             :  * @cliexpar
    2261             :  * @cliexstart{show nat44 interface address}
    2262             :  * Show NAT44 pool address interfaces
    2263             :  * vpp# show nat44 interface address
    2264             :  * NAT44 pool address interfaces:
    2265             :  *  GigabitEthernet0/a/0
    2266             :  * NAT44 twice-nat pool address interfaces:
    2267             :  *  GigabitEthernet0/8/0
    2268             :  * @cliexend
    2269             : ?*/
    2270       56709 : VLIB_CLI_COMMAND (nat44_show_interface_address_command, static) = {
    2271             :   .path = "show nat44 interface address",
    2272             :   .short_help = "show nat44 interface address",
    2273             :   .function = nat44_show_interface_address_command_fn,
    2274             : };
    2275             : 
    2276             : /*?
    2277             :  * @cliexpar
    2278             :  * @cliexstart{show nat44 sessions}
    2279             :  * Show NAT44 sessions.
    2280             :  * @cliexend
    2281             : ?*/
    2282       56709 : VLIB_CLI_COMMAND (nat44_show_sessions_command, static) = {
    2283             :   .path = "show nat44 sessions",
    2284             :   .short_help = "show nat44 sessions [filter {i2o | o2i} {saddr <ip4-addr> "
    2285             :                 "| sport <n> | daddr <ip4-addr> | dport <n> | proto <proto>} "
    2286             :                 "[filter .. [..]]]",
    2287             :   .function = nat44_show_sessions_command_fn,
    2288             : };
    2289             : 
    2290             : /*?
    2291             :  * @cliexpar
    2292             :  * @cliexstart{set nat44 session limit}
    2293             :  * Set NAT44 session limit.
    2294             :  * @cliexend
    2295             : ?*/
    2296       56709 : VLIB_CLI_COMMAND (nat44_set_session_limit_command, static) = {
    2297             :   .path = "set nat44 session limit",
    2298             :   .short_help = "set nat44 session limit <limit> [vrf <table-id>]",
    2299             :   .function = nat44_set_session_limit_command_fn,
    2300             : };
    2301             : 
    2302             : /*?
    2303             :  * @cliexpar
    2304             :  * @cliexstart{nat44 del session}
    2305             :  * To administratively delete NAT44 session by inside address and port use:
    2306             :  *  vpp# nat44 del session in 10.0.0.3:6303 tcp
    2307             :  * To administratively delete NAT44 session by outside address and port use:
    2308             :  *  vpp# nat44 del session out 1.0.0.3:6033 udp
    2309             :  * @cliexend
    2310             : ?*/
    2311       56709 : VLIB_CLI_COMMAND (nat44_del_session_command, static) = {
    2312             :     .path = "nat44 del session",
    2313             :     .short_help = "nat44 del session in|out <addr>:<port> tcp|udp|icmp [vrf <id>] [external-host <addr>:<port>]",
    2314             :     .function = nat44_del_session_command_fn,
    2315             : };
    2316             : 
    2317             : /*?
    2318             :  * @cliexpar
    2319             :  * @cliexstart{nat44 forwarding}
    2320             :  * Enable or disable forwarding
    2321             :  * Forward packets which don't match existing translation
    2322             :  * or static mapping instead of dropping them.
    2323             :  * To enable forwarding, use:
    2324             :  *  vpp# nat44 forwarding enable
    2325             :  * To disable forwarding, use:
    2326             :  *  vpp# nat44 forwarding disable
    2327             :  * @cliexend
    2328             : ?*/
    2329       56709 : VLIB_CLI_COMMAND (snat_forwarding_set_command, static) = {
    2330             :   .path = "nat44 forwarding",
    2331             :   .short_help = "nat44 forwarding enable|disable",
    2332             :   .function = snat_forwarding_set_command_fn,
    2333             : };
    2334             : 
    2335             : /*
    2336             :  * fd.io coding-style-patch-verification: ON
    2337             :  *
    2338             :  * Local Variables:
    2339             :  * eval: (c-set-style "gnu")
    2340             :  * End:
    2341             :  */

Generated by: LCOV version 1.14