snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
&s->out2in);
delete:
- nat44_delete_session (sm, s, ctx->thread_index);
+ nat44_ed_delete_session (sm, s, ctx->thread_index, 1);
return 1;
}
vlib_node_runtime_t * node, u32 next, u32 thread_index, f64 now)
{
snat_session_t *s = NULL;
- snat_user_t *u = NULL;
snat_session_key_t key0, key1;
- lb_nat_type_t lb = 0, is_sm = 0;
+ lb_nat_type_t lb = 0;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
nat_ed_ses_key_t *key = (nat_ed_ses_key_t *) kv->key;
u32 proto = ip_proto_to_snat_proto (key->proto);
if (snat_static_mapping_match
(sm, key0, &key1, 0, 0, 0, &lb, 0, &identity_nat))
{
- u =
- nat_user_get_or_create (sm, &key->l_addr, rx_fib_index, thread_index);
- if (!u)
- {
- nat_elog_warn ("create NAT user failed");
- b->error = node->errors[NAT_IN2OUT_ED_ERROR_CANNOT_CREATE_USER];
- goto drop;
- }
-
- s = nat_ed_session_alloc (sm, u, thread_index, now);
+ s = nat_ed_session_alloc (sm, thread_index, now);
if (!s)
{
nat_elog_warn ("create NAT session failed");
*sessionp = s;
return next;
}
- is_sm = 1;
- u =
- nat_user_get_or_create (sm, &key->l_addr, rx_fib_index, thread_index);
- if (!u)
- {
- nat_elog_warn ("create NAT user failed");
- b->error = node->errors[NAT_IN2OUT_ED_ERROR_CANNOT_CREATE_USER];
- goto drop;
- }
-
- s = nat_ed_session_alloc (sm, u, thread_index, now);
+ s = nat_ed_session_alloc (sm, thread_index, now);
if (!s)
{
- nat44_delete_user_with_no_session (sm, u, thread_index);
nat_elog_warn ("create NAT session failed");
b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_USER_SESS_EXCEEDED];
goto drop;
out2in_ed_inserted = true;
}
- user_session_increment (sm, u, is_sm);
if (lb)
s->flags |= SNAT_SESSION_FLAG_LOAD_BALANCING;
s->flags |= SNAT_SESSION_FLAG_ENDPOINT_DEPENDENT;
nat_free_session_data (sm, s, thread_index, 0);
nat44_ed_delete_session (sm, s, thread_index, 1);
}
- if (u)
- {
- nat44_delete_user_with_no_session (sm, u, thread_index);
- }
return NAT_NEXT_DROP;
}
if (nat44_is_ses_closed (s))
{
nat_free_session_data (sm, s, thread_index, 0);
- nat44_delete_session (sm, s, thread_index);
+ nat44_ed_delete_session (sm, s, thread_index, 1);
}
else
s->flags |= SNAT_SESSION_FLAG_OUTPUT_FEATURE;
snat_static_mapping_t *m;
u32 old_addr, new_addr = 0;
ip_csum_t sum;
- snat_user_t *u;
- dlist_elt_t *head, *elt;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- u32 elt_index, head_index, ses_index;
snat_session_t *s;
u32 outside_fib_index = sm->outside_fib_index;
int i;
return 0;
}
- u = nat_user_get_or_create (sm, &ip->src_address, rx_fib_index,
- thread_index);
- if (!u)
- {
- b->error = node->errors[NAT_IN2OUT_ED_ERROR_CANNOT_CREATE_USER];
- nat_elog_warn ("create NAT user failed");
- return 0;
- }
-
make_sm_kv (&kv, &ip->src_address, 0, rx_fib_index, 0);
/* Try to find static mapping first */
is_sm = 1;
goto create_ses;
}
- /* Fallback to 3-tuple key */
else
{
- /* Choose same out address as for TCP/UDP session to same destination */
- head_index = u->sessions_per_user_list_head_index;
- head = pool_elt_at_index (tsm->list_pool, head_index);
- elt_index = head->next;
- if (PREDICT_FALSE (elt_index == ~0))
- ses_index = ~0;
- else
- {
- elt = pool_elt_at_index (tsm->list_pool, elt_index);
- ses_index = elt->value;
- }
-
- while (ses_index != ~0)
- {
- s = pool_elt_at_index (tsm->sessions, ses_index);
- elt_index = elt->next;
- elt = pool_elt_at_index (tsm->list_pool, elt_index);
- ses_index = elt->value;
-
- if (s->ext_host_addr.as_u32 == ip->dst_address.as_u32)
- {
- new_addr = ip->src_address.as_u32 = s->out2in.addr.as_u32;
-
- make_ed_kv (&s_kv, &s->out2in.addr, &ip->dst_address,
- ip->protocol, outside_fib_index, 0, 0);
- if (clib_bihash_search_16_8
- (&tsm->out2in_ed, &s_kv, &s_value))
- goto create_ses;
-
- break;
- }
- }
+ /* *INDENT-OFF* */
+ pool_foreach (s, tsm->sessions, {
+ if (s->ext_host_addr.as_u32 == ip->dst_address.as_u32)
+ {
+ new_addr = ip->src_address.as_u32 = s->out2in.addr.as_u32;
+
+ make_ed_kv (&s_kv, &s->out2in.addr, &ip->dst_address, ip->protocol,
+ outside_fib_index, 0, 0);
+ if (clib_bihash_search_16_8 (&tsm->out2in_ed, &s_kv, &s_value))
+ goto create_ses;
+
+ break;
+ }
+ });
+ /* *INDENT-ON* */
for (i = 0; i < vec_len (sm->addresses); i++)
{
}
create_ses:
- s = nat_ed_session_alloc (sm, u, thread_index, now);
+ s = nat_ed_session_alloc (sm, thread_index, now);
if (!s)
{
b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_USER_SESS_EXCEEDED];
- nat44_delete_user_with_no_session (sm, u, thread_index);
nat_elog_warn ("create NAT session failed");
return 0;
}
s->in2out.port = s->out2in.port = ip->protocol;
if (is_sm)
s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
- user_session_increment (sm, u, is_sm);
/* Add to lookup tables */
make_ed_kv (&s_kv, &s->in2out.addr, &ip->dst_address, ip->protocol,
if (now >= sess_timeout_time)
{
nat_free_session_data (sm, s0, thread_index, 0);
- nat44_delete_session (sm, s0, thread_index);
+ nat44_ed_delete_session (sm, s0, thread_index, 1);
// session is closed, go slow path
next0 = def_slow;
goto trace0;
if (s0->tcp_close_timestamp && now >= s0->tcp_close_timestamp)
{
nat_free_session_data (sm, s0, thread_index, 0);
- nat44_delete_session (sm, s0, thread_index);
+ nat44_ed_delete_session (sm, s0, thread_index, 1);
s0 = NULL;
}
}
}
snat_session_t *
-nat_ed_session_alloc (snat_main_t * sm, snat_user_t * u, u32 thread_index,
- f64 now)
+nat_ed_session_alloc (snat_main_t * sm, u32 thread_index, f64 now)
{
- snat_session_t *s = NULL;
+ snat_session_t *s;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- dlist_elt_t *oldest_elt;
- u64 sess_timeout_time;
- u32 oldest_index;
-
- // no sessions
- if (PREDICT_FALSE (!(u->nsessions) && !(u->nstaticsessions)))
- goto alloc_new;
-
- // no free sessions
- if (PREDICT_FALSE
- ((u->nsessions + u->nstaticsessions) >= sm->max_translations_per_user))
- {
- 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,
- sm->max_translations_per_user,
- u->addr.as_u32);
- return 0;
- }
+ nat_global_lru_free_one (sm, thread_index, now);
- /* 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);
- oldest_elt = pool_elt_at_index (tsm->list_pool, oldest_index);
- s = pool_elt_at_index (tsm->sessions, oldest_elt->value);
+ pool_get (tsm->sessions, s);
+ clib_memset (s, 0, sizeof (*s));
- 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))
- {
- // reuse old session
- 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
- {
- clib_dlist_addhead (tsm->list_pool,
- u->sessions_per_user_list_head_index, oldest_index);
- s = NULL;
- }
+ nat44_global_lru_insert (tsm, s, now);
-alloc_new:
- if (!s)
- {
- nat_global_lru_free_one (sm, thread_index, now);
- s = nat44_session_alloc_new (tsm, u, now);
- vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
- pool_elts (tsm->sessions));
- }
+ s->ha_last_refreshed = now;
+ vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
+ pool_elts (tsm->sessions));
return s;
}
return thread_idx;
}
+void
+snat_static_mapping_del_sessions (snat_main_t * sm,
+ snat_main_per_thread_data_t * tsm,
+ snat_user_key_t u_key, int addr_only,
+ ip4_address_t e_addr, u16 e_port)
+{
+ clib_bihash_kv_8_8_t kv, value;
+ kv.key = u_key.as_u64;
+ u64 user_index;
+ dlist_elt_t *head, *elt;
+ snat_user_t *u;
+ snat_session_t *s;
+ u32 elt_index, head_index, ses_index;
+ if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
+ {
+ user_index = value.value;
+ u = pool_elt_at_index (tsm->users, user_index);
+ if (u->nstaticsessions)
+ {
+ head_index = u->sessions_per_user_list_head_index;
+ head = pool_elt_at_index (tsm->list_pool, head_index);
+ elt_index = head->next;
+ elt = pool_elt_at_index (tsm->list_pool, elt_index);
+ ses_index = elt->value;
+ while (ses_index != ~0)
+ {
+ s = pool_elt_at_index (tsm->sessions, ses_index);
+ elt = pool_elt_at_index (tsm->list_pool, elt->next);
+ ses_index = elt->value;
+
+ if (!addr_only)
+ {
+ if ((s->out2in.addr.as_u32 != e_addr.as_u32) ||
+ (clib_net_to_host_u16 (s->out2in.port) != e_port))
+ continue;
+ }
+
+ if (is_lb_session (s))
+ continue;
+
+ if (!snat_is_session_static (s))
+ continue;
+
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
+ nat44_delete_session (sm, s, tsm - sm->per_thread_data);
+
+ if (!addr_only)
+ break;
+ }
+ }
+ }
+}
+
+void
+snat_ed_static_mapping_del_sessions (snat_main_t * sm,
+ snat_main_per_thread_data_t * tsm,
+ ip4_address_t l_addr,
+ u16 l_port,
+ u8 protocol,
+ u32 fib_index, int addr_only,
+ ip4_address_t e_addr, u16 e_port)
+{
+ snat_session_t *s;
+ u32 *indexes_to_free = NULL;
+ /* *INDENT-OFF* */
+ pool_foreach (s, tsm->sessions, {
+ if (s->in2out.fib_index != fib_index ||
+ s->in2out.addr.as_u32 != l_addr.as_u32)
+ {
+ continue;
+ }
+ if (!addr_only)
+ {
+ if ((s->out2in.addr.as_u32 != e_addr.as_u32) ||
+ (clib_net_to_host_u16 (s->out2in.port) != e_port) ||
+ clib_net_to_host_u16 (s->in2out.port) != l_port ||
+ s->in2out.protocol != protocol)
+ continue;
+ }
+
+ if (is_lb_session (s))
+ continue;
+ if (!snat_is_session_static (s))
+ continue;
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
+ vec_add1 (indexes_to_free, s - tsm->sessions);
+ if (!addr_only)
+ break;
+ });
+ /* *INDENT-ON* */
+ u32 *ses_index;
+ vec_foreach (ses_index, indexes_to_free)
+ {
+ s = pool_elt_at_index (tsm->sessions, *ses_index);
+ nat44_ed_delete_session (sm, s, tsm - sm->per_thread_data, 1);
+ }
+ vec_free (indexes_to_free);
+}
+
int
snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
u16 l_port, u16 e_port, u32 vrf_id, int addr_only,
if (!(sm->static_mapping_only) ||
(sm->static_mapping_only && sm->static_mapping_connection_tracking))
{
- u_key.addr = m->local_addr;
- u_key.fib_index = fib_index;
- kv.key = u_key.as_u64;
- if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
+ if (sm->endpoint_dependent)
{
- user_index = value.value;
- u = pool_elt_at_index (tsm->users, user_index);
- if (u->nstaticsessions)
- {
- head_index = u->sessions_per_user_list_head_index;
- head = pool_elt_at_index (tsm->list_pool, head_index);
- elt_index = head->next;
- elt = pool_elt_at_index (tsm->list_pool, elt_index);
- ses_index = elt->value;
- while (ses_index != ~0)
- {
- s = pool_elt_at_index (tsm->sessions, ses_index);
- elt = pool_elt_at_index (tsm->list_pool, elt->next);
- ses_index = elt->value;
-
- if (!addr_only)
- {
- if ((s->out2in.addr.as_u32 != e_addr.as_u32) ||
- (clib_net_to_host_u16 (s->out2in.port) !=
- e_port))
- continue;
- }
-
- if (is_lb_session (s))
- continue;
-
- if (!snat_is_session_static (s))
- continue;
-
- nat_free_session_data (sm, s,
- tsm - sm->per_thread_data, 0);
- nat44_delete_session (sm, s, tsm - sm->per_thread_data);
-
- if (!addr_only && !sm->endpoint_dependent)
- break;
- }
- }
+ snat_ed_static_mapping_del_sessions (sm, tsm, m->local_addr,
+ m->local_port, m->proto,
+ fib_index, addr_only,
+ e_addr, e_port);
+ }
+ else
+ {
+ u_key.addr = m->local_addr;
+ u_key.fib_index = fib_index;
+ kv.key = u_key.as_u64;
+ snat_static_mapping_del_sessions (sm, tsm, u_key, addr_only,
+ e_addr, e_port);
}
}
snat_address_t *a = 0;
int i;
nat44_lb_addr_port_t *local;
- u32 elt_index, head_index, ses_index;
snat_main_per_thread_data_t *tsm;
- snat_user_key_t u_key;
- snat_user_t *u;
snat_session_t *s;
- dlist_elt_t *head, *elt;
uword *bitmap = 0;
if (!sm->endpoint_dependent)
tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
/* Delete sessions */
- u_key.addr = local->addr;
- u_key.fib_index = local->fib_index;
- kv.key = u_key.as_u64;
- if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
- {
- u = pool_elt_at_index (tsm->users, value.value);
- if (u->nstaticsessions)
- {
- head_index = u->sessions_per_user_list_head_index;
- head = pool_elt_at_index (tsm->list_pool, head_index);
- elt_index = head->next;
- elt = pool_elt_at_index (tsm->list_pool, elt_index);
- ses_index = elt->value;
- while (ses_index != ~0)
- {
- s = pool_elt_at_index (tsm->sessions, ses_index);
- elt = pool_elt_at_index (tsm->list_pool, elt->next);
- ses_index = elt->value;
-
- if (!(is_lb_session (s)))
- continue;
-
- if ((s->in2out.addr.as_u32 != local->addr.as_u32) ||
- (clib_net_to_host_u16 (s->in2out.port) != local->port))
- continue;
-
- nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
- nat44_delete_session (sm, s, tsm - sm->per_thread_data);
- }
- }
- }
+ pool_foreach (s, tsm->sessions, {
+ if (!(is_lb_session (s)))
+ continue;
+
+ if ((s->in2out.addr.as_u32 != local->addr.as_u32) ||
+ (clib_net_to_host_u16 (s->in2out.port) != local->port))
+ continue;
+
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
+ nat44_ed_delete_session (sm, s, tsm - sm->per_thread_data, 1);
+ });
}));
/* *INDENT-ON* */
if (m->affinity)
clib_bihash_kv_8_8_t kv, value;
nat44_lb_addr_port_t *local, *prev_local, *match_local = 0;
snat_main_per_thread_data_t *tsm;
- snat_user_key_t u_key;
- snat_user_t *u;
snat_session_t *s;
- dlist_elt_t *head, *elt;
- u32 elt_index, head_index, ses_index, *locals = 0;
+ u32 *locals = 0;
uword *bitmap = 0;
int i;
tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
/* Delete sessions */
- u_key.addr = match_local->addr;
- u_key.fib_index = match_local->fib_index;
- kv.key = u_key.as_u64;
- if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
- {
- u = pool_elt_at_index (tsm->users, value.value);
- if (u->nstaticsessions)
- {
- head_index = u->sessions_per_user_list_head_index;
- head = pool_elt_at_index (tsm->list_pool, head_index);
- elt_index = head->next;
- elt = pool_elt_at_index (tsm->list_pool, elt_index);
- ses_index = elt->value;
- while (ses_index != ~0)
- {
- s = pool_elt_at_index (tsm->sessions, ses_index);
- elt = pool_elt_at_index (tsm->list_pool, elt->next);
- ses_index = elt->value;
-
- if (!(is_lb_session (s)))
- continue;
+ /* *INDENT-OFF* */
+ pool_foreach (s, tsm->sessions, {
+ if (!(is_lb_session (s)))
+ continue;
- if ((s->in2out.addr.as_u32 != match_local->addr.as_u32) ||
- (clib_net_to_host_u16 (s->in2out.port) !=
- match_local->port))
- continue;
+ if ((s->in2out.addr.as_u32 != match_local->addr.as_u32) ||
+ (clib_net_to_host_u16 (s->in2out.port) != match_local->port))
+ continue;
- nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
- nat44_delete_session (sm, s, tsm - sm->per_thread_data);
- }
- }
- }
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
+ nat44_ed_delete_session (sm, s, tsm - sm->per_thread_data, 1);
+ });
+ /* *INDENT-ON* */
pool_put (m->locals, match_local);
}
}
}));
- vec_foreach (ses_index, ses_to_be_removed)
- {
- ses = pool_elt_at_index (tsm->sessions, ses_index[0]);
- nat44_delete_session (sm, ses, tsm - sm->per_thread_data);
- }
+ if (sm->endpoint_dependent){
+ vec_foreach (ses_index, ses_to_be_removed)
+ {
+ ses = pool_elt_at_index (tsm->sessions, ses_index[0]);
+ nat44_ed_delete_session (sm, ses, tsm - sm->per_thread_data, 1);
+ }
+ }else{
+ vec_foreach (ses_index, ses_to_be_removed)
+ {
+ ses = pool_elt_at_index (tsm->sessions, ses_index[0]);
+ nat44_delete_session (sm, ses, tsm - sm->per_thread_data);
+ }
+ }
vec_free (ses_to_be_removed);
}
{
snat_main_t *sm = &snat_main;
snat_session_key_t key;
- snat_user_t *u;
snat_session_t *s;
clib_bihash_kv_16_8_t kv;
f64 now = vlib_time_now (sm->vlib_main);
return;
}
- u = nat_user_get_or_create (sm, in_addr, fib_index, thread_index);
- if (!u)
- return;
-
- s = nat_ed_session_alloc (sm, u, thread_index, now);
+ s = nat_ed_session_alloc (sm, thread_index, now);
if (!s)
return;
s->ext_host_nat_addr.as_u32 = ehn_addr->as_u32;
s->ext_host_nat_port = ehn_port;
}
- user_session_increment (sm, u, snat_is_session_static (s));
switch (vec_len (sm->outside_fibs))
{
case 0:
return VNET_API_ERROR_UNSPECIFIED;
s = pool_elt_at_index (tsm->sessions, value.value);
nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
- nat44_delete_session (sm, s, tsm - sm->per_thread_data);
+ nat44_ed_delete_session (sm, s, tsm - sm->per_thread_data, 1);
return 0;
}
/**
* @brief Allocate NAT endpoint-dependent session
*
- * @param u NAT user
* @param thread_index thread index
*
* @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, f64 now);
+snat_session_t *nat_ed_session_alloc (snat_main_t * sm, u32 thread_index,
+ f64 now);
/**
* @brief Set address and port assignment algorithm for MAP-E CE
return s;
}
+static_always_inline void
+nat44_global_lru_insert (snat_main_per_thread_data_t * tsm,
+ snat_session_t * s, f64 now)
+{
+ dlist_elt_t *lru_list_elt;
+ pool_get (tsm->global_lru_pool, lru_list_elt);
+ s->global_lru_index = lru_list_elt - tsm->global_lru_pool;
+ clib_dlist_addtail (tsm->global_lru_pool, tsm->global_lru_head_index,
+ s->global_lru_index);
+ lru_list_elt->value = s - tsm->sessions;
+ s->last_lru_update = now;
+}
+
static_always_inline snat_session_t *
nat44_session_alloc_new (snat_main_per_thread_data_t * tsm, snat_user_t * u,
f64 now)
s->per_user_list_head_index,
per_user_translation_list_elt - tsm->list_pool);
- dlist_elt_t *lru_list_elt;
- pool_get (tsm->global_lru_pool, lru_list_elt);
- s->global_lru_index = lru_list_elt - tsm->global_lru_pool;
- clib_dlist_addtail (tsm->global_lru_pool, tsm->global_lru_head_index,
- s->global_lru_index);
- lru_list_elt->value = s - tsm->sessions;
- s->last_lru_update = now;
-
+ nat44_global_lru_insert (tsm, s, now);
s->ha_last_refreshed = now;
return s;
}
sm->worker_in2out_cb (&ip, ukey.fib_index, 0));
else
tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
- if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
- return;
- u = pool_elt_at_index (tsm->users, value.value);
- if (!u->nsessions && !u->nstaticsessions)
- return;
-
- head_index = u->sessions_per_user_list_head_index;
- head = pool_elt_at_index (tsm->list_pool, head_index);
- elt_index = head->next;
- elt = pool_elt_at_index (tsm->list_pool, elt_index);
- session_index = elt->value;
- while (session_index != ~0)
+ if (!sm->endpoint_dependent)
{
- s = pool_elt_at_index (tsm->sessions, session_index);
-
- send_nat44_user_session_details (s, reg, mp->context);
-
- elt_index = elt->next;
+ if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
+ return;
+ u = pool_elt_at_index (tsm->users, value.value);
+ if (!u->nsessions && !u->nstaticsessions)
+ return;
+
+ head_index = u->sessions_per_user_list_head_index;
+ head = pool_elt_at_index (tsm->list_pool, head_index);
+ elt_index = head->next;
elt = pool_elt_at_index (tsm->list_pool, elt_index);
session_index = elt->value;
+ while (session_index != ~0)
+ {
+ s = pool_elt_at_index (tsm->sessions, session_index);
+
+ send_nat44_user_session_details (s, reg, mp->context);
+
+ elt_index = elt->next;
+ elt = pool_elt_at_index (tsm->list_pool, elt_index);
+ session_index = elt->value;
+ }
+ }
+ else
+ {
+ /* *INDENT-OFF* */
+ pool_foreach (s, tsm->sessions, {
+ if (s->in2out.addr.as_u32 == ukey.addr.as_u32)
+ {
+ send_nat44_user_session_details (s, reg, mp->context);
+ }
+ });
+ /* *INDENT-ON* */
}
}
vec_add1 (ses_to_be_removed, s - tsm->sessions);
}
}));
- vec_foreach (ses_index, ses_to_be_removed)
- {
- s = pool_elt_at_index(tsm->sessions, ses_index[0]);
- nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
- nat44_delete_session (sm, s, tsm - sm->per_thread_data);
- }
+ if(sm->endpoint_dependent){
+ vec_foreach (ses_index, ses_to_be_removed)
+ {
+ s = pool_elt_at_index(tsm->sessions, ses_index[0]);
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
+ nat44_ed_delete_session (sm, s, tsm - sm->per_thread_data, 1);
+ }
+ }else{
+ vec_foreach (ses_index, ses_to_be_removed)
+ {
+ s = pool_elt_at_index(tsm->sessions, ses_index[0]);
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
+ nat44_delete_session (sm, s, tsm - sm->per_thread_data);
+ }
+ }
vec_free (ses_to_be_removed);
}
/* *INDENT-ON* */
}
always_inline void
-nat44_delete_session_internal (snat_main_t * sm, snat_session_t * ses,
- u32 thread_index, int global_lru_delete
- /* delete from global LRU list */ )
+nat44_delete_session (snat_main_t * sm, snat_session_t * ses,
+ u32 thread_index)
{
snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
thread_index);
clib_dlist_remove (tsm->list_pool, ses->per_user_index);
pool_put_index (tsm->list_pool, ses->per_user_index);
- if (global_lru_delete)
- {
- clib_dlist_remove (tsm->global_lru_pool, ses->global_lru_index);
- }
+ clib_dlist_remove (tsm->global_lru_pool, ses->global_lru_index);
pool_put_index (tsm->global_lru_pool, ses->global_lru_index);
pool_put (tsm->sessions, ses);
vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
}
}
-always_inline void
-nat44_delete_session (snat_main_t * sm, snat_session_t * ses,
- u32 thread_index)
-{
- return nat44_delete_session_internal (sm, ses, thread_index, 1);
-}
-
always_inline void
nat44_ed_delete_session (snat_main_t * sm, snat_session_t * ses,
u32 thread_index, int global_lru_delete
/* delete from global LRU list */ )
{
- return nat44_delete_session_internal (sm, ses, thread_index,
- global_lru_delete);
+ snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
+ thread_index);
+
+ if (global_lru_delete)
+ {
+ clib_dlist_remove (tsm->global_lru_pool, ses->global_lru_index);
+ }
+ pool_put_index (tsm->global_lru_pool, ses->global_lru_index);
+ pool_put (tsm->sessions, ses);
+ vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
+ pool_elts (tsm->sessions));
+
}
/** \brief Set TCP session state.
/* don't update too often - timeout is in a magnitude of seconds anyway */
if (s->last_heard > s->last_lru_update + 1)
{
- clib_dlist_remove (sm->per_thread_data[thread_index].list_pool,
- s->per_user_index);
- clib_dlist_addtail (sm->per_thread_data[thread_index].list_pool,
- s->per_user_list_head_index, s->per_user_index);
+ if (!sm->endpoint_dependent)
+ {
+ clib_dlist_remove (sm->per_thread_data[thread_index].list_pool,
+ s->per_user_index);
+ clib_dlist_addtail (sm->per_thread_data[thread_index].list_pool,
+ s->per_user_list_head_index, s->per_user_index);
+ }
clib_dlist_remove (sm->per_thread_data[thread_index].global_lru_pool,
s->global_lru_index);
snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
&s->out2in);
delete:
- nat44_delete_session (sm, s, ctx->thread_index);
+ nat44_ed_delete_session (sm, s, ctx->thread_index, 1);
return 1;
}
lb_nat_type_t lb_nat, f64 now)
{
snat_session_t *s;
- snat_user_t *u;
ip4_header_t *ip;
udp_header_t *udp;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
return 0;
}
- u = nat_user_get_or_create (sm, &l_key.addr, l_key.fib_index, thread_index);
- if (!u)
- {
- b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
- nat_elog_warn ("create NAT user failed");
- return 0;
- }
-
- s = nat_ed_session_alloc (sm, u, thread_index, now);
+ s = nat_ed_session_alloc (sm, thread_index, now);
if (!s)
{
b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_USER_SESS_EXCEEDED];
- nat44_delete_user_with_no_session (sm, u, thread_index);
nat_elog_warn ("create NAT session failed");
return 0;
}
s->out2in = e_key;
s->in2out = l_key;
s->in2out.protocol = s->out2in.protocol;
- user_session_increment (sm, u, 1);
/* Add to lookup tables */
make_ed_kv (&kv, &e_key.addr, &s->ext_host_addr, ip->protocol,
tsm->snat_thread_index))
{
b->error = node->errors[NAT_OUT2IN_ED_ERROR_OUT_OF_PORTS];
- nat44_delete_session (sm, s, thread_index);
+ nat44_ed_delete_session (sm, s, thread_index, 1);
if (clib_bihash_add_del_16_8 (&tsm->out2in_ed, &kv, 0))
nat_elog_notice ("out2in-ed key del failed");
return 0;
nat_ed_ses_key_t key;
clib_bihash_kv_16_8_t kv, value;
udp_header_t *udp;
- snat_user_t *u;
snat_session_t *s = 0;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
f64 now = vlib_time_now (sm->vlib_main);
if (PREDICT_FALSE (nat44_maximum_sessions_exceeded (sm, thread_index)))
return;
- u = nat_user_get_or_create (sm, &ip->dst_address, sm->inside_fib_index,
- thread_index);
- if (!u)
- {
- nat_elog_warn ("create NAT user failed");
- return;
- }
-
- s = nat_ed_session_alloc (sm, u, thread_index, now);
+ s = nat_ed_session_alloc (sm, thread_index, now);
if (!s)
{
- nat44_delete_user_with_no_session (sm, u, thread_index);
nat_elog_warn ("create NAT session failed");
return;
}
}
s->out2in.fib_index = 0;
s->in2out = s->out2in;
- user_session_increment (sm, u, 0);
kv.value = s - tsm->sessions;
if (clib_bihash_add_del_16_8 (&tsm->in2out_ed, &kv, 1))
ip_csum_t sum;
snat_session_t *s;
snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- snat_user_t *u;
old_addr = ip->dst_address.as_u32;
new_addr = ip->dst_address.as_u32 = m->local_addr.as_u32;
- u = nat_user_get_or_create (sm, &m->local_addr, m->fib_index,
- thread_index);
- if (!u)
- {
- b->error = node->errors[NAT_OUT2IN_ED_ERROR_CANNOT_CREATE_USER];
- nat_elog_warn ("create NAT user failed");
- return 0;
- }
-
/* Create a new session */
- s = nat_ed_session_alloc (sm, u, thread_index, now);
+ s = nat_ed_session_alloc (sm, thread_index, now);
if (!s)
{
b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_USER_SESS_EXCEEDED];
- nat44_delete_user_with_no_session (sm, u, thread_index);
nat_elog_warn ("create NAT session failed");
return 0;
}
s->in2out.addr.as_u32 = new_addr;
s->in2out.fib_index = m->fib_index;
s->in2out.port = s->out2in.port = ip->protocol;
- user_session_increment (sm, u, 1);
/* Add to lookup tables */
s_kv.value = s - tsm->sessions;
{
// session is closed, go slow path
nat_free_session_data (sm, s0, thread_index, 0);
- nat44_delete_session (sm, s0, thread_index);
+ nat44_ed_delete_session (sm, s0, thread_index, 1);
next0 = NAT_NEXT_OUT2IN_ED_SLOW_PATH;
goto trace0;
}
if (s0->tcp_close_timestamp && now >= s0->tcp_close_timestamp)
{
nat_free_session_data (sm, s0, thread_index, 0);
- nat44_delete_session (sm, s0, thread_index);
+ nat44_ed_delete_session (sm, s0, thread_index, 1);
s0 = NULL;
}
}
'/err/nat44-ed-out2in/good out2in packets processed')
self.assertEqual(err - totaln, 3)
- users = self.statistics.get_counter('/nat44/total-users')
- self.assertEqual(users[0][0], 1)
sessions = self.statistics.get_counter('/nat44/total-sessions')
self.assertEqual(sessions[0][0], 3)
'/err/nat44-ed-out2in/good out2in packets processed')
self.assertEqual(err - totaln, 3)
- users = self.statistics.get_counter('/nat44/total-users')
- self.assertEqual(users[0][0], 1)
sessions = self.statistics.get_counter('/nat44/total-sessions')
self.assertEqual(sessions[0][0], 3)
self.pg_start()
self.pg1.get_capture(1)
- nsessions = 0
- users = self.vapi.nat44_user_dump()
- self.assertEqual(len(users), 1)
- self.assertEqual(str(users[0].ip_address),
- self.pg0.remote_ip4)
- self.assertEqual(users[0].nsessions, 1)
-
def test_syslog_sess(self):
""" Test syslog session creation and deletion """
self.vapi.syslog_set_filter(