aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/nat/nat.c77
-rw-r--r--src/plugins/nat/nat.h11
-rw-r--r--src/plugins/nat/nat44_cli.c71
3 files changed, 109 insertions, 50 deletions
diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c
index 66a5243af1c..796d9d010d4 100644
--- a/src/plugins/nat/nat.c
+++ b/src/plugins/nat/nat.c
@@ -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);
diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h
index 8bec46a3704..518f2002056 100644
--- a/src/plugins/nat/nat.h
+++ b/src/plugins/nat/nat.h
@@ -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;
@@ -1268,6 +1271,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)
*
* @param s NAT session
diff --git a/src/plugins/nat/nat44_cli.c b/src/plugins/nat/nat44_cli.c
index ad2e9b7ae07..65f40753a3f 100644
--- a/src/plugins/nat/nat44_cli.c
+++ b/src/plugins/nat/nat44_cli.c
@@ -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: