return;
/* log NAT event */
- snat_ipfix_logging_nat44_ses_delete (s->in2out.addr.as_u32,
+ snat_ipfix_logging_nat44_ses_delete (thread_index,
+ s->in2out.addr.as_u32,
s->out2in.addr.as_u32,
s->in2out.protocol,
s->in2out.port,
/* add user */
if (clib_bihash_add_del_8_8 (&tsm->user_hash, &kv, 1))
nat_log_warn ("user_hash keay add failed");
+
+ vlib_set_simple_counter (&sm->total_users, thread_index, 0,
+ pool_elts (tsm->users));
}
else
{
per_user_translation_list_elt - tsm->list_pool);
s->user_index = u - tsm->users;
+ vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
+ pool_elts (tsm->sessions));
}
return s;
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);
+ (thread_index, sm->max_translations_per_user, u->addr.as_u32);
return 0;
}
else
s->per_user_list_head_index,
per_user_translation_list_elt - tsm->list_pool);
}
+
+ vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
+ pool_elts (tsm->sessions));
}
return s;
}));
/* *INDENT-ON* */
+ ASSERT (vec_len (locals) > 1);
+
local = pool_elt_at_index (m->locals, locals[0]);
local->prefix = local->probability;
for (i = 1; i < vec_len (locals); i++)
{
if (is_del)
{
- outside_fib->refcount--;
+ outside_fib->refcount--;
if (!outside_fib->refcount)
vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs);
}
snat_interface_t *i;
snat_address_t *ap;
snat_static_mapping_t *m;
+ nat_outside_fib_t *outside_fib;
+ u32 fib_index = fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4,
+ sw_if_index);
+
if (sm->deterministic ||
(sm->static_mapping_only && !(sm->static_mapping_connection_tracking)))
}));
/* *INDENT-ON* */
+ if (!is_inside)
+ {
+ /* *INDENT-OFF* */
+ vec_foreach (outside_fib, sm->outside_fibs)
+ {
+ if (outside_fib->fib_index == fib_index)
+ {
+ if (is_del)
+ {
+ outside_fib->refcount--;
+ if (!outside_fib->refcount)
+ vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs);
+ }
+ else
+ outside_fib->refcount++;
+ goto feature_set;
+ }
+ }
+ /* *INDENT-ON* */
+ if (!is_del)
+ {
+ vec_add2 (sm->outside_fibs, outside_fib, 1);
+ outside_fib->refcount = 1;
+ outside_fib->fib_index = fib_index;
+ }
+ }
+
+feature_set:
if (is_inside)
{
if (sm->endpoint_dependent)
return 0;
}
+static void
+snat_update_outside_fib (u32 sw_if_index, u32 new_fib_index,
+ u32 old_fib_index)
+{
+ snat_main_t *sm = &snat_main;
+ nat_outside_fib_t *outside_fib;
+ snat_interface_t *i;
+ u8 is_add = 1;
+
+ if (new_fib_index == old_fib_index)
+ return;
+
+ if (!vec_len (sm->outside_fibs))
+ return;
+
+ pool_foreach (i, sm->interfaces, (
+ {
+ if (i->sw_if_index == sw_if_index)
+ {
+ if (!(nat_interface_is_outside (i)))
+ return;}
+ }
+ ));
+ vec_foreach (outside_fib, sm->outside_fibs)
+ {
+ if (outside_fib->fib_index == old_fib_index)
+ {
+ outside_fib->refcount--;
+ if (!outside_fib->refcount)
+ vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs);
+ break;
+ }
+ }
+
+ vec_foreach (outside_fib, sm->outside_fibs)
+ {
+ if (outside_fib->fib_index == new_fib_index)
+ {
+ outside_fib->refcount++;
+ is_add = 0;
+ break;
+ }
+ }
+
+ if (is_add)
+ {
+ vec_add2 (sm->outside_fibs, outside_fib, 1);
+ outside_fib->refcount = 1;
+ outside_fib->fib_index = new_fib_index;
+ }
+}
+
+static void
+snat_ip4_table_bind (ip4_main_t * im,
+ uword opaque,
+ u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
+{
+ snat_update_outside_fib (sw_if_index, new_fib_index, old_fib_index);
+}
static void
snat_ip4_add_del_interface_address_cb (ip4_main_t * im,
nat_dpo_module_init ();
+ /* Init counters */
+ sm->total_users.name = "total-users";
+ sm->total_users.stat_segment_name = "/nat44/total-users";
+ vlib_validate_simple_counter (&sm->total_users, 0);
+ vlib_zero_simple_counter (&sm->total_users, 0);
+ sm->total_sessions.name = "total-sessions";
+ sm->total_sessions.stat_segment_name = "/nat44/total-sessions";
+ vlib_validate_simple_counter (&sm->total_sessions, 0);
+ vlib_zero_simple_counter (&sm->total_sessions, 0);
+
/* Init IPFIX logging */
snat_ipfix_logging_init (vm);
nat66_init ();
+ ip4_table_bind_callback_t cbt4 = {
+ .function = snat_ip4_table_bind,
+ };
+ vec_add1 (ip4_main.table_bind_callbacks, cbt4);
+
/* Init virtual fragmenentation reassembly */
return nat_reass_init (vm);
}
}
/* Totally out of translations to use... */
- snat_ipfix_logging_addresses_exhausted (0);
+ snat_ipfix_logging_addresses_exhausted (thread_index, 0);
return 1;
}
exhausted:
/* Totally out of translations to use... */
- snat_ipfix_logging_addresses_exhausted (0);
+ snat_ipfix_logging_addresses_exhausted (thread_index, 0);
return 1;
}
exhausted:
/* Totally out of translations to use... */
- snat_ipfix_logging_addresses_exhausted (0);
+ snat_ipfix_logging_addresses_exhausted (thread_index, 0);
return 1;
}
if (PREDICT_FALSE (nat_reass_is_drop_frag (0)))
return vlib_get_thread_index ();
- if (PREDICT_TRUE (!ip4_is_first_fragment (ip0)))
- {
- nat_reass_ip4_t *reass;
+ nat_reass_ip4_t *reass;
+ reass = nat_ip4_reass_find (ip0->src_address, ip0->dst_address,
+ ip0->fragment_id, ip0->protocol);
- reass = nat_ip4_reass_find (ip0->src_address, ip0->dst_address,
- ip0->fragment_id, ip0->protocol);
+ if (reass && (reass->thread_index != (u32) ~ 0))
+ return reass->thread_index;
- if (reass && (reass->thread_index != (u32) ~ 0))
- return reass->thread_index;
- else
- return vlib_get_thread_index ();
+ if (ip4_is_first_fragment (ip0))
+ {
+ reass =
+ nat_ip4_reass_create (ip0->src_address, ip0->dst_address,
+ ip0->fragment_id, ip0->protocol);
+ if (!reass)
+ goto no_reass;
+
+ if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
+ {
+ m_key.addr = ip0->dst_address;
+ m_key.port = clib_net_to_host_u16 (port);
+ m_key.protocol = proto;
+ m_key.fib_index = rx_fib_index0;
+ kv.key = m_key.as_u64;
+ if (!clib_bihash_search_8_8
+ (&sm->static_mapping_by_external, &kv, &value))
+ {
+ m = pool_elt_at_index (sm->static_mappings, value.value);
+ reass->thread_index = m->workers[0];
+ return reass->thread_index;
+ }
+ }
+ reass->thread_index = sm->first_worker_index;
+ reass->thread_index +=
+ sm->workers[(clib_net_to_host_u16 (port) - 1024) /
+ sm->port_per_thread];
+ return reass->thread_index;
}
+ else
+ return vlib_get_thread_index ();
}
+no_reass:
/* unknown protocol */
if (PREDICT_FALSE (proto == ~0))
{