nat: fixed cli nat summary and nat limit 15/28515/2
authorFilip Varga <fivarga@cisco.com>
Wed, 19 Aug 2020 12:57:10 +0000 (14:57 +0200)
committerOle Trøan <otroan@employees.org>
Thu, 20 Aug 2020 07:17:49 +0000 (07:17 +0000)
Type: fix

Change-Id: I78017b02015116f93b579c7381119f618351c98d
Signed-off-by: Filip Varga <fivarga@cisco.com>
src/plugins/nat/nat.c
src/plugins/nat/nat.h
src/plugins/nat/nat44_cli.c

index 66a5243..796d9d0 100644 (file)
@@ -313,25 +313,6 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
                                      s->nat_proto);
 }
 
-int
-nat44_set_session_limit (u32 session_limit, u32 vrf_id)
-{
-  snat_main_t *sm = &snat_main;
-  u32 fib_index = fib_table_find (FIB_PROTOCOL_IP4, vrf_id);
-  u32 len = vec_len (sm->max_translations_per_fib);
-
-  if (len <= fib_index)
-    {
-      vec_validate (sm->max_translations_per_fib, fib_index + 1);
-
-      for (; len < vec_len (sm->max_translations_per_fib); len++)
-       sm->max_translations_per_fib[len] = sm->max_translations_per_thread;
-    }
-
-  sm->max_translations_per_fib[fib_index] = session_limit;
-  return 0;
-}
-
 void
 nat44_free_session_data (snat_main_t * sm, snat_session_t * s,
                         u32 thread_index, u8 is_ha)
@@ -3909,6 +3890,62 @@ nat_calc_bihash_memory (u32 n_buckets, uword kv_size)
   return n_buckets * (8 + kv_size * 4);
 }
 
+u32
+nat44_get_max_session_limit ()
+{
+  snat_main_t *sm = &snat_main;
+  u32 max_limit = 0, len = 0;
+
+  for (; len < vec_len (sm->max_translations_per_fib); len++)
+    {
+      if (max_limit < sm->max_translations_per_fib[len])
+       max_limit = sm->max_translations_per_fib[len];
+    }
+  return max_limit;
+}
+
+int
+nat44_set_session_limit (u32 session_limit, u32 vrf_id)
+{
+  snat_main_t *sm = &snat_main;
+  u32 fib_index = fib_table_find (FIB_PROTOCOL_IP4, vrf_id);
+  u32 len = vec_len (sm->max_translations_per_fib);
+
+  if (len <= fib_index)
+    {
+      vec_validate (sm->max_translations_per_fib, fib_index + 1);
+
+      for (; len < vec_len (sm->max_translations_per_fib); len++)
+       sm->max_translations_per_fib[len] = sm->max_translations_per_thread;
+    }
+
+  sm->max_translations_per_fib[fib_index] = session_limit;
+  return 0;
+}
+
+int
+nat44_update_session_limit (u32 session_limit, u32 vrf_id)
+{
+  snat_main_t *sm = &snat_main;
+
+  if (nat44_set_session_limit (session_limit, vrf_id))
+    return 1;
+  sm->max_translations_per_thread = nat44_get_max_session_limit ();
+
+  sm->translation_buckets =
+    nat_calc_bihash_buckets (sm->max_translations_per_thread);
+
+  if (!sm->translation_memory_size_set)
+    {
+      sm->translation_memory_size =
+       nat_calc_bihash_memory (sm->translation_buckets,
+                               sizeof (clib_bihash_16_8_t));
+    }
+
+  nat44_sessions_clear ();
+  return 0;
+}
+
 void
 nat44_db_init (snat_main_per_thread_data_t * tsm)
 {
@@ -4157,6 +4194,8 @@ snat_config (vlib_main_t * vm, unformat_input_t * input)
       // translation buckets 1024
       max_translations_per_thread = 10 * 1024;
     }
+  sm->translation_memory_size_set = translation_memory_size != 0;
+
   sm->max_translations_per_thread = max_translations_per_thread;
   sm->translation_buckets =
     nat_calc_bihash_buckets (sm->max_translations_per_thread);
index 8bec46a..518f200 100644 (file)
@@ -590,6 +590,9 @@ typedef struct snat_main_s
   u8 out2in_dpo;
   u8 endpoint_dependent;
 
+  /* Is translation memory size calculated or user defined */
+  u8 translation_memory_size_set;
+
   u32 translation_buckets;
   uword translation_memory_size;
   u32 max_translations_per_thread;
@@ -1267,6 +1270,14 @@ void nat_free_session_data (snat_main_t * sm, snat_session_t * s,
  */
 int nat44_set_session_limit (u32 session_limit, u32 vrf_id);
 
+/**
+ * @brief Update NAT44 session limit flushing all data (session limit, vrf id)
+ *
+ * @param session_limit Session limit
+ * @param vrf_id        VRF id
+ * @return 0 on success, non-zero value otherwise
+ */
+int nat44_update_session_limit (u32 session_limit, u32 vrf_id);
 /**
  * @brief Free NAT44 ED session data (lookup keys, external address port)
  *
index ad2e9b7..65f4075 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);
@@ -1561,7 +1570,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: