nat: twice-nat static mapping pool address
[vpp.git] / src / plugins / nat / nat44_cli.c
index 64529af..f61ce2c 100644 (file)
@@ -618,6 +618,37 @@ done:
   return error;
 }
 
+static void
+nat44_show_lru_summary (vlib_main_t * vm, snat_main_per_thread_data_t * tsm,
+                       u64 now, u64 sess_timeout_time)
+{
+  snat_main_t *sm = &snat_main;
+  dlist_elt_t *oldest_elt;
+  snat_session_t *s;
+  u32 oldest_index;
+
+#define _(n, d)                                                          \
+  oldest_index =                                                         \
+      clib_dlist_remove_head (tsm->lru_pool, tsm->n##_lru_head_index);   \
+  if (~0 != oldest_index)                                                \
+    {                                                                    \
+      oldest_elt = pool_elt_at_index (tsm->lru_pool, oldest_index);      \
+      s = pool_elt_at_index (tsm->sessions, oldest_elt->value);          \
+      sess_timeout_time =                                                \
+          s->last_heard + (f64)nat44_session_get_timeout (sm, s);        \
+      vlib_cli_output (vm, d " LRU min session timeout %llu (now %llu)", \
+                       sess_timeout_time, now);                          \
+      clib_dlist_addhead (tsm->lru_pool, tsm->n##_lru_head_index,        \
+                          oldest_index);                                 \
+    }
+  _(tcp_estab, "established tcp");
+  _(tcp_trans, "transitory tcp");
+  _(udp, "udp");
+  _(unk_proto, "unknown protocol");
+  _(icmp, "icmp");
+#undef _
+}
+
 static clib_error_t *
 nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
                               vlib_cli_command_t * cmd)
@@ -629,11 +660,6 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
   if (!sm->endpoint_dependent)
     return clib_error_return (0, SUPPORTED_ONLY_IN_ED_MODE_STR);
 
-  vlib_cli_output (vm, "max translations per thread: %u",
-                  sm->max_translations_per_thread);
-  vlib_cli_output (vm, "max translations per user: %u",
-                  sm->max_translations_per_user);
-
   u32 count = 0;
 
   u64 now = vlib_time_now (vm);
@@ -649,6 +675,12 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
   u32 transitory_closed = 0;
   u32 established = 0;
 
+  u32 fib;
+
+  for (fib = 0; fib < vec_len (sm->max_translations_per_fib); fib++)
+    vlib_cli_output (vm, "max translations per thread: %u fib %u",
+                    sm->max_translations_per_fib[fib], fib);
+
   if (sm->num_workers > 1)
     {
       /* *INDENT-OFF* */
@@ -692,6 +724,7 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
                 break;
               }
           }));
+          nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
           count += pool_elts (tsm->sessions);
         }
       /* *INDENT-ON* */
@@ -739,32 +772,8 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
           }
       }));
       /* *INDENT-ON* */
+      nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
       count = pool_elts (tsm->sessions);
-      if (sm->endpoint_dependent)
-       {
-         dlist_elt_t *oldest_elt;
-         u32 oldest_index;
-#define _(n, d)                                                          \
-  oldest_index =                                                         \
-      clib_dlist_remove_head (tsm->lru_pool, tsm->n##_lru_head_index);   \
-  if (~0 != oldest_index)                                                \
-    {                                                                    \
-      oldest_elt = pool_elt_at_index (tsm->lru_pool, oldest_index);      \
-      s = pool_elt_at_index (tsm->sessions, oldest_elt->value);          \
-      sess_timeout_time =                                                \
-          s->last_heard + (f64)nat44_session_get_timeout (sm, s);        \
-      vlib_cli_output (vm, d " LRU min session timeout %llu (now %llu)", \
-                       sess_timeout_time, now);                          \
-      clib_dlist_addhead (tsm->lru_pool, tsm->n##_lru_head_index,        \
-                          oldest_index);                                 \
-    }
-         _(tcp_estab, "established tcp");
-         _(tcp_trans, "transitory tcp");
-         _(udp, "udp");
-         _(unk_proto, "unknown protocol");
-         _(icmp, "icmp");
-#undef _
-       }
     }
 
   vlib_cli_output (vm, "total timed out sessions: %u", timed_out);
