From 8fdc015ddde7620d37d5a46cc66deb9791e634c1 Mon Sep 17 00:00:00 2001 From: Matus Fabian Date: Mon, 24 Sep 2018 04:41:28 -0700 Subject: NAT44: endpoint-dependent mode session timeout improvement (VPP-1423) Change-Id: I630f3da1ea4e6e50a50f1352c097becef1efe3c0 Signed-off-by: Matus Fabian --- src/plugins/nat/in2out_ed.c | 4 +-- src/plugins/nat/nat.c | 78 +++++++++++++++++++++++++++++++++------------ src/plugins/nat/nat.h | 2 +- src/plugins/nat/out2in_ed.c | 6 ++-- 4 files changed, 63 insertions(+), 27 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/nat/in2out_ed.c b/src/plugins/nat/in2out_ed.c index d4f70f5a12b..77630268047 100644 --- a/src/plugins/nat/in2out_ed.c +++ b/src/plugins/nat/in2out_ed.c @@ -315,7 +315,7 @@ slow_path_ed (snat_main_t * sm, return NAT_IN2OUT_ED_NEXT_DROP; } - s = nat_ed_session_alloc (sm, u, thread_index); + s = nat_ed_session_alloc (sm, u, thread_index, now); if (!s) { nat44_delete_user_with_no_session (sm, u, thread_index); @@ -777,7 +777,7 @@ nat44_ed_in2out_unknown_proto (snat_main_t * sm, } create_ses: - s = nat_ed_session_alloc (sm, u, thread_index); + s = nat_ed_session_alloc (sm, u, thread_index, now); if (!s) { nat44_delete_user_with_no_session (sm, u, thread_index); diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c index efca4404ddd..0818332eeb3 100755 --- a/src/plugins/nat/nat.c +++ b/src/plugins/nat/nat.c @@ -388,37 +388,73 @@ nat_session_alloc_or_recycle (snat_main_t * sm, snat_user_t * u, } snat_session_t * -nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, u32 thread_index) +nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, u32 thread_index, + f64 now) { snat_session_t *s; snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index]; - dlist_elt_t *per_user_translation_list_elt; + dlist_elt_t *per_user_translation_list_elt, *oldest_elt; + u32 oldest_index; + u64 sess_timeout_time; if ((u->nsessions + u->nstaticsessions) >= sm->max_translations_per_user) { - nat_log_warn ("max translations per user %U", format_ip4_address, - &u->addr); - snat_ipfix_logging_max_entries_per_user (sm->max_translations_per_user, - u->addr.as_u32); - return 0; + oldest_index = + clib_dlist_remove_head (tsm->list_pool, + u->sessions_per_user_list_head_index); + oldest_elt = pool_elt_at_index (tsm->list_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); + if (now >= sess_timeout_time) + { + clib_dlist_addtail (tsm->list_pool, + u->sessions_per_user_list_head_index, + oldest_index); + nat_free_session_data (sm, s, thread_index); + if (snat_is_session_static (s)) + u->nstaticsessions--; + else + u->nsessions--; + s->flags = 0; + s->total_bytes = 0; + s->total_pkts = 0; + s->state = 0; + s->ext_host_addr.as_u32 = 0; + s->ext_host_port = 0; + s->ext_host_nat_addr.as_u32 = 0; + s->ext_host_nat_port = 0; + } + else + { + clib_dlist_addhead (tsm->list_pool, + u->sessions_per_user_list_head_index, + oldest_index); + nat_log_warn ("max translations per user %U", format_ip4_address, + &u->addr); + snat_ipfix_logging_max_entries_per_user + (sm->max_translations_per_user, u->addr.as_u32); + return 0; + } } + else + { + pool_get (tsm->sessions, s); + memset (s, 0, sizeof (*s)); - pool_get (tsm->sessions, s); - memset (s, 0, sizeof (*s)); - - /* Create list elts */ - pool_get (tsm->list_pool, per_user_translation_list_elt); - clib_dlist_init (tsm->list_pool, - per_user_translation_list_elt - tsm->list_pool); - - per_user_translation_list_elt->value = s - tsm->sessions; - s->per_user_index = per_user_translation_list_elt - tsm->list_pool; - s->per_user_list_head_index = u->sessions_per_user_list_head_index; + /* Create list elts */ + pool_get (tsm->list_pool, per_user_translation_list_elt); + clib_dlist_init (tsm->list_pool, + per_user_translation_list_elt - tsm->list_pool); - clib_dlist_addtail (tsm->list_pool, - s->per_user_list_head_index, - per_user_translation_list_elt - tsm->list_pool); + per_user_translation_list_elt->value = s - tsm->sessions; + s->per_user_index = per_user_translation_list_elt - tsm->list_pool; + s->per_user_list_head_index = u->sessions_per_user_list_head_index; + clib_dlist_addtail (tsm->list_pool, + s->per_user_list_head_index, + per_user_translation_list_elt - tsm->list_pool); + } return s; } diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat.h index 865d27efb5a..1baf10ff43c 100644 --- a/src/plugins/nat/nat.h +++ b/src/plugins/nat/nat.h @@ -933,7 +933,7 @@ snat_session_t *nat_session_alloc_or_recycle (snat_main_t * sm, * @return session data structure on success otherwise zero value */ snat_session_t *nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, - u32 thread_index); + u32 thread_index, f64 now); /** * @brief Set address and port assignment algorithm for MAP-E CE diff --git a/src/plugins/nat/out2in_ed.c b/src/plugins/nat/out2in_ed.c index 4236285df8d..ef772334292 100644 --- a/src/plugins/nat/out2in_ed.c +++ b/src/plugins/nat/out2in_ed.c @@ -233,7 +233,7 @@ create_session_for_static_mapping_ed (snat_main_t * sm, return 0; } - s = nat_ed_session_alloc (sm, u, thread_index); + s = nat_ed_session_alloc (sm, u, thread_index, now); if (!s) { nat44_delete_user_with_no_session (sm, u, thread_index); @@ -421,7 +421,7 @@ create_bypass_for_fwd (snat_main_t * sm, ip4_header_t * ip, u32 rx_fib_index, return; } - s = nat_ed_session_alloc (sm, u, thread_index); + s = nat_ed_session_alloc (sm, u, thread_index, now); if (!s) { nat44_delete_user_with_no_session (sm, u, thread_index); @@ -623,7 +623,7 @@ nat44_ed_out2in_unknown_proto (snat_main_t * sm, } /* Create a new session */ - s = nat_ed_session_alloc (sm, u, thread_index); + s = nat_ed_session_alloc (sm, u, thread_index, now); if (!s) { nat44_delete_user_with_no_session (sm, u, thread_index); -- cgit 1.2.3-korg