From 9f57c72e27e21ce8dc8ebfee059711e3102d0c6b Mon Sep 17 00:00:00 2001 From: Filip Varga Date: Wed, 19 Aug 2020 14:57:10 +0200 Subject: [PATCH] nat: fixed cli nat summary and nat limit Type: fix Change-Id: I78017b02015116f93b579c7381119f618351c98d Signed-off-by: Filip Varga --- src/plugins/nat/nat.c | 77 ++++++++++++++++++++++++++++++++++----------- src/plugins/nat/nat.h | 11 +++++++ src/plugins/nat/nat44_cli.c | 71 +++++++++++++++++++++++------------------ 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; @@ -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) * 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: -- 2.16.6