pool_get (tsm->users, u);
clib_memset (u, 0, sizeof (*u));
- u->min_session_timeout = 0;
-
u->addr.as_u32 = addr->as_u32;
u->fib_index = fib_index;
s->per_user_list_head_index,
per_user_translation_list_elt - tsm->list_pool);
+ dlist_elt_t *global_lru_list_elt;
+ pool_get (tsm->global_lru_pool, global_lru_list_elt);
+ global_lru_list_elt->value = s - tsm->sessions;
+ s->global_lru_index = global_lru_list_elt - tsm->global_lru_pool;
+ clib_dlist_addtail (tsm->global_lru_pool, tsm->global_lru_head_index,
+ s->global_lru_index);
+ s->last_lru_update = now;
+
s->user_index = u - tsm->users;
vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
pool_elts (tsm->sessions));
nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, u32 thread_index,
f64 now)
{
- snat_session_t *s;
+ snat_session_t *s = NULL;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
dlist_elt_t *oldest_elt;
if (PREDICT_FALSE
((u->nsessions + u->nstaticsessions) >= sm->max_translations_per_user))
{
- if (nat44_max_translations_per_user_cleanup (u, thread_index, now))
- goto alloc_new;
-
nat_elog_addr (SNAT_LOG_WARNING, "[warn] max translations per user",
clib_net_to_host_u32 (u->addr.as_u32));
snat_ipfix_logging_max_entries_per_user (thread_index,
return 0;
}
+ /* first try to reuse an expired session from this ip */
oldest_index =
clib_dlist_remove_head (tsm->list_pool,
u->sessions_per_user_list_head_index);
clib_dlist_addtail (tsm->list_pool,
u->sessions_per_user_list_head_index, oldest_index);
s = nat44_session_reuse_old (sm, u, s, thread_index, now);
+ s->last_lru_update = now;
}
else
{
- // alloc new session
clib_dlist_addhead (tsm->list_pool,
u->sessions_per_user_list_head_index, oldest_index);
- alloc_new:
+ s = NULL;
+ }
+
+alloc_new:
+ /* try to free an expired session from global LRU list */
+ if (!s)
+ {
+ oldest_index = clib_dlist_remove_head (tsm->global_lru_pool,
+ tsm->global_lru_head_index);
+ if (~0 != oldest_index)
+ {
+ oldest_elt = pool_elt_at_index (tsm->global_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);
+ if (now >= sess_timeout_time
+ || (s->tcp_close_timestamp && now >= s->tcp_close_timestamp))
+ {
+ nat_free_session_data (sm, s, thread_index, 0);
+ nat44_ed_delete_session (sm, s, thread_index, 0);
+ }
+ else
+ {
+ clib_dlist_addhead (tsm->global_lru_pool,
+ tsm->global_lru_head_index, oldest_index);
+ }
+ s = NULL;
+ }
+ }
+ if (!s)
+ {
s = nat44_session_alloc_new (tsm, u, now);
vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
pool_elts (tsm->sessions));
snat_main_per_thread_data_t *tsm;
u32 static_mapping_buckets = 1024;
- u32 static_mapping_memory_size = 64 << 20;
+ uword static_mapping_memory_size = 64 << 20;
u32 nat64_bib_buckets = 1024;
u32 nat64_bib_memory_size = 128 << 20;
u32 nat64_st_buckets = 2048;
- u32 nat64_st_memory_size = 256 << 20;
+ uword nat64_st_memory_size = 256 << 20;
u32 user_buckets = 128;
- u32 user_memory_size = 64 << 20;
+ uword user_memory_size = 64 << 20;
u32 translation_buckets = 1024;
- u32 translation_memory_size = 128 << 20;
+ uword translation_memory_size = 128 << 20;
u32 max_translations_per_user = ~0;
sm->tcp_established_timeout = tcp_established_timeout;
sm->icmp_timeout = icmp_timeout;
- sm->min_timeout = nat44_minimal_timeout (sm);
-
sm->user_buckets = user_buckets;
sm->user_memory_size = user_memory_size;
/* *INDENT-OFF* */
vec_foreach (tsm, sm->per_thread_data)
{
- tsm->min_session_timeout = 0;
-
- tsm->cleared = 0;
- tsm->cleanup_runs = 0;
- tsm->cleanup_timeout = 0;
+ pool_alloc (tsm->sessions, sm->max_translations);
+ pool_alloc (tsm->list_pool, sm->max_translations);
+ pool_alloc (tsm->global_lru_pool, sm->max_translations);
+
+ dlist_elt_t *head;
+ pool_get (tsm->global_lru_pool, head);
+ tsm->global_lru_head_index = head - tsm->global_lru_pool;
+ clib_dlist_init (tsm->global_lru_pool,
+ tsm->global_lru_head_index);
if (sm->endpoint_dependent)
{