diff options
Diffstat (limited to 'src/plugins/nat/nat.c')
-rwxr-xr-x | src/plugins/nat/nat.c | 78 |
1 files changed, 57 insertions, 21 deletions
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; } |