@@ -971,13 +980,11 @@ add_static_mapping_command_fn (vlib_main_t * vm,
 {
   unformat_input_t _line_input, *line_input = &_line_input;
   clib_error_t *error = 0;
-  ip4_address_t l_addr, e_addr;
+  ip4_address_t l_addr, e_addr, exact_addr;
   u32 l_port = 0, e_port = 0, vrf_id = ~0;
-  int is_add = 1;
-  int addr_only = 1;
+  int is_add = 1, addr_only = 1, rv, exact = 0;
   u32 sw_if_index = ~0;
   vnet_main_t *vnm = vnet_get_main ();
-  int rv;
   nat_protocol_t proto = NAT_PROTOCOL_OTHER;
   u8 proto_set = 0;
   twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
@@ -1005,10 +1012,12 @@ add_static_mapping_command_fn (vlib_main_t * vm,
                         unformat_vnet_sw_interface, vnm, &sw_if_index,
                         &e_port))
        addr_only = 0;
-
       else if (unformat (line_input, "external %U",
                         unformat_vnet_sw_interface, vnm, &sw_if_index))
        ;
+      else if (unformat (line_input, "exact %U", unformat_ip4_address,
+                        &exact_addr))
+       exact = 1;
       else if (unformat (line_input, "vrf %u", &vrf_id))
        ;
       else if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
@@ -1054,7 +1063,8 @@ add_static_mapping_command_fn (vlib_main_t * vm,
   rv = snat_add_static_mapping (l_addr, e_addr, clib_host_to_net_u16 (l_port),
                                clib_host_to_net_u16 (e_port),
                                vrf_id, addr_only, sw_if_index, proto, is_add,
-                               twice_nat, out2in_only, 0, 0);
+                               twice_nat, out2in_only, 0, 0, exact_addr,
+                               exact);
 
   switch (rv)
     {
@@ -1095,7 +1105,7 @@ add_identity_mapping_command_fn (vlib_main_t * vm,
 {
   unformat_input_t _line_input, *line_input = &_line_input;
   clib_error_t *error = 0;
-  ip4_address_t addr;
+  ip4_address_t addr, pool_addr = { 0 };
   u32 port = 0, vrf_id = ~0;
   int is_add = 1;
   int addr_only = 1;
@@ -1135,7 +1145,8 @@ add_identity_mapping_command_fn (vlib_main_t * vm,
   rv =
     snat_add_static_mapping (addr, addr, clib_host_to_net_u16 (port),
                             clib_host_to_net_u16 (port), vrf_id, addr_only,
-                            sw_if_index, proto, is_add, 0, 0, 0, 1);
+                            sw_if_index, proto, is_add, 0, 0, 0, 1,
+                            pool_addr, 0);
 
   switch (rv)
     {
@@ -1561,7 +1572,7 @@ nat44_set_session_limit_command_fn (vlib_main_t * vm,
 
   if (!session_limit)
     error = clib_error_return (0, "missing value of session limit");
-  else if (nat44_set_session_limit (session_limit, vrf_id))
+  else if (nat44_update_session_limit (session_limit, vrf_id))
     error = clib_error_return (0, "nat44_set_session_limit failed");
 
 done:
@@ -1842,8 +1853,79 @@ nat_show_timeouts_command_fn (vlib_main_t * vm,
   return 0;
 }
 
+static clib_error_t *
+nat44_debug_fib_expire_command_fn (vlib_main_t * vm,
+                                  unformat_input_t * input,
+                                  vlib_cli_command_t * cmd)
+{
+  unformat_input_t _line_input, *line_input = &_line_input;
+  clib_error_t *error = 0;
+  u32 fib = ~0;
+
+  /* Get a line of input. */
+  if (!unformat_user (input, unformat_line_input, line_input))
+    return 0;
+
+  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (line_input, "%u", &fib))
+       ;
+      else
+       {
+         error = clib_error_return (0, "unknown input '%U'",
+                                    format_unformat_error, line_input);
+         goto done;
+       }
+    }
+  expire_per_vrf_sessions (fib);
+done:
+  unformat_free (line_input);
+  return error;
+}
+
+static clib_error_t *
+nat44_debug_fib_registration_command_fn (vlib_main_t * vm,
+                                        unformat_input_t * input,
+                                        vlib_cli_command_t * cmd)
+{
+  snat_main_t *sm = &snat_main;
+  snat_main_per_thread_data_t *tsm;
+  per_vrf_sessions_t *per_vrf_sessions;
+
+  vlib_cli_output (vm, "VRF registration debug:");
+  vec_foreach (tsm, sm->per_thread_data)
+  {
+    vlib_cli_output (vm, "thread %u:", tsm->thread_index);
+    vec_foreach (per_vrf_sessions, tsm->per_vrf_sessions_vec)
+    {
+      vlib_cli_output (vm, "rx fib %u tx fib %u ses count %u %s",
+                      per_vrf_sessions->rx_fib_index,
+                      per_vrf_sessions->tx_fib_index,
+                      per_vrf_sessions->ses_count,
+                      per_vrf_sessions->expired ? "expired" : "");
+    }
+  }
+  return 0;
+}
+
 /* *INDENT-OFF* */
 
+/*?
+?*/
+VLIB_CLI_COMMAND (nat44_debug_fib_expire_command, static) = {
+  .path = "debug nat44 fib expire",
+  .short_help = "debug nat44 fib expire <fib-index>",
+  .function = nat44_debug_fib_expire_command_fn,
+};
+
+/*?
+?*/
+VLIB_CLI_COMMAND (nat44_debug_fib_registration_command, static) = {
+  .path = "debug nat44 fib registration",
+  .short_help = "debug nat44 fib registration",
+  .function = nat44_debug_fib_registration_command_fn,
+};
+
 /*?
  * @cliexpar
  * @cliexstart{set snat workers}
@@ -2174,6 +2256,8 @@ VLIB_CLI_COMMAND (nat44_show_interfaces_command, static) = {
  * To create ICMP static mapping between local and external with ICMP echo
  * identifier 10 use:
  *  vpp# nat44 add static mapping icmp local 10.0.0.3 10 external 4.4.4.4 10
+ * To force use of specific pool address, vrf independent
+ *  vpp# nat44 add static mapping local 10.0.0.2 1234 external 10.0.2.2 1234 twice-nat exact 10.0.1.2
  * @cliexend
 ?*/
 VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
@@ -2182,7 +2266,7 @@ VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
   .short_help =
     "nat44 add static mapping tcp|udp|icmp local <addr> [<port|icmp-echo-id>] "
     "external <addr> [<port|icmp-echo-id>] [vrf <table-id>] [twice-nat|self-twice-nat] "
-    "[out2in-only] [del]",
+    "[out2in-only] [exact <pool-addr>] [del]",
 };
 
 /*?